19066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project/*
29066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Copyright (C) 2006 The Android Open Source Project
39066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project *
49066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Licensed under the Apache License, Version 2.0 (the "License");
59066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * you may not use this file except in compliance with the License.
69066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * You may obtain a copy of the License at
79066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project *
89066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project *      http://www.apache.org/licenses/LICENSE-2.0
99066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project *
109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Unless required by applicable law or agreed to in writing, software
119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * distributed under the License is distributed on an "AS IS" BASIS,
129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * See the License for the specific language governing permissions and
149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * limitations under the License.
159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */
169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectpackage android.widget;
189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
196518ad760f98a0aa5db8c49ce1564bf5907a2c15Svetoslav Ganovimport com.android.internal.R;
206518ad760f98a0aa5db8c49ce1564bf5907a2c15Svetoslav Ganov
219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.content.Context;
229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.content.res.TypedArray;
239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.graphics.Bitmap;
249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.graphics.BitmapShader;
259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.graphics.Canvas;
269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.graphics.Rect;
27b25ffffc3157c4c471c326147be750f4ebec456aSteve Howardimport android.graphics.Shader;
28b25ffffc3157c4c471c326147be750f4ebec456aSteve Howardimport android.graphics.drawable.Animatable;
299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.graphics.drawable.AnimationDrawable;
309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.graphics.drawable.BitmapDrawable;
319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.graphics.drawable.ClipDrawable;
329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.graphics.drawable.Drawable;
339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.graphics.drawable.LayerDrawable;
349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.graphics.drawable.ShapeDrawable;
359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.graphics.drawable.StateListDrawable;
369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.graphics.drawable.shapes.RoundRectShape;
379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.graphics.drawable.shapes.Shape;
38b25ffffc3157c4c471c326147be750f4ebec456aSteve Howardimport android.os.Parcel;
39b25ffffc3157c4c471c326147be750f4ebec456aSteve Howardimport android.os.Parcelable;
409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.util.AttributeSet;
41abae2a1b891772d36d8f781adfcc8969e551691fSvetoslav Ganovimport android.util.Pools.SynchronizedPool;
429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.view.Gravity;
43b25ffffc3157c4c471c326147be750f4ebec456aSteve Howardimport android.view.RemotableViewMethod;
449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.view.View;
457a36788f4a69b3ddaf8fb8e250e1a13bee7238faSteve Zeiglerimport android.view.ViewDebug;
466518ad760f98a0aa5db8c49ce1564bf5907a2c15Svetoslav Ganovimport android.view.accessibility.AccessibilityEvent;
476518ad760f98a0aa5db8c49ce1564bf5907a2c15Svetoslav Ganovimport android.view.accessibility.AccessibilityManager;
488a78fd4d9572dff95432fcc4ba0e87563415b728Svetoslav Ganovimport android.view.accessibility.AccessibilityNodeInfo;
499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.view.animation.AlphaAnimation;
509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.view.animation.Animation;
519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.view.animation.AnimationUtils;
529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.view.animation.Interpolator;
539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.view.animation.LinearInterpolator;
549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.view.animation.Transformation;
559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.widget.RemoteViews.RemoteView;
569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
57a050663feb6309c63867abd746cdf97388e289a4Adam Powellimport java.util.ArrayList;
58a050663feb6309c63867abd746cdf97388e289a4Adam Powell
599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project/**
619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <p>
629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Visual indicator of progress in some operation.  Displays a bar to the user
639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * representing how far the operation has progressed; the application can
649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * change the amount of progress (modifying the length of the bar) as it moves
659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * forward.  There is also a secondary progress displayable on a progress bar
669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * which is useful for displaying intermediate progress, such as the buffer
679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * level during a streaming playback progress bar.
689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * </p>
699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project *
709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <p>
719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * A progress bar can also be made indeterminate. In indeterminate mode, the
7242f139c0696e2988adb24048fab998695e95fba3Scott Main * progress bar shows a cyclic animation without an indication of progress. This mode is used by
7342f139c0696e2988adb24048fab998695e95fba3Scott Main * applications when the length of the task is unknown. The indeterminate progress bar can be either
7442f139c0696e2988adb24048fab998695e95fba3Scott Main * a spinning wheel or a horizontal bar.
759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * </p>
769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project *
779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <p>The following code example shows how a progress bar can be used from
789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * a worker thread to update the user interface to notify the user of progress:
799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * </p>
809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project *
8142f139c0696e2988adb24048fab998695e95fba3Scott Main * <pre>
829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * public class MyActivity extends Activity {
839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project *     private static final int PROGRESS = 0x1;
849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project *
859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project *     private ProgressBar mProgress;
869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project *     private int mProgressStatus = 0;
879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project *
889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project *     private Handler mHandler = new Handler();
899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project *
909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project *     protected void onCreate(Bundle icicle) {
919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project *         super.onCreate(icicle);
929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project *
939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project *         setContentView(R.layout.progressbar_activity);
949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project *
959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project *         mProgress = (ProgressBar) findViewById(R.id.progress_bar);
969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project *
979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project *         // Start lengthy operation in a background thread
989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project *         new Thread(new Runnable() {
999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project *             public void run() {
10042f139c0696e2988adb24048fab998695e95fba3Scott Main *                 while (mProgressStatus &lt; 100) {
1019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project *                     mProgressStatus = doWork();
1029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project *
1039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project *                     // Update the progress bar
1049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project *                     mHandler.post(new Runnable() {
1059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project *                         public void run() {
1069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project *                             mProgress.setProgress(mProgressStatus);
1079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project *                         }
1089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project *                     });
1099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project *                 }
1109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project *             }
1119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project *         }).start();
1129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project *     }
11342f139c0696e2988adb24048fab998695e95fba3Scott Main * }</pre>
11442f139c0696e2988adb24048fab998695e95fba3Scott Main *
11542f139c0696e2988adb24048fab998695e95fba3Scott Main * <p>To add a progress bar to a layout file, you can use the {@code &lt;ProgressBar&gt;} element.
11642f139c0696e2988adb24048fab998695e95fba3Scott Main * By default, the progress bar is a spinning wheel (an indeterminate indicator). To change to a
11742f139c0696e2988adb24048fab998695e95fba3Scott Main * horizontal progress bar, apply the {@link android.R.style#Widget_ProgressBar_Horizontal
11842f139c0696e2988adb24048fab998695e95fba3Scott Main * Widget.ProgressBar.Horizontal} style, like so:</p>
11942f139c0696e2988adb24048fab998695e95fba3Scott Main *
12042f139c0696e2988adb24048fab998695e95fba3Scott Main * <pre>
12142f139c0696e2988adb24048fab998695e95fba3Scott Main * &lt;ProgressBar
12242f139c0696e2988adb24048fab998695e95fba3Scott Main *     style="@android:style/Widget.ProgressBar.Horizontal"
12342f139c0696e2988adb24048fab998695e95fba3Scott Main *     ... /&gt;</pre>
12442f139c0696e2988adb24048fab998695e95fba3Scott Main *
12542f139c0696e2988adb24048fab998695e95fba3Scott Main * <p>If you will use the progress bar to show real progress, you must use the horizontal bar. You
12642f139c0696e2988adb24048fab998695e95fba3Scott Main * can then increment the  progress with {@link #incrementProgressBy incrementProgressBy()} or
12742f139c0696e2988adb24048fab998695e95fba3Scott Main * {@link #setProgress setProgress()}. By default, the progress bar is full when it reaches 100. If
12842f139c0696e2988adb24048fab998695e95fba3Scott Main * necessary, you can adjust the maximum value (the value for a full bar) using the {@link
12942f139c0696e2988adb24048fab998695e95fba3Scott Main * android.R.styleable#ProgressBar_max android:max} attribute. Other attributes available are listed
13042f139c0696e2988adb24048fab998695e95fba3Scott Main * below.</p>
13142f139c0696e2988adb24048fab998695e95fba3Scott Main *
13242f139c0696e2988adb24048fab998695e95fba3Scott Main * <p>Another common style to apply to the progress bar is {@link
13342f139c0696e2988adb24048fab998695e95fba3Scott Main * android.R.style#Widget_ProgressBar_Small Widget.ProgressBar.Small}, which shows a smaller
13442f139c0696e2988adb24048fab998695e95fba3Scott Main * version of the spinning wheel&mdash;useful when waiting for content to load.
13542f139c0696e2988adb24048fab998695e95fba3Scott Main * For example, you can insert this kind of progress bar into your default layout for
13642f139c0696e2988adb24048fab998695e95fba3Scott Main * a view that will be populated by some content fetched from the Internet&mdash;the spinning wheel
13742f139c0696e2988adb24048fab998695e95fba3Scott Main * appears immediately and when your application receives the content, it replaces the progress bar
13842f139c0696e2988adb24048fab998695e95fba3Scott Main * with the loaded content. For example:</p>
13942f139c0696e2988adb24048fab998695e95fba3Scott Main *
14042f139c0696e2988adb24048fab998695e95fba3Scott Main * <pre>
14142f139c0696e2988adb24048fab998695e95fba3Scott Main * &lt;LinearLayout
14242f139c0696e2988adb24048fab998695e95fba3Scott Main *     android:orientation="horizontal"
14342f139c0696e2988adb24048fab998695e95fba3Scott Main *     ... &gt;
14442f139c0696e2988adb24048fab998695e95fba3Scott Main *     &lt;ProgressBar
14542f139c0696e2988adb24048fab998695e95fba3Scott Main *         android:layout_width="wrap_content"
14642f139c0696e2988adb24048fab998695e95fba3Scott Main *         android:layout_height="wrap_content"
14742f139c0696e2988adb24048fab998695e95fba3Scott Main *         style="@android:style/Widget.ProgressBar.Small"
14842f139c0696e2988adb24048fab998695e95fba3Scott Main *         android:layout_marginRight="5dp" /&gt;
14942f139c0696e2988adb24048fab998695e95fba3Scott Main *     &lt;TextView
15042f139c0696e2988adb24048fab998695e95fba3Scott Main *         android:layout_width="wrap_content"
15142f139c0696e2988adb24048fab998695e95fba3Scott Main *         android:layout_height="wrap_content"
15242f139c0696e2988adb24048fab998695e95fba3Scott Main *         android:text="@string/loading" /&gt;
15342f139c0696e2988adb24048fab998695e95fba3Scott Main * &lt;/LinearLayout&gt;</pre>
15442f139c0696e2988adb24048fab998695e95fba3Scott Main *
15542f139c0696e2988adb24048fab998695e95fba3Scott Main * <p>Other progress bar styles provided by the system include:</p>
15642f139c0696e2988adb24048fab998695e95fba3Scott Main * <ul>
15742f139c0696e2988adb24048fab998695e95fba3Scott Main * <li>{@link android.R.style#Widget_ProgressBar_Horizontal Widget.ProgressBar.Horizontal}</li>
15842f139c0696e2988adb24048fab998695e95fba3Scott Main * <li>{@link android.R.style#Widget_ProgressBar_Small Widget.ProgressBar.Small}</li>
15942f139c0696e2988adb24048fab998695e95fba3Scott Main * <li>{@link android.R.style#Widget_ProgressBar_Large Widget.ProgressBar.Large}</li>
16042f139c0696e2988adb24048fab998695e95fba3Scott Main * <li>{@link android.R.style#Widget_ProgressBar_Inverse Widget.ProgressBar.Inverse}</li>
16142f139c0696e2988adb24048fab998695e95fba3Scott Main * <li>{@link android.R.style#Widget_ProgressBar_Small_Inverse
16242f139c0696e2988adb24048fab998695e95fba3Scott Main * Widget.ProgressBar.Small.Inverse}</li>
16342f139c0696e2988adb24048fab998695e95fba3Scott Main * <li>{@link android.R.style#Widget_ProgressBar_Large_Inverse
16442f139c0696e2988adb24048fab998695e95fba3Scott Main * Widget.ProgressBar.Large.Inverse}</li>
16542f139c0696e2988adb24048fab998695e95fba3Scott Main * </ul>
16642f139c0696e2988adb24048fab998695e95fba3Scott Main * <p>The "inverse" styles provide an inverse color scheme for the spinner, which may be necessary
16742f139c0696e2988adb24048fab998695e95fba3Scott Main * if your application uses a light colored theme (a white background).</p>
1689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project *
1699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <p><strong>XML attributes</b></strong>
1709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <p>
1719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * See {@link android.R.styleable#ProgressBar ProgressBar Attributes},
1729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * {@link android.R.styleable#View View Attributes}
1739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * </p>
1749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project *
17542f139c0696e2988adb24048fab998695e95fba3Scott Main * @attr ref android.R.styleable#ProgressBar_animationResolution
17642f139c0696e2988adb24048fab998695e95fba3Scott Main * @attr ref android.R.styleable#ProgressBar_indeterminate
17742f139c0696e2988adb24048fab998695e95fba3Scott Main * @attr ref android.R.styleable#ProgressBar_indeterminateBehavior
17842f139c0696e2988adb24048fab998695e95fba3Scott Main * @attr ref android.R.styleable#ProgressBar_indeterminateDrawable
17942f139c0696e2988adb24048fab998695e95fba3Scott Main * @attr ref android.R.styleable#ProgressBar_indeterminateDuration
18042f139c0696e2988adb24048fab998695e95fba3Scott Main * @attr ref android.R.styleable#ProgressBar_indeterminateOnly
18142f139c0696e2988adb24048fab998695e95fba3Scott Main * @attr ref android.R.styleable#ProgressBar_interpolator
18242f139c0696e2988adb24048fab998695e95fba3Scott Main * @attr ref android.R.styleable#ProgressBar_max
18342f139c0696e2988adb24048fab998695e95fba3Scott Main * @attr ref android.R.styleable#ProgressBar_maxHeight
18442f139c0696e2988adb24048fab998695e95fba3Scott Main * @attr ref android.R.styleable#ProgressBar_maxWidth
18542f139c0696e2988adb24048fab998695e95fba3Scott Main * @attr ref android.R.styleable#ProgressBar_minHeight
18642f139c0696e2988adb24048fab998695e95fba3Scott Main * @attr ref android.R.styleable#ProgressBar_minWidth
187b40c1fdaee6e6cabea8d1ed78f56d5b6bd133cfbScott Main * @attr ref android.R.styleable#ProgressBar_mirrorForRtl
18842f139c0696e2988adb24048fab998695e95fba3Scott Main * @attr ref android.R.styleable#ProgressBar_progress
18942f139c0696e2988adb24048fab998695e95fba3Scott Main * @attr ref android.R.styleable#ProgressBar_progressDrawable
19042f139c0696e2988adb24048fab998695e95fba3Scott Main * @attr ref android.R.styleable#ProgressBar_secondaryProgress
1919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */
1929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project@RemoteView
1939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectpublic class ProgressBar extends View {
1949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private static final int MAX_LEVEL = 10000;
1956518ad760f98a0aa5db8c49ce1564bf5907a2c15Svetoslav Ganov    private static final int TIMEOUT_SEND_ACCESSIBILITY_EVENT = 200;
1969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    int mMinWidth;
1989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    int mMaxWidth;
1999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    int mMinHeight;
2009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    int mMaxHeight;
2019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private int mProgress;
2039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private int mSecondaryProgress;
2049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private int mMax;
2059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private int mBehavior;
2079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private int mDuration;
2089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private boolean mIndeterminate;
2099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private boolean mOnlyIndeterminate;
2109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private Transformation mTransformation;
2119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private AlphaAnimation mAnimation;
212ab4c4f4ff73e66b7767640dbe6d4115237c48242Romain Guy    private boolean mHasAnimation;
2139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private Drawable mIndeterminateDrawable;
2149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private Drawable mProgressDrawable;
2159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private Drawable mCurrentDrawable;
2169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    Bitmap mSampleTile;
2179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private boolean mNoInvalidate;
2189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private Interpolator mInterpolator;
2199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private RefreshProgressRunnable mRefreshProgressRunnable;
2209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private long mUiThreadId;
2219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private boolean mShouldStartAnimationDrawable;
2229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private boolean mInDrawing;
224a050663feb6309c63867abd746cdf97388e289a4Adam Powell    private boolean mAttached;
225a050663feb6309c63867abd746cdf97388e289a4Adam Powell    private boolean mRefreshIsPosted;
226a050663feb6309c63867abd746cdf97388e289a4Adam Powell
2272b378cde411b551464f0040e935692073cfb119fFabrice Di Meglio    boolean mMirrorForRtl = false;
2282b378cde411b551464f0040e935692073cfb119fFabrice Di Meglio
229a050663feb6309c63867abd746cdf97388e289a4Adam Powell    private final ArrayList<RefreshData> mRefreshData = new ArrayList<RefreshData>();
2309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2316518ad760f98a0aa5db8c49ce1564bf5907a2c15Svetoslav Ganov    private AccessibilityEventSender mAccessibilityEventSender;
2326518ad760f98a0aa5db8c49ce1564bf5907a2c15Svetoslav Ganov
2339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
2349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Create a new progress bar with range 0...100 and initial progress of 0.
2359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param context the application environment
2369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
2379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public ProgressBar(Context context) {
2389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        this(context, null);
2399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
2409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public ProgressBar(Context context, AttributeSet attrs) {
2429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        this(context, attrs, com.android.internal.R.attr.progressBarStyle);
2439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
2449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public ProgressBar(Context context, AttributeSet attrs, int defStyle) {
2466af97e1c20df4d7010fafd7059c95d9b4113e4a6Adam Powell        this(context, attrs, defStyle, 0);
2476af97e1c20df4d7010fafd7059c95d9b4113e4a6Adam Powell    }
2486af97e1c20df4d7010fafd7059c95d9b4113e4a6Adam Powell
2496af97e1c20df4d7010fafd7059c95d9b4113e4a6Adam Powell    /**
2506af97e1c20df4d7010fafd7059c95d9b4113e4a6Adam Powell     * @hide
2516af97e1c20df4d7010fafd7059c95d9b4113e4a6Adam Powell     */
2526af97e1c20df4d7010fafd7059c95d9b4113e4a6Adam Powell    public ProgressBar(Context context, AttributeSet attrs, int defStyle, int styleRes) {
2539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        super(context, attrs, defStyle);
2549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        mUiThreadId = Thread.currentThread().getId();
2559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        initProgressBar();
2569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        TypedArray a =
2586af97e1c20df4d7010fafd7059c95d9b4113e4a6Adam Powell            context.obtainStyledAttributes(attrs, R.styleable.ProgressBar, defStyle, styleRes);
2599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        mNoInvalidate = true;
2619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        Drawable drawable = a.getDrawable(R.styleable.ProgressBar_progressDrawable);
2639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (drawable != null) {
2649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            drawable = tileify(drawable, false);
2658d21bdb90573ec48491c44eca312c162e262298dRomain Guy            // Calling this method can set mMaxHeight, make sure the corresponding
2668d21bdb90573ec48491c44eca312c162e262298dRomain Guy            // XML attribute for mMaxHeight is read after calling this method
2679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            setProgressDrawable(drawable);
2689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
2699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        mDuration = a.getInt(R.styleable.ProgressBar_indeterminateDuration, mDuration);
2729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        mMinWidth = a.getDimensionPixelSize(R.styleable.ProgressBar_minWidth, mMinWidth);
2749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        mMaxWidth = a.getDimensionPixelSize(R.styleable.ProgressBar_maxWidth, mMaxWidth);
2759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        mMinHeight = a.getDimensionPixelSize(R.styleable.ProgressBar_minHeight, mMinHeight);
2769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        mMaxHeight = a.getDimensionPixelSize(R.styleable.ProgressBar_maxHeight, mMaxHeight);
2779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        mBehavior = a.getInt(R.styleable.ProgressBar_indeterminateBehavior, mBehavior);
2799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
28072b1f379d5c97c8ff31d2201e78215af777d6bdaJean-Baptiste Queru        final int resID = a.getResourceId(
28172b1f379d5c97c8ff31d2201e78215af777d6bdaJean-Baptiste Queru                com.android.internal.R.styleable.ProgressBar_interpolator,
28272b1f379d5c97c8ff31d2201e78215af777d6bdaJean-Baptiste Queru                android.R.anim.linear_interpolator); // default to linear interpolator
2839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (resID > 0) {
2849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            setInterpolator(context, resID);
28572b1f379d5c97c8ff31d2201e78215af777d6bdaJean-Baptiste Queru        }
2869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        setMax(a.getInt(R.styleable.ProgressBar_max, mMax));
2889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        setProgress(a.getInt(R.styleable.ProgressBar_progress, mProgress));
2909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        setSecondaryProgress(
2929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                a.getInt(R.styleable.ProgressBar_secondaryProgress, mSecondaryProgress));
2939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        drawable = a.getDrawable(R.styleable.ProgressBar_indeterminateDrawable);
2959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (drawable != null) {
2969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            drawable = tileifyIndeterminate(drawable);
2979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            setIndeterminateDrawable(drawable);
2989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
2999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
3009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        mOnlyIndeterminate = a.getBoolean(
3019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                R.styleable.ProgressBar_indeterminateOnly, mOnlyIndeterminate);
3029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
3039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        mNoInvalidate = false;
3049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
3059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        setIndeterminate(mOnlyIndeterminate || a.getBoolean(
3069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                R.styleable.ProgressBar_indeterminate, mIndeterminate));
3079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
3082b378cde411b551464f0040e935692073cfb119fFabrice Di Meglio        mMirrorForRtl = a.getBoolean(R.styleable.ProgressBar_mirrorForRtl, mMirrorForRtl);
3092b378cde411b551464f0040e935692073cfb119fFabrice Di Meglio
3109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        a.recycle();
3116a1846a084fd09b3ade3fa80a49c29dcbe7cd60dSvetoslav
3126a1846a084fd09b3ade3fa80a49c29dcbe7cd60dSvetoslav        // If not explicitly specified this view is important for accessibility.
3136a1846a084fd09b3ade3fa80a49c29dcbe7cd60dSvetoslav        if (getImportantForAccessibility() == View.IMPORTANT_FOR_ACCESSIBILITY_AUTO) {
3146a1846a084fd09b3ade3fa80a49c29dcbe7cd60dSvetoslav            setImportantForAccessibility(View.IMPORTANT_FOR_ACCESSIBILITY_YES);
3156a1846a084fd09b3ade3fa80a49c29dcbe7cd60dSvetoslav        }
3169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
3179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
3189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
3199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Converts a drawable to a tiled version of itself. It will recursively
3209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * traverse layer and state list drawables.
3219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
3229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private Drawable tileify(Drawable drawable, boolean clip) {
3239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
3249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (drawable instanceof LayerDrawable) {
3259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            LayerDrawable background = (LayerDrawable) drawable;
3269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            final int N = background.getNumberOfLayers();
3279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            Drawable[] outDrawables = new Drawable[N];
3289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
3299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            for (int i = 0; i < N; i++) {
3309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                int id = background.getId(i);
3319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                outDrawables[i] = tileify(background.getDrawable(i),
3329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        (id == R.id.progress || id == R.id.secondaryProgress));
3339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
3349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
3359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            LayerDrawable newBg = new LayerDrawable(outDrawables);
3369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
3379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            for (int i = 0; i < N; i++) {
3389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                newBg.setId(i, background.getId(i));
3399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
3409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
3419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            return newBg;
3429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
3439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        } else if (drawable instanceof StateListDrawable) {
3449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            StateListDrawable in = (StateListDrawable) drawable;
3459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            StateListDrawable out = new StateListDrawable();
3469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            int numStates = in.getStateCount();
3479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            for (int i = 0; i < numStates; i++) {
3489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                out.addState(in.getStateSet(i), tileify(in.getStateDrawable(i), clip));
3499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
3509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            return out;
3519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
3529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        } else if (drawable instanceof BitmapDrawable) {
3539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            final Bitmap tileBitmap = ((BitmapDrawable) drawable).getBitmap();
3549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            if (mSampleTile == null) {
3559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                mSampleTile = tileBitmap;
3569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
3579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
3589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            final ShapeDrawable shapeDrawable = new ShapeDrawable(getDrawableShape());
3599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
3609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            final BitmapShader bitmapShader = new BitmapShader(tileBitmap,
3619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    Shader.TileMode.REPEAT, Shader.TileMode.CLAMP);
3629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            shapeDrawable.getPaint().setShader(bitmapShader);
3639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
3647fb98b34492012aad10d1c5bcaaa4064c7a79760Fabrice Di Meglio            return (clip) ? new ClipDrawable(shapeDrawable, Gravity.LEFT,
3659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    ClipDrawable.HORIZONTAL) : shapeDrawable;
3669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
3679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
3689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return drawable;
3699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
3709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
3719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    Shape getDrawableShape() {
3729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        final float[] roundedCorners = new float[] { 5, 5, 5, 5, 5, 5, 5, 5 };
3739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return new RoundRectShape(roundedCorners, null, null);
3749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
3759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
3769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
3779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Convert a AnimationDrawable for use as a barberpole animation.
3789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Each frame of the animation is wrapped in a ClipDrawable and
3799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * given a tiling BitmapShader.
3809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
3819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private Drawable tileifyIndeterminate(Drawable drawable) {
3829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (drawable instanceof AnimationDrawable) {
3839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            AnimationDrawable background = (AnimationDrawable) drawable;
3849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            final int N = background.getNumberOfFrames();
3859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            AnimationDrawable newBg = new AnimationDrawable();
3869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            newBg.setOneShot(background.isOneShot());
3879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
3889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            for (int i = 0; i < N; i++) {
3899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                Drawable frame = tileify(background.getFrame(i), true);
3909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                frame.setLevel(10000);
3919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                newBg.addFrame(frame, background.getDuration(i));
3929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
3939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            newBg.setLevel(10000);
3949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            drawable = newBg;
3959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
3969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return drawable;
3979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
3989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
3999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
4009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * <p>
4019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Initialize the progress bar's default values:
4029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * </p>
4039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * <ul>
4049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * <li>progress = 0</li>
4059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * <li>max = 100</li>
4069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * <li>animation duration = 4000 ms</li>
4079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * <li>indeterminate = false</li>
4089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * <li>behavior = repeat</li>
4099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * </ul>
4109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
4119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private void initProgressBar() {
4129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        mMax = 100;
4139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        mProgress = 0;
4149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        mSecondaryProgress = 0;
4159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        mIndeterminate = false;
4169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        mOnlyIndeterminate = false;
4179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        mDuration = 4000;
4189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        mBehavior = AlphaAnimation.RESTART;
4199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        mMinWidth = 24;
4209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        mMaxWidth = 48;
4219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        mMinHeight = 24;
4229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        mMaxHeight = 48;
4239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
4249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
4259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
4269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * <p>Indicate whether this progress bar is in indeterminate mode.</p>
4279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
4289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @return true if the progress bar is in indeterminate mode
4299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
430bea95162ca25bd00b0479d93739b6283795c3986Konstantin Lopyrev    @ViewDebug.ExportedProperty(category = "progress")
4319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public synchronized boolean isIndeterminate() {
4329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return mIndeterminate;
4339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
4349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
4359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
4369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * <p>Change the indeterminate mode for this progress bar. In indeterminate
4379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * mode, the progress is ignored and the progress bar shows an infinite
4389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * animation instead.</p>
4399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
4409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * If this progress bar's style only supports indeterminate mode (such as the circular
4419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * progress bars), then this will be ignored.
4429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
4439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param indeterminate true to enable the indeterminate mode
4449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
4459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    @android.view.RemotableViewMethod
4469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public synchronized void setIndeterminate(boolean indeterminate) {
4479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if ((!mOnlyIndeterminate || !mIndeterminate) && indeterminate != mIndeterminate) {
4489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            mIndeterminate = indeterminate;
4499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
4509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            if (indeterminate) {
4519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                // swap between indeterminate and regular backgrounds
4529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                mCurrentDrawable = mIndeterminateDrawable;
4539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                startAnimation();
4549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            } else {
4559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                mCurrentDrawable = mProgressDrawable;
4569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                stopAnimation();
4579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
4589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
4599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
4609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
4619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
4629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * <p>Get the drawable used to draw the progress bar in
4639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * indeterminate mode.</p>
4649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
4659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @return a {@link android.graphics.drawable.Drawable} instance
4669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
4679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @see #setIndeterminateDrawable(android.graphics.drawable.Drawable)
4689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @see #setIndeterminate(boolean)
4699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
4709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public Drawable getIndeterminateDrawable() {
4719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return mIndeterminateDrawable;
4729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
4739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
4749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
4759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * <p>Define the drawable used to draw the progress bar in
4769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * indeterminate mode.</p>
4779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
4789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param d the new drawable
4799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
4809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @see #getIndeterminateDrawable()
4819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @see #setIndeterminate(boolean)
4829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
4839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public void setIndeterminateDrawable(Drawable d) {
4849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (d != null) {
4859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            d.setCallback(this);
4869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
4879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        mIndeterminateDrawable = d;
4880af4b8b0c8b038bca9b4f60eb81f71e186f471ceFabrice Di Meglio        if (mIndeterminateDrawable != null && canResolveLayoutDirection()) {
489e56ffdc7b31b0937628609cc3bbaa15879023569Fabrice Di Meglio            mIndeterminateDrawable.setLayoutDirection(getLayoutDirection());
490b03b434089cf2106c467b2827a65e5c589c91d01Fabrice Di Meglio        }
4919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (mIndeterminate) {
4929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            mCurrentDrawable = d;
4939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            postInvalidate();
4949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
4959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
4969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
4979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
4989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * <p>Get the drawable used to draw the progress bar in
4999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * progress mode.</p>
5009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
5019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @return a {@link android.graphics.drawable.Drawable} instance
5029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
5039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @see #setProgressDrawable(android.graphics.drawable.Drawable)
5049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @see #setIndeterminate(boolean)
5059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
5069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public Drawable getProgressDrawable() {
5079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return mProgressDrawable;
5089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
5099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
5109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
5119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * <p>Define the drawable used to draw the progress bar in
5129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * progress mode.</p>
5139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
5149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param d the new drawable
5159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
5169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @see #getProgressDrawable()
5179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @see #setIndeterminate(boolean)
5189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
5199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public void setProgressDrawable(Drawable d) {
520aa072634630c9515e44890dc302307fa969bbb85Joe Onorato        boolean needUpdate;
521aa072634630c9515e44890dc302307fa969bbb85Joe Onorato        if (mProgressDrawable != null && d != mProgressDrawable) {
522aa072634630c9515e44890dc302307fa969bbb85Joe Onorato            mProgressDrawable.setCallback(null);
523aa072634630c9515e44890dc302307fa969bbb85Joe Onorato            needUpdate = true;
524aa072634630c9515e44890dc302307fa969bbb85Joe Onorato        } else {
525aa072634630c9515e44890dc302307fa969bbb85Joe Onorato            needUpdate = false;
526aa072634630c9515e44890dc302307fa969bbb85Joe Onorato        }
527aa072634630c9515e44890dc302307fa969bbb85Joe Onorato
5289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (d != null) {
5299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            d.setCallback(this);
5300af4b8b0c8b038bca9b4f60eb81f71e186f471ceFabrice Di Meglio            if (canResolveLayoutDirection()) {
531e56ffdc7b31b0937628609cc3bbaa15879023569Fabrice Di Meglio                d.setLayoutDirection(getLayoutDirection());
5320af4b8b0c8b038bca9b4f60eb81f71e186f471ceFabrice Di Meglio            }
533a7f7e2ac9270e58f8c45006a239a1c3c0cdc0309NoraBora
5348d21bdb90573ec48491c44eca312c162e262298dRomain Guy            // Make sure the ProgressBar is always tall enough
5358d21bdb90573ec48491c44eca312c162e262298dRomain Guy            int drawableHeight = d.getMinimumHeight();
536a7f7e2ac9270e58f8c45006a239a1c3c0cdc0309NoraBora            if (mMaxHeight < drawableHeight) {
537a7f7e2ac9270e58f8c45006a239a1c3c0cdc0309NoraBora                mMaxHeight = drawableHeight;
538a7f7e2ac9270e58f8c45006a239a1c3c0cdc0309NoraBora                requestLayout();
539a7f7e2ac9270e58f8c45006a239a1c3c0cdc0309NoraBora            }
5409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
5419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        mProgressDrawable = d;
5429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (!mIndeterminate) {
5439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            mCurrentDrawable = d;
5449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            postInvalidate();
5459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
546aa072634630c9515e44890dc302307fa969bbb85Joe Onorato
547aa072634630c9515e44890dc302307fa969bbb85Joe Onorato        if (needUpdate) {
548aa072634630c9515e44890dc302307fa969bbb85Joe Onorato            updateDrawableBounds(getWidth(), getHeight());
549aa072634630c9515e44890dc302307fa969bbb85Joe Onorato            updateDrawableState();
550aa072634630c9515e44890dc302307fa969bbb85Joe Onorato            doRefreshProgress(R.id.progress, mProgress, false, false);
551aa072634630c9515e44890dc302307fa969bbb85Joe Onorato            doRefreshProgress(R.id.secondaryProgress, mSecondaryProgress, false, false);
552aa072634630c9515e44890dc302307fa969bbb85Joe Onorato        }
5539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
5549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
5559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
5569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @return The drawable currently used to draw the progress bar
5579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
5589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    Drawable getCurrentDrawable() {
5599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return mCurrentDrawable;
5609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
5619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
5629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    @Override
5639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    protected boolean verifyDrawable(Drawable who) {
5649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return who == mProgressDrawable || who == mIndeterminateDrawable
5659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                || super.verifyDrawable(who);
5669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
5679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
5689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    @Override
569e213677037f836529efcc0ac201fc61dd95481c5Dianne Hackborn    public void jumpDrawablesToCurrentState() {
570e213677037f836529efcc0ac201fc61dd95481c5Dianne Hackborn        super.jumpDrawablesToCurrentState();
571e213677037f836529efcc0ac201fc61dd95481c5Dianne Hackborn        if (mProgressDrawable != null) mProgressDrawable.jumpToCurrentState();
572e213677037f836529efcc0ac201fc61dd95481c5Dianne Hackborn        if (mIndeterminateDrawable != null) mIndeterminateDrawable.jumpToCurrentState();
573e213677037f836529efcc0ac201fc61dd95481c5Dianne Hackborn    }
574e213677037f836529efcc0ac201fc61dd95481c5Dianne Hackborn
5754457e85a7090ad51726d50a4daf981d917cceeddFabrice Di Meglio    /**
5764457e85a7090ad51726d50a4daf981d917cceeddFabrice Di Meglio     * @hide
5774457e85a7090ad51726d50a4daf981d917cceeddFabrice Di Meglio     */
578e213677037f836529efcc0ac201fc61dd95481c5Dianne Hackborn    @Override
5790af4b8b0c8b038bca9b4f60eb81f71e186f471ceFabrice Di Meglio    public void onResolveDrawables(int layoutDirection) {
5800af4b8b0c8b038bca9b4f60eb81f71e186f471ceFabrice Di Meglio        final Drawable d = mCurrentDrawable;
5810af4b8b0c8b038bca9b4f60eb81f71e186f471ceFabrice Di Meglio        if (d != null) {
5820af4b8b0c8b038bca9b4f60eb81f71e186f471ceFabrice Di Meglio            d.setLayoutDirection(layoutDirection);
5830af4b8b0c8b038bca9b4f60eb81f71e186f471ceFabrice Di Meglio        }
5840af4b8b0c8b038bca9b4f60eb81f71e186f471ceFabrice Di Meglio        if (mIndeterminateDrawable != null) {
5850af4b8b0c8b038bca9b4f60eb81f71e186f471ceFabrice Di Meglio            mIndeterminateDrawable.setLayoutDirection(layoutDirection);
5860af4b8b0c8b038bca9b4f60eb81f71e186f471ceFabrice Di Meglio        }
5870af4b8b0c8b038bca9b4f60eb81f71e186f471ceFabrice Di Meglio        if (mProgressDrawable != null) {
5880af4b8b0c8b038bca9b4f60eb81f71e186f471ceFabrice Di Meglio            mProgressDrawable.setLayoutDirection(layoutDirection);
5890af4b8b0c8b038bca9b4f60eb81f71e186f471ceFabrice Di Meglio        }
5900af4b8b0c8b038bca9b4f60eb81f71e186f471ceFabrice Di Meglio    }
5910af4b8b0c8b038bca9b4f60eb81f71e186f471ceFabrice Di Meglio
5920af4b8b0c8b038bca9b4f60eb81f71e186f471ceFabrice Di Meglio    @Override
5939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public void postInvalidate() {
5949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (!mNoInvalidate) {
5959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            super.postInvalidate();
5969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
5979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
5989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
5999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private class RefreshProgressRunnable implements Runnable {
600a050663feb6309c63867abd746cdf97388e289a4Adam Powell        public void run() {
601a050663feb6309c63867abd746cdf97388e289a4Adam Powell            synchronized (ProgressBar.this) {
602a050663feb6309c63867abd746cdf97388e289a4Adam Powell                final int count = mRefreshData.size();
603a050663feb6309c63867abd746cdf97388e289a4Adam Powell                for (int i = 0; i < count; i++) {
604a050663feb6309c63867abd746cdf97388e289a4Adam Powell                    final RefreshData rd = mRefreshData.get(i);
605a050663feb6309c63867abd746cdf97388e289a4Adam Powell                    doRefreshProgress(rd.id, rd.progress, rd.fromUser, true);
606a050663feb6309c63867abd746cdf97388e289a4Adam Powell                    rd.recycle();
607a050663feb6309c63867abd746cdf97388e289a4Adam Powell                }
608a050663feb6309c63867abd746cdf97388e289a4Adam Powell                mRefreshData.clear();
609a050663feb6309c63867abd746cdf97388e289a4Adam Powell                mRefreshIsPosted = false;
610a050663feb6309c63867abd746cdf97388e289a4Adam Powell            }
611a050663feb6309c63867abd746cdf97388e289a4Adam Powell        }
612a050663feb6309c63867abd746cdf97388e289a4Adam Powell    }
6139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
614abae2a1b891772d36d8f781adfcc8969e551691fSvetoslav Ganov    private static class RefreshData {
615abae2a1b891772d36d8f781adfcc8969e551691fSvetoslav Ganov        private static final int POOL_MAX = 24;
616abae2a1b891772d36d8f781adfcc8969e551691fSvetoslav Ganov        private static final SynchronizedPool<RefreshData> sPool =
617abae2a1b891772d36d8f781adfcc8969e551691fSvetoslav Ganov                new SynchronizedPool<RefreshData>(POOL_MAX);
618abae2a1b891772d36d8f781adfcc8969e551691fSvetoslav Ganov
619a050663feb6309c63867abd746cdf97388e289a4Adam Powell        public int id;
620a050663feb6309c63867abd746cdf97388e289a4Adam Powell        public int progress;
621a050663feb6309c63867abd746cdf97388e289a4Adam Powell        public boolean fromUser;
622a050663feb6309c63867abd746cdf97388e289a4Adam Powell
623a050663feb6309c63867abd746cdf97388e289a4Adam Powell        public static RefreshData obtain(int id, int progress, boolean fromUser) {
624a050663feb6309c63867abd746cdf97388e289a4Adam Powell            RefreshData rd = sPool.acquire();
625abae2a1b891772d36d8f781adfcc8969e551691fSvetoslav Ganov            if (rd == null) {
626abae2a1b891772d36d8f781adfcc8969e551691fSvetoslav Ganov                rd = new RefreshData();
627abae2a1b891772d36d8f781adfcc8969e551691fSvetoslav Ganov            }
628a050663feb6309c63867abd746cdf97388e289a4Adam Powell            rd.id = id;
629a050663feb6309c63867abd746cdf97388e289a4Adam Powell            rd.progress = progress;
630a050663feb6309c63867abd746cdf97388e289a4Adam Powell            rd.fromUser = fromUser;
631a050663feb6309c63867abd746cdf97388e289a4Adam Powell            return rd;
6329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
6339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
634a050663feb6309c63867abd746cdf97388e289a4Adam Powell        public void recycle() {
635a050663feb6309c63867abd746cdf97388e289a4Adam Powell            sPool.release(this);
636a050663feb6309c63867abd746cdf97388e289a4Adam Powell        }
6379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
638abae2a1b891772d36d8f781adfcc8969e551691fSvetoslav Ganov
639aa072634630c9515e44890dc302307fa969bbb85Joe Onorato    private synchronized void doRefreshProgress(int id, int progress, boolean fromUser,
640aa072634630c9515e44890dc302307fa969bbb85Joe Onorato            boolean callBackToApp) {
6419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        float scale = mMax > 0 ? (float) progress / (float) mMax : 0;
6429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        final Drawable d = mCurrentDrawable;
6439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (d != null) {
6449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            Drawable progressDrawable = null;
6459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
6469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            if (d instanceof LayerDrawable) {
6479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                progressDrawable = ((LayerDrawable) d).findDrawableByLayerId(id);
6480af4b8b0c8b038bca9b4f60eb81f71e186f471ceFabrice Di Meglio                if (progressDrawable != null && canResolveLayoutDirection()) {
649e56ffdc7b31b0937628609cc3bbaa15879023569Fabrice Di Meglio                    progressDrawable.setLayoutDirection(getLayoutDirection());
6500af4b8b0c8b038bca9b4f60eb81f71e186f471ceFabrice Di Meglio                }
6519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
6529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
6539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            final int level = (int) (scale * MAX_LEVEL);
6549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            (progressDrawable != null ? progressDrawable : d).setLevel(level);
6559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        } else {
6569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            invalidate();
6579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
6589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
659aa072634630c9515e44890dc302307fa969bbb85Joe Onorato        if (callBackToApp && id == R.id.progress) {
6609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            onProgressRefresh(scale, fromUser);
6619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
6629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
6636518ad760f98a0aa5db8c49ce1564bf5907a2c15Svetoslav Ganov
6646518ad760f98a0aa5db8c49ce1564bf5907a2c15Svetoslav Ganov    void onProgressRefresh(float scale, boolean fromUser) {
6656518ad760f98a0aa5db8c49ce1564bf5907a2c15Svetoslav Ganov        if (AccessibilityManager.getInstance(mContext).isEnabled()) {
6666518ad760f98a0aa5db8c49ce1564bf5907a2c15Svetoslav Ganov            scheduleAccessibilityEventSender();
6676518ad760f98a0aa5db8c49ce1564bf5907a2c15Svetoslav Ganov        }
6689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
6699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
6709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private synchronized void refreshProgress(int id, int progress, boolean fromUser) {
6719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (mUiThreadId == Thread.currentThread().getId()) {
672aa072634630c9515e44890dc302307fa969bbb85Joe Onorato            doRefreshProgress(id, progress, fromUser, true);
6739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        } else {
674ab4c4f4ff73e66b7767640dbe6d4115237c48242Romain Guy            if (mRefreshProgressRunnable == null) {
675ab4c4f4ff73e66b7767640dbe6d4115237c48242Romain Guy                mRefreshProgressRunnable = new RefreshProgressRunnable();
676a050663feb6309c63867abd746cdf97388e289a4Adam Powell            }
677ab4c4f4ff73e66b7767640dbe6d4115237c48242Romain Guy
678a050663feb6309c63867abd746cdf97388e289a4Adam Powell            final RefreshData rd = RefreshData.obtain(id, progress, fromUser);
679a050663feb6309c63867abd746cdf97388e289a4Adam Powell            mRefreshData.add(rd);
680a050663feb6309c63867abd746cdf97388e289a4Adam Powell            if (mAttached && !mRefreshIsPosted) {
681ab4c4f4ff73e66b7767640dbe6d4115237c48242Romain Guy                post(mRefreshProgressRunnable);
682a050663feb6309c63867abd746cdf97388e289a4Adam Powell                mRefreshIsPosted = true;
6839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
6849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
6859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
6869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
6879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
6889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * <p>Set the current progress to the specified value. Does not do anything
6899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * if the progress bar is in indeterminate mode.</p>
6909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
6919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param progress the new progress, between 0 and {@link #getMax()}
6929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
6939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @see #setIndeterminate(boolean)
6949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @see #isIndeterminate()
6959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @see #getProgress()
6969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @see #incrementProgressBy(int)
6979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
6989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    @android.view.RemotableViewMethod
6999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public synchronized void setProgress(int progress) {
7009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        setProgress(progress, false);
7019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
7029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
7039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    @android.view.RemotableViewMethod
7049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    synchronized void setProgress(int progress, boolean fromUser) {
7059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (mIndeterminate) {
7069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            return;
7079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
7089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
7099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (progress < 0) {
7109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            progress = 0;
7119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
7129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
7139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (progress > mMax) {
7149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            progress = mMax;
7159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
7169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
7179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (progress != mProgress) {
7189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            mProgress = progress;
7199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            refreshProgress(R.id.progress, mProgress, fromUser);
7209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
7219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
7229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
7239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
7249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * <p>
7259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Set the current secondary progress to the specified value. Does not do
7269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * anything if the progress bar is in indeterminate mode.
7279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * </p>
7289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
7299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param secondaryProgress the new secondary progress, between 0 and {@link #getMax()}
7309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @see #setIndeterminate(boolean)
7319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @see #isIndeterminate()
7329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @see #getSecondaryProgress()
7339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @see #incrementSecondaryProgressBy(int)
7349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
7359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    @android.view.RemotableViewMethod
7369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public synchronized void setSecondaryProgress(int secondaryProgress) {
7379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (mIndeterminate) {
7389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            return;
7399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
7409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
7419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (secondaryProgress < 0) {
7429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            secondaryProgress = 0;
7439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
7449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
7459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (secondaryProgress > mMax) {
7469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            secondaryProgress = mMax;
7479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
7489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
7499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (secondaryProgress != mSecondaryProgress) {
7509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            mSecondaryProgress = secondaryProgress;
7519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            refreshProgress(R.id.secondaryProgress, mSecondaryProgress, false);
7529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
7539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
7549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
7559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
7569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * <p>Get the progress bar's current level of progress. Return 0 when the
7579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * progress bar is in indeterminate mode.</p>
7589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
7599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @return the current progress, between 0 and {@link #getMax()}
7609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
7619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @see #setIndeterminate(boolean)
7629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @see #isIndeterminate()
7639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @see #setProgress(int)
7649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @see #setMax(int)
7659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @see #getMax()
7669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
767bea95162ca25bd00b0479d93739b6283795c3986Konstantin Lopyrev    @ViewDebug.ExportedProperty(category = "progress")
7689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public synchronized int getProgress() {
7699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return mIndeterminate ? 0 : mProgress;
7709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
7719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
7729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
7739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * <p>Get the progress bar's current level of secondary progress. Return 0 when the
7749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * progress bar is in indeterminate mode.</p>
7759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
7769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @return the current secondary progress, between 0 and {@link #getMax()}
7779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
7789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @see #setIndeterminate(boolean)
7799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @see #isIndeterminate()
7809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @see #setSecondaryProgress(int)
7819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @see #setMax(int)
7829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @see #getMax()
7839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
784bea95162ca25bd00b0479d93739b6283795c3986Konstantin Lopyrev    @ViewDebug.ExportedProperty(category = "progress")
7859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public synchronized int getSecondaryProgress() {
7869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return mIndeterminate ? 0 : mSecondaryProgress;
7879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
7889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
7899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
7909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * <p>Return the upper limit of this progress bar's range.</p>
7919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
7929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @return a positive integer
7939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
7949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @see #setMax(int)
7959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @see #getProgress()
7969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @see #getSecondaryProgress()
7979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
798bea95162ca25bd00b0479d93739b6283795c3986Konstantin Lopyrev    @ViewDebug.ExportedProperty(category = "progress")
7999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public synchronized int getMax() {
8009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return mMax;
8019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
8029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
8039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
8049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * <p>Set the range of the progress bar to 0...<tt>max</tt>.</p>
8059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
8069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param max the upper range of this progress bar
8079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
8089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @see #getMax()
8099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @see #setProgress(int)
8109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @see #setSecondaryProgress(int)
8119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
8129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    @android.view.RemotableViewMethod
8139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public synchronized void setMax(int max) {
8149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (max < 0) {
8159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            max = 0;
8169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
8179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (max != mMax) {
8189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            mMax = max;
8199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            postInvalidate();
8209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
8219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            if (mProgress > max) {
8229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                mProgress = max;
8239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
82458e3822b5973e766f79046e8964457d9ef26df55Michael Krehan            refreshProgress(R.id.progress, mProgress, false);
8259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
8269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
8279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
8289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
8299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * <p>Increase the progress bar's progress by the specified amount.</p>
8309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
8319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param diff the amount by which the progress must be increased
8329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
8339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @see #setProgress(int)
8349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
8359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public synchronized final void incrementProgressBy(int diff) {
8369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        setProgress(mProgress + diff);
8379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
8389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
8399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
8409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * <p>Increase the progress bar's secondary progress by the specified amount.</p>
8419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
8429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param diff the amount by which the secondary progress must be increased
8439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
8449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @see #setSecondaryProgress(int)
8459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
8469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public synchronized final void incrementSecondaryProgressBy(int diff) {
8479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        setSecondaryProgress(mSecondaryProgress + diff);
8489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
8499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
8509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
8519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * <p>Start the indeterminate progress animation.</p>
8529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
8539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    void startAnimation() {
854a05e8a5869ad2117485938cd52d4b891672a1873Romain Guy        if (getVisibility() != VISIBLE) {
8559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            return;
8569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
8579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
858cf4550c3198d6b3d92cdc52707fe70d7cc0caa9fJean-Baptiste Queru        if (mIndeterminateDrawable instanceof Animatable) {
8599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            mShouldStartAnimationDrawable = true;
860ab4c4f4ff73e66b7767640dbe6d4115237c48242Romain Guy            mHasAnimation = false;
8619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        } else {
862ab4c4f4ff73e66b7767640dbe6d4115237c48242Romain Guy            mHasAnimation = true;
863ab4c4f4ff73e66b7767640dbe6d4115237c48242Romain Guy
8649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            if (mInterpolator == null) {
8659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                mInterpolator = new LinearInterpolator();
8669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
8679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
868ab4c4f4ff73e66b7767640dbe6d4115237c48242Romain Guy            if (mTransformation == null) {
869ab4c4f4ff73e66b7767640dbe6d4115237c48242Romain Guy                mTransformation = new Transformation();
870ab4c4f4ff73e66b7767640dbe6d4115237c48242Romain Guy            } else {
871ab4c4f4ff73e66b7767640dbe6d4115237c48242Romain Guy                mTransformation.clear();
872ab4c4f4ff73e66b7767640dbe6d4115237c48242Romain Guy            }
873ab4c4f4ff73e66b7767640dbe6d4115237c48242Romain Guy
874ab4c4f4ff73e66b7767640dbe6d4115237c48242Romain Guy            if (mAnimation == null) {
875ab4c4f4ff73e66b7767640dbe6d4115237c48242Romain Guy                mAnimation = new AlphaAnimation(0.0f, 1.0f);
876ab4c4f4ff73e66b7767640dbe6d4115237c48242Romain Guy            } else {
877ab4c4f4ff73e66b7767640dbe6d4115237c48242Romain Guy                mAnimation.reset();
878ab4c4f4ff73e66b7767640dbe6d4115237c48242Romain Guy            }
879ab4c4f4ff73e66b7767640dbe6d4115237c48242Romain Guy
8809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            mAnimation.setRepeatMode(mBehavior);
8819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            mAnimation.setRepeatCount(Animation.INFINITE);
8829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            mAnimation.setDuration(mDuration);
8839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            mAnimation.setInterpolator(mInterpolator);
8849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            mAnimation.setStartTime(Animation.START_ON_FIRST_FRAME);
8859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
88608e1473ca30ef1756c6694cc1ed0aff27f11807dEvan Charlton        postInvalidate();
8879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
8889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
8899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
8909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * <p>Stop the indeterminate progress animation.</p>
8919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
8929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    void stopAnimation() {
893ab4c4f4ff73e66b7767640dbe6d4115237c48242Romain Guy        mHasAnimation = false;
894cf4550c3198d6b3d92cdc52707fe70d7cc0caa9fJean-Baptiste Queru        if (mIndeterminateDrawable instanceof Animatable) {
895cf4550c3198d6b3d92cdc52707fe70d7cc0caa9fJean-Baptiste Queru            ((Animatable) mIndeterminateDrawable).stop();
8969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            mShouldStartAnimationDrawable = false;
8979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
89808e1473ca30ef1756c6694cc1ed0aff27f11807dEvan Charlton        postInvalidate();
8999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
9009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
9019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
9029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Sets the acceleration curve for the indeterminate animation.
9039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * The interpolator is loaded as a resource from the specified context.
9049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
9059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param context The application environment
9069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param resID The resource identifier of the interpolator to load
9079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
9089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public void setInterpolator(Context context, int resID) {
9099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        setInterpolator(AnimationUtils.loadInterpolator(context, resID));
9109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
9119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
9129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
9139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Sets the acceleration curve for the indeterminate animation.
9149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Defaults to a linear interpolation.
9159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
9169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param interpolator The interpolator which defines the acceleration curve
9179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
9189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public void setInterpolator(Interpolator interpolator) {
9199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        mInterpolator = interpolator;
9209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
9219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
9229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
9239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Gets the acceleration curve type for the indeterminate animation.
9249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
9259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @return the {@link Interpolator} associated to this animation
9269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
9279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public Interpolator getInterpolator() {
9289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return mInterpolator;
9299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
9309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
9319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    @Override
932b25ffffc3157c4c471c326147be750f4ebec456aSteve Howard    @RemotableViewMethod
9339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public void setVisibility(int v) {
9349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (getVisibility() != v) {
9359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            super.setVisibility(v);
9369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
9379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            if (mIndeterminate) {
9389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                // let's be nice with the UI thread
9399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                if (v == GONE || v == INVISIBLE) {
9409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    stopAnimation();
941a05e8a5869ad2117485938cd52d4b891672a1873Romain Guy                } else {
9429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    startAnimation();
9439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                }
9449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
9459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
9469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
9479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
9489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    @Override
949a05e8a5869ad2117485938cd52d4b891672a1873Romain Guy    protected void onVisibilityChanged(View changedView, int visibility) {
950a05e8a5869ad2117485938cd52d4b891672a1873Romain Guy        super.onVisibilityChanged(changedView, visibility);
951a05e8a5869ad2117485938cd52d4b891672a1873Romain Guy
952a05e8a5869ad2117485938cd52d4b891672a1873Romain Guy        if (mIndeterminate) {
953a05e8a5869ad2117485938cd52d4b891672a1873Romain Guy            // let's be nice with the UI thread
954a05e8a5869ad2117485938cd52d4b891672a1873Romain Guy            if (visibility == GONE || visibility == INVISIBLE) {
955a05e8a5869ad2117485938cd52d4b891672a1873Romain Guy                stopAnimation();
956a05e8a5869ad2117485938cd52d4b891672a1873Romain Guy            } else {
957a05e8a5869ad2117485938cd52d4b891672a1873Romain Guy                startAnimation();
958a05e8a5869ad2117485938cd52d4b891672a1873Romain Guy            }
959a05e8a5869ad2117485938cd52d4b891672a1873Romain Guy        }
960a05e8a5869ad2117485938cd52d4b891672a1873Romain Guy    }
961a05e8a5869ad2117485938cd52d4b891672a1873Romain Guy
962a05e8a5869ad2117485938cd52d4b891672a1873Romain Guy    @Override
9639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public void invalidateDrawable(Drawable dr) {
9649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (!mInDrawing) {
965ba87e3e6c985e7175152993b5efcc7dd2f0e1c93The Android Open Source Project            if (verifyDrawable(dr)) {
9669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                final Rect dirty = dr.getBounds();
9677546a4bea78487bb868d2d95b7e4ba9ce9d2612aChris Craik                final int scrollX = mScrollX + mPaddingLeft;
9687546a4bea78487bb868d2d95b7e4ba9ce9d2612aChris Craik                final int scrollY = mScrollY + mPaddingTop;
9699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
9707546a4bea78487bb868d2d95b7e4ba9ce9d2612aChris Craik                invalidate(dirty.left + scrollX, dirty.top + scrollY,
9717546a4bea78487bb868d2d95b7e4ba9ce9d2612aChris Craik                        dirty.right + scrollX, dirty.bottom + scrollY);
9729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            } else {
9739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                super.invalidateDrawable(dr);
9749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
9759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
9769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
9779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
9789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    @Override
9799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    protected void onSizeChanged(int w, int h, int oldw, int oldh) {
980aa072634630c9515e44890dc302307fa969bbb85Joe Onorato        updateDrawableBounds(w, h);
981aa072634630c9515e44890dc302307fa969bbb85Joe Onorato    }
982aa072634630c9515e44890dc302307fa969bbb85Joe Onorato
983aa072634630c9515e44890dc302307fa969bbb85Joe Onorato    private void updateDrawableBounds(int w, int h) {
9846322af54cfb74be22386e4b7d17350cebf2da58fAdam Powell        // onDraw will translate the canvas so we draw starting at 0,0.
9856322af54cfb74be22386e4b7d17350cebf2da58fAdam Powell        // Subtract out padding for the purposes of the calculations below.
9866322af54cfb74be22386e4b7d17350cebf2da58fAdam Powell        w -= mPaddingRight + mPaddingLeft;
9876322af54cfb74be22386e4b7d17350cebf2da58fAdam Powell        h -= mPaddingTop + mPaddingBottom;
9886322af54cfb74be22386e4b7d17350cebf2da58fAdam Powell
9896322af54cfb74be22386e4b7d17350cebf2da58fAdam Powell        int right = w;
9906322af54cfb74be22386e4b7d17350cebf2da58fAdam Powell        int bottom = h;
991a1b92c5e8b750d8f5b2dc5ca7e8b4edc97de5575Adam Powell        int top = 0;
992a1b92c5e8b750d8f5b2dc5ca7e8b4edc97de5575Adam Powell        int left = 0;
9939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
9949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (mIndeterminateDrawable != null) {
995a79803c0924836053a6f97cc0e73f7ad56f763bdChet Haase            // Aspect ratio logic does not apply to AnimationDrawables
996a79803c0924836053a6f97cc0e73f7ad56f763bdChet Haase            if (mOnlyIndeterminate && !(mIndeterminateDrawable instanceof AnimationDrawable)) {
997a1b92c5e8b750d8f5b2dc5ca7e8b4edc97de5575Adam Powell                // Maintain aspect ratio. Certain kinds of animated drawables
998a1b92c5e8b750d8f5b2dc5ca7e8b4edc97de5575Adam Powell                // get very confused otherwise.
999a1b92c5e8b750d8f5b2dc5ca7e8b4edc97de5575Adam Powell                final int intrinsicWidth = mIndeterminateDrawable.getIntrinsicWidth();
1000a1b92c5e8b750d8f5b2dc5ca7e8b4edc97de5575Adam Powell                final int intrinsicHeight = mIndeterminateDrawable.getIntrinsicHeight();
1001a1b92c5e8b750d8f5b2dc5ca7e8b4edc97de5575Adam Powell                final float intrinsicAspect = (float) intrinsicWidth / intrinsicHeight;
1002a1b92c5e8b750d8f5b2dc5ca7e8b4edc97de5575Adam Powell                final float boundAspect = (float) w / h;
1003a1b92c5e8b750d8f5b2dc5ca7e8b4edc97de5575Adam Powell                if (intrinsicAspect != boundAspect) {
1004a1b92c5e8b750d8f5b2dc5ca7e8b4edc97de5575Adam Powell                    if (boundAspect > intrinsicAspect) {
1005a1b92c5e8b750d8f5b2dc5ca7e8b4edc97de5575Adam Powell                        // New width is larger. Make it smaller to match height.
1006a1b92c5e8b750d8f5b2dc5ca7e8b4edc97de5575Adam Powell                        final int width = (int) (h * intrinsicAspect);
1007a1b92c5e8b750d8f5b2dc5ca7e8b4edc97de5575Adam Powell                        left = (w - width) / 2;
1008a1b92c5e8b750d8f5b2dc5ca7e8b4edc97de5575Adam Powell                        right = left + width;
1009a1b92c5e8b750d8f5b2dc5ca7e8b4edc97de5575Adam Powell                    } else {
1010a1b92c5e8b750d8f5b2dc5ca7e8b4edc97de5575Adam Powell                        // New height is larger. Make it smaller to match width.
1011a1b92c5e8b750d8f5b2dc5ca7e8b4edc97de5575Adam Powell                        final int height = (int) (w * (1 / intrinsicAspect));
1012a1b92c5e8b750d8f5b2dc5ca7e8b4edc97de5575Adam Powell                        top = (h - height) / 2;
1013a1b92c5e8b750d8f5b2dc5ca7e8b4edc97de5575Adam Powell                        bottom = top + height;
1014a1b92c5e8b750d8f5b2dc5ca7e8b4edc97de5575Adam Powell                    }
1015a1b92c5e8b750d8f5b2dc5ca7e8b4edc97de5575Adam Powell                }
1016a1b92c5e8b750d8f5b2dc5ca7e8b4edc97de5575Adam Powell            }
10172b378cde411b551464f0040e935692073cfb119fFabrice Di Meglio            if (isLayoutRtl() && mMirrorForRtl) {
10187fb98b34492012aad10d1c5bcaaa4064c7a79760Fabrice Di Meglio                int tempLeft = left;
10197fb98b34492012aad10d1c5bcaaa4064c7a79760Fabrice Di Meglio                left = w - right;
10207fb98b34492012aad10d1c5bcaaa4064c7a79760Fabrice Di Meglio                right = w - tempLeft;
10217fb98b34492012aad10d1c5bcaaa4064c7a79760Fabrice Di Meglio            }
1022a1b92c5e8b750d8f5b2dc5ca7e8b4edc97de5575Adam Powell            mIndeterminateDrawable.setBounds(left, top, right, bottom);
10239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
10249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
10259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (mProgressDrawable != null) {
10269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            mProgressDrawable.setBounds(0, 0, right, bottom);
10279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
10289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
10299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
10309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    @Override
10319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    protected synchronized void onDraw(Canvas canvas) {
10329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        super.onDraw(canvas);
10339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
10349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        Drawable d = mCurrentDrawable;
10359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (d != null) {
10369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            // Translate canvas so a indeterminate circular progress bar with padding
10379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            // rotates properly in its animation
10389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            canvas.save();
10392b378cde411b551464f0040e935692073cfb119fFabrice Di Meglio            if(isLayoutRtl() && mMirrorForRtl) {
10407fb98b34492012aad10d1c5bcaaa4064c7a79760Fabrice Di Meglio                canvas.translate(getWidth() - mPaddingRight, mPaddingTop);
10417fb98b34492012aad10d1c5bcaaa4064c7a79760Fabrice Di Meglio                canvas.scale(-1.0f, 1.0f);
10427fb98b34492012aad10d1c5bcaaa4064c7a79760Fabrice Di Meglio            } else {
10437fb98b34492012aad10d1c5bcaaa4064c7a79760Fabrice Di Meglio                canvas.translate(mPaddingLeft, mPaddingTop);
10447fb98b34492012aad10d1c5bcaaa4064c7a79760Fabrice Di Meglio            }
10459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            long time = getDrawingTime();
1046ab4c4f4ff73e66b7767640dbe6d4115237c48242Romain Guy            if (mHasAnimation) {
10479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                mAnimation.getTransformation(time, mTransformation);
10489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                float scale = mTransformation.getAlpha();
10499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                try {
10509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    mInDrawing = true;
10519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    d.setLevel((int) (scale * MAX_LEVEL));
10529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                } finally {
10539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    mInDrawing = false;
10549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                }
10556cb7b46c56449e84434b11eb12f9b8977fcd0398Jeff Brown                postInvalidateOnAnimation();
10569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
10579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            d.draw(canvas);
10589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            canvas.restore();
1059cf4550c3198d6b3d92cdc52707fe70d7cc0caa9fJean-Baptiste Queru            if (mShouldStartAnimationDrawable && d instanceof Animatable) {
1060cf4550c3198d6b3d92cdc52707fe70d7cc0caa9fJean-Baptiste Queru                ((Animatable) d).start();
10619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                mShouldStartAnimationDrawable = false;
10629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
10639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
10649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
10659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
10669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    @Override
10679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    protected synchronized void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
10689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        Drawable d = mCurrentDrawable;
10699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
10709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        int dw = 0;
10719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        int dh = 0;
10729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (d != null) {
10739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            dw = Math.max(mMinWidth, Math.min(mMaxWidth, d.getIntrinsicWidth()));
10749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            dh = Math.max(mMinHeight, Math.min(mMaxHeight, d.getIntrinsicHeight()));
10759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
1076aa072634630c9515e44890dc302307fa969bbb85Joe Onorato        updateDrawableState();
10779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        dw += mPaddingLeft + mPaddingRight;
10789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        dh += mPaddingTop + mPaddingBottom;
10799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1080189ee18d6c6483ad63cc864267328259e2e00b95Dianne Hackborn        setMeasuredDimension(resolveSizeAndState(dw, widthMeasureSpec, 0),
1081189ee18d6c6483ad63cc864267328259e2e00b95Dianne Hackborn                resolveSizeAndState(dh, heightMeasureSpec, 0));
10829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
10839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
10849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    @Override
10859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    protected void drawableStateChanged() {
10869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        super.drawableStateChanged();
1087aa072634630c9515e44890dc302307fa969bbb85Joe Onorato        updateDrawableState();
1088aa072634630c9515e44890dc302307fa969bbb85Joe Onorato    }
10899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1090aa072634630c9515e44890dc302307fa969bbb85Joe Onorato    private void updateDrawableState() {
10919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        int[] state = getDrawableState();
10929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
10939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (mProgressDrawable != null && mProgressDrawable.isStateful()) {
10949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            mProgressDrawable.setState(state);
10959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
10969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
10979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (mIndeterminateDrawable != null && mIndeterminateDrawable.isStateful()) {
10989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            mIndeterminateDrawable.setState(state);
10999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
11009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
11019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
11029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    static class SavedState extends BaseSavedState {
11039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        int progress;
11049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        int secondaryProgress;
11059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
11069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        /**
11079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project         * Constructor called from {@link ProgressBar#onSaveInstanceState()}
11089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project         */
11099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        SavedState(Parcelable superState) {
11109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            super(superState);
11119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
11129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
11139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        /**
11149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project         * Constructor called from {@link #CREATOR}
11159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project         */
11169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        private SavedState(Parcel in) {
11179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            super(in);
11189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            progress = in.readInt();
11199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            secondaryProgress = in.readInt();
11209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
11219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
11229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        @Override
11239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        public void writeToParcel(Parcel out, int flags) {
11249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            super.writeToParcel(out, flags);
11259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            out.writeInt(progress);
11269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            out.writeInt(secondaryProgress);
11279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
11289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
11299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        public static final Parcelable.Creator<SavedState> CREATOR
11309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                = new Parcelable.Creator<SavedState>() {
11319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            public SavedState createFromParcel(Parcel in) {
11329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                return new SavedState(in);
11339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
11349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
11359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            public SavedState[] newArray(int size) {
11369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                return new SavedState[size];
11379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
11389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        };
11399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
11409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
11419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    @Override
11429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public Parcelable onSaveInstanceState() {
11439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        // Force our ancestor class to save its state
11449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        Parcelable superState = super.onSaveInstanceState();
11459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        SavedState ss = new SavedState(superState);
11469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
11479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        ss.progress = mProgress;
11489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        ss.secondaryProgress = mSecondaryProgress;
11499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
11509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return ss;
11519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
11529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
11539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    @Override
11549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public void onRestoreInstanceState(Parcelable state) {
11559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        SavedState ss = (SavedState) state;
11569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        super.onRestoreInstanceState(ss.getSuperState());
11579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
11589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        setProgress(ss.progress);
11599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        setSecondaryProgress(ss.secondaryProgress);
11609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
116152a35433cfdd2c177e3c642ae8a35998f1ace1e9David Sobreira Marques
116252a35433cfdd2c177e3c642ae8a35998f1ace1e9David Sobreira Marques    @Override
116352a35433cfdd2c177e3c642ae8a35998f1ace1e9David Sobreira Marques    protected void onAttachedToWindow() {
116452a35433cfdd2c177e3c642ae8a35998f1ace1e9David Sobreira Marques        super.onAttachedToWindow();
116552a35433cfdd2c177e3c642ae8a35998f1ace1e9David Sobreira Marques        if (mIndeterminate) {
116652a35433cfdd2c177e3c642ae8a35998f1ace1e9David Sobreira Marques            startAnimation();
116752a35433cfdd2c177e3c642ae8a35998f1ace1e9David Sobreira Marques        }
1168a050663feb6309c63867abd746cdf97388e289a4Adam Powell        if (mRefreshData != null) {
1169a050663feb6309c63867abd746cdf97388e289a4Adam Powell            synchronized (this) {
1170a050663feb6309c63867abd746cdf97388e289a4Adam Powell                final int count = mRefreshData.size();
1171a050663feb6309c63867abd746cdf97388e289a4Adam Powell                for (int i = 0; i < count; i++) {
1172a050663feb6309c63867abd746cdf97388e289a4Adam Powell                    final RefreshData rd = mRefreshData.get(i);
1173a050663feb6309c63867abd746cdf97388e289a4Adam Powell                    doRefreshProgress(rd.id, rd.progress, rd.fromUser, true);
1174a050663feb6309c63867abd746cdf97388e289a4Adam Powell                    rd.recycle();
1175a050663feb6309c63867abd746cdf97388e289a4Adam Powell                }
1176a050663feb6309c63867abd746cdf97388e289a4Adam Powell                mRefreshData.clear();
1177a050663feb6309c63867abd746cdf97388e289a4Adam Powell            }
1178a050663feb6309c63867abd746cdf97388e289a4Adam Powell        }
1179a050663feb6309c63867abd746cdf97388e289a4Adam Powell        mAttached = true;
118052a35433cfdd2c177e3c642ae8a35998f1ace1e9David Sobreira Marques    }
118152a35433cfdd2c177e3c642ae8a35998f1ace1e9David Sobreira Marques
118252a35433cfdd2c177e3c642ae8a35998f1ace1e9David Sobreira Marques    @Override
118352a35433cfdd2c177e3c642ae8a35998f1ace1e9David Sobreira Marques    protected void onDetachedFromWindow() {
118452a35433cfdd2c177e3c642ae8a35998f1ace1e9David Sobreira Marques        if (mIndeterminate) {
118552a35433cfdd2c177e3c642ae8a35998f1ace1e9David Sobreira Marques            stopAnimation();
118652a35433cfdd2c177e3c642ae8a35998f1ace1e9David Sobreira Marques        }
1187a050663feb6309c63867abd746cdf97388e289a4Adam Powell        if (mRefreshProgressRunnable != null) {
1188a050663feb6309c63867abd746cdf97388e289a4Adam Powell            removeCallbacks(mRefreshProgressRunnable);
1189a050663feb6309c63867abd746cdf97388e289a4Adam Powell        }
1190a050663feb6309c63867abd746cdf97388e289a4Adam Powell        if (mRefreshProgressRunnable != null && mRefreshIsPosted) {
11916518ad760f98a0aa5db8c49ce1564bf5907a2c15Svetoslav Ganov            removeCallbacks(mRefreshProgressRunnable);
11926518ad760f98a0aa5db8c49ce1564bf5907a2c15Svetoslav Ganov        }
11936518ad760f98a0aa5db8c49ce1564bf5907a2c15Svetoslav Ganov        if (mAccessibilityEventSender != null) {
11946518ad760f98a0aa5db8c49ce1564bf5907a2c15Svetoslav Ganov            removeCallbacks(mAccessibilityEventSender);
11956518ad760f98a0aa5db8c49ce1564bf5907a2c15Svetoslav Ganov        }
1196ec84c3a189e4aa70aa6ea8ba712e5a4f260a153bPatrick Dubroy        // This should come after stopAnimation(), otherwise an invalidate message remains in the
1197ec84c3a189e4aa70aa6ea8ba712e5a4f260a153bPatrick Dubroy        // queue, which can prevent the entire view hierarchy from being GC'ed during a rotation
1198ec84c3a189e4aa70aa6ea8ba712e5a4f260a153bPatrick Dubroy        super.onDetachedFromWindow();
1199a050663feb6309c63867abd746cdf97388e289a4Adam Powell        mAttached = false;
120052a35433cfdd2c177e3c642ae8a35998f1ace1e9David Sobreira Marques    }
12016518ad760f98a0aa5db8c49ce1564bf5907a2c15Svetoslav Ganov
12026518ad760f98a0aa5db8c49ce1564bf5907a2c15Svetoslav Ganov    @Override
120330401328c1026389171d454c934c15875c3f7ff0Svetoslav Ganov    public void onInitializeAccessibilityEvent(AccessibilityEvent event) {
120430401328c1026389171d454c934c15875c3f7ff0Svetoslav Ganov        super.onInitializeAccessibilityEvent(event);
12058a78fd4d9572dff95432fcc4ba0e87563415b728Svetoslav Ganov        event.setClassName(ProgressBar.class.getName());
1206736c2756bf3c14ae9fef7255c119057f7a2be1edSvetoslav Ganov        event.setItemCount(mMax);
1207736c2756bf3c14ae9fef7255c119057f7a2be1edSvetoslav Ganov        event.setCurrentItemIndex(mProgress);
12086518ad760f98a0aa5db8c49ce1564bf5907a2c15Svetoslav Ganov    }
12096518ad760f98a0aa5db8c49ce1564bf5907a2c15Svetoslav Ganov
12108a78fd4d9572dff95432fcc4ba0e87563415b728Svetoslav Ganov    @Override
12118a78fd4d9572dff95432fcc4ba0e87563415b728Svetoslav Ganov    public void onInitializeAccessibilityNodeInfo(AccessibilityNodeInfo info) {
12128a78fd4d9572dff95432fcc4ba0e87563415b728Svetoslav Ganov        super.onInitializeAccessibilityNodeInfo(info);
12138a78fd4d9572dff95432fcc4ba0e87563415b728Svetoslav Ganov        info.setClassName(ProgressBar.class.getName());
12148a78fd4d9572dff95432fcc4ba0e87563415b728Svetoslav Ganov    }
12158a78fd4d9572dff95432fcc4ba0e87563415b728Svetoslav Ganov
12166518ad760f98a0aa5db8c49ce1564bf5907a2c15Svetoslav Ganov    /**
12176518ad760f98a0aa5db8c49ce1564bf5907a2c15Svetoslav Ganov     * Schedule a command for sending an accessibility event.
12186518ad760f98a0aa5db8c49ce1564bf5907a2c15Svetoslav Ganov     * </br>
12196518ad760f98a0aa5db8c49ce1564bf5907a2c15Svetoslav Ganov     * Note: A command is used to ensure that accessibility events
12206518ad760f98a0aa5db8c49ce1564bf5907a2c15Svetoslav Ganov     *       are sent at most one in a given time frame to save
12216518ad760f98a0aa5db8c49ce1564bf5907a2c15Svetoslav Ganov     *       system resources while the progress changes quickly.
12226518ad760f98a0aa5db8c49ce1564bf5907a2c15Svetoslav Ganov     */
12236518ad760f98a0aa5db8c49ce1564bf5907a2c15Svetoslav Ganov    private void scheduleAccessibilityEventSender() {
12246518ad760f98a0aa5db8c49ce1564bf5907a2c15Svetoslav Ganov        if (mAccessibilityEventSender == null) {
12256518ad760f98a0aa5db8c49ce1564bf5907a2c15Svetoslav Ganov            mAccessibilityEventSender = new AccessibilityEventSender();
12266518ad760f98a0aa5db8c49ce1564bf5907a2c15Svetoslav Ganov        } else {
12276518ad760f98a0aa5db8c49ce1564bf5907a2c15Svetoslav Ganov            removeCallbacks(mAccessibilityEventSender);
12286518ad760f98a0aa5db8c49ce1564bf5907a2c15Svetoslav Ganov        }
12296518ad760f98a0aa5db8c49ce1564bf5907a2c15Svetoslav Ganov        postDelayed(mAccessibilityEventSender, TIMEOUT_SEND_ACCESSIBILITY_EVENT);
12306518ad760f98a0aa5db8c49ce1564bf5907a2c15Svetoslav Ganov    }
12316518ad760f98a0aa5db8c49ce1564bf5907a2c15Svetoslav Ganov
12326518ad760f98a0aa5db8c49ce1564bf5907a2c15Svetoslav Ganov    /**
12336518ad760f98a0aa5db8c49ce1564bf5907a2c15Svetoslav Ganov     * Command for sending an accessibility event.
12346518ad760f98a0aa5db8c49ce1564bf5907a2c15Svetoslav Ganov     */
12356518ad760f98a0aa5db8c49ce1564bf5907a2c15Svetoslav Ganov    private class AccessibilityEventSender implements Runnable {
12366518ad760f98a0aa5db8c49ce1564bf5907a2c15Svetoslav Ganov        public void run() {
12376518ad760f98a0aa5db8c49ce1564bf5907a2c15Svetoslav Ganov            sendAccessibilityEvent(AccessibilityEvent.TYPE_VIEW_SELECTED);
12386518ad760f98a0aa5db8c49ce1564bf5907a2c15Svetoslav Ganov        }
12396518ad760f98a0aa5db8c49ce1564bf5907a2c15Svetoslav Ganov    }
12409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
1241