OSDN Git Service

Merge "Map KEY_VOICECOMMAND to KEYCODE_VOICE_ASSIST" into lmp-dev
[android-x86/frameworks-base.git] / core / java / android / view / View.java
1 /*
2  * Copyright (C) 2006 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16
17 package android.view;
18
19 import android.animation.AnimatorInflater;
20 import android.animation.StateListAnimator;
21 import android.annotation.IntDef;
22 import android.annotation.NonNull;
23 import android.annotation.Nullable;
24 import android.content.ClipData;
25 import android.content.Context;
26 import android.content.res.ColorStateList;
27 import android.content.res.Configuration;
28 import android.content.res.Resources;
29 import android.content.res.TypedArray;
30 import android.graphics.Bitmap;
31 import android.graphics.Canvas;
32 import android.graphics.Insets;
33 import android.graphics.Interpolator;
34 import android.graphics.LinearGradient;
35 import android.graphics.Matrix;
36 import android.graphics.Outline;
37 import android.graphics.Paint;
38 import android.graphics.Path;
39 import android.graphics.PathMeasure;
40 import android.graphics.PixelFormat;
41 import android.graphics.Point;
42 import android.graphics.PorterDuff;
43 import android.graphics.PorterDuffXfermode;
44 import android.graphics.Rect;
45 import android.graphics.RectF;
46 import android.graphics.Region;
47 import android.graphics.Shader;
48 import android.graphics.drawable.ColorDrawable;
49 import android.graphics.drawable.Drawable;
50 import android.hardware.display.DisplayManagerGlobal;
51 import android.os.Bundle;
52 import android.os.Handler;
53 import android.os.IBinder;
54 import android.os.Parcel;
55 import android.os.Parcelable;
56 import android.os.RemoteException;
57 import android.os.SystemClock;
58 import android.os.SystemProperties;
59 import android.text.TextUtils;
60 import android.util.AttributeSet;
61 import android.util.FloatProperty;
62 import android.util.LayoutDirection;
63 import android.util.Log;
64 import android.util.LongSparseLongArray;
65 import android.util.Pools.SynchronizedPool;
66 import android.util.Property;
67 import android.util.SparseArray;
68 import android.util.SuperNotCalledException;
69 import android.util.TypedValue;
70 import android.view.ContextMenu.ContextMenuInfo;
71 import android.view.AccessibilityIterators.TextSegmentIterator;
72 import android.view.AccessibilityIterators.CharacterTextSegmentIterator;
73 import android.view.AccessibilityIterators.WordTextSegmentIterator;
74 import android.view.AccessibilityIterators.ParagraphTextSegmentIterator;
75 import android.view.accessibility.AccessibilityEvent;
76 import android.view.accessibility.AccessibilityEventSource;
77 import android.view.accessibility.AccessibilityManager;
78 import android.view.accessibility.AccessibilityNodeInfo;
79 import android.view.accessibility.AccessibilityNodeProvider;
80 import android.view.animation.Animation;
81 import android.view.animation.AnimationUtils;
82 import android.view.animation.Transformation;
83 import android.view.inputmethod.EditorInfo;
84 import android.view.inputmethod.InputConnection;
85 import android.view.inputmethod.InputMethodManager;
86 import android.widget.ScrollBarDrawable;
87
88 import static android.os.Build.VERSION_CODES.*;
89 import static java.lang.Math.max;
90
91 import com.android.internal.R;
92 import com.android.internal.util.Predicate;
93 import com.android.internal.view.menu.MenuBuilder;
94 import com.google.android.collect.Lists;
95 import com.google.android.collect.Maps;
96
97 import java.lang.annotation.Retention;
98 import java.lang.annotation.RetentionPolicy;
99 import java.lang.ref.WeakReference;
100 import java.lang.reflect.Field;
101 import java.lang.reflect.InvocationTargetException;
102 import java.lang.reflect.Method;
103 import java.lang.reflect.Modifier;
104 import java.util.ArrayList;
105 import java.util.Arrays;
106 import java.util.Collections;
107 import java.util.HashMap;
108 import java.util.List;
109 import java.util.Locale;
110 import java.util.Map;
111 import java.util.concurrent.CopyOnWriteArrayList;
112 import java.util.concurrent.atomic.AtomicInteger;
113
114 /**
115  * <p>
116  * This class represents the basic building block for user interface components. A View
117  * occupies a rectangular area on the screen and is responsible for drawing and
118  * event handling. View is the base class for <em>widgets</em>, which are
119  * used to create interactive UI components (buttons, text fields, etc.). The
120  * {@link android.view.ViewGroup} subclass is the base class for <em>layouts</em>, which
121  * are invisible containers that hold other Views (or other ViewGroups) and define
122  * their layout properties.
123  * </p>
124  *
125  * <div class="special reference">
126  * <h3>Developer Guides</h3>
127  * <p>For information about using this class to develop your application's user interface,
128  * read the <a href="{@docRoot}guide/topics/ui/index.html">User Interface</a> developer guide.
129  * </div>
130  *
131  * <a name="Using"></a>
132  * <h3>Using Views</h3>
133  * <p>
134  * All of the views in a window are arranged in a single tree. You can add views
135  * either from code or by specifying a tree of views in one or more XML layout
136  * files. There are many specialized subclasses of views that act as controls or
137  * are capable of displaying text, images, or other content.
138  * </p>
139  * <p>
140  * Once you have created a tree of views, there are typically a few types of
141  * common operations you may wish to perform:
142  * <ul>
143  * <li><strong>Set properties:</strong> for example setting the text of a
144  * {@link android.widget.TextView}. The available properties and the methods
145  * that set them will vary among the different subclasses of views. Note that
146  * properties that are known at build time can be set in the XML layout
147  * files.</li>
148  * <li><strong>Set focus:</strong> The framework will handled moving focus in
149  * response to user input. To force focus to a specific view, call
150  * {@link #requestFocus}.</li>
151  * <li><strong>Set up listeners:</strong> Views allow clients to set listeners
152  * that will be notified when something interesting happens to the view. For
153  * example, all views will let you set a listener to be notified when the view
154  * gains or loses focus. You can register such a listener using
155  * {@link #setOnFocusChangeListener(android.view.View.OnFocusChangeListener)}.
156  * Other view subclasses offer more specialized listeners. For example, a Button
157  * exposes a listener to notify clients when the button is clicked.</li>
158  * <li><strong>Set visibility:</strong> You can hide or show views using
159  * {@link #setVisibility(int)}.</li>
160  * </ul>
161  * </p>
162  * <p><em>
163  * Note: The Android framework is responsible for measuring, laying out and
164  * drawing views. You should not call methods that perform these actions on
165  * views yourself unless you are actually implementing a
166  * {@link android.view.ViewGroup}.
167  * </em></p>
168  *
169  * <a name="Lifecycle"></a>
170  * <h3>Implementing a Custom View</h3>
171  *
172  * <p>
173  * To implement a custom view, you will usually begin by providing overrides for
174  * some of the standard methods that the framework calls on all views. You do
175  * not need to override all of these methods. In fact, you can start by just
176  * overriding {@link #onDraw(android.graphics.Canvas)}.
177  * <table border="2" width="85%" align="center" cellpadding="5">
178  *     <thead>
179  *         <tr><th>Category</th> <th>Methods</th> <th>Description</th></tr>
180  *     </thead>
181  *
182  *     <tbody>
183  *     <tr>
184  *         <td rowspan="2">Creation</td>
185  *         <td>Constructors</td>
186  *         <td>There is a form of the constructor that are called when the view
187  *         is created from code and a form that is called when the view is
188  *         inflated from a layout file. The second form should parse and apply
189  *         any attributes defined in the layout file.
190  *         </td>
191  *     </tr>
192  *     <tr>
193  *         <td><code>{@link #onFinishInflate()}</code></td>
194  *         <td>Called after a view and all of its children has been inflated
195  *         from XML.</td>
196  *     </tr>
197  *
198  *     <tr>
199  *         <td rowspan="3">Layout</td>
200  *         <td><code>{@link #onMeasure(int, int)}</code></td>
201  *         <td>Called to determine the size requirements for this view and all
202  *         of its children.
203  *         </td>
204  *     </tr>
205  *     <tr>
206  *         <td><code>{@link #onLayout(boolean, int, int, int, int)}</code></td>
207  *         <td>Called when this view should assign a size and position to all
208  *         of its children.
209  *         </td>
210  *     </tr>
211  *     <tr>
212  *         <td><code>{@link #onSizeChanged(int, int, int, int)}</code></td>
213  *         <td>Called when the size of this view has changed.
214  *         </td>
215  *     </tr>
216  *
217  *     <tr>
218  *         <td>Drawing</td>
219  *         <td><code>{@link #onDraw(android.graphics.Canvas)}</code></td>
220  *         <td>Called when the view should render its content.
221  *         </td>
222  *     </tr>
223  *
224  *     <tr>
225  *         <td rowspan="4">Event processing</td>
226  *         <td><code>{@link #onKeyDown(int, KeyEvent)}</code></td>
227  *         <td>Called when a new hardware key event occurs.
228  *         </td>
229  *     </tr>
230  *     <tr>
231  *         <td><code>{@link #onKeyUp(int, KeyEvent)}</code></td>
232  *         <td>Called when a hardware key up event occurs.
233  *         </td>
234  *     </tr>
235  *     <tr>
236  *         <td><code>{@link #onTrackballEvent(MotionEvent)}</code></td>
237  *         <td>Called when a trackball motion event occurs.
238  *         </td>
239  *     </tr>
240  *     <tr>
241  *         <td><code>{@link #onTouchEvent(MotionEvent)}</code></td>
242  *         <td>Called when a touch screen motion event occurs.
243  *         </td>
244  *     </tr>
245  *
246  *     <tr>
247  *         <td rowspan="2">Focus</td>
248  *         <td><code>{@link #onFocusChanged(boolean, int, android.graphics.Rect)}</code></td>
249  *         <td>Called when the view gains or loses focus.
250  *         </td>
251  *     </tr>
252  *
253  *     <tr>
254  *         <td><code>{@link #onWindowFocusChanged(boolean)}</code></td>
255  *         <td>Called when the window containing the view gains or loses focus.
256  *         </td>
257  *     </tr>
258  *
259  *     <tr>
260  *         <td rowspan="3">Attaching</td>
261  *         <td><code>{@link #onAttachedToWindow()}</code></td>
262  *         <td>Called when the view is attached to a window.
263  *         </td>
264  *     </tr>
265  *
266  *     <tr>
267  *         <td><code>{@link #onDetachedFromWindow}</code></td>
268  *         <td>Called when the view is detached from its window.
269  *         </td>
270  *     </tr>
271  *
272  *     <tr>
273  *         <td><code>{@link #onWindowVisibilityChanged(int)}</code></td>
274  *         <td>Called when the visibility of the window containing the view
275  *         has changed.
276  *         </td>
277  *     </tr>
278  *     </tbody>
279  *
280  * </table>
281  * </p>
282  *
283  * <a name="IDs"></a>
284  * <h3>IDs</h3>
285  * Views may have an integer id associated with them. These ids are typically
286  * assigned in the layout XML files, and are used to find specific views within
287  * the view tree. A common pattern is to:
288  * <ul>
289  * <li>Define a Button in the layout file and assign it a unique ID.
290  * <pre>
291  * &lt;Button
292  *     android:id="@+id/my_button"
293  *     android:layout_width="wrap_content"
294  *     android:layout_height="wrap_content"
295  *     android:text="@string/my_button_text"/&gt;
296  * </pre></li>
297  * <li>From the onCreate method of an Activity, find the Button
298  * <pre class="prettyprint">
299  *      Button myButton = (Button) findViewById(R.id.my_button);
300  * </pre></li>
301  * </ul>
302  * <p>
303  * View IDs need not be unique throughout the tree, but it is good practice to
304  * ensure that they are at least unique within the part of the tree you are
305  * searching.
306  * </p>
307  *
308  * <a name="Position"></a>
309  * <h3>Position</h3>
310  * <p>
311  * The geometry of a view is that of a rectangle. A view has a location,
312  * expressed as a pair of <em>left</em> and <em>top</em> coordinates, and
313  * two dimensions, expressed as a width and a height. The unit for location
314  * and dimensions is the pixel.
315  * </p>
316  *
317  * <p>
318  * It is possible to retrieve the location of a view by invoking the methods
319  * {@link #getLeft()} and {@link #getTop()}. The former returns the left, or X,
320  * coordinate of the rectangle representing the view. The latter returns the
321  * top, or Y, coordinate of the rectangle representing the view. These methods
322  * both return the location of the view relative to its parent. For instance,
323  * when getLeft() returns 20, that means the view is located 20 pixels to the
324  * right of the left edge of its direct parent.
325  * </p>
326  *
327  * <p>
328  * In addition, several convenience methods are offered to avoid unnecessary
329  * computations, namely {@link #getRight()} and {@link #getBottom()}.
330  * These methods return the coordinates of the right and bottom edges of the
331  * rectangle representing the view. For instance, calling {@link #getRight()}
332  * is similar to the following computation: <code>getLeft() + getWidth()</code>
333  * (see <a href="#SizePaddingMargins">Size</a> for more information about the width.)
334  * </p>
335  *
336  * <a name="SizePaddingMargins"></a>
337  * <h3>Size, padding and margins</h3>
338  * <p>
339  * The size of a view is expressed with a width and a height. A view actually
340  * possess two pairs of width and height values.
341  * </p>
342  *
343  * <p>
344  * The first pair is known as <em>measured width</em> and
345  * <em>measured height</em>. These dimensions define how big a view wants to be
346  * within its parent (see <a href="#Layout">Layout</a> for more details.) The
347  * measured dimensions can be obtained by calling {@link #getMeasuredWidth()}
348  * and {@link #getMeasuredHeight()}.
349  * </p>
350  *
351  * <p>
352  * The second pair is simply known as <em>width</em> and <em>height</em>, or
353  * sometimes <em>drawing width</em> and <em>drawing height</em>. These
354  * dimensions define the actual size of the view on screen, at drawing time and
355  * after layout. These values may, but do not have to, be different from the
356  * measured width and height. The width and height can be obtained by calling
357  * {@link #getWidth()} and {@link #getHeight()}.
358  * </p>
359  *
360  * <p>
361  * To measure its dimensions, a view takes into account its padding. The padding
362  * is expressed in pixels for the left, top, right and bottom parts of the view.
363  * Padding can be used to offset the content of the view by a specific amount of
364  * pixels. For instance, a left padding of 2 will push the view's content by
365  * 2 pixels to the right of the left edge. Padding can be set using the
366  * {@link #setPadding(int, int, int, int)} or {@link #setPaddingRelative(int, int, int, int)}
367  * method and queried by calling {@link #getPaddingLeft()}, {@link #getPaddingTop()},
368  * {@link #getPaddingRight()}, {@link #getPaddingBottom()}, {@link #getPaddingStart()},
369  * {@link #getPaddingEnd()}.
370  * </p>
371  *
372  * <p>
373  * Even though a view can define a padding, it does not provide any support for
374  * margins. However, view groups provide such a support. Refer to
375  * {@link android.view.ViewGroup} and
376  * {@link android.view.ViewGroup.MarginLayoutParams} for further information.
377  * </p>
378  *
379  * <a name="Layout"></a>
380  * <h3>Layout</h3>
381  * <p>
382  * Layout is a two pass process: a measure pass and a layout pass. The measuring
383  * pass is implemented in {@link #measure(int, int)} and is a top-down traversal
384  * of the view tree. Each view pushes dimension specifications down the tree
385  * during the recursion. At the end of the measure pass, every view has stored
386  * its measurements. The second pass happens in
387  * {@link #layout(int,int,int,int)} and is also top-down. During
388  * this pass each parent is responsible for positioning all of its children
389  * using the sizes computed in the measure pass.
390  * </p>
391  *
392  * <p>
393  * When a view's measure() method returns, its {@link #getMeasuredWidth()} and
394  * {@link #getMeasuredHeight()} values must be set, along with those for all of
395  * that view's descendants. A view's measured width and measured height values
396  * must respect the constraints imposed by the view's parents. This guarantees
397  * that at the end of the measure pass, all parents accept all of their
398  * children's measurements. A parent view may call measure() more than once on
399  * its children. For example, the parent may measure each child once with
400  * unspecified dimensions to find out how big they want to be, then call
401  * measure() on them again with actual numbers if the sum of all the children's
402  * unconstrained sizes is too big or too small.
403  * </p>
404  *
405  * <p>
406  * The measure pass uses two classes to communicate dimensions. The
407  * {@link MeasureSpec} class is used by views to tell their parents how they
408  * want to be measured and positioned. The base LayoutParams class just
409  * describes how big the view wants to be for both width and height. For each
410  * dimension, it can specify one of:
411  * <ul>
412  * <li> an exact number
413  * <li>MATCH_PARENT, which means the view wants to be as big as its parent
414  * (minus padding)
415  * <li> WRAP_CONTENT, which means that the view wants to be just big enough to
416  * enclose its content (plus padding).
417  * </ul>
418  * There are subclasses of LayoutParams for different subclasses of ViewGroup.
419  * For example, AbsoluteLayout has its own subclass of LayoutParams which adds
420  * an X and Y value.
421  * </p>
422  *
423  * <p>
424  * MeasureSpecs are used to push requirements down the tree from parent to
425  * child. A MeasureSpec can be in one of three modes:
426  * <ul>
427  * <li>UNSPECIFIED: This is used by a parent to determine the desired dimension
428  * of a child view. For example, a LinearLayout may call measure() on its child
429  * with the height set to UNSPECIFIED and a width of EXACTLY 240 to find out how
430  * tall the child view wants to be given a width of 240 pixels.
431  * <li>EXACTLY: This is used by the parent to impose an exact size on the
432  * child. The child must use this size, and guarantee that all of its
433  * descendants will fit within this size.
434  * <li>AT_MOST: This is used by the parent to impose a maximum size on the
435  * child. The child must guarantee that it and all of its descendants will fit
436  * within this size.
437  * </ul>
438  * </p>
439  *
440  * <p>
441  * To intiate a layout, call {@link #requestLayout}. This method is typically
442  * called by a view on itself when it believes that is can no longer fit within
443  * its current bounds.
444  * </p>
445  *
446  * <a name="Drawing"></a>
447  * <h3>Drawing</h3>
448  * <p>
449  * Drawing is handled by walking the tree and recording the drawing commands of
450  * any View that needs to update. After this, the drawing commands of the
451  * entire tree are issued to screen, clipped to the newly damaged area.
452  * </p>
453  *
454  * <p>
455  * The tree is largely recorded and drawn in order, with parents drawn before
456  * (i.e., behind) their children, with siblings drawn in the order they appear
457  * in the tree. If you set a background drawable for a View, then the View will
458  * draw it before calling back to its <code>onDraw()</code> method. The child
459  * drawing order can be overridden with
460  * {@link ViewGroup#setChildrenDrawingOrderEnabled(boolean) custom child drawing order}
461  * in a ViewGroup, and with {@link #setZ(float)} custom Z values} set on Views.
462  * </p>
463  *
464  * <p>
465  * To force a view to draw, call {@link #invalidate()}.
466  * </p>
467  *
468  * <a name="EventHandlingThreading"></a>
469  * <h3>Event Handling and Threading</h3>
470  * <p>
471  * The basic cycle of a view is as follows:
472  * <ol>
473  * <li>An event comes in and is dispatched to the appropriate view. The view
474  * handles the event and notifies any listeners.</li>
475  * <li>If in the course of processing the event, the view's bounds may need
476  * to be changed, the view will call {@link #requestLayout()}.</li>
477  * <li>Similarly, if in the course of processing the event the view's appearance
478  * may need to be changed, the view will call {@link #invalidate()}.</li>
479  * <li>If either {@link #requestLayout()} or {@link #invalidate()} were called,
480  * the framework will take care of measuring, laying out, and drawing the tree
481  * as appropriate.</li>
482  * </ol>
483  * </p>
484  *
485  * <p><em>Note: The entire view tree is single threaded. You must always be on
486  * the UI thread when calling any method on any view.</em>
487  * If you are doing work on other threads and want to update the state of a view
488  * from that thread, you should use a {@link Handler}.
489  * </p>
490  *
491  * <a name="FocusHandling"></a>
492  * <h3>Focus Handling</h3>
493  * <p>
494  * The framework will handle routine focus movement in response to user input.
495  * This includes changing the focus as views are removed or hidden, or as new
496  * views become available. Views indicate their willingness to take focus
497  * through the {@link #isFocusable} method. To change whether a view can take
498  * focus, call {@link #setFocusable(boolean)}.  When in touch mode (see notes below)
499  * views indicate whether they still would like focus via {@link #isFocusableInTouchMode}
500  * and can change this via {@link #setFocusableInTouchMode(boolean)}.
501  * </p>
502  * <p>
503  * Focus movement is based on an algorithm which finds the nearest neighbor in a
504  * given direction. In rare cases, the default algorithm may not match the
505  * intended behavior of the developer. In these situations, you can provide
506  * explicit overrides by using these XML attributes in the layout file:
507  * <pre>
508  * nextFocusDown
509  * nextFocusLeft
510  * nextFocusRight
511  * nextFocusUp
512  * </pre>
513  * </p>
514  *
515  *
516  * <p>
517  * To get a particular view to take focus, call {@link #requestFocus()}.
518  * </p>
519  *
520  * <a name="TouchMode"></a>
521  * <h3>Touch Mode</h3>
522  * <p>
523  * When a user is navigating a user interface via directional keys such as a D-pad, it is
524  * necessary to give focus to actionable items such as buttons so the user can see
525  * what will take input.  If the device has touch capabilities, however, and the user
526  * begins interacting with the interface by touching it, it is no longer necessary to
527  * always highlight, or give focus to, a particular view.  This motivates a mode
528  * for interaction named 'touch mode'.
529  * </p>
530  * <p>
531  * For a touch capable device, once the user touches the screen, the device
532  * will enter touch mode.  From this point onward, only views for which
533  * {@link #isFocusableInTouchMode} is true will be focusable, such as text editing widgets.
534  * Other views that are touchable, like buttons, will not take focus when touched; they will
535  * only fire the on click listeners.
536  * </p>
537  * <p>
538  * Any time a user hits a directional key, such as a D-pad direction, the view device will
539  * exit touch mode, and find a view to take focus, so that the user may resume interacting
540  * with the user interface without touching the screen again.
541  * </p>
542  * <p>
543  * The touch mode state is maintained across {@link android.app.Activity}s.  Call
544  * {@link #isInTouchMode} to see whether the device is currently in touch mode.
545  * </p>
546  *
547  * <a name="Scrolling"></a>
548  * <h3>Scrolling</h3>
549  * <p>
550  * The framework provides basic support for views that wish to internally
551  * scroll their content. This includes keeping track of the X and Y scroll
552  * offset as well as mechanisms for drawing scrollbars. See
553  * {@link #scrollBy(int, int)}, {@link #scrollTo(int, int)}, and
554  * {@link #awakenScrollBars()} for more details.
555  * </p>
556  *
557  * <a name="Tags"></a>
558  * <h3>Tags</h3>
559  * <p>
560  * Unlike IDs, tags are not used to identify views. Tags are essentially an
561  * extra piece of information that can be associated with a view. They are most
562  * often used as a convenience to store data related to views in the views
563  * themselves rather than by putting them in a separate structure.
564  * </p>
565  *
566  * <a name="Properties"></a>
567  * <h3>Properties</h3>
568  * <p>
569  * The View class exposes an {@link #ALPHA} property, as well as several transform-related
570  * properties, such as {@link #TRANSLATION_X} and {@link #TRANSLATION_Y}. These properties are
571  * available both in the {@link Property} form as well as in similarly-named setter/getter
572  * methods (such as {@link #setAlpha(float)} for {@link #ALPHA}). These properties can
573  * be used to set persistent state associated with these rendering-related properties on the view.
574  * The properties and methods can also be used in conjunction with
575  * {@link android.animation.Animator Animator}-based animations, described more in the
576  * <a href="#Animation">Animation</a> section.
577  * </p>
578  *
579  * <a name="Animation"></a>
580  * <h3>Animation</h3>
581  * <p>
582  * Starting with Android 3.0, the preferred way of animating views is to use the
583  * {@link android.animation} package APIs. These {@link android.animation.Animator Animator}-based
584  * classes change actual properties of the View object, such as {@link #setAlpha(float) alpha} and
585  * {@link #setTranslationX(float) translationX}. This behavior is contrasted to that of the pre-3.0
586  * {@link android.view.animation.Animation Animation}-based classes, which instead animate only
587  * how the view is drawn on the display. In particular, the {@link ViewPropertyAnimator} class
588  * makes animating these View properties particularly easy and efficient.
589  * </p>
590  * <p>
591  * Alternatively, you can use the pre-3.0 animation classes to animate how Views are rendered.
592  * You can attach an {@link Animation} object to a view using
593  * {@link #setAnimation(Animation)} or
594  * {@link #startAnimation(Animation)}. The animation can alter the scale,
595  * rotation, translation and alpha of a view over time. If the animation is
596  * attached to a view that has children, the animation will affect the entire
597  * subtree rooted by that node. When an animation is started, the framework will
598  * take care of redrawing the appropriate views until the animation completes.
599  * </p>
600  *
601  * <a name="Security"></a>
602  * <h3>Security</h3>
603  * <p>
604  * Sometimes it is essential that an application be able to verify that an action
605  * is being performed with the full knowledge and consent of the user, such as
606  * granting a permission request, making a purchase or clicking on an advertisement.
607  * Unfortunately, a malicious application could try to spoof the user into
608  * performing these actions, unaware, by concealing the intended purpose of the view.
609  * As a remedy, the framework offers a touch filtering mechanism that can be used to
610  * improve the security of views that provide access to sensitive functionality.
611  * </p><p>
612  * To enable touch filtering, call {@link #setFilterTouchesWhenObscured(boolean)} or set the
613  * android:filterTouchesWhenObscured layout attribute to true.  When enabled, the framework
614  * will discard touches that are received whenever the view's window is obscured by
615  * another visible window.  As a result, the view will not receive touches whenever a
616  * toast, dialog or other window appears above the view's window.
617  * </p><p>
618  * For more fine-grained control over security, consider overriding the
619  * {@link #onFilterTouchEventForSecurity(MotionEvent)} method to implement your own
620  * security policy. See also {@link MotionEvent#FLAG_WINDOW_IS_OBSCURED}.
621  * </p>
622  *
623  * @attr ref android.R.styleable#View_alpha
624  * @attr ref android.R.styleable#View_background
625  * @attr ref android.R.styleable#View_clickable
626  * @attr ref android.R.styleable#View_contentDescription
627  * @attr ref android.R.styleable#View_drawingCacheQuality
628  * @attr ref android.R.styleable#View_duplicateParentState
629  * @attr ref android.R.styleable#View_id
630  * @attr ref android.R.styleable#View_requiresFadingEdge
631  * @attr ref android.R.styleable#View_fadeScrollbars
632  * @attr ref android.R.styleable#View_fadingEdgeLength
633  * @attr ref android.R.styleable#View_filterTouchesWhenObscured
634  * @attr ref android.R.styleable#View_fitsSystemWindows
635  * @attr ref android.R.styleable#View_isScrollContainer
636  * @attr ref android.R.styleable#View_focusable
637  * @attr ref android.R.styleable#View_focusableInTouchMode
638  * @attr ref android.R.styleable#View_hapticFeedbackEnabled
639  * @attr ref android.R.styleable#View_keepScreenOn
640  * @attr ref android.R.styleable#View_layerType
641  * @attr ref android.R.styleable#View_layoutDirection
642  * @attr ref android.R.styleable#View_longClickable
643  * @attr ref android.R.styleable#View_minHeight
644  * @attr ref android.R.styleable#View_minWidth
645  * @attr ref android.R.styleable#View_nextFocusDown
646  * @attr ref android.R.styleable#View_nextFocusLeft
647  * @attr ref android.R.styleable#View_nextFocusRight
648  * @attr ref android.R.styleable#View_nextFocusUp
649  * @attr ref android.R.styleable#View_onClick
650  * @attr ref android.R.styleable#View_padding
651  * @attr ref android.R.styleable#View_paddingBottom
652  * @attr ref android.R.styleable#View_paddingLeft
653  * @attr ref android.R.styleable#View_paddingRight
654  * @attr ref android.R.styleable#View_paddingTop
655  * @attr ref android.R.styleable#View_paddingStart
656  * @attr ref android.R.styleable#View_paddingEnd
657  * @attr ref android.R.styleable#View_saveEnabled
658  * @attr ref android.R.styleable#View_rotation
659  * @attr ref android.R.styleable#View_rotationX
660  * @attr ref android.R.styleable#View_rotationY
661  * @attr ref android.R.styleable#View_scaleX
662  * @attr ref android.R.styleable#View_scaleY
663  * @attr ref android.R.styleable#View_scrollX
664  * @attr ref android.R.styleable#View_scrollY
665  * @attr ref android.R.styleable#View_scrollbarSize
666  * @attr ref android.R.styleable#View_scrollbarStyle
667  * @attr ref android.R.styleable#View_scrollbars
668  * @attr ref android.R.styleable#View_scrollbarDefaultDelayBeforeFade
669  * @attr ref android.R.styleable#View_scrollbarFadeDuration
670  * @attr ref android.R.styleable#View_scrollbarTrackHorizontal
671  * @attr ref android.R.styleable#View_scrollbarThumbHorizontal
672  * @attr ref android.R.styleable#View_scrollbarThumbVertical
673  * @attr ref android.R.styleable#View_scrollbarTrackVertical
674  * @attr ref android.R.styleable#View_scrollbarAlwaysDrawHorizontalTrack
675  * @attr ref android.R.styleable#View_scrollbarAlwaysDrawVerticalTrack
676  * @attr ref android.R.styleable#View_stateListAnimator
677  * @attr ref android.R.styleable#View_transitionName
678  * @attr ref android.R.styleable#View_soundEffectsEnabled
679  * @attr ref android.R.styleable#View_tag
680  * @attr ref android.R.styleable#View_textAlignment
681  * @attr ref android.R.styleable#View_textDirection
682  * @attr ref android.R.styleable#View_transformPivotX
683  * @attr ref android.R.styleable#View_transformPivotY
684  * @attr ref android.R.styleable#View_translationX
685  * @attr ref android.R.styleable#View_translationY
686  * @attr ref android.R.styleable#View_translationZ
687  * @attr ref android.R.styleable#View_visibility
688  *
689  * @see android.view.ViewGroup
690  */
691 public class View implements Drawable.Callback, KeyEvent.Callback,
692         AccessibilityEventSource {
693     private static final boolean DBG = false;
694
695     /**
696      * The logging tag used by this class with android.util.Log.
697      */
698     protected static final String VIEW_LOG_TAG = "View";
699
700     /**
701      * When set to true, apps will draw debugging information about their layouts.
702      *
703      * @hide
704      */
705     public static final String DEBUG_LAYOUT_PROPERTY = "debug.layout";
706
707     /**
708      * When set to true, this view will save its attribute data.
709      *
710      * @hide
711      */
712     public static boolean mDebugViewAttributes = false;
713
714     /**
715      * Used to mark a View that has no ID.
716      */
717     public static final int NO_ID = -1;
718
719     /**
720      * Signals that compatibility booleans have been initialized according to
721      * target SDK versions.
722      */
723     private static boolean sCompatibilityDone = false;
724
725     /**
726      * Use the old (broken) way of building MeasureSpecs.
727      */
728     private static boolean sUseBrokenMakeMeasureSpec = false;
729
730     /**
731      * Ignore any optimizations using the measure cache.
732      */
733     private static boolean sIgnoreMeasureCache = false;
734
735     /**
736      * This view does not want keystrokes. Use with TAKES_FOCUS_MASK when
737      * calling setFlags.
738      */
739     private static final int NOT_FOCUSABLE = 0x00000000;
740
741     /**
742      * This view wants keystrokes. Use with TAKES_FOCUS_MASK when calling
743      * setFlags.
744      */
745     private static final int FOCUSABLE = 0x00000001;
746
747     /**
748      * Mask for use with setFlags indicating bits used for focus.
749      */
750     private static final int FOCUSABLE_MASK = 0x00000001;
751
752     /**
753      * This view will adjust its padding to fit sytem windows (e.g. status bar)
754      */
755     private static final int FITS_SYSTEM_WINDOWS = 0x00000002;
756
757     /** @hide */
758     @IntDef({VISIBLE, INVISIBLE, GONE})
759     @Retention(RetentionPolicy.SOURCE)
760     public @interface Visibility {}
761
762     /**
763      * This view is visible.
764      * Use with {@link #setVisibility} and <a href="#attr_android:visibility">{@code
765      * android:visibility}.
766      */
767     public static final int VISIBLE = 0x00000000;
768
769     /**
770      * This view is invisible, but it still takes up space for layout purposes.
771      * Use with {@link #setVisibility} and <a href="#attr_android:visibility">{@code
772      * android:visibility}.
773      */
774     public static final int INVISIBLE = 0x00000004;
775
776     /**
777      * This view is invisible, and it doesn't take any space for layout
778      * purposes. Use with {@link #setVisibility} and <a href="#attr_android:visibility">{@code
779      * android:visibility}.
780      */
781     public static final int GONE = 0x00000008;
782
783     /**
784      * Mask for use with setFlags indicating bits used for visibility.
785      * {@hide}
786      */
787     static final int VISIBILITY_MASK = 0x0000000C;
788
789     private static final int[] VISIBILITY_FLAGS = {VISIBLE, INVISIBLE, GONE};
790
791     /**
792      * This view is enabled. Interpretation varies by subclass.
793      * Use with ENABLED_MASK when calling setFlags.
794      * {@hide}
795      */
796     static final int ENABLED = 0x00000000;
797
798     /**
799      * This view is disabled. Interpretation varies by subclass.
800      * Use with ENABLED_MASK when calling setFlags.
801      * {@hide}
802      */
803     static final int DISABLED = 0x00000020;
804
805    /**
806     * Mask for use with setFlags indicating bits used for indicating whether
807     * this view is enabled
808     * {@hide}
809     */
810     static final int ENABLED_MASK = 0x00000020;
811
812     /**
813      * This view won't draw. {@link #onDraw(android.graphics.Canvas)} won't be
814      * called and further optimizations will be performed. It is okay to have
815      * this flag set and a background. Use with DRAW_MASK when calling setFlags.
816      * {@hide}
817      */
818     static final int WILL_NOT_DRAW = 0x00000080;
819
820     /**
821      * Mask for use with setFlags indicating bits used for indicating whether
822      * this view is will draw
823      * {@hide}
824      */
825     static final int DRAW_MASK = 0x00000080;
826
827     /**
828      * <p>This view doesn't show scrollbars.</p>
829      * {@hide}
830      */
831     static final int SCROLLBARS_NONE = 0x00000000;
832
833     /**
834      * <p>This view shows horizontal scrollbars.</p>
835      * {@hide}
836      */
837     static final int SCROLLBARS_HORIZONTAL = 0x00000100;
838
839     /**
840      * <p>This view shows vertical scrollbars.</p>
841      * {@hide}
842      */
843     static final int SCROLLBARS_VERTICAL = 0x00000200;
844
845     /**
846      * <p>Mask for use with setFlags indicating bits used for indicating which
847      * scrollbars are enabled.</p>
848      * {@hide}
849      */
850     static final int SCROLLBARS_MASK = 0x00000300;
851
852     /**
853      * Indicates that the view should filter touches when its window is obscured.
854      * Refer to the class comments for more information about this security feature.
855      * {@hide}
856      */
857     static final int FILTER_TOUCHES_WHEN_OBSCURED = 0x00000400;
858
859     /**
860      * Set for framework elements that use FITS_SYSTEM_WINDOWS, to indicate
861      * that they are optional and should be skipped if the window has
862      * requested system UI flags that ignore those insets for layout.
863      */
864     static final int OPTIONAL_FITS_SYSTEM_WINDOWS = 0x00000800;
865
866     /**
867      * <p>This view doesn't show fading edges.</p>
868      * {@hide}
869      */
870     static final int FADING_EDGE_NONE = 0x00000000;
871
872     /**
873      * <p>This view shows horizontal fading edges.</p>
874      * {@hide}
875      */
876     static final int FADING_EDGE_HORIZONTAL = 0x00001000;
877
878     /**
879      * <p>This view shows vertical fading edges.</p>
880      * {@hide}
881      */
882     static final int FADING_EDGE_VERTICAL = 0x00002000;
883
884     /**
885      * <p>Mask for use with setFlags indicating bits used for indicating which
886      * fading edges are enabled.</p>
887      * {@hide}
888      */
889     static final int FADING_EDGE_MASK = 0x00003000;
890
891     /**
892      * <p>Indicates this view can be clicked. When clickable, a View reacts
893      * to clicks by notifying the OnClickListener.<p>
894      * {@hide}
895      */
896     static final int CLICKABLE = 0x00004000;
897
898     /**
899      * <p>Indicates this view is caching its drawing into a bitmap.</p>
900      * {@hide}
901      */
902     static final int DRAWING_CACHE_ENABLED = 0x00008000;
903
904     /**
905      * <p>Indicates that no icicle should be saved for this view.<p>
906      * {@hide}
907      */
908     static final int SAVE_DISABLED = 0x000010000;
909
910     /**
911      * <p>Mask for use with setFlags indicating bits used for the saveEnabled
912      * property.</p>
913      * {@hide}
914      */
915     static final int SAVE_DISABLED_MASK = 0x000010000;
916
917     /**
918      * <p>Indicates that no drawing cache should ever be created for this view.<p>
919      * {@hide}
920      */
921     static final int WILL_NOT_CACHE_DRAWING = 0x000020000;
922
923     /**
924      * <p>Indicates this view can take / keep focus when int touch mode.</p>
925      * {@hide}
926      */
927     static final int FOCUSABLE_IN_TOUCH_MODE = 0x00040000;
928
929     /** @hide */
930     @Retention(RetentionPolicy.SOURCE)
931     @IntDef({DRAWING_CACHE_QUALITY_LOW, DRAWING_CACHE_QUALITY_HIGH, DRAWING_CACHE_QUALITY_AUTO})
932     public @interface DrawingCacheQuality {}
933
934     /**
935      * <p>Enables low quality mode for the drawing cache.</p>
936      */
937     public static final int DRAWING_CACHE_QUALITY_LOW = 0x00080000;
938
939     /**
940      * <p>Enables high quality mode for the drawing cache.</p>
941      */
942     public static final int DRAWING_CACHE_QUALITY_HIGH = 0x00100000;
943
944     /**
945      * <p>Enables automatic quality mode for the drawing cache.</p>
946      */
947     public static final int DRAWING_CACHE_QUALITY_AUTO = 0x00000000;
948
949     private static final int[] DRAWING_CACHE_QUALITY_FLAGS = {
950             DRAWING_CACHE_QUALITY_AUTO, DRAWING_CACHE_QUALITY_LOW, DRAWING_CACHE_QUALITY_HIGH
951     };
952
953     /**
954      * <p>Mask for use with setFlags indicating bits used for the cache
955      * quality property.</p>
956      * {@hide}
957      */
958     static final int DRAWING_CACHE_QUALITY_MASK = 0x00180000;
959
960     /**
961      * <p>
962      * Indicates this view can be long clicked. When long clickable, a View
963      * reacts to long clicks by notifying the OnLongClickListener or showing a
964      * context menu.
965      * </p>
966      * {@hide}
967      */
968     static final int LONG_CLICKABLE = 0x00200000;
969
970     /**
971      * <p>Indicates that this view gets its drawable states from its direct parent
972      * and ignores its original internal states.</p>
973      *
974      * @hide
975      */
976     static final int DUPLICATE_PARENT_STATE = 0x00400000;
977
978     /** @hide */
979     @IntDef({
980         SCROLLBARS_INSIDE_OVERLAY,
981         SCROLLBARS_INSIDE_INSET,
982         SCROLLBARS_OUTSIDE_OVERLAY,
983         SCROLLBARS_OUTSIDE_INSET
984     })
985     @Retention(RetentionPolicy.SOURCE)
986     public @interface ScrollBarStyle {}
987
988     /**
989      * The scrollbar style to display the scrollbars inside the content area,
990      * without increasing the padding. The scrollbars will be overlaid with
991      * translucency on the view's content.
992      */
993     public static final int SCROLLBARS_INSIDE_OVERLAY = 0;
994
995     /**
996      * The scrollbar style to display the scrollbars inside the padded area,
997      * increasing the padding of the view. The scrollbars will not overlap the
998      * content area of the view.
999      */
1000     public static final int SCROLLBARS_INSIDE_INSET = 0x01000000;
1001
1002     /**
1003      * The scrollbar style to display the scrollbars at the edge of the view,
1004      * without increasing the padding. The scrollbars will be overlaid with
1005      * translucency.
1006      */
1007     public static final int SCROLLBARS_OUTSIDE_OVERLAY = 0x02000000;
1008
1009     /**
1010      * The scrollbar style to display the scrollbars at the edge of the view,
1011      * increasing the padding of the view. The scrollbars will only overlap the
1012      * background, if any.
1013      */
1014     public static final int SCROLLBARS_OUTSIDE_INSET = 0x03000000;
1015
1016     /**
1017      * Mask to check if the scrollbar style is overlay or inset.
1018      * {@hide}
1019      */
1020     static final int SCROLLBARS_INSET_MASK = 0x01000000;
1021
1022     /**
1023      * Mask to check if the scrollbar style is inside or outside.
1024      * {@hide}
1025      */
1026     static final int SCROLLBARS_OUTSIDE_MASK = 0x02000000;
1027
1028     /**
1029      * Mask for scrollbar style.
1030      * {@hide}
1031      */
1032     static final int SCROLLBARS_STYLE_MASK = 0x03000000;
1033
1034     /**
1035      * View flag indicating that the screen should remain on while the
1036      * window containing this view is visible to the user.  This effectively
1037      * takes care of automatically setting the WindowManager's
1038      * {@link WindowManager.LayoutParams#FLAG_KEEP_SCREEN_ON}.
1039      */
1040     public static final int KEEP_SCREEN_ON = 0x04000000;
1041
1042     /**
1043      * View flag indicating whether this view should have sound effects enabled
1044      * for events such as clicking and touching.
1045      */
1046     public static final int SOUND_EFFECTS_ENABLED = 0x08000000;
1047
1048     /**
1049      * View flag indicating whether this view should have haptic feedback
1050      * enabled for events such as long presses.
1051      */
1052     public static final int HAPTIC_FEEDBACK_ENABLED = 0x10000000;
1053
1054     /**
1055      * <p>Indicates that the view hierarchy should stop saving state when
1056      * it reaches this view.  If state saving is initiated immediately at
1057      * the view, it will be allowed.
1058      * {@hide}
1059      */
1060     static final int PARENT_SAVE_DISABLED = 0x20000000;
1061
1062     /**
1063      * <p>Mask for use with setFlags indicating bits used for PARENT_SAVE_DISABLED.</p>
1064      * {@hide}
1065      */
1066     static final int PARENT_SAVE_DISABLED_MASK = 0x20000000;
1067
1068     /** @hide */
1069     @IntDef(flag = true,
1070             value = {
1071                 FOCUSABLES_ALL,
1072                 FOCUSABLES_TOUCH_MODE
1073             })
1074     @Retention(RetentionPolicy.SOURCE)
1075     public @interface FocusableMode {}
1076
1077     /**
1078      * View flag indicating whether {@link #addFocusables(ArrayList, int, int)}
1079      * should add all focusable Views regardless if they are focusable in touch mode.
1080      */
1081     public static final int FOCUSABLES_ALL = 0x00000000;
1082
1083     /**
1084      * View flag indicating whether {@link #addFocusables(ArrayList, int, int)}
1085      * should add only Views focusable in touch mode.
1086      */
1087     public static final int FOCUSABLES_TOUCH_MODE = 0x00000001;
1088
1089     /** @hide */
1090     @IntDef({
1091             FOCUS_BACKWARD,
1092             FOCUS_FORWARD,
1093             FOCUS_LEFT,
1094             FOCUS_UP,
1095             FOCUS_RIGHT,
1096             FOCUS_DOWN
1097     })
1098     @Retention(RetentionPolicy.SOURCE)
1099     public @interface FocusDirection {}
1100
1101     /** @hide */
1102     @IntDef({
1103             FOCUS_LEFT,
1104             FOCUS_UP,
1105             FOCUS_RIGHT,
1106             FOCUS_DOWN
1107     })
1108     @Retention(RetentionPolicy.SOURCE)
1109     public @interface FocusRealDirection {} // Like @FocusDirection, but without forward/backward
1110
1111     /**
1112      * Use with {@link #focusSearch(int)}. Move focus to the previous selectable
1113      * item.
1114      */
1115     public static final int FOCUS_BACKWARD = 0x00000001;
1116
1117     /**
1118      * Use with {@link #focusSearch(int)}. Move focus to the next selectable
1119      * item.
1120      */
1121     public static final int FOCUS_FORWARD = 0x00000002;
1122
1123     /**
1124      * Use with {@link #focusSearch(int)}. Move focus to the left.
1125      */
1126     public static final int FOCUS_LEFT = 0x00000011;
1127
1128     /**
1129      * Use with {@link #focusSearch(int)}. Move focus up.
1130      */
1131     public static final int FOCUS_UP = 0x00000021;
1132
1133     /**
1134      * Use with {@link #focusSearch(int)}. Move focus to the right.
1135      */
1136     public static final int FOCUS_RIGHT = 0x00000042;
1137
1138     /**
1139      * Use with {@link #focusSearch(int)}. Move focus down.
1140      */
1141     public static final int FOCUS_DOWN = 0x00000082;
1142
1143     /**
1144      * Bits of {@link #getMeasuredWidthAndState()} and
1145      * {@link #getMeasuredWidthAndState()} that provide the actual measured size.
1146      */
1147     public static final int MEASURED_SIZE_MASK = 0x00ffffff;
1148
1149     /**
1150      * Bits of {@link #getMeasuredWidthAndState()} and
1151      * {@link #getMeasuredWidthAndState()} that provide the additional state bits.
1152      */
1153     public static final int MEASURED_STATE_MASK = 0xff000000;
1154
1155     /**
1156      * Bit shift of {@link #MEASURED_STATE_MASK} to get to the height bits
1157      * for functions that combine both width and height into a single int,
1158      * such as {@link #getMeasuredState()} and the childState argument of
1159      * {@link #resolveSizeAndState(int, int, int)}.
1160      */
1161     public static final int MEASURED_HEIGHT_STATE_SHIFT = 16;
1162
1163     /**
1164      * Bit of {@link #getMeasuredWidthAndState()} and
1165      * {@link #getMeasuredWidthAndState()} that indicates the measured size
1166      * is smaller that the space the view would like to have.
1167      */
1168     public static final int MEASURED_STATE_TOO_SMALL = 0x01000000;
1169
1170     /**
1171      * Base View state sets
1172      */
1173     // Singles
1174     /**
1175      * Indicates the view has no states set. States are used with
1176      * {@link android.graphics.drawable.Drawable} to change the drawing of the
1177      * view depending on its state.
1178      *
1179      * @see android.graphics.drawable.Drawable
1180      * @see #getDrawableState()
1181      */
1182     protected static final int[] EMPTY_STATE_SET;
1183     /**
1184      * Indicates the view is enabled. States are used with
1185      * {@link android.graphics.drawable.Drawable} to change the drawing of the
1186      * view depending on its state.
1187      *
1188      * @see android.graphics.drawable.Drawable
1189      * @see #getDrawableState()
1190      */
1191     protected static final int[] ENABLED_STATE_SET;
1192     /**
1193      * Indicates the view is focused. States are used with
1194      * {@link android.graphics.drawable.Drawable} to change the drawing of the
1195      * view depending on its state.
1196      *
1197      * @see android.graphics.drawable.Drawable
1198      * @see #getDrawableState()
1199      */
1200     protected static final int[] FOCUSED_STATE_SET;
1201     /**
1202      * Indicates the view is selected. States are used with
1203      * {@link android.graphics.drawable.Drawable} to change the drawing of the
1204      * view depending on its state.
1205      *
1206      * @see android.graphics.drawable.Drawable
1207      * @see #getDrawableState()
1208      */
1209     protected static final int[] SELECTED_STATE_SET;
1210     /**
1211      * Indicates the view is pressed. States are used with
1212      * {@link android.graphics.drawable.Drawable} to change the drawing of the
1213      * view depending on its state.
1214      *
1215      * @see android.graphics.drawable.Drawable
1216      * @see #getDrawableState()
1217      */
1218     protected static final int[] PRESSED_STATE_SET;
1219     /**
1220      * Indicates the view's window has focus. States are used with
1221      * {@link android.graphics.drawable.Drawable} to change the drawing of the
1222      * view depending on its state.
1223      *
1224      * @see android.graphics.drawable.Drawable
1225      * @see #getDrawableState()
1226      */
1227     protected static final int[] WINDOW_FOCUSED_STATE_SET;
1228     // Doubles
1229     /**
1230      * Indicates the view is enabled and has the focus.
1231      *
1232      * @see #ENABLED_STATE_SET
1233      * @see #FOCUSED_STATE_SET
1234      */
1235     protected static final int[] ENABLED_FOCUSED_STATE_SET;
1236     /**
1237      * Indicates the view is enabled and selected.
1238      *
1239      * @see #ENABLED_STATE_SET
1240      * @see #SELECTED_STATE_SET
1241      */
1242     protected static final int[] ENABLED_SELECTED_STATE_SET;
1243     /**
1244      * Indicates the view is enabled and that its window has focus.
1245      *
1246      * @see #ENABLED_STATE_SET
1247      * @see #WINDOW_FOCUSED_STATE_SET
1248      */
1249     protected static final int[] ENABLED_WINDOW_FOCUSED_STATE_SET;
1250     /**
1251      * Indicates the view is focused and selected.
1252      *
1253      * @see #FOCUSED_STATE_SET
1254      * @see #SELECTED_STATE_SET
1255      */
1256     protected static final int[] FOCUSED_SELECTED_STATE_SET;
1257     /**
1258      * Indicates the view has the focus and that its window has the focus.
1259      *
1260      * @see #FOCUSED_STATE_SET
1261      * @see #WINDOW_FOCUSED_STATE_SET
1262      */
1263     protected static final int[] FOCUSED_WINDOW_FOCUSED_STATE_SET;
1264     /**
1265      * Indicates the view is selected and that its window has the focus.
1266      *
1267      * @see #SELECTED_STATE_SET
1268      * @see #WINDOW_FOCUSED_STATE_SET
1269      */
1270     protected static final int[] SELECTED_WINDOW_FOCUSED_STATE_SET;
1271     // Triples
1272     /**
1273      * Indicates the view is enabled, focused and selected.
1274      *
1275      * @see #ENABLED_STATE_SET
1276      * @see #FOCUSED_STATE_SET
1277      * @see #SELECTED_STATE_SET
1278      */
1279     protected static final int[] ENABLED_FOCUSED_SELECTED_STATE_SET;
1280     /**
1281      * Indicates the view is enabled, focused and its window has the focus.
1282      *
1283      * @see #ENABLED_STATE_SET
1284      * @see #FOCUSED_STATE_SET
1285      * @see #WINDOW_FOCUSED_STATE_SET
1286      */
1287     protected static final int[] ENABLED_FOCUSED_WINDOW_FOCUSED_STATE_SET;
1288     /**
1289      * Indicates the view is enabled, selected and its window has the focus.
1290      *
1291      * @see #ENABLED_STATE_SET
1292      * @see #SELECTED_STATE_SET
1293      * @see #WINDOW_FOCUSED_STATE_SET
1294      */
1295     protected static final int[] ENABLED_SELECTED_WINDOW_FOCUSED_STATE_SET;
1296     /**
1297      * Indicates the view is focused, selected and its window has the focus.
1298      *
1299      * @see #FOCUSED_STATE_SET
1300      * @see #SELECTED_STATE_SET
1301      * @see #WINDOW_FOCUSED_STATE_SET
1302      */
1303     protected static final int[] FOCUSED_SELECTED_WINDOW_FOCUSED_STATE_SET;
1304     /**
1305      * Indicates the view is enabled, focused, selected and its window
1306      * has the focus.
1307      *
1308      * @see #ENABLED_STATE_SET
1309      * @see #FOCUSED_STATE_SET
1310      * @see #SELECTED_STATE_SET
1311      * @see #WINDOW_FOCUSED_STATE_SET
1312      */
1313     protected static final int[] ENABLED_FOCUSED_SELECTED_WINDOW_FOCUSED_STATE_SET;
1314     /**
1315      * Indicates the view is pressed and its window has the focus.
1316      *
1317      * @see #PRESSED_STATE_SET
1318      * @see #WINDOW_FOCUSED_STATE_SET
1319      */
1320     protected static final int[] PRESSED_WINDOW_FOCUSED_STATE_SET;
1321     /**
1322      * Indicates the view is pressed and selected.
1323      *
1324      * @see #PRESSED_STATE_SET
1325      * @see #SELECTED_STATE_SET
1326      */
1327     protected static final int[] PRESSED_SELECTED_STATE_SET;
1328     /**
1329      * Indicates the view is pressed, selected and its window has the focus.
1330      *
1331      * @see #PRESSED_STATE_SET
1332      * @see #SELECTED_STATE_SET
1333      * @see #WINDOW_FOCUSED_STATE_SET
1334      */
1335     protected static final int[] PRESSED_SELECTED_WINDOW_FOCUSED_STATE_SET;
1336     /**
1337      * Indicates the view is pressed and focused.
1338      *
1339      * @see #PRESSED_STATE_SET
1340      * @see #FOCUSED_STATE_SET
1341      */
1342     protected static final int[] PRESSED_FOCUSED_STATE_SET;
1343     /**
1344      * Indicates the view is pressed, focused and its window has the focus.
1345      *
1346      * @see #PRESSED_STATE_SET
1347      * @see #FOCUSED_STATE_SET
1348      * @see #WINDOW_FOCUSED_STATE_SET
1349      */
1350     protected static final int[] PRESSED_FOCUSED_WINDOW_FOCUSED_STATE_SET;
1351     /**
1352      * Indicates the view is pressed, focused and selected.
1353      *
1354      * @see #PRESSED_STATE_SET
1355      * @see #SELECTED_STATE_SET
1356      * @see #FOCUSED_STATE_SET
1357      */
1358     protected static final int[] PRESSED_FOCUSED_SELECTED_STATE_SET;
1359     /**
1360      * Indicates the view is pressed, focused, selected and its window has the focus.
1361      *
1362      * @see #PRESSED_STATE_SET
1363      * @see #FOCUSED_STATE_SET
1364      * @see #SELECTED_STATE_SET
1365      * @see #WINDOW_FOCUSED_STATE_SET
1366      */
1367     protected static final int[] PRESSED_FOCUSED_SELECTED_WINDOW_FOCUSED_STATE_SET;
1368     /**
1369      * Indicates the view is pressed and enabled.
1370      *
1371      * @see #PRESSED_STATE_SET
1372      * @see #ENABLED_STATE_SET
1373      */
1374     protected static final int[] PRESSED_ENABLED_STATE_SET;
1375     /**
1376      * Indicates the view is pressed, enabled and its window has the focus.
1377      *
1378      * @see #PRESSED_STATE_SET
1379      * @see #ENABLED_STATE_SET
1380      * @see #WINDOW_FOCUSED_STATE_SET
1381      */
1382     protected static final int[] PRESSED_ENABLED_WINDOW_FOCUSED_STATE_SET;
1383     /**
1384      * Indicates the view is pressed, enabled and selected.
1385      *
1386      * @see #PRESSED_STATE_SET
1387      * @see #ENABLED_STATE_SET
1388      * @see #SELECTED_STATE_SET
1389      */
1390     protected static final int[] PRESSED_ENABLED_SELECTED_STATE_SET;
1391     /**
1392      * Indicates the view is pressed, enabled, selected and its window has the
1393      * focus.
1394      *
1395      * @see #PRESSED_STATE_SET
1396      * @see #ENABLED_STATE_SET
1397      * @see #SELECTED_STATE_SET
1398      * @see #WINDOW_FOCUSED_STATE_SET
1399      */
1400     protected static final int[] PRESSED_ENABLED_SELECTED_WINDOW_FOCUSED_STATE_SET;
1401     /**
1402      * Indicates the view is pressed, enabled and focused.
1403      *
1404      * @see #PRESSED_STATE_SET
1405      * @see #ENABLED_STATE_SET
1406      * @see #FOCUSED_STATE_SET
1407      */
1408     protected static final int[] PRESSED_ENABLED_FOCUSED_STATE_SET;
1409     /**
1410      * Indicates the view is pressed, enabled, focused and its window has the
1411      * focus.
1412      *
1413      * @see #PRESSED_STATE_SET
1414      * @see #ENABLED_STATE_SET
1415      * @see #FOCUSED_STATE_SET
1416      * @see #WINDOW_FOCUSED_STATE_SET
1417      */
1418     protected static final int[] PRESSED_ENABLED_FOCUSED_WINDOW_FOCUSED_STATE_SET;
1419     /**
1420      * Indicates the view is pressed, enabled, focused and selected.
1421      *
1422      * @see #PRESSED_STATE_SET
1423      * @see #ENABLED_STATE_SET
1424      * @see #SELECTED_STATE_SET
1425      * @see #FOCUSED_STATE_SET
1426      */
1427     protected static final int[] PRESSED_ENABLED_FOCUSED_SELECTED_STATE_SET;
1428     /**
1429      * Indicates the view is pressed, enabled, focused, selected and its window
1430      * has the focus.
1431      *
1432      * @see #PRESSED_STATE_SET
1433      * @see #ENABLED_STATE_SET
1434      * @see #SELECTED_STATE_SET
1435      * @see #FOCUSED_STATE_SET
1436      * @see #WINDOW_FOCUSED_STATE_SET
1437      */
1438     protected static final int[] PRESSED_ENABLED_FOCUSED_SELECTED_WINDOW_FOCUSED_STATE_SET;
1439
1440     /**
1441      * The order here is very important to {@link #getDrawableState()}
1442      */
1443     private static final int[][] VIEW_STATE_SETS;
1444
1445     static final int VIEW_STATE_WINDOW_FOCUSED = 1;
1446     static final int VIEW_STATE_SELECTED = 1 << 1;
1447     static final int VIEW_STATE_FOCUSED = 1 << 2;
1448     static final int VIEW_STATE_ENABLED = 1 << 3;
1449     static final int VIEW_STATE_PRESSED = 1 << 4;
1450     static final int VIEW_STATE_ACTIVATED = 1 << 5;
1451     static final int VIEW_STATE_ACCELERATED = 1 << 6;
1452     static final int VIEW_STATE_HOVERED = 1 << 7;
1453     static final int VIEW_STATE_DRAG_CAN_ACCEPT = 1 << 8;
1454     static final int VIEW_STATE_DRAG_HOVERED = 1 << 9;
1455
1456     static final int[] VIEW_STATE_IDS = new int[] {
1457         R.attr.state_window_focused,    VIEW_STATE_WINDOW_FOCUSED,
1458         R.attr.state_selected,          VIEW_STATE_SELECTED,
1459         R.attr.state_focused,           VIEW_STATE_FOCUSED,
1460         R.attr.state_enabled,           VIEW_STATE_ENABLED,
1461         R.attr.state_pressed,           VIEW_STATE_PRESSED,
1462         R.attr.state_activated,         VIEW_STATE_ACTIVATED,
1463         R.attr.state_accelerated,       VIEW_STATE_ACCELERATED,
1464         R.attr.state_hovered,           VIEW_STATE_HOVERED,
1465         R.attr.state_drag_can_accept,   VIEW_STATE_DRAG_CAN_ACCEPT,
1466         R.attr.state_drag_hovered,      VIEW_STATE_DRAG_HOVERED
1467     };
1468
1469     static {
1470         if ((VIEW_STATE_IDS.length/2) != R.styleable.ViewDrawableStates.length) {
1471             throw new IllegalStateException(
1472                     "VIEW_STATE_IDs array length does not match ViewDrawableStates style array");
1473         }
1474         int[] orderedIds = new int[VIEW_STATE_IDS.length];
1475         for (int i = 0; i < R.styleable.ViewDrawableStates.length; i++) {
1476             int viewState = R.styleable.ViewDrawableStates[i];
1477             for (int j = 0; j<VIEW_STATE_IDS.length; j += 2) {
1478                 if (VIEW_STATE_IDS[j] == viewState) {
1479                     orderedIds[i * 2] = viewState;
1480                     orderedIds[i * 2 + 1] = VIEW_STATE_IDS[j + 1];
1481                 }
1482             }
1483         }
1484         final int NUM_BITS = VIEW_STATE_IDS.length / 2;
1485         VIEW_STATE_SETS = new int[1 << NUM_BITS][];
1486         for (int i = 0; i < VIEW_STATE_SETS.length; i++) {
1487             int numBits = Integer.bitCount(i);
1488             int[] set = new int[numBits];
1489             int pos = 0;
1490             for (int j = 0; j < orderedIds.length; j += 2) {
1491                 if ((i & orderedIds[j+1]) != 0) {
1492                     set[pos++] = orderedIds[j];
1493                 }
1494             }
1495             VIEW_STATE_SETS[i] = set;
1496         }
1497
1498         EMPTY_STATE_SET = VIEW_STATE_SETS[0];
1499         WINDOW_FOCUSED_STATE_SET = VIEW_STATE_SETS[VIEW_STATE_WINDOW_FOCUSED];
1500         SELECTED_STATE_SET = VIEW_STATE_SETS[VIEW_STATE_SELECTED];
1501         SELECTED_WINDOW_FOCUSED_STATE_SET = VIEW_STATE_SETS[
1502                 VIEW_STATE_WINDOW_FOCUSED | VIEW_STATE_SELECTED];
1503         FOCUSED_STATE_SET = VIEW_STATE_SETS[VIEW_STATE_FOCUSED];
1504         FOCUSED_WINDOW_FOCUSED_STATE_SET = VIEW_STATE_SETS[
1505                 VIEW_STATE_WINDOW_FOCUSED | VIEW_STATE_FOCUSED];
1506         FOCUSED_SELECTED_STATE_SET = VIEW_STATE_SETS[
1507                 VIEW_STATE_SELECTED | VIEW_STATE_FOCUSED];
1508         FOCUSED_SELECTED_WINDOW_FOCUSED_STATE_SET = VIEW_STATE_SETS[
1509                 VIEW_STATE_WINDOW_FOCUSED | VIEW_STATE_SELECTED
1510                 | VIEW_STATE_FOCUSED];
1511         ENABLED_STATE_SET = VIEW_STATE_SETS[VIEW_STATE_ENABLED];
1512         ENABLED_WINDOW_FOCUSED_STATE_SET = VIEW_STATE_SETS[
1513                 VIEW_STATE_WINDOW_FOCUSED | VIEW_STATE_ENABLED];
1514         ENABLED_SELECTED_STATE_SET = VIEW_STATE_SETS[
1515                 VIEW_STATE_SELECTED | VIEW_STATE_ENABLED];
1516         ENABLED_SELECTED_WINDOW_FOCUSED_STATE_SET = VIEW_STATE_SETS[
1517                 VIEW_STATE_WINDOW_FOCUSED | VIEW_STATE_SELECTED
1518                 | VIEW_STATE_ENABLED];
1519         ENABLED_FOCUSED_STATE_SET = VIEW_STATE_SETS[
1520                 VIEW_STATE_FOCUSED | VIEW_STATE_ENABLED];
1521         ENABLED_FOCUSED_WINDOW_FOCUSED_STATE_SET = VIEW_STATE_SETS[
1522                 VIEW_STATE_WINDOW_FOCUSED | VIEW_STATE_FOCUSED
1523                 | VIEW_STATE_ENABLED];
1524         ENABLED_FOCUSED_SELECTED_STATE_SET = VIEW_STATE_SETS[
1525                 VIEW_STATE_SELECTED | VIEW_STATE_FOCUSED
1526                 | VIEW_STATE_ENABLED];
1527         ENABLED_FOCUSED_SELECTED_WINDOW_FOCUSED_STATE_SET = VIEW_STATE_SETS[
1528                 VIEW_STATE_WINDOW_FOCUSED | VIEW_STATE_SELECTED
1529                 | VIEW_STATE_FOCUSED| VIEW_STATE_ENABLED];
1530
1531         PRESSED_STATE_SET = VIEW_STATE_SETS[VIEW_STATE_PRESSED];
1532         PRESSED_WINDOW_FOCUSED_STATE_SET = VIEW_STATE_SETS[
1533                 VIEW_STATE_WINDOW_FOCUSED | VIEW_STATE_PRESSED];
1534         PRESSED_SELECTED_STATE_SET = VIEW_STATE_SETS[
1535                 VIEW_STATE_SELECTED | VIEW_STATE_PRESSED];
1536         PRESSED_SELECTED_WINDOW_FOCUSED_STATE_SET = VIEW_STATE_SETS[
1537                 VIEW_STATE_WINDOW_FOCUSED | VIEW_STATE_SELECTED
1538                 | VIEW_STATE_PRESSED];
1539         PRESSED_FOCUSED_STATE_SET = VIEW_STATE_SETS[
1540                 VIEW_STATE_FOCUSED | VIEW_STATE_PRESSED];
1541         PRESSED_FOCUSED_WINDOW_FOCUSED_STATE_SET = VIEW_STATE_SETS[
1542                 VIEW_STATE_WINDOW_FOCUSED | VIEW_STATE_FOCUSED
1543                 | VIEW_STATE_PRESSED];
1544         PRESSED_FOCUSED_SELECTED_STATE_SET = VIEW_STATE_SETS[
1545                 VIEW_STATE_SELECTED | VIEW_STATE_FOCUSED
1546                 | VIEW_STATE_PRESSED];
1547         PRESSED_FOCUSED_SELECTED_WINDOW_FOCUSED_STATE_SET = VIEW_STATE_SETS[
1548                 VIEW_STATE_WINDOW_FOCUSED | VIEW_STATE_SELECTED
1549                 | VIEW_STATE_FOCUSED | VIEW_STATE_PRESSED];
1550         PRESSED_ENABLED_STATE_SET = VIEW_STATE_SETS[
1551                 VIEW_STATE_ENABLED | VIEW_STATE_PRESSED];
1552         PRESSED_ENABLED_WINDOW_FOCUSED_STATE_SET = VIEW_STATE_SETS[
1553                 VIEW_STATE_WINDOW_FOCUSED | VIEW_STATE_ENABLED
1554                 | VIEW_STATE_PRESSED];
1555         PRESSED_ENABLED_SELECTED_STATE_SET = VIEW_STATE_SETS[
1556                 VIEW_STATE_SELECTED | VIEW_STATE_ENABLED
1557                 | VIEW_STATE_PRESSED];
1558         PRESSED_ENABLED_SELECTED_WINDOW_FOCUSED_STATE_SET = VIEW_STATE_SETS[
1559                 VIEW_STATE_WINDOW_FOCUSED | VIEW_STATE_SELECTED
1560                 | VIEW_STATE_ENABLED | VIEW_STATE_PRESSED];
1561         PRESSED_ENABLED_FOCUSED_STATE_SET = VIEW_STATE_SETS[
1562                 VIEW_STATE_FOCUSED | VIEW_STATE_ENABLED
1563                 | VIEW_STATE_PRESSED];
1564         PRESSED_ENABLED_FOCUSED_WINDOW_FOCUSED_STATE_SET = VIEW_STATE_SETS[
1565                 VIEW_STATE_WINDOW_FOCUSED | VIEW_STATE_FOCUSED
1566                 | VIEW_STATE_ENABLED | VIEW_STATE_PRESSED];
1567         PRESSED_ENABLED_FOCUSED_SELECTED_STATE_SET = VIEW_STATE_SETS[
1568                 VIEW_STATE_SELECTED | VIEW_STATE_FOCUSED
1569                 | VIEW_STATE_ENABLED | VIEW_STATE_PRESSED];
1570         PRESSED_ENABLED_FOCUSED_SELECTED_WINDOW_FOCUSED_STATE_SET = VIEW_STATE_SETS[
1571                 VIEW_STATE_WINDOW_FOCUSED | VIEW_STATE_SELECTED
1572                 | VIEW_STATE_FOCUSED| VIEW_STATE_ENABLED
1573                 | VIEW_STATE_PRESSED];
1574     }
1575
1576     /**
1577      * Accessibility event types that are dispatched for text population.
1578      */
1579     private static final int POPULATING_ACCESSIBILITY_EVENT_TYPES =
1580             AccessibilityEvent.TYPE_VIEW_CLICKED
1581             | AccessibilityEvent.TYPE_VIEW_LONG_CLICKED
1582             | AccessibilityEvent.TYPE_VIEW_SELECTED
1583             | AccessibilityEvent.TYPE_VIEW_FOCUSED
1584             | AccessibilityEvent.TYPE_WINDOW_STATE_CHANGED
1585             | AccessibilityEvent.TYPE_VIEW_HOVER_ENTER
1586             | AccessibilityEvent.TYPE_VIEW_HOVER_EXIT
1587             | AccessibilityEvent.TYPE_VIEW_TEXT_CHANGED
1588             | AccessibilityEvent.TYPE_VIEW_TEXT_SELECTION_CHANGED
1589             | AccessibilityEvent.TYPE_VIEW_ACCESSIBILITY_FOCUSED
1590             | AccessibilityEvent.TYPE_VIEW_TEXT_TRAVERSED_AT_MOVEMENT_GRANULARITY;
1591
1592     /**
1593      * Temporary Rect currently for use in setBackground().  This will probably
1594      * be extended in the future to hold our own class with more than just
1595      * a Rect. :)
1596      */
1597     static final ThreadLocal<Rect> sThreadLocal = new ThreadLocal<Rect>();
1598
1599     /**
1600      * Map used to store views' tags.
1601      */
1602     private SparseArray<Object> mKeyedTags;
1603
1604     /**
1605      * The next available accessibility id.
1606      */
1607     private static int sNextAccessibilityViewId;
1608
1609     /**
1610      * The animation currently associated with this view.
1611      * @hide
1612      */
1613     protected Animation mCurrentAnimation = null;
1614
1615     /**
1616      * Width as measured during measure pass.
1617      * {@hide}
1618      */
1619     @ViewDebug.ExportedProperty(category = "measurement")
1620     int mMeasuredWidth;
1621
1622     /**
1623      * Height as measured during measure pass.
1624      * {@hide}
1625      */
1626     @ViewDebug.ExportedProperty(category = "measurement")
1627     int mMeasuredHeight;
1628
1629     /**
1630      * Flag to indicate that this view was marked INVALIDATED, or had its display list
1631      * invalidated, prior to the current drawing iteration. If true, the view must re-draw
1632      * its display list. This flag, used only when hw accelerated, allows us to clear the
1633      * flag while retaining this information until it's needed (at getDisplayList() time and
1634      * in drawChild(), when we decide to draw a view's children's display lists into our own).
1635      *
1636      * {@hide}
1637      */
1638     boolean mRecreateDisplayList = false;
1639
1640     /**
1641      * The view's identifier.
1642      * {@hide}
1643      *
1644      * @see #setId(int)
1645      * @see #getId()
1646      */
1647     @ViewDebug.ExportedProperty(resolveId = true)
1648     int mID = NO_ID;
1649
1650     /**
1651      * The stable ID of this view for accessibility purposes.
1652      */
1653     int mAccessibilityViewId = NO_ID;
1654
1655     private int mAccessibilityCursorPosition = ACCESSIBILITY_CURSOR_POSITION_UNDEFINED;
1656
1657     SendViewStateChangedAccessibilityEvent mSendViewStateChangedAccessibilityEvent;
1658
1659     /**
1660      * The view's tag.
1661      * {@hide}
1662      *
1663      * @see #setTag(Object)
1664      * @see #getTag()
1665      */
1666     protected Object mTag = null;
1667
1668     // for mPrivateFlags:
1669     /** {@hide} */
1670     static final int PFLAG_WANTS_FOCUS                 = 0x00000001;
1671     /** {@hide} */
1672     static final int PFLAG_FOCUSED                     = 0x00000002;
1673     /** {@hide} */
1674     static final int PFLAG_SELECTED                    = 0x00000004;
1675     /** {@hide} */
1676     static final int PFLAG_IS_ROOT_NAMESPACE           = 0x00000008;
1677     /** {@hide} */
1678     static final int PFLAG_HAS_BOUNDS                  = 0x00000010;
1679     /** {@hide} */
1680     static final int PFLAG_DRAWN                       = 0x00000020;
1681     /**
1682      * When this flag is set, this view is running an animation on behalf of its
1683      * children and should therefore not cancel invalidate requests, even if they
1684      * lie outside of this view's bounds.
1685      *
1686      * {@hide}
1687      */
1688     static final int PFLAG_DRAW_ANIMATION              = 0x00000040;
1689     /** {@hide} */
1690     static final int PFLAG_SKIP_DRAW                   = 0x00000080;
1691     /** {@hide} */
1692     static final int PFLAG_ONLY_DRAWS_BACKGROUND       = 0x00000100;
1693     /** {@hide} */
1694     static final int PFLAG_REQUEST_TRANSPARENT_REGIONS = 0x00000200;
1695     /** {@hide} */
1696     static final int PFLAG_DRAWABLE_STATE_DIRTY        = 0x00000400;
1697     /** {@hide} */
1698     static final int PFLAG_MEASURED_DIMENSION_SET      = 0x00000800;
1699     /** {@hide} */
1700     static final int PFLAG_FORCE_LAYOUT                = 0x00001000;
1701     /** {@hide} */
1702     static final int PFLAG_LAYOUT_REQUIRED             = 0x00002000;
1703
1704     private static final int PFLAG_PRESSED             = 0x00004000;
1705
1706     /** {@hide} */
1707     static final int PFLAG_DRAWING_CACHE_VALID         = 0x00008000;
1708     /**
1709      * Flag used to indicate that this view should be drawn once more (and only once
1710      * more) after its animation has completed.
1711      * {@hide}
1712      */
1713     static final int PFLAG_ANIMATION_STARTED           = 0x00010000;
1714
1715     private static final int PFLAG_SAVE_STATE_CALLED   = 0x00020000;
1716
1717     /**
1718      * Indicates that the View returned true when onSetAlpha() was called and that
1719      * the alpha must be restored.
1720      * {@hide}
1721      */
1722     static final int PFLAG_ALPHA_SET                   = 0x00040000;
1723
1724     /**
1725      * Set by {@link #setScrollContainer(boolean)}.
1726      */
1727     static final int PFLAG_SCROLL_CONTAINER            = 0x00080000;
1728
1729     /**
1730      * Set by {@link #setScrollContainer(boolean)}.
1731      */
1732     static final int PFLAG_SCROLL_CONTAINER_ADDED      = 0x00100000;
1733
1734     /**
1735      * View flag indicating whether this view was invalidated (fully or partially.)
1736      *
1737      * @hide
1738      */
1739     static final int PFLAG_DIRTY                       = 0x00200000;
1740
1741     /**
1742      * View flag indicating whether this view was invalidated by an opaque
1743      * invalidate request.
1744      *
1745      * @hide
1746      */
1747     static final int PFLAG_DIRTY_OPAQUE                = 0x00400000;
1748
1749     /**
1750      * Mask for {@link #PFLAG_DIRTY} and {@link #PFLAG_DIRTY_OPAQUE}.
1751      *
1752      * @hide
1753      */
1754     static final int PFLAG_DIRTY_MASK                  = 0x00600000;
1755
1756     /**
1757      * Indicates whether the background is opaque.
1758      *
1759      * @hide
1760      */
1761     static final int PFLAG_OPAQUE_BACKGROUND           = 0x00800000;
1762
1763     /**
1764      * Indicates whether the scrollbars are opaque.
1765      *
1766      * @hide
1767      */
1768     static final int PFLAG_OPAQUE_SCROLLBARS           = 0x01000000;
1769
1770     /**
1771      * Indicates whether the view is opaque.
1772      *
1773      * @hide
1774      */
1775     static final int PFLAG_OPAQUE_MASK                 = 0x01800000;
1776
1777     /**
1778      * Indicates a prepressed state;
1779      * the short time between ACTION_DOWN and recognizing
1780      * a 'real' press. Prepressed is used to recognize quick taps
1781      * even when they are shorter than ViewConfiguration.getTapTimeout().
1782      *
1783      * @hide
1784      */
1785     private static final int PFLAG_PREPRESSED          = 0x02000000;
1786
1787     /**
1788      * Indicates whether the view is temporarily detached.
1789      *
1790      * @hide
1791      */
1792     static final int PFLAG_CANCEL_NEXT_UP_EVENT        = 0x04000000;
1793
1794     /**
1795      * Indicates that we should awaken scroll bars once attached
1796      *
1797      * @hide
1798      */
1799     private static final int PFLAG_AWAKEN_SCROLL_BARS_ON_ATTACH = 0x08000000;
1800
1801     /**
1802      * Indicates that the view has received HOVER_ENTER.  Cleared on HOVER_EXIT.
1803      * @hide
1804      */
1805     private static final int PFLAG_HOVERED             = 0x10000000;
1806
1807     /**
1808      * no longer needed, should be reused
1809      */
1810     private static final int PFLAG_DOES_NOTHING_REUSE_PLEASE = 0x20000000;
1811
1812     /** {@hide} */
1813     static final int PFLAG_ACTIVATED                   = 0x40000000;
1814
1815     /**
1816      * Indicates that this view was specifically invalidated, not just dirtied because some
1817      * child view was invalidated. The flag is used to determine when we need to recreate
1818      * a view's display list (as opposed to just returning a reference to its existing
1819      * display list).
1820      *
1821      * @hide
1822      */
1823     static final int PFLAG_INVALIDATED                 = 0x80000000;
1824
1825     /**
1826      * Masks for mPrivateFlags2, as generated by dumpFlags():
1827      *
1828      * |-------|-------|-------|-------|
1829      *                                 1 PFLAG2_DRAG_CAN_ACCEPT
1830      *                                1  PFLAG2_DRAG_HOVERED
1831      *                              11   PFLAG2_LAYOUT_DIRECTION_MASK
1832      *                             1     PFLAG2_LAYOUT_DIRECTION_RESOLVED_RTL
1833      *                            1      PFLAG2_LAYOUT_DIRECTION_RESOLVED
1834      *                            11     PFLAG2_LAYOUT_DIRECTION_RESOLVED_MASK
1835      *                           1       PFLAG2_TEXT_DIRECTION_FLAGS[1]
1836      *                          1        PFLAG2_TEXT_DIRECTION_FLAGS[2]
1837      *                          11       PFLAG2_TEXT_DIRECTION_FLAGS[3]
1838      *                         1         PFLAG2_TEXT_DIRECTION_FLAGS[4]
1839      *                         1 1       PFLAG2_TEXT_DIRECTION_FLAGS[5]
1840      *                         111       PFLAG2_TEXT_DIRECTION_MASK
1841      *                        1          PFLAG2_TEXT_DIRECTION_RESOLVED
1842      *                       1           PFLAG2_TEXT_DIRECTION_RESOLVED_DEFAULT
1843      *                     111           PFLAG2_TEXT_DIRECTION_RESOLVED_MASK
1844      *                    1              PFLAG2_TEXT_ALIGNMENT_FLAGS[1]
1845      *                   1               PFLAG2_TEXT_ALIGNMENT_FLAGS[2]
1846      *                   11              PFLAG2_TEXT_ALIGNMENT_FLAGS[3]
1847      *                  1                PFLAG2_TEXT_ALIGNMENT_FLAGS[4]
1848      *                  1 1              PFLAG2_TEXT_ALIGNMENT_FLAGS[5]
1849      *                  11               PFLAG2_TEXT_ALIGNMENT_FLAGS[6]
1850      *                  111              PFLAG2_TEXT_ALIGNMENT_MASK
1851      *                 1                 PFLAG2_TEXT_ALIGNMENT_RESOLVED
1852      *                1                  PFLAG2_TEXT_ALIGNMENT_RESOLVED_DEFAULT
1853      *              111                  PFLAG2_TEXT_ALIGNMENT_RESOLVED_MASK
1854      *           111                     PFLAG2_IMPORTANT_FOR_ACCESSIBILITY_MASK
1855      *         11                        PFLAG2_ACCESSIBILITY_LIVE_REGION_MASK
1856      *       1                           PFLAG2_ACCESSIBILITY_FOCUSED
1857      *      1                            PFLAG2_SUBTREE_ACCESSIBILITY_STATE_CHANGED
1858      *     1                             PFLAG2_VIEW_QUICK_REJECTED
1859      *    1                              PFLAG2_PADDING_RESOLVED
1860      *   1                               PFLAG2_DRAWABLE_RESOLVED
1861      *  1                                PFLAG2_HAS_TRANSIENT_STATE
1862      * |-------|-------|-------|-------|
1863      */
1864
1865     /**
1866      * Indicates that this view has reported that it can accept the current drag's content.
1867      * Cleared when the drag operation concludes.
1868      * @hide
1869      */
1870     static final int PFLAG2_DRAG_CAN_ACCEPT            = 0x00000001;
1871
1872     /**
1873      * Indicates that this view is currently directly under the drag location in a
1874      * drag-and-drop operation involving content that it can accept.  Cleared when
1875      * the drag exits the view, or when the drag operation concludes.
1876      * @hide
1877      */
1878     static final int PFLAG2_DRAG_HOVERED               = 0x00000002;
1879
1880     /** @hide */
1881     @IntDef({
1882         LAYOUT_DIRECTION_LTR,
1883         LAYOUT_DIRECTION_RTL,
1884         LAYOUT_DIRECTION_INHERIT,
1885         LAYOUT_DIRECTION_LOCALE
1886     })
1887     @Retention(RetentionPolicy.SOURCE)
1888     // Not called LayoutDirection to avoid conflict with android.util.LayoutDirection
1889     public @interface LayoutDir {}
1890
1891     /** @hide */
1892     @IntDef({
1893         LAYOUT_DIRECTION_LTR,
1894         LAYOUT_DIRECTION_RTL
1895     })
1896     @Retention(RetentionPolicy.SOURCE)
1897     public @interface ResolvedLayoutDir {}
1898
1899     /**
1900      * Horizontal layout direction of this view is from Left to Right.
1901      * Use with {@link #setLayoutDirection}.
1902      */
1903     public static final int LAYOUT_DIRECTION_LTR = LayoutDirection.LTR;
1904
1905     /**
1906      * Horizontal layout direction of this view is from Right to Left.
1907      * Use with {@link #setLayoutDirection}.
1908      */
1909     public static final int LAYOUT_DIRECTION_RTL = LayoutDirection.RTL;
1910
1911     /**
1912      * Horizontal layout direction of this view is inherited from its parent.
1913      * Use with {@link #setLayoutDirection}.
1914      */
1915     public static final int LAYOUT_DIRECTION_INHERIT = LayoutDirection.INHERIT;
1916
1917     /**
1918      * Horizontal layout direction of this view is from deduced from the default language
1919      * script for the locale. Use with {@link #setLayoutDirection}.
1920      */
1921     public static final int LAYOUT_DIRECTION_LOCALE = LayoutDirection.LOCALE;
1922
1923     /**
1924      * Bit shift to get the horizontal layout direction. (bits after DRAG_HOVERED)
1925      * @hide
1926      */
1927     static final int PFLAG2_LAYOUT_DIRECTION_MASK_SHIFT = 2;
1928
1929     /**
1930      * Mask for use with private flags indicating bits used for horizontal layout direction.
1931      * @hide
1932      */
1933     static final int PFLAG2_LAYOUT_DIRECTION_MASK = 0x00000003 << PFLAG2_LAYOUT_DIRECTION_MASK_SHIFT;
1934
1935     /**
1936      * Indicates whether the view horizontal layout direction has been resolved and drawn to the
1937      * right-to-left direction.
1938      * @hide
1939      */
1940     static final int PFLAG2_LAYOUT_DIRECTION_RESOLVED_RTL = 4 << PFLAG2_LAYOUT_DIRECTION_MASK_SHIFT;
1941
1942     /**
1943      * Indicates whether the view horizontal layout direction has been resolved.
1944      * @hide
1945      */
1946     static final int PFLAG2_LAYOUT_DIRECTION_RESOLVED = 8 << PFLAG2_LAYOUT_DIRECTION_MASK_SHIFT;
1947
1948     /**
1949      * Mask for use with private flags indicating bits used for resolved horizontal layout direction.
1950      * @hide
1951      */
1952     static final int PFLAG2_LAYOUT_DIRECTION_RESOLVED_MASK = 0x0000000C
1953             << PFLAG2_LAYOUT_DIRECTION_MASK_SHIFT;
1954
1955     /*
1956      * Array of horizontal layout direction flags for mapping attribute "layoutDirection" to correct
1957      * flag value.
1958      * @hide
1959      */
1960     private static final int[] LAYOUT_DIRECTION_FLAGS = {
1961             LAYOUT_DIRECTION_LTR,
1962             LAYOUT_DIRECTION_RTL,
1963             LAYOUT_DIRECTION_INHERIT,
1964             LAYOUT_DIRECTION_LOCALE
1965     };
1966
1967     /**
1968      * Default horizontal layout direction.
1969      */
1970     private static final int LAYOUT_DIRECTION_DEFAULT = LAYOUT_DIRECTION_INHERIT;
1971
1972     /**
1973      * Default horizontal layout direction.
1974      * @hide
1975      */
1976     static final int LAYOUT_DIRECTION_RESOLVED_DEFAULT = LAYOUT_DIRECTION_LTR;
1977
1978     /**
1979      * Text direction is inherited thru {@link ViewGroup}
1980      */
1981     public static final int TEXT_DIRECTION_INHERIT = 0;
1982
1983     /**
1984      * Text direction is using "first strong algorithm". The first strong directional character
1985      * determines the paragraph direction. If there is no strong directional character, the
1986      * paragraph direction is the view's resolved layout direction.
1987      */
1988     public static final int TEXT_DIRECTION_FIRST_STRONG = 1;
1989
1990     /**
1991      * Text direction is using "any-RTL" algorithm. The paragraph direction is RTL if it contains
1992      * any strong RTL character, otherwise it is LTR if it contains any strong LTR characters.
1993      * If there are neither, the paragraph direction is the view's resolved layout direction.
1994      */
1995     public static final int TEXT_DIRECTION_ANY_RTL = 2;
1996
1997     /**
1998      * Text direction is forced to LTR.
1999      */
2000     public static final int TEXT_DIRECTION_LTR = 3;
2001
2002     /**
2003      * Text direction is forced to RTL.
2004      */
2005     public static final int TEXT_DIRECTION_RTL = 4;
2006
2007     /**
2008      * Text direction is coming from the system Locale.
2009      */
2010     public static final int TEXT_DIRECTION_LOCALE = 5;
2011
2012     /**
2013      * Default text direction is inherited
2014      */
2015     private static final int TEXT_DIRECTION_DEFAULT = TEXT_DIRECTION_INHERIT;
2016
2017     /**
2018      * Default resolved text direction
2019      * @hide
2020      */
2021     static final int TEXT_DIRECTION_RESOLVED_DEFAULT = TEXT_DIRECTION_FIRST_STRONG;
2022
2023     /**
2024      * Bit shift to get the horizontal layout direction. (bits after LAYOUT_DIRECTION_RESOLVED)
2025      * @hide
2026      */
2027     static final int PFLAG2_TEXT_DIRECTION_MASK_SHIFT = 6;
2028
2029     /**
2030      * Mask for use with private flags indicating bits used for text direction.
2031      * @hide
2032      */
2033     static final int PFLAG2_TEXT_DIRECTION_MASK = 0x00000007
2034             << PFLAG2_TEXT_DIRECTION_MASK_SHIFT;
2035
2036     /**
2037      * Array of text direction flags for mapping attribute "textDirection" to correct
2038      * flag value.
2039      * @hide
2040      */
2041     private static final int[] PFLAG2_TEXT_DIRECTION_FLAGS = {
2042             TEXT_DIRECTION_INHERIT << PFLAG2_TEXT_DIRECTION_MASK_SHIFT,
2043             TEXT_DIRECTION_FIRST_STRONG << PFLAG2_TEXT_DIRECTION_MASK_SHIFT,
2044             TEXT_DIRECTION_ANY_RTL << PFLAG2_TEXT_DIRECTION_MASK_SHIFT,
2045             TEXT_DIRECTION_LTR << PFLAG2_TEXT_DIRECTION_MASK_SHIFT,
2046             TEXT_DIRECTION_RTL << PFLAG2_TEXT_DIRECTION_MASK_SHIFT,
2047             TEXT_DIRECTION_LOCALE << PFLAG2_TEXT_DIRECTION_MASK_SHIFT
2048     };
2049
2050     /**
2051      * Indicates whether the view text direction has been resolved.
2052      * @hide
2053      */
2054     static final int PFLAG2_TEXT_DIRECTION_RESOLVED = 0x00000008
2055             << PFLAG2_TEXT_DIRECTION_MASK_SHIFT;
2056
2057     /**
2058      * Bit shift to get the horizontal layout direction. (bits after DRAG_HOVERED)
2059      * @hide
2060      */
2061     static final int PFLAG2_TEXT_DIRECTION_RESOLVED_MASK_SHIFT = 10;
2062
2063     /**
2064      * Mask for use with private flags indicating bits used for resolved text direction.
2065      * @hide
2066      */
2067     static final int PFLAG2_TEXT_DIRECTION_RESOLVED_MASK = 0x00000007
2068             << PFLAG2_TEXT_DIRECTION_RESOLVED_MASK_SHIFT;
2069
2070     /**
2071      * Indicates whether the view text direction has been resolved to the "first strong" heuristic.
2072      * @hide
2073      */
2074     static final int PFLAG2_TEXT_DIRECTION_RESOLVED_DEFAULT =
2075             TEXT_DIRECTION_RESOLVED_DEFAULT << PFLAG2_TEXT_DIRECTION_RESOLVED_MASK_SHIFT;
2076
2077     /** @hide */
2078     @IntDef({
2079         TEXT_ALIGNMENT_INHERIT,
2080         TEXT_ALIGNMENT_GRAVITY,
2081         TEXT_ALIGNMENT_CENTER,
2082         TEXT_ALIGNMENT_TEXT_START,
2083         TEXT_ALIGNMENT_TEXT_END,
2084         TEXT_ALIGNMENT_VIEW_START,
2085         TEXT_ALIGNMENT_VIEW_END
2086     })
2087     @Retention(RetentionPolicy.SOURCE)
2088     public @interface TextAlignment {}
2089
2090     /**
2091      * Default text alignment. The text alignment of this View is inherited from its parent.
2092      * Use with {@link #setTextAlignment(int)}
2093      */
2094     public static final int TEXT_ALIGNMENT_INHERIT = 0;
2095
2096     /**
2097      * Default for the root view. The gravity determines the text alignment, ALIGN_NORMAL,
2098      * ALIGN_CENTER, or ALIGN_OPPOSITE, which are relative to each paragraph’s text direction.
2099      *
2100      * Use with {@link #setTextAlignment(int)}
2101      */
2102     public static final int TEXT_ALIGNMENT_GRAVITY = 1;
2103
2104     /**
2105      * Align to the start of the paragraph, e.g. ALIGN_NORMAL.
2106      *
2107      * Use with {@link #setTextAlignment(int)}
2108      */
2109     public static final int TEXT_ALIGNMENT_TEXT_START = 2;
2110
2111     /**
2112      * Align to the end of the paragraph, e.g. ALIGN_OPPOSITE.
2113      *
2114      * Use with {@link #setTextAlignment(int)}
2115      */
2116     public static final int TEXT_ALIGNMENT_TEXT_END = 3;
2117
2118     /**
2119      * Center the paragraph, e.g. ALIGN_CENTER.
2120      *
2121      * Use with {@link #setTextAlignment(int)}
2122      */
2123     public static final int TEXT_ALIGNMENT_CENTER = 4;
2124
2125     /**
2126      * Align to the start of the view, which is ALIGN_LEFT if the view’s resolved
2127      * layoutDirection is LTR, and ALIGN_RIGHT otherwise.
2128      *
2129      * Use with {@link #setTextAlignment(int)}
2130      */
2131     public static final int TEXT_ALIGNMENT_VIEW_START = 5;
2132
2133     /**
2134      * Align to the end of the view, which is ALIGN_RIGHT if the view’s resolved
2135      * layoutDirection is LTR, and ALIGN_LEFT otherwise.
2136      *
2137      * Use with {@link #setTextAlignment(int)}
2138      */
2139     public static final int TEXT_ALIGNMENT_VIEW_END = 6;
2140
2141     /**
2142      * Default text alignment is inherited
2143      */
2144     private static final int TEXT_ALIGNMENT_DEFAULT = TEXT_ALIGNMENT_GRAVITY;
2145
2146     /**
2147      * Default resolved text alignment
2148      * @hide
2149      */
2150     static final int TEXT_ALIGNMENT_RESOLVED_DEFAULT = TEXT_ALIGNMENT_GRAVITY;
2151
2152     /**
2153       * Bit shift to get the horizontal layout direction. (bits after DRAG_HOVERED)
2154       * @hide
2155       */
2156     static final int PFLAG2_TEXT_ALIGNMENT_MASK_SHIFT = 13;
2157
2158     /**
2159       * Mask for use with private flags indicating bits used for text alignment.
2160       * @hide
2161       */
2162     static final int PFLAG2_TEXT_ALIGNMENT_MASK = 0x00000007 << PFLAG2_TEXT_ALIGNMENT_MASK_SHIFT;
2163
2164     /**
2165      * Array of text direction flags for mapping attribute "textAlignment" to correct
2166      * flag value.
2167      * @hide
2168      */
2169     private static final int[] PFLAG2_TEXT_ALIGNMENT_FLAGS = {
2170             TEXT_ALIGNMENT_INHERIT << PFLAG2_TEXT_ALIGNMENT_MASK_SHIFT,
2171             TEXT_ALIGNMENT_GRAVITY << PFLAG2_TEXT_ALIGNMENT_MASK_SHIFT,
2172             TEXT_ALIGNMENT_TEXT_START << PFLAG2_TEXT_ALIGNMENT_MASK_SHIFT,
2173             TEXT_ALIGNMENT_TEXT_END << PFLAG2_TEXT_ALIGNMENT_MASK_SHIFT,
2174             TEXT_ALIGNMENT_CENTER << PFLAG2_TEXT_ALIGNMENT_MASK_SHIFT,
2175             TEXT_ALIGNMENT_VIEW_START << PFLAG2_TEXT_ALIGNMENT_MASK_SHIFT,
2176             TEXT_ALIGNMENT_VIEW_END << PFLAG2_TEXT_ALIGNMENT_MASK_SHIFT
2177     };
2178
2179     /**
2180      * Indicates whether the view text alignment has been resolved.
2181      * @hide
2182      */
2183     static final int PFLAG2_TEXT_ALIGNMENT_RESOLVED = 0x00000008 << PFLAG2_TEXT_ALIGNMENT_MASK_SHIFT;
2184
2185     /**
2186      * Bit shift to get the resolved text alignment.
2187      * @hide
2188      */
2189     static final int PFLAG2_TEXT_ALIGNMENT_RESOLVED_MASK_SHIFT = 17;
2190
2191     /**
2192      * Mask for use with private flags indicating bits used for text alignment.
2193      * @hide
2194      */
2195     static final int PFLAG2_TEXT_ALIGNMENT_RESOLVED_MASK = 0x00000007
2196             << PFLAG2_TEXT_ALIGNMENT_RESOLVED_MASK_SHIFT;
2197
2198     /**
2199      * Indicates whether if the view text alignment has been resolved to gravity
2200      */
2201     private static final int PFLAG2_TEXT_ALIGNMENT_RESOLVED_DEFAULT =
2202             TEXT_ALIGNMENT_RESOLVED_DEFAULT << PFLAG2_TEXT_ALIGNMENT_RESOLVED_MASK_SHIFT;
2203
2204     // Accessiblity constants for mPrivateFlags2
2205
2206     /**
2207      * Shift for the bits in {@link #mPrivateFlags2} related to the
2208      * "importantForAccessibility" attribute.
2209      */
2210     static final int PFLAG2_IMPORTANT_FOR_ACCESSIBILITY_SHIFT = 20;
2211
2212     /**
2213      * Automatically determine whether a view is important for accessibility.
2214      */
2215     public static final int IMPORTANT_FOR_ACCESSIBILITY_AUTO = 0x00000000;
2216
2217     /**
2218      * The view is important for accessibility.
2219      */
2220     public static final int IMPORTANT_FOR_ACCESSIBILITY_YES = 0x00000001;
2221
2222     /**
2223      * The view is not important for accessibility.
2224      */
2225     public static final int IMPORTANT_FOR_ACCESSIBILITY_NO = 0x00000002;
2226
2227     /**
2228      * The view is not important for accessibility, nor are any of its
2229      * descendant views.
2230      */
2231     public static final int IMPORTANT_FOR_ACCESSIBILITY_NO_HIDE_DESCENDANTS = 0x00000004;
2232
2233     /**
2234      * The default whether the view is important for accessibility.
2235      */
2236     static final int IMPORTANT_FOR_ACCESSIBILITY_DEFAULT = IMPORTANT_FOR_ACCESSIBILITY_AUTO;
2237
2238     /**
2239      * Mask for obtainig the bits which specify how to determine
2240      * whether a view is important for accessibility.
2241      */
2242     static final int PFLAG2_IMPORTANT_FOR_ACCESSIBILITY_MASK = (IMPORTANT_FOR_ACCESSIBILITY_AUTO
2243         | IMPORTANT_FOR_ACCESSIBILITY_YES | IMPORTANT_FOR_ACCESSIBILITY_NO
2244         | IMPORTANT_FOR_ACCESSIBILITY_NO_HIDE_DESCENDANTS)
2245         << PFLAG2_IMPORTANT_FOR_ACCESSIBILITY_SHIFT;
2246
2247     /**
2248      * Shift for the bits in {@link #mPrivateFlags2} related to the
2249      * "accessibilityLiveRegion" attribute.
2250      */
2251     static final int PFLAG2_ACCESSIBILITY_LIVE_REGION_SHIFT = 23;
2252
2253     /**
2254      * Live region mode specifying that accessibility services should not
2255      * automatically announce changes to this view. This is the default live
2256      * region mode for most views.
2257      * <p>
2258      * Use with {@link #setAccessibilityLiveRegion(int)}.
2259      */
2260     public static final int ACCESSIBILITY_LIVE_REGION_NONE = 0x00000000;
2261
2262     /**
2263      * Live region mode specifying that accessibility services should announce
2264      * changes to this view.
2265      * <p>
2266      * Use with {@link #setAccessibilityLiveRegion(int)}.
2267      */
2268     public static final int ACCESSIBILITY_LIVE_REGION_POLITE = 0x00000001;
2269
2270     /**
2271      * Live region mode specifying that accessibility services should interrupt
2272      * ongoing speech to immediately announce changes to this view.
2273      * <p>
2274      * Use with {@link #setAccessibilityLiveRegion(int)}.
2275      */
2276     public static final int ACCESSIBILITY_LIVE_REGION_ASSERTIVE = 0x00000002;
2277
2278     /**
2279      * The default whether the view is important for accessibility.
2280      */
2281     static final int ACCESSIBILITY_LIVE_REGION_DEFAULT = ACCESSIBILITY_LIVE_REGION_NONE;
2282
2283     /**
2284      * Mask for obtaining the bits which specify a view's accessibility live
2285      * region mode.
2286      */
2287     static final int PFLAG2_ACCESSIBILITY_LIVE_REGION_MASK = (ACCESSIBILITY_LIVE_REGION_NONE
2288             | ACCESSIBILITY_LIVE_REGION_POLITE | ACCESSIBILITY_LIVE_REGION_ASSERTIVE)
2289             << PFLAG2_ACCESSIBILITY_LIVE_REGION_SHIFT;
2290
2291     /**
2292      * Flag indicating whether a view has accessibility focus.
2293      */
2294     static final int PFLAG2_ACCESSIBILITY_FOCUSED = 0x04000000;
2295
2296     /**
2297      * Flag whether the accessibility state of the subtree rooted at this view changed.
2298      */
2299     static final int PFLAG2_SUBTREE_ACCESSIBILITY_STATE_CHANGED = 0x08000000;
2300
2301     /**
2302      * Flag indicating whether a view failed the quickReject() check in draw(). This condition
2303      * is used to check whether later changes to the view's transform should invalidate the
2304      * view to force the quickReject test to run again.
2305      */
2306     static final int PFLAG2_VIEW_QUICK_REJECTED = 0x10000000;
2307
2308     /**
2309      * Flag indicating that start/end padding has been resolved into left/right padding
2310      * for use in measurement, layout, drawing, etc. This is set by {@link #resolvePadding()}
2311      * and checked by {@link #measure(int, int)} to determine if padding needs to be resolved
2312      * during measurement. In some special cases this is required such as when an adapter-based
2313      * view measures prospective children without attaching them to a window.
2314      */
2315     static final int PFLAG2_PADDING_RESOLVED = 0x20000000;
2316
2317     /**
2318      * Flag indicating that the start/end drawables has been resolved into left/right ones.
2319      */
2320     static final int PFLAG2_DRAWABLE_RESOLVED = 0x40000000;
2321
2322     /**
2323      * Indicates that the view is tracking some sort of transient state
2324      * that the app should not need to be aware of, but that the framework
2325      * should take special care to preserve.
2326      */
2327     static final int PFLAG2_HAS_TRANSIENT_STATE = 0x80000000;
2328
2329     /**
2330      * Group of bits indicating that RTL properties resolution is done.
2331      */
2332     static final int ALL_RTL_PROPERTIES_RESOLVED = PFLAG2_LAYOUT_DIRECTION_RESOLVED |
2333             PFLAG2_TEXT_DIRECTION_RESOLVED |
2334             PFLAG2_TEXT_ALIGNMENT_RESOLVED |
2335             PFLAG2_PADDING_RESOLVED |
2336             PFLAG2_DRAWABLE_RESOLVED;
2337
2338     // There are a couple of flags left in mPrivateFlags2
2339
2340     /* End of masks for mPrivateFlags2 */
2341
2342     /**
2343      * Masks for mPrivateFlags3, as generated by dumpFlags():
2344      *
2345      * |-------|-------|-------|-------|
2346      *                                 1 PFLAG3_VIEW_IS_ANIMATING_TRANSFORM
2347      *                                1  PFLAG3_VIEW_IS_ANIMATING_ALPHA
2348      *                               1   PFLAG3_IS_LAID_OUT
2349      *                              1    PFLAG3_MEASURE_NEEDED_BEFORE_LAYOUT
2350      *                             1     PFLAG3_CALLED_SUPER
2351      * |-------|-------|-------|-------|
2352      */
2353
2354     /**
2355      * Flag indicating that view has a transform animation set on it. This is used to track whether
2356      * an animation is cleared between successive frames, in order to tell the associated
2357      * DisplayList to clear its animation matrix.
2358      */
2359     static final int PFLAG3_VIEW_IS_ANIMATING_TRANSFORM = 0x1;
2360
2361     /**
2362      * Flag indicating that view has an alpha animation set on it. This is used to track whether an
2363      * animation is cleared between successive frames, in order to tell the associated
2364      * DisplayList to restore its alpha value.
2365      */
2366     static final int PFLAG3_VIEW_IS_ANIMATING_ALPHA = 0x2;
2367
2368     /**
2369      * Flag indicating that the view has been through at least one layout since it
2370      * was last attached to a window.
2371      */
2372     static final int PFLAG3_IS_LAID_OUT = 0x4;
2373
2374     /**
2375      * Flag indicating that a call to measure() was skipped and should be done
2376      * instead when layout() is invoked.
2377      */
2378     static final int PFLAG3_MEASURE_NEEDED_BEFORE_LAYOUT = 0x8;
2379
2380     /**
2381      * Flag indicating that an overridden method correctly called down to
2382      * the superclass implementation as required by the API spec.
2383      */
2384     static final int PFLAG3_CALLED_SUPER = 0x10;
2385
2386     /**
2387      * Flag indicating that we're in the process of applying window insets.
2388      */
2389     static final int PFLAG3_APPLYING_INSETS = 0x20;
2390
2391     /**
2392      * Flag indicating that we're in the process of fitting system windows using the old method.
2393      */
2394     static final int PFLAG3_FITTING_SYSTEM_WINDOWS = 0x40;
2395
2396     /**
2397      * Flag indicating that nested scrolling is enabled for this view.
2398      * The view will optionally cooperate with views up its parent chain to allow for
2399      * integrated nested scrolling along the same axis.
2400      */
2401     static final int PFLAG3_NESTED_SCROLLING_ENABLED = 0x80;
2402
2403     /* End of masks for mPrivateFlags3 */
2404
2405     static final int DRAG_MASK = PFLAG2_DRAG_CAN_ACCEPT | PFLAG2_DRAG_HOVERED;
2406
2407     /**
2408      * Always allow a user to over-scroll this view, provided it is a
2409      * view that can scroll.
2410      *
2411      * @see #getOverScrollMode()
2412      * @see #setOverScrollMode(int)
2413      */
2414     public static final int OVER_SCROLL_ALWAYS = 0;
2415
2416     /**
2417      * Allow a user to over-scroll this view only if the content is large
2418      * enough to meaningfully scroll, provided it is a view that can scroll.
2419      *
2420      * @see #getOverScrollMode()
2421      * @see #setOverScrollMode(int)
2422      */
2423     public static final int OVER_SCROLL_IF_CONTENT_SCROLLS = 1;
2424
2425     /**
2426      * Never allow a user to over-scroll this view.
2427      *
2428      * @see #getOverScrollMode()
2429      * @see #setOverScrollMode(int)
2430      */
2431     public static final int OVER_SCROLL_NEVER = 2;
2432
2433     /**
2434      * Special constant for {@link #setSystemUiVisibility(int)}: View has
2435      * requested the system UI (status bar) to be visible (the default).
2436      *
2437      * @see #setSystemUiVisibility(int)
2438      */
2439     public static final int SYSTEM_UI_FLAG_VISIBLE = 0;
2440
2441     /**
2442      * Flag for {@link #setSystemUiVisibility(int)}: View has requested the
2443      * system UI to enter an unobtrusive "low profile" mode.
2444      *
2445      * <p>This is for use in games, book readers, video players, or any other
2446      * "immersive" application where the usual system chrome is deemed too distracting.
2447      *
2448      * <p>In low profile mode, the status bar and/or navigation icons may dim.
2449      *
2450      * @see #setSystemUiVisibility(int)
2451      */
2452     public static final int SYSTEM_UI_FLAG_LOW_PROFILE = 0x00000001;
2453
2454     /**
2455      * Flag for {@link #setSystemUiVisibility(int)}: View has requested that the
2456      * system navigation be temporarily hidden.
2457      *
2458      * <p>This is an even less obtrusive state than that called for by
2459      * {@link #SYSTEM_UI_FLAG_LOW_PROFILE}; on devices that draw essential navigation controls
2460      * (Home, Back, and the like) on screen, <code>SYSTEM_UI_FLAG_HIDE_NAVIGATION</code> will cause
2461      * those to disappear. This is useful (in conjunction with the
2462      * {@link android.view.WindowManager.LayoutParams#FLAG_FULLSCREEN FLAG_FULLSCREEN} and
2463      * {@link android.view.WindowManager.LayoutParams#FLAG_LAYOUT_IN_SCREEN FLAG_LAYOUT_IN_SCREEN}
2464      * window flags) for displaying content using every last pixel on the display.
2465      *
2466      * <p>There is a limitation: because navigation controls are so important, the least user
2467      * interaction will cause them to reappear immediately.  When this happens, both
2468      * this flag and {@link #SYSTEM_UI_FLAG_FULLSCREEN} will be cleared automatically,
2469      * so that both elements reappear at the same time.
2470      *
2471      * @see #setSystemUiVisibility(int)
2472      */
2473     public static final int SYSTEM_UI_FLAG_HIDE_NAVIGATION = 0x00000002;
2474
2475     /**
2476      * Flag for {@link #setSystemUiVisibility(int)}: View has requested to go
2477      * into the normal fullscreen mode so that its content can take over the screen
2478      * while still allowing the user to interact with the application.
2479      *
2480      * <p>This has the same visual effect as
2481      * {@link android.view.WindowManager.LayoutParams#FLAG_FULLSCREEN
2482      * WindowManager.LayoutParams.FLAG_FULLSCREEN},
2483      * meaning that non-critical screen decorations (such as the status bar) will be
2484      * hidden while the user is in the View's window, focusing the experience on
2485      * that content.  Unlike the window flag, if you are using ActionBar in
2486      * overlay mode with {@link Window#FEATURE_ACTION_BAR_OVERLAY
2487      * Window.FEATURE_ACTION_BAR_OVERLAY}, then enabling this flag will also
2488      * hide the action bar.
2489      *
2490      * <p>This approach to going fullscreen is best used over the window flag when
2491      * it is a transient state -- that is, the application does this at certain
2492      * points in its user interaction where it wants to allow the user to focus
2493      * on content, but not as a continuous state.  For situations where the application
2494      * would like to simply stay full screen the entire time (such as a game that
2495      * wants to take over the screen), the
2496      * {@link android.view.WindowManager.LayoutParams#FLAG_FULLSCREEN window flag}
2497      * is usually a better approach.  The state set here will be removed by the system
2498      * in various situations (such as the user moving to another application) like
2499      * the other system UI states.
2500      *
2501      * <p>When using this flag, the application should provide some easy facility
2502      * for the user to go out of it.  A common example would be in an e-book
2503      * reader, where tapping on the screen brings back whatever screen and UI
2504      * decorations that had been hidden while the user was immersed in reading
2505      * the book.
2506      *
2507      * @see #setSystemUiVisibility(int)
2508      */
2509     public static final int SYSTEM_UI_FLAG_FULLSCREEN = 0x00000004;
2510
2511     /**
2512      * Flag for {@link #setSystemUiVisibility(int)}: When using other layout
2513      * flags, we would like a stable view of the content insets given to
2514      * {@link #fitSystemWindows(Rect)}.  This means that the insets seen there
2515      * will always represent the worst case that the application can expect
2516      * as a continuous state.  In the stock Android UI this is the space for
2517      * the system bar, nav bar, and status bar, but not more transient elements
2518      * such as an input method.
2519      *
2520      * The stable layout your UI sees is based on the system UI modes you can
2521      * switch to.  That is, if you specify {@link #SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN}
2522      * then you will get a stable layout for changes of the
2523      * {@link #SYSTEM_UI_FLAG_FULLSCREEN} mode; if you specify
2524      * {@link #SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN} and
2525      * {@link #SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION}, then you can transition
2526      * to {@link #SYSTEM_UI_FLAG_FULLSCREEN} and {@link #SYSTEM_UI_FLAG_HIDE_NAVIGATION}
2527      * with a stable layout.  (Note that you should avoid using
2528      * {@link #SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION} by itself.)
2529      *
2530      * If you have set the window flag {@link WindowManager.LayoutParams#FLAG_FULLSCREEN}
2531      * to hide the status bar (instead of using {@link #SYSTEM_UI_FLAG_FULLSCREEN}),
2532      * then a hidden status bar will be considered a "stable" state for purposes
2533      * here.  This allows your UI to continually hide the status bar, while still
2534      * using the system UI flags to hide the action bar while still retaining
2535      * a stable layout.  Note that changing the window fullscreen flag will never
2536      * provide a stable layout for a clean transition.
2537      *
2538      * <p>If you are using ActionBar in
2539      * overlay mode with {@link Window#FEATURE_ACTION_BAR_OVERLAY
2540      * Window.FEATURE_ACTION_BAR_OVERLAY}, this flag will also impact the
2541      * insets it adds to those given to the application.
2542      */
2543     public static final int SYSTEM_UI_FLAG_LAYOUT_STABLE = 0x00000100;
2544
2545     /**
2546      * Flag for {@link #setSystemUiVisibility(int)}: View would like its window
2547      * to be layed out as if it has requested
2548      * {@link #SYSTEM_UI_FLAG_HIDE_NAVIGATION}, even if it currently hasn't.  This
2549      * allows it to avoid artifacts when switching in and out of that mode, at
2550      * the expense that some of its user interface may be covered by screen
2551      * decorations when they are shown.  You can perform layout of your inner
2552      * UI elements to account for the navigation system UI through the
2553      * {@link #fitSystemWindows(Rect)} method.
2554      */
2555     public static final int SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION = 0x00000200;
2556
2557     /**
2558      * Flag for {@link #setSystemUiVisibility(int)}: View would like its window
2559      * to be layed out as if it has requested
2560      * {@link #SYSTEM_UI_FLAG_FULLSCREEN}, even if it currently hasn't.  This
2561      * allows it to avoid artifacts when switching in and out of that mode, at
2562      * the expense that some of its user interface may be covered by screen
2563      * decorations when they are shown.  You can perform layout of your inner
2564      * UI elements to account for non-fullscreen system UI through the
2565      * {@link #fitSystemWindows(Rect)} method.
2566      */
2567     public static final int SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN = 0x00000400;
2568
2569     /**
2570      * Flag for {@link #setSystemUiVisibility(int)}: View would like to remain interactive when
2571      * hiding the navigation bar with {@link #SYSTEM_UI_FLAG_HIDE_NAVIGATION}.  If this flag is
2572      * not set, {@link #SYSTEM_UI_FLAG_HIDE_NAVIGATION} will be force cleared by the system on any
2573      * user interaction.
2574      * <p>Since this flag is a modifier for {@link #SYSTEM_UI_FLAG_HIDE_NAVIGATION}, it only
2575      * has an effect when used in combination with that flag.</p>
2576      */
2577     public static final int SYSTEM_UI_FLAG_IMMERSIVE = 0x00000800;
2578
2579     /**
2580      * Flag for {@link #setSystemUiVisibility(int)}: View would like to remain interactive when
2581      * hiding the status bar with {@link #SYSTEM_UI_FLAG_FULLSCREEN} and/or hiding the navigation
2582      * bar with {@link #SYSTEM_UI_FLAG_HIDE_NAVIGATION}.  Use this flag to create an immersive
2583      * experience while also hiding the system bars.  If this flag is not set,
2584      * {@link #SYSTEM_UI_FLAG_HIDE_NAVIGATION} will be force cleared by the system on any user
2585      * interaction, and {@link #SYSTEM_UI_FLAG_FULLSCREEN} will be force-cleared by the system
2586      * if the user swipes from the top of the screen.
2587      * <p>When system bars are hidden in immersive mode, they can be revealed temporarily with
2588      * system gestures, such as swiping from the top of the screen.  These transient system bars
2589      * will overlay app’s content, may have some degree of transparency, and will automatically
2590      * hide after a short timeout.
2591      * </p><p>Since this flag is a modifier for {@link #SYSTEM_UI_FLAG_FULLSCREEN} and
2592      * {@link #SYSTEM_UI_FLAG_HIDE_NAVIGATION}, it only has an effect when used in combination
2593      * with one or both of those flags.</p>
2594      */
2595     public static final int SYSTEM_UI_FLAG_IMMERSIVE_STICKY = 0x00001000;
2596
2597     /**
2598      * @deprecated Use {@link #SYSTEM_UI_FLAG_LOW_PROFILE} instead.
2599      */
2600     public static final int STATUS_BAR_HIDDEN = SYSTEM_UI_FLAG_LOW_PROFILE;
2601
2602     /**
2603      * @deprecated Use {@link #SYSTEM_UI_FLAG_VISIBLE} instead.
2604      */
2605     public static final int STATUS_BAR_VISIBLE = SYSTEM_UI_FLAG_VISIBLE;
2606
2607     /**
2608      * @hide
2609      *
2610      * NOTE: This flag may only be used in subtreeSystemUiVisibility. It is masked
2611      * out of the public fields to keep the undefined bits out of the developer's way.
2612      *
2613      * Flag to make the status bar not expandable.  Unless you also
2614      * set {@link #STATUS_BAR_DISABLE_NOTIFICATION_ICONS}, new notifications will continue to show.
2615      */
2616     public static final int STATUS_BAR_DISABLE_EXPAND = 0x00010000;
2617
2618     /**
2619      * @hide
2620      *
2621      * NOTE: This flag may only be used in subtreeSystemUiVisibility. It is masked
2622      * out of the public fields to keep the undefined bits out of the developer's way.
2623      *
2624      * Flag to hide notification icons and scrolling ticker text.
2625      */
2626     public static final int STATUS_BAR_DISABLE_NOTIFICATION_ICONS = 0x00020000;
2627
2628     /**
2629      * @hide
2630      *
2631      * NOTE: This flag may only be used in subtreeSystemUiVisibility. It is masked
2632      * out of the public fields to keep the undefined bits out of the developer's way.
2633      *
2634      * Flag to disable incoming notification alerts.  This will not block
2635      * icons, but it will block sound, vibrating and other visual or aural notifications.
2636      */
2637     public static final int STATUS_BAR_DISABLE_NOTIFICATION_ALERTS = 0x00040000;
2638
2639     /**
2640      * @hide
2641      *
2642      * NOTE: This flag may only be used in subtreeSystemUiVisibility. It is masked
2643      * out of the public fields to keep the undefined bits out of the developer's way.
2644      *
2645      * Flag to hide only the scrolling ticker.  Note that
2646      * {@link #STATUS_BAR_DISABLE_NOTIFICATION_ICONS} implies
2647      * {@link #STATUS_BAR_DISABLE_NOTIFICATION_TICKER}.
2648      */
2649     public static final int STATUS_BAR_DISABLE_NOTIFICATION_TICKER = 0x00080000;
2650
2651     /**
2652      * @hide
2653      *
2654      * NOTE: This flag may only be used in subtreeSystemUiVisibility. It is masked
2655      * out of the public fields to keep the undefined bits out of the developer's way.
2656      *
2657      * Flag to hide the center system info area.
2658      */
2659     public static final int STATUS_BAR_DISABLE_SYSTEM_INFO = 0x00100000;
2660
2661     /**
2662      * @hide
2663      *
2664      * NOTE: This flag may only be used in subtreeSystemUiVisibility. It is masked
2665      * out of the public fields to keep the undefined bits out of the developer's way.
2666      *
2667      * Flag to hide only the home button.  Don't use this
2668      * unless you're a special part of the system UI (i.e., setup wizard, keyguard).
2669      */
2670     public static final int STATUS_BAR_DISABLE_HOME = 0x00200000;
2671
2672     /**
2673      * @hide
2674      *
2675      * NOTE: This flag may only be used in subtreeSystemUiVisibility. It is masked
2676      * out of the public fields to keep the undefined bits out of the developer's way.
2677      *
2678      * Flag to hide only the back button. Don't use this
2679      * unless you're a special part of the system UI (i.e., setup wizard, keyguard).
2680      */
2681     public static final int STATUS_BAR_DISABLE_BACK = 0x00400000;
2682
2683     /**
2684      * @hide
2685      *
2686      * NOTE: This flag may only be used in subtreeSystemUiVisibility. It is masked
2687      * out of the public fields to keep the undefined bits out of the developer's way.
2688      *
2689      * Flag to hide only the clock.  You might use this if your activity has
2690      * its own clock making the status bar's clock redundant.
2691      */
2692     public static final int STATUS_BAR_DISABLE_CLOCK = 0x00800000;
2693
2694     /**
2695      * @hide
2696      *
2697      * NOTE: This flag may only be used in subtreeSystemUiVisibility. It is masked
2698      * out of the public fields to keep the undefined bits out of the developer's way.
2699      *
2700      * Flag to hide only the recent apps button. Don't use this
2701      * unless you're a special part of the system UI (i.e., setup wizard, keyguard).
2702      */
2703     public static final int STATUS_BAR_DISABLE_RECENT = 0x01000000;
2704
2705     /**
2706      * @hide
2707      *
2708      * NOTE: This flag may only be used in subtreeSystemUiVisibility. It is masked
2709      * out of the public fields to keep the undefined bits out of the developer's way.
2710      *
2711      * Flag to disable the global search gesture. Don't use this
2712      * unless you're a special part of the system UI (i.e., setup wizard, keyguard).
2713      */
2714     public static final int STATUS_BAR_DISABLE_SEARCH = 0x02000000;
2715
2716     /**
2717      * @hide
2718      *
2719      * NOTE: This flag may only be used in subtreeSystemUiVisibility. It is masked
2720      * out of the public fields to keep the undefined bits out of the developer's way.
2721      *
2722      * Flag to specify that the status bar is displayed in transient mode.
2723      */
2724     public static final int STATUS_BAR_TRANSIENT = 0x04000000;
2725
2726     /**
2727      * @hide
2728      *
2729      * NOTE: This flag may only be used in subtreeSystemUiVisibility. It is masked
2730      * out of the public fields to keep the undefined bits out of the developer's way.
2731      *
2732      * Flag to specify that the navigation bar is displayed in transient mode.
2733      */
2734     public static final int NAVIGATION_BAR_TRANSIENT = 0x08000000;
2735
2736     /**
2737      * @hide
2738      *
2739      * NOTE: This flag may only be used in subtreeSystemUiVisibility. It is masked
2740      * out of the public fields to keep the undefined bits out of the developer's way.
2741      *
2742      * Flag to specify that the hidden status bar would like to be shown.
2743      */
2744     public static final int STATUS_BAR_UNHIDE = 0x10000000;
2745
2746     /**
2747      * @hide
2748      *
2749      * NOTE: This flag may only be used in subtreeSystemUiVisibility. It is masked
2750      * out of the public fields to keep the undefined bits out of the developer's way.
2751      *
2752      * Flag to specify that the hidden navigation bar would like to be shown.
2753      */
2754     public static final int NAVIGATION_BAR_UNHIDE = 0x20000000;
2755
2756     /**
2757      * @hide
2758      *
2759      * NOTE: This flag may only be used in subtreeSystemUiVisibility. It is masked
2760      * out of the public fields to keep the undefined bits out of the developer's way.
2761      *
2762      * Flag to specify that the status bar is displayed in translucent mode.
2763      */
2764     public static final int STATUS_BAR_TRANSLUCENT = 0x40000000;
2765
2766     /**
2767      * @hide
2768      *
2769      * NOTE: This flag may only be used in subtreeSystemUiVisibility. It is masked
2770      * out of the public fields to keep the undefined bits out of the developer's way.
2771      *
2772      * Flag to specify that the navigation bar is displayed in translucent mode.
2773      */
2774     public static final int NAVIGATION_BAR_TRANSLUCENT = 0x80000000;
2775
2776     /**
2777      * @hide
2778      *
2779      * Whether Recents is visible or not.
2780      */
2781     public static final int RECENT_APPS_VISIBLE = 0x00004000;
2782
2783     /**
2784      * @hide
2785      *
2786      * Makes system ui transparent.
2787      */
2788     public static final int SYSTEM_UI_TRANSPARENT = 0x00008000;
2789
2790     /**
2791      * @hide
2792      */
2793     public static final int PUBLIC_STATUS_BAR_VISIBILITY_MASK = 0x00003FFF;
2794
2795     /**
2796      * These are the system UI flags that can be cleared by events outside
2797      * of an application.  Currently this is just the ability to tap on the
2798      * screen while hiding the navigation bar to have it return.
2799      * @hide
2800      */
2801     public static final int SYSTEM_UI_CLEARABLE_FLAGS =
2802             SYSTEM_UI_FLAG_LOW_PROFILE | SYSTEM_UI_FLAG_HIDE_NAVIGATION
2803             | SYSTEM_UI_FLAG_FULLSCREEN;
2804
2805     /**
2806      * Flags that can impact the layout in relation to system UI.
2807      */
2808     public static final int SYSTEM_UI_LAYOUT_FLAGS =
2809             SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION
2810             | SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN;
2811
2812     /** @hide */
2813     @IntDef(flag = true,
2814             value = { FIND_VIEWS_WITH_TEXT, FIND_VIEWS_WITH_CONTENT_DESCRIPTION })
2815     @Retention(RetentionPolicy.SOURCE)
2816     public @interface FindViewFlags {}
2817
2818     /**
2819      * Find views that render the specified text.
2820      *
2821      * @see #findViewsWithText(ArrayList, CharSequence, int)
2822      */
2823     public static final int FIND_VIEWS_WITH_TEXT = 0x00000001;
2824
2825     /**
2826      * Find find views that contain the specified content description.
2827      *
2828      * @see #findViewsWithText(ArrayList, CharSequence, int)
2829      */
2830     public static final int FIND_VIEWS_WITH_CONTENT_DESCRIPTION = 0x00000002;
2831
2832     /**
2833      * Find views that contain {@link AccessibilityNodeProvider}. Such
2834      * a View is a root of virtual view hierarchy and may contain the searched
2835      * text. If this flag is set Views with providers are automatically
2836      * added and it is a responsibility of the client to call the APIs of
2837      * the provider to determine whether the virtual tree rooted at this View
2838      * contains the text, i.e. getting the list of {@link AccessibilityNodeInfo}s
2839      * representing the virtual views with this text.
2840      *
2841      * @see #findViewsWithText(ArrayList, CharSequence, int)
2842      *
2843      * @hide
2844      */
2845     public static final int FIND_VIEWS_WITH_ACCESSIBILITY_NODE_PROVIDERS = 0x00000004;
2846
2847     /**
2848      * The undefined cursor position.
2849      *
2850      * @hide
2851      */
2852     public static final int ACCESSIBILITY_CURSOR_POSITION_UNDEFINED = -1;
2853
2854     /**
2855      * Indicates that the screen has changed state and is now off.
2856      *
2857      * @see #onScreenStateChanged(int)
2858      */
2859     public static final int SCREEN_STATE_OFF = 0x0;
2860
2861     /**
2862      * Indicates that the screen has changed state and is now on.
2863      *
2864      * @see #onScreenStateChanged(int)
2865      */
2866     public static final int SCREEN_STATE_ON = 0x1;
2867
2868     /**
2869      * Indicates no axis of view scrolling.
2870      */
2871     public static final int SCROLL_AXIS_NONE = 0;
2872
2873     /**
2874      * Indicates scrolling along the horizontal axis.
2875      */
2876     public static final int SCROLL_AXIS_HORIZONTAL = 1 << 0;
2877
2878     /**
2879      * Indicates scrolling along the vertical axis.
2880      */
2881     public static final int SCROLL_AXIS_VERTICAL = 1 << 1;
2882
2883     /**
2884      * Controls the over-scroll mode for this view.
2885      * See {@link #overScrollBy(int, int, int, int, int, int, int, int, boolean)},
2886      * {@link #OVER_SCROLL_ALWAYS}, {@link #OVER_SCROLL_IF_CONTENT_SCROLLS},
2887      * and {@link #OVER_SCROLL_NEVER}.
2888      */
2889     private int mOverScrollMode;
2890
2891     /**
2892      * The parent this view is attached to.
2893      * {@hide}
2894      *
2895      * @see #getParent()
2896      */
2897     protected ViewParent mParent;
2898
2899     /**
2900      * {@hide}
2901      */
2902     AttachInfo mAttachInfo;
2903
2904     /**
2905      * {@hide}
2906      */
2907     @ViewDebug.ExportedProperty(flagMapping = {
2908         @ViewDebug.FlagToString(mask = PFLAG_FORCE_LAYOUT, equals = PFLAG_FORCE_LAYOUT,
2909                 name = "FORCE_LAYOUT"),
2910         @ViewDebug.FlagToString(mask = PFLAG_LAYOUT_REQUIRED, equals = PFLAG_LAYOUT_REQUIRED,
2911                 name = "LAYOUT_REQUIRED"),
2912         @ViewDebug.FlagToString(mask = PFLAG_DRAWING_CACHE_VALID, equals = PFLAG_DRAWING_CACHE_VALID,
2913             name = "DRAWING_CACHE_INVALID", outputIf = false),
2914         @ViewDebug.FlagToString(mask = PFLAG_DRAWN, equals = PFLAG_DRAWN, name = "DRAWN", outputIf = true),
2915         @ViewDebug.FlagToString(mask = PFLAG_DRAWN, equals = PFLAG_DRAWN, name = "NOT_DRAWN", outputIf = false),
2916         @ViewDebug.FlagToString(mask = PFLAG_DIRTY_MASK, equals = PFLAG_DIRTY_OPAQUE, name = "DIRTY_OPAQUE"),
2917         @ViewDebug.FlagToString(mask = PFLAG_DIRTY_MASK, equals = PFLAG_DIRTY, name = "DIRTY")
2918     }, formatToHexString = true)
2919     int mPrivateFlags;
2920     int mPrivateFlags2;
2921     int mPrivateFlags3;
2922
2923     /**
2924      * This view's request for the visibility of the status bar.
2925      * @hide
2926      */
2927     @ViewDebug.ExportedProperty(flagMapping = {
2928         @ViewDebug.FlagToString(mask = SYSTEM_UI_FLAG_LOW_PROFILE,
2929                                 equals = SYSTEM_UI_FLAG_LOW_PROFILE,
2930                                 name = "SYSTEM_UI_FLAG_LOW_PROFILE", outputIf = true),
2931         @ViewDebug.FlagToString(mask = SYSTEM_UI_FLAG_HIDE_NAVIGATION,
2932                                 equals = SYSTEM_UI_FLAG_HIDE_NAVIGATION,
2933                                 name = "SYSTEM_UI_FLAG_HIDE_NAVIGATION", outputIf = true),
2934         @ViewDebug.FlagToString(mask = PUBLIC_STATUS_BAR_VISIBILITY_MASK,
2935                                 equals = SYSTEM_UI_FLAG_VISIBLE,
2936                                 name = "SYSTEM_UI_FLAG_VISIBLE", outputIf = true)
2937     }, formatToHexString = true)
2938     int mSystemUiVisibility;
2939
2940     /**
2941      * Reference count for transient state.
2942      * @see #setHasTransientState(boolean)
2943      */
2944     int mTransientStateCount = 0;
2945
2946     /**
2947      * Count of how many windows this view has been attached to.
2948      */
2949     int mWindowAttachCount;
2950
2951     /**
2952      * The layout parameters associated with this view and used by the parent
2953      * {@link android.view.ViewGroup} to determine how this view should be
2954      * laid out.
2955      * {@hide}
2956      */
2957     protected ViewGroup.LayoutParams mLayoutParams;
2958
2959     /**
2960      * The view flags hold various views states.
2961      * {@hide}
2962      */
2963     @ViewDebug.ExportedProperty(formatToHexString = true)
2964     int mViewFlags;
2965
2966     static class TransformationInfo {
2967         /**
2968          * The transform matrix for the View. This transform is calculated internally
2969          * based on the translation, rotation, and scale properties.
2970          *
2971          * Do *not* use this variable directly; instead call getMatrix(), which will
2972          * load the value from the View's RenderNode.
2973          */
2974         private final Matrix mMatrix = new Matrix();
2975
2976         /**
2977          * The inverse transform matrix for the View. This transform is calculated
2978          * internally based on the translation, rotation, and scale properties.
2979          *
2980          * Do *not* use this variable directly; instead call getInverseMatrix(),
2981          * which will load the value from the View's RenderNode.
2982          */
2983         private Matrix mInverseMatrix;
2984
2985         /**
2986          * The opacity of the View. This is a value from 0 to 1, where 0 means
2987          * completely transparent and 1 means completely opaque.
2988          */
2989         @ViewDebug.ExportedProperty
2990         float mAlpha = 1f;
2991
2992         /**
2993          * The opacity of the view as manipulated by the Fade transition. This is a hidden
2994          * property only used by transitions, which is composited with the other alpha
2995          * values to calculate the final visual alpha value.
2996          */
2997         float mTransitionAlpha = 1f;
2998     }
2999
3000     TransformationInfo mTransformationInfo;
3001
3002     /**
3003      * Current clip bounds. to which all drawing of this view are constrained.
3004      */
3005     Rect mClipBounds = null;
3006
3007     private boolean mLastIsOpaque;
3008
3009     /**
3010      * The distance in pixels from the left edge of this view's parent
3011      * to the left edge of this view.
3012      * {@hide}
3013      */
3014     @ViewDebug.ExportedProperty(category = "layout")
3015     protected int mLeft;
3016     /**
3017      * The distance in pixels from the left edge of this view's parent
3018      * to the right edge of this view.
3019      * {@hide}
3020      */
3021     @ViewDebug.ExportedProperty(category = "layout")
3022     protected int mRight;
3023     /**
3024      * The distance in pixels from the top edge of this view's parent
3025      * to the top edge of this view.
3026      * {@hide}
3027      */
3028     @ViewDebug.ExportedProperty(category = "layout")
3029     protected int mTop;
3030     /**
3031      * The distance in pixels from the top edge of this view's parent
3032      * to the bottom edge of this view.
3033      * {@hide}
3034      */
3035     @ViewDebug.ExportedProperty(category = "layout")
3036     protected int mBottom;
3037
3038     /**
3039      * The offset, in pixels, by which the content of this view is scrolled
3040      * horizontally.
3041      * {@hide}
3042      */
3043     @ViewDebug.ExportedProperty(category = "scrolling")
3044     protected int mScrollX;
3045     /**
3046      * The offset, in pixels, by which the content of this view is scrolled
3047      * vertically.
3048      * {@hide}
3049      */
3050     @ViewDebug.ExportedProperty(category = "scrolling")
3051     protected int mScrollY;
3052
3053     /**
3054      * The left padding in pixels, that is the distance in pixels between the
3055      * left edge of this view and the left edge of its content.
3056      * {@hide}
3057      */
3058     @ViewDebug.ExportedProperty(category = "padding")
3059     protected int mPaddingLeft = 0;
3060     /**
3061      * The right padding in pixels, that is the distance in pixels between the
3062      * right edge of this view and the right edge of its content.
3063      * {@hide}
3064      */
3065     @ViewDebug.ExportedProperty(category = "padding")
3066     protected int mPaddingRight = 0;
3067     /**
3068      * The top padding in pixels, that is the distance in pixels between the
3069      * top edge of this view and the top edge of its content.
3070      * {@hide}
3071      */
3072     @ViewDebug.ExportedProperty(category = "padding")
3073     protected int mPaddingTop;
3074     /**
3075      * The bottom padding in pixels, that is the distance in pixels between the
3076      * bottom edge of this view and the bottom edge of its content.
3077      * {@hide}
3078      */
3079     @ViewDebug.ExportedProperty(category = "padding")
3080     protected int mPaddingBottom;
3081
3082     /**
3083      * The layout insets in pixels, that is the distance in pixels between the
3084      * visible edges of this view its bounds.
3085      */
3086     private Insets mLayoutInsets;
3087
3088     /**
3089      * Briefly describes the view and is primarily used for accessibility support.
3090      */
3091     private CharSequence mContentDescription;
3092
3093     /**
3094      * Specifies the id of a view for which this view serves as a label for
3095      * accessibility purposes.
3096      */
3097     private int mLabelForId = View.NO_ID;
3098
3099     /**
3100      * Predicate for matching labeled view id with its label for
3101      * accessibility purposes.
3102      */
3103     private MatchLabelForPredicate mMatchLabelForPredicate;
3104
3105     /**
3106      * Predicate for matching a view by its id.
3107      */
3108     private MatchIdPredicate mMatchIdPredicate;
3109
3110     /**
3111      * Cache the paddingRight set by the user to append to the scrollbar's size.
3112      *
3113      * @hide
3114      */
3115     @ViewDebug.ExportedProperty(category = "padding")
3116     protected int mUserPaddingRight;
3117
3118     /**
3119      * Cache the paddingBottom set by the user to append to the scrollbar's size.
3120      *
3121      * @hide
3122      */
3123     @ViewDebug.ExportedProperty(category = "padding")
3124     protected int mUserPaddingBottom;
3125
3126     /**
3127      * Cache the paddingLeft set by the user to append to the scrollbar's size.
3128      *
3129      * @hide
3130      */
3131     @ViewDebug.ExportedProperty(category = "padding")
3132     protected int mUserPaddingLeft;
3133
3134     /**
3135      * Cache the paddingStart set by the user to append to the scrollbar's size.
3136      *
3137      */
3138     @ViewDebug.ExportedProperty(category = "padding")
3139     int mUserPaddingStart;
3140
3141     /**
3142      * Cache the paddingEnd set by the user to append to the scrollbar's size.
3143      *
3144      */
3145     @ViewDebug.ExportedProperty(category = "padding")
3146     int mUserPaddingEnd;
3147
3148     /**
3149      * Cache initial left padding.
3150      *
3151      * @hide
3152      */
3153     int mUserPaddingLeftInitial;
3154
3155     /**
3156      * Cache initial right padding.
3157      *
3158      * @hide
3159      */
3160     int mUserPaddingRightInitial;
3161
3162     /**
3163      * Default undefined padding
3164      */
3165     private static final int UNDEFINED_PADDING = Integer.MIN_VALUE;
3166
3167     /**
3168      * Cache if a left padding has been defined
3169      */
3170     private boolean mLeftPaddingDefined = false;
3171
3172     /**
3173      * Cache if a right padding has been defined
3174      */
3175     private boolean mRightPaddingDefined = false;
3176
3177     /**
3178      * @hide
3179      */
3180     int mOldWidthMeasureSpec = Integer.MIN_VALUE;
3181     /**
3182      * @hide
3183      */
3184     int mOldHeightMeasureSpec = Integer.MIN_VALUE;
3185
3186     private LongSparseLongArray mMeasureCache;
3187
3188     @ViewDebug.ExportedProperty(deepExport = true, prefix = "bg_")
3189     private Drawable mBackground;
3190     private ColorStateList mBackgroundTintList = null;
3191     private PorterDuff.Mode mBackgroundTintMode = PorterDuff.Mode.SRC_ATOP;
3192     private boolean mHasBackgroundTint = false;
3193
3194     /**
3195      * RenderNode used for backgrounds.
3196      * <p>
3197      * When non-null and valid, this is expected to contain an up-to-date copy
3198      * of the background drawable. It is cleared on temporary detach, and reset
3199      * on cleanup.
3200      */
3201     private RenderNode mBackgroundRenderNode;
3202
3203     private int mBackgroundResource;
3204     private boolean mBackgroundSizeChanged;
3205
3206     private String mTransitionName;
3207
3208     static class ListenerInfo {
3209         /**
3210          * Listener used to dispatch focus change events.
3211          * This field should be made private, so it is hidden from the SDK.
3212          * {@hide}
3213          */
3214         protected OnFocusChangeListener mOnFocusChangeListener;
3215
3216         /**
3217          * Listeners for layout change events.
3218          */
3219         private ArrayList<OnLayoutChangeListener> mOnLayoutChangeListeners;
3220
3221         /**
3222          * Listeners for attach events.
3223          */
3224         private CopyOnWriteArrayList<OnAttachStateChangeListener> mOnAttachStateChangeListeners;
3225
3226         /**
3227          * Listener used to dispatch click events.
3228          * This field should be made private, so it is hidden from the SDK.
3229          * {@hide}
3230          */
3231         public OnClickListener mOnClickListener;
3232
3233         /**
3234          * Listener used to dispatch long click events.
3235          * This field should be made private, so it is hidden from the SDK.
3236          * {@hide}
3237          */
3238         protected OnLongClickListener mOnLongClickListener;
3239
3240         /**
3241          * Listener used to build the context menu.
3242          * This field should be made private, so it is hidden from the SDK.
3243          * {@hide}
3244          */
3245         protected OnCreateContextMenuListener mOnCreateContextMenuListener;
3246
3247         private OnKeyListener mOnKeyListener;
3248
3249         private OnTouchListener mOnTouchListener;
3250
3251         private OnHoverListener mOnHoverListener;
3252
3253         private OnGenericMotionListener mOnGenericMotionListener;
3254
3255         private OnDragListener mOnDragListener;
3256
3257         private OnSystemUiVisibilityChangeListener mOnSystemUiVisibilityChangeListener;
3258
3259         OnApplyWindowInsetsListener mOnApplyWindowInsetsListener;
3260     }
3261
3262     ListenerInfo mListenerInfo;
3263
3264     /**
3265      * The application environment this view lives in.
3266      * This field should be made private, so it is hidden from the SDK.
3267      * {@hide}
3268      */
3269     @ViewDebug.ExportedProperty(deepExport = true)
3270     protected Context mContext;
3271
3272     private final Resources mResources;
3273
3274     private ScrollabilityCache mScrollCache;
3275
3276     private int[] mDrawableState = null;
3277
3278     ViewOutlineProvider mOutlineProvider = ViewOutlineProvider.BACKGROUND;
3279
3280     /**
3281      * Animator that automatically runs based on state changes.
3282      */
3283     private StateListAnimator mStateListAnimator;
3284
3285     /**
3286      * When this view has focus and the next focus is {@link #FOCUS_LEFT},
3287      * the user may specify which view to go to next.
3288      */
3289     private int mNextFocusLeftId = View.NO_ID;
3290
3291     /**
3292      * When this view has focus and the next focus is {@link #FOCUS_RIGHT},
3293      * the user may specify which view to go to next.
3294      */
3295     private int mNextFocusRightId = View.NO_ID;
3296
3297     /**
3298      * When this view has focus and the next focus is {@link #FOCUS_UP},
3299      * the user may specify which view to go to next.
3300      */
3301     private int mNextFocusUpId = View.NO_ID;
3302
3303     /**
3304      * When this view has focus and the next focus is {@link #FOCUS_DOWN},
3305      * the user may specify which view to go to next.
3306      */
3307     private int mNextFocusDownId = View.NO_ID;
3308
3309     /**
3310      * When this view has focus and the next focus is {@link #FOCUS_FORWARD},
3311      * the user may specify which view to go to next.
3312      */
3313     int mNextFocusForwardId = View.NO_ID;
3314
3315     private CheckForLongPress mPendingCheckForLongPress;
3316     private CheckForTap mPendingCheckForTap = null;
3317     private PerformClick mPerformClick;
3318     private SendViewScrolledAccessibilityEvent mSendViewScrolledAccessibilityEvent;
3319
3320     private UnsetPressedState mUnsetPressedState;
3321
3322     /**
3323      * Whether the long press's action has been invoked.  The tap's action is invoked on the
3324      * up event while a long press is invoked as soon as the long press duration is reached, so
3325      * a long press could be performed before the tap is checked, in which case the tap's action
3326      * should not be invoked.
3327      */
3328     private boolean mHasPerformedLongPress;
3329
3330     /**
3331      * The minimum height of the view. We'll try our best to have the height
3332      * of this view to at least this amount.
3333      */
3334     @ViewDebug.ExportedProperty(category = "measurement")
3335     private int mMinHeight;
3336
3337     /**
3338      * The minimum width of the view. We'll try our best to have the width
3339      * of this view to at least this amount.
3340      */
3341     @ViewDebug.ExportedProperty(category = "measurement")
3342     private int mMinWidth;
3343
3344     /**
3345      * The delegate to handle touch events that are physically in this view
3346      * but should be handled by another view.
3347      */
3348     private TouchDelegate mTouchDelegate = null;
3349
3350     /**
3351      * Solid color to use as a background when creating the drawing cache. Enables
3352      * the cache to use 16 bit bitmaps instead of 32 bit.
3353      */
3354     private int mDrawingCacheBackgroundColor = 0;
3355
3356     /**
3357      * Special tree observer used when mAttachInfo is null.
3358      */
3359     private ViewTreeObserver mFloatingTreeObserver;
3360
3361     /**
3362      * Cache the touch slop from the context that created the view.
3363      */
3364     private int mTouchSlop;
3365
3366     /**
3367      * Object that handles automatic animation of view properties.
3368      */
3369     private ViewPropertyAnimator mAnimator = null;
3370
3371     /**
3372      * Flag indicating that a drag can cross window boundaries.  When
3373      * {@link #startDrag(ClipData, DragShadowBuilder, Object, int)} is called
3374      * with this flag set, all visible applications will be able to participate
3375      * in the drag operation and receive the dragged content.
3376      *
3377      * @hide
3378      */
3379     public static final int DRAG_FLAG_GLOBAL = 1;
3380
3381     /**
3382      * Vertical scroll factor cached by {@link #getVerticalScrollFactor}.
3383      */
3384     private float mVerticalScrollFactor;
3385
3386     /**
3387      * Position of the vertical scroll bar.
3388      */
3389     private int mVerticalScrollbarPosition;
3390
3391     /**
3392      * Position the scroll bar at the default position as determined by the system.
3393      */
3394     public static final int SCROLLBAR_POSITION_DEFAULT = 0;
3395
3396     /**
3397      * Position the scroll bar along the left edge.
3398      */
3399     public static final int SCROLLBAR_POSITION_LEFT = 1;
3400
3401     /**
3402      * Position the scroll bar along the right edge.
3403      */
3404     public static final int SCROLLBAR_POSITION_RIGHT = 2;
3405
3406     /**
3407      * Indicates that the view does not have a layer.
3408      *
3409      * @see #getLayerType()
3410      * @see #setLayerType(int, android.graphics.Paint)
3411      * @see #LAYER_TYPE_SOFTWARE
3412      * @see #LAYER_TYPE_HARDWARE
3413      */
3414     public static final int LAYER_TYPE_NONE = 0;
3415
3416     /**
3417      * <p>Indicates that the view has a software layer. A software layer is backed
3418      * by a bitmap and causes the view to be rendered using Android's software
3419      * rendering pipeline, even if hardware acceleration is enabled.</p>
3420      *
3421      * <p>Software layers have various usages:</p>
3422      * <p>When the application is not using hardware acceleration, a software layer
3423      * is useful to apply a specific color filter and/or blending mode and/or
3424      * translucency to a view and all its children.</p>
3425      * <p>When the application is using hardware acceleration, a software layer
3426      * is useful to render drawing primitives not supported by the hardware
3427      * accelerated pipeline. It can also be used to cache a complex view tree
3428      * into a texture and reduce the complexity of drawing operations. For instance,
3429      * when animating a complex view tree with a translation, a software layer can
3430      * be used to render the view tree only once.</p>
3431      * <p>Software layers should be avoided when the affected view tree updates
3432      * often. Every update will require to re-render the software layer, which can
3433      * potentially be slow (particularly when hardware acceleration is turned on
3434      * since the layer will have to be uploaded into a hardware texture after every
3435      * update.)</p>
3436      *
3437      * @see #getLayerType()
3438      * @see #setLayerType(int, android.graphics.Paint)
3439      * @see #LAYER_TYPE_NONE
3440      * @see #LAYER_TYPE_HARDWARE
3441      */
3442     public static final int LAYER_TYPE_SOFTWARE = 1;
3443
3444     /**
3445      * <p>Indicates that the view has a hardware layer. A hardware layer is backed
3446      * by a hardware specific texture (generally Frame Buffer Objects or FBO on
3447      * OpenGL hardware) and causes the view to be rendered using Android's hardware
3448      * rendering pipeline, but only if hardware acceleration is turned on for the
3449      * view hierarchy. When hardware acceleration is turned off, hardware layers
3450      * behave exactly as {@link #LAYER_TYPE_SOFTWARE software layers}.</p>
3451      *
3452      * <p>A hardware layer is useful to apply a specific color filter and/or
3453      * blending mode and/or translucency to a view and all its children.</p>
3454      * <p>A hardware layer can be used to cache a complex view tree into a
3455      * texture and reduce the complexity of drawing operations. For instance,
3456      * when animating a complex view tree with a translation, a hardware layer can
3457      * be used to render the view tree only once.</p>
3458      * <p>A hardware layer can also be used to increase the rendering quality when
3459      * rotation transformations are applied on a view. It can also be used to
3460      * prevent potential clipping issues when applying 3D transforms on a view.</p>
3461      *
3462      * @see #getLayerType()
3463      * @see #setLayerType(int, android.graphics.Paint)
3464      * @see #LAYER_TYPE_NONE
3465      * @see #LAYER_TYPE_SOFTWARE
3466      */
3467     public static final int LAYER_TYPE_HARDWARE = 2;
3468
3469     @ViewDebug.ExportedProperty(category = "drawing", mapping = {
3470             @ViewDebug.IntToString(from = LAYER_TYPE_NONE, to = "NONE"),
3471             @ViewDebug.IntToString(from = LAYER_TYPE_SOFTWARE, to = "SOFTWARE"),
3472             @ViewDebug.IntToString(from = LAYER_TYPE_HARDWARE, to = "HARDWARE")
3473     })
3474     int mLayerType = LAYER_TYPE_NONE;
3475     Paint mLayerPaint;
3476
3477     /**
3478      * Set to true when drawing cache is enabled and cannot be created.
3479      *
3480      * @hide
3481      */
3482     public boolean mCachingFailed;
3483     private Bitmap mDrawingCache;
3484     private Bitmap mUnscaledDrawingCache;
3485
3486     /**
3487      * RenderNode holding View properties, potentially holding a DisplayList of View content.
3488      * <p>
3489      * When non-null and valid, this is expected to contain an up-to-date copy
3490      * of the View content. Its DisplayList content is cleared on temporary detach and reset on
3491      * cleanup.
3492      */
3493     final RenderNode mRenderNode;
3494
3495     /**
3496      * Set to true when the view is sending hover accessibility events because it
3497      * is the innermost hovered view.
3498      */
3499     private boolean mSendingHoverAccessibilityEvents;
3500
3501     /**
3502      * Delegate for injecting accessibility functionality.
3503      */
3504     AccessibilityDelegate mAccessibilityDelegate;
3505
3506     /**
3507      * The view's overlay layer. Developers get a reference to the overlay via getOverlay()
3508      * and add/remove objects to/from the overlay directly through the Overlay methods.
3509      */
3510     ViewOverlay mOverlay;
3511
3512     /**
3513      * The currently active parent view for receiving delegated nested scrolling events.
3514      * This is set by {@link #startNestedScroll(int)} during a touch interaction and cleared
3515      * by {@link #stopNestedScroll()} at the same point where we clear
3516      * requestDisallowInterceptTouchEvent.
3517      */
3518     private ViewParent mNestedScrollingParent;
3519
3520     /**
3521      * Consistency verifier for debugging purposes.
3522      * @hide
3523      */
3524     protected final InputEventConsistencyVerifier mInputEventConsistencyVerifier =
3525             InputEventConsistencyVerifier.isInstrumentationEnabled() ?
3526                     new InputEventConsistencyVerifier(this, 0) : null;
3527
3528     private static final AtomicInteger sNextGeneratedId = new AtomicInteger(1);
3529
3530     private int[] mTempNestedScrollConsumed;
3531
3532     /**
3533      * An overlay is going to draw this View instead of being drawn as part of this
3534      * View's parent. mGhostView is the View in the Overlay that must be invalidated
3535      * when this view is invalidated.
3536      */
3537     GhostView mGhostView;
3538
3539     /**
3540      * Holds pairs of adjacent attribute data: attribute name followed by its value.
3541      * @hide
3542      */
3543     @ViewDebug.ExportedProperty(category = "attributes", hasAdjacentMapping = true)
3544     public String[] mAttributes;
3545
3546     /**
3547      * Maps a Resource id to its name.
3548      */
3549     private static SparseArray<String> mAttributeMap;
3550
3551     /**
3552      * Simple constructor to use when creating a view from code.
3553      *
3554      * @param context The Context the view is running in, through which it can
3555      *        access the current theme, resources, etc.
3556      */
3557     public View(Context context) {
3558         mContext = context;
3559         mResources = context != null ? context.getResources() : null;
3560         mViewFlags = SOUND_EFFECTS_ENABLED | HAPTIC_FEEDBACK_ENABLED;
3561         // Set some flags defaults
3562         mPrivateFlags2 =
3563                 (LAYOUT_DIRECTION_DEFAULT << PFLAG2_LAYOUT_DIRECTION_MASK_SHIFT) |
3564                 (TEXT_DIRECTION_DEFAULT << PFLAG2_TEXT_DIRECTION_MASK_SHIFT) |
3565                 (PFLAG2_TEXT_DIRECTION_RESOLVED_DEFAULT) |
3566                 (TEXT_ALIGNMENT_DEFAULT << PFLAG2_TEXT_ALIGNMENT_MASK_SHIFT) |
3567                 (PFLAG2_TEXT_ALIGNMENT_RESOLVED_DEFAULT) |
3568                 (IMPORTANT_FOR_ACCESSIBILITY_DEFAULT << PFLAG2_IMPORTANT_FOR_ACCESSIBILITY_SHIFT);
3569         mTouchSlop = ViewConfiguration.get(context).getScaledTouchSlop();
3570         setOverScrollMode(OVER_SCROLL_IF_CONTENT_SCROLLS);
3571         mUserPaddingStart = UNDEFINED_PADDING;
3572         mUserPaddingEnd = UNDEFINED_PADDING;
3573         mRenderNode = RenderNode.create(getClass().getName(), this);
3574
3575         if (!sCompatibilityDone && context != null) {
3576             final int targetSdkVersion = context.getApplicationInfo().targetSdkVersion;
3577
3578             // Older apps may need this compatibility hack for measurement.
3579             sUseBrokenMakeMeasureSpec = targetSdkVersion <= JELLY_BEAN_MR1;
3580
3581             // Older apps expect onMeasure() to always be called on a layout pass, regardless
3582             // of whether a layout was requested on that View.
3583             sIgnoreMeasureCache = targetSdkVersion < KITKAT;
3584
3585             sCompatibilityDone = true;
3586         }
3587     }
3588
3589     /**
3590      * Constructor that is called when inflating a view from XML. This is called
3591      * when a view is being constructed from an XML file, supplying attributes
3592      * that were specified in the XML file. This version uses a default style of
3593      * 0, so the only attribute values applied are those in the Context's Theme
3594      * and the given AttributeSet.
3595      *
3596      * <p>
3597      * The method onFinishInflate() will be called after all children have been
3598      * added.
3599      *
3600      * @param context The Context the view is running in, through which it can
3601      *        access the current theme, resources, etc.
3602      * @param attrs The attributes of the XML tag that is inflating the view.
3603      * @see #View(Context, AttributeSet, int)
3604      */
3605     public View(Context context, AttributeSet attrs) {
3606         this(context, attrs, 0);
3607     }
3608
3609     /**
3610      * Perform inflation from XML and apply a class-specific base style from a
3611      * theme attribute. This constructor of View allows subclasses to use their
3612      * own base style when they are inflating. For example, a Button class's
3613      * constructor would call this version of the super class constructor and
3614      * supply <code>R.attr.buttonStyle</code> for <var>defStyleAttr</var>; this
3615      * allows the theme's button style to modify all of the base view attributes
3616      * (in particular its background) as well as the Button class's attributes.
3617      *
3618      * @param context The Context the view is running in, through which it can
3619      *        access the current theme, resources, etc.
3620      * @param attrs The attributes of the XML tag that is inflating the view.
3621      * @param defStyleAttr An attribute in the current theme that contains a
3622      *        reference to a style resource that supplies default values for
3623      *        the view. Can be 0 to not look for defaults.
3624      * @see #View(Context, AttributeSet)
3625      */
3626     public View(Context context, AttributeSet attrs, int defStyleAttr) {
3627         this(context, attrs, defStyleAttr, 0);
3628     }
3629
3630     /**
3631      * Perform inflation from XML and apply a class-specific base style from a
3632      * theme attribute or style resource. This constructor of View allows
3633      * subclasses to use their own base style when they are inflating.
3634      * <p>
3635      * When determining the final value of a particular attribute, there are
3636      * four inputs that come into play:
3637      * <ol>
3638      * <li>Any attribute values in the given AttributeSet.
3639      * <li>The style resource specified in the AttributeSet (named "style").
3640      * <li>The default style specified by <var>defStyleAttr</var>.
3641      * <li>The default style specified by <var>defStyleRes</var>.
3642      * <li>The base values in this theme.
3643      * </ol>
3644      * <p>
3645      * Each of these inputs is considered in-order, with the first listed taking
3646      * precedence over the following ones. In other words, if in the
3647      * AttributeSet you have supplied <code>&lt;Button * textColor="#ff000000"&gt;</code>
3648      * , then the button's text will <em>always</em> be black, regardless of
3649      * what is specified in any of the styles.
3650      *
3651      * @param context The Context the view is running in, through which it can
3652      *        access the current theme, resources, etc.
3653      * @param attrs The attributes of the XML tag that is inflating the view.
3654      * @param defStyleAttr An attribute in the current theme that contains a
3655      *        reference to a style resource that supplies default values for
3656      *        the view. Can be 0 to not look for defaults.
3657      * @param defStyleRes A resource identifier of a style resource that
3658      *        supplies default values for the view, used only if
3659      *        defStyleAttr is 0 or can not be found in the theme. Can be 0
3660      *        to not look for defaults.
3661      * @see #View(Context, AttributeSet, int)
3662      */
3663     public View(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
3664         this(context);
3665
3666         final TypedArray a = context.obtainStyledAttributes(
3667                 attrs, com.android.internal.R.styleable.View, defStyleAttr, defStyleRes);
3668
3669         if (mDebugViewAttributes) {
3670             saveAttributeData(attrs, a);
3671         }
3672
3673         Drawable background = null;
3674
3675         int leftPadding = -1;
3676         int topPadding = -1;
3677         int rightPadding = -1;
3678         int bottomPadding = -1;
3679         int startPadding = UNDEFINED_PADDING;
3680         int endPadding = UNDEFINED_PADDING;
3681
3682         int padding = -1;
3683
3684         int viewFlagValues = 0;
3685         int viewFlagMasks = 0;
3686
3687         boolean setScrollContainer = false;
3688
3689         int x = 0;
3690         int y = 0;
3691
3692         float tx = 0;
3693         float ty = 0;
3694         float tz = 0;
3695         float elevation = 0;
3696         float rotation = 0;
3697         float rotationX = 0;
3698         float rotationY = 0;
3699         float sx = 1f;
3700         float sy = 1f;
3701         boolean transformSet = false;
3702
3703         int scrollbarStyle = SCROLLBARS_INSIDE_OVERLAY;
3704         int overScrollMode = mOverScrollMode;
3705         boolean initializeScrollbars = false;
3706
3707         boolean startPaddingDefined = false;
3708         boolean endPaddingDefined = false;
3709         boolean leftPaddingDefined = false;
3710         boolean rightPaddingDefined = false;
3711
3712         final int targetSdkVersion = context.getApplicationInfo().targetSdkVersion;
3713
3714         final int N = a.getIndexCount();
3715         for (int i = 0; i < N; i++) {
3716             int attr = a.getIndex(i);
3717             switch (attr) {
3718                 case com.android.internal.R.styleable.View_background:
3719                     background = a.getDrawable(attr);
3720                     break;
3721                 case com.android.internal.R.styleable.View_padding:
3722                     padding = a.getDimensionPixelSize(attr, -1);
3723                     mUserPaddingLeftInitial = padding;
3724                     mUserPaddingRightInitial = padding;
3725                     leftPaddingDefined = true;
3726                     rightPaddingDefined = true;
3727                     break;
3728                  case com.android.internal.R.styleable.View_paddingLeft:
3729                     leftPadding = a.getDimensionPixelSize(attr, -1);
3730                     mUserPaddingLeftInitial = leftPadding;
3731                     leftPaddingDefined = true;
3732                     break;
3733                 case com.android.internal.R.styleable.View_paddingTop:
3734                     topPadding = a.getDimensionPixelSize(attr, -1);
3735                     break;
3736                 case com.android.internal.R.styleable.View_paddingRight:
3737                     rightPadding = a.getDimensionPixelSize(attr, -1);
3738                     mUserPaddingRightInitial = rightPadding;
3739                     rightPaddingDefined = true;
3740                     break;
3741                 case com.android.internal.R.styleable.View_paddingBottom:
3742                     bottomPadding = a.getDimensionPixelSize(attr, -1);
3743                     break;
3744                 case com.android.internal.R.styleable.View_paddingStart:
3745                     startPadding = a.getDimensionPixelSize(attr, UNDEFINED_PADDING);
3746                     startPaddingDefined = (startPadding != UNDEFINED_PADDING);
3747                     break;
3748                 case com.android.internal.R.styleable.View_paddingEnd:
3749                     endPadding = a.getDimensionPixelSize(attr, UNDEFINED_PADDING);
3750                     endPaddingDefined = (endPadding != UNDEFINED_PADDING);
3751                     break;
3752                 case com.android.internal.R.styleable.View_scrollX:
3753                     x = a.getDimensionPixelOffset(attr, 0);
3754                     break;
3755                 case com.android.internal.R.styleable.View_scrollY:
3756                     y = a.getDimensionPixelOffset(attr, 0);
3757                     break;
3758                 case com.android.internal.R.styleable.View_alpha:
3759                     setAlpha(a.getFloat(attr, 1f));
3760                     break;
3761                 case com.android.internal.R.styleable.View_transformPivotX:
3762                     setPivotX(a.getDimensionPixelOffset(attr, 0));
3763                     break;
3764                 case com.android.internal.R.styleable.View_transformPivotY:
3765                     setPivotY(a.getDimensionPixelOffset(attr, 0));
3766                     break;
3767                 case com.android.internal.R.styleable.View_translationX:
3768                     tx = a.getDimensionPixelOffset(attr, 0);
3769                     transformSet = true;
3770                     break;
3771                 case com.android.internal.R.styleable.View_translationY:
3772                     ty = a.getDimensionPixelOffset(attr, 0);
3773                     transformSet = true;
3774                     break;
3775                 case com.android.internal.R.styleable.View_translationZ:
3776                     tz = a.getDimensionPixelOffset(attr, 0);
3777                     transformSet = true;
3778                     break;
3779                 case com.android.internal.R.styleable.View_elevation:
3780                     elevation = a.getDimensionPixelOffset(attr, 0);
3781                     transformSet = true;
3782                     break;
3783                 case com.android.internal.R.styleable.View_rotation:
3784                     rotation = a.getFloat(attr, 0);
3785                     transformSet = true;
3786                     break;
3787                 case com.android.internal.R.styleable.View_rotationX:
3788                     rotationX = a.getFloat(attr, 0);
3789                     transformSet = true;
3790                     break;
3791                 case com.android.internal.R.styleable.View_rotationY:
3792                     rotationY = a.getFloat(attr, 0);
3793                     transformSet = true;
3794                     break;
3795                 case com.android.internal.R.styleable.View_scaleX:
3796                     sx = a.getFloat(attr, 1f);
3797                     transformSet = true;
3798                     break;
3799                 case com.android.internal.R.styleable.View_scaleY:
3800                     sy = a.getFloat(attr, 1f);
3801                     transformSet = true;
3802                     break;
3803                 case com.android.internal.R.styleable.View_id:
3804                     mID = a.getResourceId(attr, NO_ID);
3805                     break;
3806                 case com.android.internal.R.styleable.View_tag:
3807                     mTag = a.getText(attr);
3808                     break;
3809                 case com.android.internal.R.styleable.View_fitsSystemWindows:
3810                     if (a.getBoolean(attr, false)) {
3811                         viewFlagValues |= FITS_SYSTEM_WINDOWS;
3812                         viewFlagMasks |= FITS_SYSTEM_WINDOWS;
3813                     }
3814                     break;
3815                 case com.android.internal.R.styleable.View_focusable:
3816                     if (a.getBoolean(attr, false)) {
3817                         viewFlagValues |= FOCUSABLE;
3818                         viewFlagMasks |= FOCUSABLE_MASK;
3819                     }
3820                     break;
3821                 case com.android.internal.R.styleable.View_focusableInTouchMode:
3822                     if (a.getBoolean(attr, false)) {
3823                         viewFlagValues |= FOCUSABLE_IN_TOUCH_MODE | FOCUSABLE;
3824                         viewFlagMasks |= FOCUSABLE_IN_TOUCH_MODE | FOCUSABLE_MASK;
3825                     }
3826                     break;
3827                 case com.android.internal.R.styleable.View_clickable:
3828                     if (a.getBoolean(attr, false)) {
3829                         viewFlagValues |= CLICKABLE;
3830                         viewFlagMasks |= CLICKABLE;
3831                     }
3832                     break;
3833                 case com.android.internal.R.styleable.View_longClickable:
3834                     if (a.getBoolean(attr, false)) {
3835                         viewFlagValues |= LONG_CLICKABLE;
3836                         viewFlagMasks |= LONG_CLICKABLE;
3837                     }
3838                     break;
3839                 case com.android.internal.R.styleable.View_saveEnabled:
3840                     if (!a.getBoolean(attr, true)) {
3841                         viewFlagValues |= SAVE_DISABLED;
3842                         viewFlagMasks |= SAVE_DISABLED_MASK;
3843                     }
3844                     break;
3845                 case com.android.internal.R.styleable.View_duplicateParentState:
3846                     if (a.getBoolean(attr, false)) {
3847                         viewFlagValues |= DUPLICATE_PARENT_STATE;
3848                         viewFlagMasks |= DUPLICATE_PARENT_STATE;
3849                     }
3850                     break;
3851                 case com.android.internal.R.styleable.View_visibility:
3852                     final int visibility = a.getInt(attr, 0);
3853                     if (visibility != 0) {
3854                         viewFlagValues |= VISIBILITY_FLAGS[visibility];
3855                         viewFlagMasks |= VISIBILITY_MASK;
3856                     }
3857                     break;
3858                 case com.android.internal.R.styleable.View_layoutDirection:
3859                     // Clear any layout direction flags (included resolved bits) already set
3860                     mPrivateFlags2 &=
3861                             ~(PFLAG2_LAYOUT_DIRECTION_MASK | PFLAG2_LAYOUT_DIRECTION_RESOLVED_MASK);
3862                     // Set the layout direction flags depending on the value of the attribute
3863                     final int layoutDirection = a.getInt(attr, -1);
3864                     final int value = (layoutDirection != -1) ?
3865                             LAYOUT_DIRECTION_FLAGS[layoutDirection] : LAYOUT_DIRECTION_DEFAULT;
3866                     mPrivateFlags2 |= (value << PFLAG2_LAYOUT_DIRECTION_MASK_SHIFT);
3867                     break;
3868                 case com.android.internal.R.styleable.View_drawingCacheQuality:
3869                     final int cacheQuality = a.getInt(attr, 0);
3870                     if (cacheQuality != 0) {
3871                         viewFlagValues |= DRAWING_CACHE_QUALITY_FLAGS[cacheQuality];
3872                         viewFlagMasks |= DRAWING_CACHE_QUALITY_MASK;
3873                     }
3874                     break;
3875                 case com.android.internal.R.styleable.View_contentDescription:
3876                     setContentDescription(a.getString(attr));
3877                     break;
3878                 case com.android.internal.R.styleable.View_labelFor:
3879                     setLabelFor(a.getResourceId(attr, NO_ID));
3880                     break;
3881                 case com.android.internal.R.styleable.View_soundEffectsEnabled:
3882                     if (!a.getBoolean(attr, true)) {
3883                         viewFlagValues &= ~SOUND_EFFECTS_ENABLED;
3884                         viewFlagMasks |= SOUND_EFFECTS_ENABLED;
3885                     }
3886                     break;
3887                 case com.android.internal.R.styleable.View_hapticFeedbackEnabled:
3888                     if (!a.getBoolean(attr, true)) {
3889                         viewFlagValues &= ~HAPTIC_FEEDBACK_ENABLED;
3890                         viewFlagMasks |= HAPTIC_FEEDBACK_ENABLED;
3891                     }
3892                     break;
3893                 case R.styleable.View_scrollbars:
3894                     final int scrollbars = a.getInt(attr, SCROLLBARS_NONE);
3895                     if (scrollbars != SCROLLBARS_NONE) {
3896                         viewFlagValues |= scrollbars;
3897                         viewFlagMasks |= SCROLLBARS_MASK;
3898                         initializeScrollbars = true;
3899                     }
3900                     break;
3901                 //noinspection deprecation
3902                 case R.styleable.View_fadingEdge:
3903                     if (targetSdkVersion >= ICE_CREAM_SANDWICH) {
3904                         // Ignore the attribute starting with ICS
3905                         break;
3906                     }
3907                     // With builds < ICS, fall through and apply fading edges
3908                 case R.styleable.View_requiresFadingEdge:
3909                     final int fadingEdge = a.getInt(attr, FADING_EDGE_NONE);
3910                     if (fadingEdge != FADING_EDGE_NONE) {
3911                         viewFlagValues |= fadingEdge;
3912                         viewFlagMasks |= FADING_EDGE_MASK;
3913                         initializeFadingEdgeInternal(a);
3914                     }
3915                     break;
3916                 case R.styleable.View_scrollbarStyle:
3917                     scrollbarStyle = a.getInt(attr, SCROLLBARS_INSIDE_OVERLAY);
3918                     if (scrollbarStyle != SCROLLBARS_INSIDE_OVERLAY) {
3919                         viewFlagValues |= scrollbarStyle & SCROLLBARS_STYLE_MASK;
3920                         viewFlagMasks |= SCROLLBARS_STYLE_MASK;
3921                     }
3922                     break;
3923                 case R.styleable.View_isScrollContainer:
3924                     setScrollContainer = true;
3925                     if (a.getBoolean(attr, false)) {
3926                         setScrollContainer(true);
3927                     }
3928                     break;
3929                 case com.android.internal.R.styleable.View_keepScreenOn:
3930                     if (a.getBoolean(attr, false)) {
3931                         viewFlagValues |= KEEP_SCREEN_ON;
3932                         viewFlagMasks |= KEEP_SCREEN_ON;
3933                     }
3934                     break;
3935                 case R.styleable.View_filterTouchesWhenObscured:
3936                     if (a.getBoolean(attr, false)) {
3937                         viewFlagValues |= FILTER_TOUCHES_WHEN_OBSCURED;
3938                         viewFlagMasks |= FILTER_TOUCHES_WHEN_OBSCURED;
3939                     }
3940                     break;
3941                 case R.styleable.View_nextFocusLeft:
3942                     mNextFocusLeftId = a.getResourceId(attr, View.NO_ID);
3943                     break;
3944                 case R.styleable.View_nextFocusRight:
3945                     mNextFocusRightId = a.getResourceId(attr, View.NO_ID);
3946                     break;
3947                 case R.styleable.View_nextFocusUp:
3948                     mNextFocusUpId = a.getResourceId(attr, View.NO_ID);
3949                     break;
3950                 case R.styleable.View_nextFocusDown:
3951                     mNextFocusDownId = a.getResourceId(attr, View.NO_ID);
3952                     break;
3953                 case R.styleable.View_nextFocusForward:
3954                     mNextFocusForwardId = a.getResourceId(attr, View.NO_ID);
3955                     break;
3956                 case R.styleable.View_minWidth:
3957                     mMinWidth = a.getDimensionPixelSize(attr, 0);
3958                     break;
3959                 case R.styleable.View_minHeight:
3960                     mMinHeight = a.getDimensionPixelSize(attr, 0);
3961                     break;
3962                 case R.styleable.View_onClick:
3963                     if (context.isRestricted()) {
3964                         throw new IllegalStateException("The android:onClick attribute cannot "
3965                                 + "be used within a restricted context");
3966                     }
3967
3968                     final String handlerName = a.getString(attr);
3969                     if (handlerName != null) {
3970                         setOnClickListener(new OnClickListener() {
3971                             private Method mHandler;
3972
3973                             public void onClick(View v) {
3974                                 if (mHandler == null) {
3975                                     try {
3976                                         mHandler = getContext().getClass().getMethod(handlerName,
3977                                                 View.class);
3978                                     } catch (NoSuchMethodException e) {
3979                                         int id = getId();
3980                                         String idText = id == NO_ID ? "" : " with id '"
3981                                                 + getContext().getResources().getResourceEntryName(
3982                                                     id) + "'";
3983                                         throw new IllegalStateException("Could not find a method " +
3984                                                 handlerName + "(View) in the activity "
3985                                                 + getContext().getClass() + " for onClick handler"
3986                                                 + " on view " + View.this.getClass() + idText, e);
3987                                     }
3988                                 }
3989
3990                                 try {
3991                                     mHandler.invoke(getContext(), View.this);
3992                                 } catch (IllegalAccessException e) {
3993                                     throw new IllegalStateException("Could not execute non "
3994                                             + "public method of the activity", e);
3995                                 } catch (InvocationTargetException e) {
3996                                     throw new IllegalStateException("Could not execute "
3997                                             + "method of the activity", e);
3998                                 }
3999                             }
4000                         });
4001                     }
4002                     break;
4003                 case R.styleable.View_overScrollMode:
4004                     overScrollMode = a.getInt(attr, OVER_SCROLL_IF_CONTENT_SCROLLS);
4005                     break;
4006                 case R.styleable.View_verticalScrollbarPosition:
4007                     mVerticalScrollbarPosition = a.getInt(attr, SCROLLBAR_POSITION_DEFAULT);
4008                     break;
4009                 case R.styleable.View_layerType:
4010                     setLayerType(a.getInt(attr, LAYER_TYPE_NONE), null);
4011                     break;
4012                 case R.styleable.View_textDirection:
4013                     // Clear any text direction flag already set
4014                     mPrivateFlags2 &= ~PFLAG2_TEXT_DIRECTION_MASK;
4015                     // Set the text direction flags depending on the value of the attribute
4016                     final int textDirection = a.getInt(attr, -1);
4017                     if (textDirection != -1) {
4018                         mPrivateFlags2 |= PFLAG2_TEXT_DIRECTION_FLAGS[textDirection];
4019                     }
4020                     break;
4021                 case R.styleable.View_textAlignment:
4022                     // Clear any text alignment flag already set
4023                     mPrivateFlags2 &= ~PFLAG2_TEXT_ALIGNMENT_MASK;
4024                     // Set the text alignment flag depending on the value of the attribute
4025                     final int textAlignment = a.getInt(attr, TEXT_ALIGNMENT_DEFAULT);
4026                     mPrivateFlags2 |= PFLAG2_TEXT_ALIGNMENT_FLAGS[textAlignment];
4027                     break;
4028                 case R.styleable.View_importantForAccessibility:
4029                     setImportantForAccessibility(a.getInt(attr,
4030                             IMPORTANT_FOR_ACCESSIBILITY_DEFAULT));
4031                     break;
4032                 case R.styleable.View_accessibilityLiveRegion:
4033                     setAccessibilityLiveRegion(a.getInt(attr, ACCESSIBILITY_LIVE_REGION_DEFAULT));
4034                     break;
4035                 case R.styleable.View_transitionName:
4036                     setTransitionName(a.getString(attr));
4037                     break;
4038                 case R.styleable.View_nestedScrollingEnabled:
4039                     setNestedScrollingEnabled(a.getBoolean(attr, false));
4040                     break;
4041                 case R.styleable.View_stateListAnimator:
4042                     setStateListAnimator(AnimatorInflater.loadStateListAnimator(context,
4043                             a.getResourceId(attr, 0)));
4044                     break;
4045                 case R.styleable.View_backgroundTint:
4046                     // This will get applied later during setBackground().
4047                     mBackgroundTintList = a.getColorStateList(R.styleable.View_backgroundTint);
4048                     mHasBackgroundTint = true;
4049                     break;
4050                 case R.styleable.View_backgroundTintMode:
4051                     // This will get applied later during setBackground().
4052                     mBackgroundTintMode = Drawable.parseTintMode(a.getInt(
4053                             R.styleable.View_backgroundTintMode, -1), mBackgroundTintMode);
4054                     break;
4055                 case R.styleable.View_outlineProvider:
4056                     setOutlineProviderFromAttribute(a.getInt(R.styleable.View_outlineProvider,
4057                             PROVIDER_BACKGROUND));
4058                     break;
4059             }
4060         }
4061
4062         setOverScrollMode(overScrollMode);
4063
4064         // Cache start/end user padding as we cannot fully resolve padding here (we dont have yet
4065         // the resolved layout direction). Those cached values will be used later during padding
4066         // resolution.
4067         mUserPaddingStart = startPadding;
4068         mUserPaddingEnd = endPadding;
4069
4070         if (background != null) {
4071             setBackground(background);
4072         }
4073
4074         // setBackground above will record that padding is currently provided by the background.
4075         // If we have padding specified via xml, record that here instead and use it.
4076         mLeftPaddingDefined = leftPaddingDefined;
4077         mRightPaddingDefined = rightPaddingDefined;
4078
4079         if (padding >= 0) {
4080             leftPadding = padding;
4081             topPadding = padding;
4082             rightPadding = padding;
4083             bottomPadding = padding;
4084             mUserPaddingLeftInitial = padding;
4085             mUserPaddingRightInitial = padding;
4086         }
4087
4088         if (isRtlCompatibilityMode()) {
4089             // RTL compatibility mode: pre Jelly Bean MR1 case OR no RTL support case.
4090             // left / right padding are used if defined (meaning here nothing to do). If they are not
4091             // defined and start / end padding are defined (e.g. in Frameworks resources), then we use
4092             // start / end and resolve them as left / right (layout direction is not taken into account).
4093             // Padding from the background drawable is stored at this point in mUserPaddingLeftInitial
4094             // and mUserPaddingRightInitial) so drawable padding will be used as ultimate default if
4095             // defined.
4096             if (!mLeftPaddingDefined && startPaddingDefined) {
4097                 leftPadding = startPadding;
4098             }
4099             mUserPaddingLeftInitial = (leftPadding >= 0) ? leftPadding : mUserPaddingLeftInitial;
4100             if (!mRightPaddingDefined && endPaddingDefined) {
4101                 rightPadding = endPadding;
4102             }
4103             mUserPaddingRightInitial = (rightPadding >= 0) ? rightPadding : mUserPaddingRightInitial;
4104         } else {
4105             // Jelly Bean MR1 and after case: if start/end defined, they will override any left/right
4106             // values defined. Otherwise, left /right values are used.
4107             // Padding from the background drawable is stored at this point in mUserPaddingLeftInitial
4108             // and mUserPaddingRightInitial) so drawable padding will be used as ultimate default if
4109             // defined.
4110             final boolean hasRelativePadding = startPaddingDefined || endPaddingDefined;
4111
4112             if (mLeftPaddingDefined && !hasRelativePadding) {
4113                 mUserPaddingLeftInitial = leftPadding;
4114             }
4115             if (mRightPaddingDefined && !hasRelativePadding) {
4116                 mUserPaddingRightInitial = rightPadding;
4117             }
4118         }
4119
4120         internalSetPadding(
4121                 mUserPaddingLeftInitial,
4122                 topPadding >= 0 ? topPadding : mPaddingTop,
4123                 mUserPaddingRightInitial,
4124                 bottomPadding >= 0 ? bottomPadding : mPaddingBottom);
4125
4126         if (viewFlagMasks != 0) {
4127             setFlags(viewFlagValues, viewFlagMasks);
4128         }
4129
4130         if (initializeScrollbars) {
4131             initializeScrollbarsInternal(a);
4132         }
4133
4134         a.recycle();
4135
4136         // Needs to be called after mViewFlags is set
4137         if (scrollbarStyle != SCROLLBARS_INSIDE_OVERLAY) {
4138             recomputePadding();
4139         }
4140
4141         if (x != 0 || y != 0) {
4142             scrollTo(x, y);
4143         }
4144
4145         if (transformSet) {
4146             setTranslationX(tx);
4147             setTranslationY(ty);
4148             setTranslationZ(tz);
4149             setElevation(elevation);
4150             setRotation(rotation);
4151             setRotationX(rotationX);
4152             setRotationY(rotationY);
4153             setScaleX(sx);
4154             setScaleY(sy);
4155         }
4156
4157         if (!setScrollContainer && (viewFlagValues&SCROLLBARS_VERTICAL) != 0) {
4158             setScrollContainer(true);
4159         }
4160
4161         computeOpaqueFlags();
4162     }
4163
4164     /**
4165      * Non-public constructor for use in testing
4166      */
4167     View() {
4168         mResources = null;
4169         mRenderNode = RenderNode.create(getClass().getName(), this);
4170     }
4171
4172     private static SparseArray<String> getAttributeMap() {
4173         if (mAttributeMap == null) {
4174             mAttributeMap = new SparseArray<String>();
4175         }
4176         return mAttributeMap;
4177     }
4178
4179     private void saveAttributeData(AttributeSet attrs, TypedArray a) {
4180         int length = ((attrs == null ? 0 : attrs.getAttributeCount()) + a.getIndexCount()) * 2;
4181         mAttributes = new String[length];
4182
4183         int i = 0;
4184         if (attrs != null) {
4185             for (i = 0; i < attrs.getAttributeCount(); i += 2) {
4186                 mAttributes[i] = attrs.getAttributeName(i);
4187                 mAttributes[i + 1] = attrs.getAttributeValue(i);
4188             }
4189
4190         }
4191
4192         SparseArray<String> attributeMap = getAttributeMap();
4193         for (int j = 0; j < a.length(); ++j) {
4194             if (a.hasValue(j)) {
4195                 try {
4196                     int resourceId = a.getResourceId(j, 0);
4197                     if (resourceId == 0) {
4198                         continue;
4199                     }
4200
4201                     String resourceName = attributeMap.get(resourceId);
4202                     if (resourceName == null) {
4203                         resourceName = a.getResources().getResourceName(resourceId);
4204                         attributeMap.put(resourceId, resourceName);
4205                     }
4206
4207                     mAttributes[i] = resourceName;
4208                     mAttributes[i + 1] = a.getText(j).toString();
4209                     i += 2;
4210                 } catch (Resources.NotFoundException e) {
4211                     // if we can't get the resource name, we just ignore it
4212                 }
4213             }
4214         }
4215     }
4216
4217     public String toString() {
4218         StringBuilder out = new StringBuilder(128);
4219         out.append(getClass().getName());
4220         out.append('{');
4221         out.append(Integer.toHexString(System.identityHashCode(this)));
4222         out.append(' ');
4223         switch (mViewFlags&VISIBILITY_MASK) {
4224             case VISIBLE: out.append('V'); break;
4225             case INVISIBLE: out.append('I'); break;
4226             case GONE: out.append('G'); break;
4227             default: out.append('.'); break;
4228         }
4229         out.append((mViewFlags&FOCUSABLE_MASK) == FOCUSABLE ? 'F' : '.');
4230         out.append((mViewFlags&ENABLED_MASK) == ENABLED ? 'E' : '.');
4231         out.append((mViewFlags&DRAW_MASK) == WILL_NOT_DRAW ? '.' : 'D');
4232         out.append((mViewFlags&SCROLLBARS_HORIZONTAL) != 0 ? 'H' : '.');
4233         out.append((mViewFlags&SCROLLBARS_VERTICAL) != 0 ? 'V' : '.');
4234         out.append((mViewFlags&CLICKABLE) != 0 ? 'C' : '.');
4235         out.append((mViewFlags&LONG_CLICKABLE) != 0 ? 'L' : '.');
4236         out.append(' ');
4237         out.append((mPrivateFlags&PFLAG_IS_ROOT_NAMESPACE) != 0 ? 'R' : '.');
4238         out.append((mPrivateFlags&PFLAG_FOCUSED) != 0 ? 'F' : '.');
4239         out.append((mPrivateFlags&PFLAG_SELECTED) != 0 ? 'S' : '.');
4240         if ((mPrivateFlags&PFLAG_PREPRESSED) != 0) {
4241             out.append('p');
4242         } else {
4243             out.append((mPrivateFlags&PFLAG_PRESSED) != 0 ? 'P' : '.');
4244         }
4245         out.append((mPrivateFlags&PFLAG_HOVERED) != 0 ? 'H' : '.');
4246         out.append((mPrivateFlags&PFLAG_ACTIVATED) != 0 ? 'A' : '.');
4247         out.append((mPrivateFlags&PFLAG_INVALIDATED) != 0 ? 'I' : '.');
4248         out.append((mPrivateFlags&PFLAG_DIRTY_MASK) != 0 ? 'D' : '.');
4249         out.append(' ');
4250         out.append(mLeft);
4251         out.append(',');
4252         out.append(mTop);
4253         out.append('-');
4254         out.append(mRight);
4255         out.append(',');
4256         out.append(mBottom);
4257         final int id = getId();
4258         if (id != NO_ID) {
4259             out.append(" #");
4260             out.append(Integer.toHexString(id));
4261             final Resources r = mResources;
4262             if (Resources.resourceHasPackage(id) && r != null) {
4263                 try {
4264                     String pkgname;
4265                     switch (id&0xff000000) {
4266                         case 0x7f000000:
4267                             pkgname="app";
4268                             break;
4269                         case 0x01000000:
4270                             pkgname="android";
4271                             break;
4272                         default:
4273                             pkgname = r.getResourcePackageName(id);
4274                             break;
4275                     }
4276                     String typename = r.getResourceTypeName(id);
4277                     String entryname = r.getResourceEntryName(id);
4278                     out.append(" ");
4279                     out.append(pkgname);
4280                     out.append(":");
4281                     out.append(typename);
4282                     out.append("/");
4283                     out.append(entryname);
4284                 } catch (Resources.NotFoundException e) {
4285                 }
4286             }
4287         }
4288         out.append("}");
4289         return out.toString();
4290     }
4291
4292     /**
4293      * <p>
4294      * Initializes the fading edges from a given set of styled attributes. This
4295      * method should be called by subclasses that need fading edges and when an
4296      * instance of these subclasses is created programmatically rather than
4297      * being inflated from XML. This method is automatically called when the XML
4298      * is inflated.
4299      * </p>
4300      *
4301      * @param a the styled attributes set to initialize the fading edges from
4302      */
4303     protected void initializeFadingEdge(TypedArray a) {
4304         // This method probably shouldn't have been included in the SDK to begin with.
4305         // It relies on 'a' having been initialized using an attribute filter array that is
4306         // not publicly available to the SDK. The old method has been renamed
4307         // to initializeFadingEdgeInternal and hidden for framework use only;
4308         // this one initializes using defaults to make it safe to call for apps.
4309
4310         TypedArray arr = mContext.obtainStyledAttributes(com.android.internal.R.styleable.View);
4311
4312         initializeFadingEdgeInternal(arr);
4313
4314         arr.recycle();
4315     }
4316
4317     /**
4318      * <p>
4319      * Initializes the fading edges from a given set of styled attributes. This
4320      * method should be called by subclasses that need fading edges and when an
4321      * instance of these subclasses is created programmatically rather than
4322      * being inflated from XML. This method is automatically called when the XML
4323      * is inflated.
4324      * </p>
4325      *
4326      * @param a the styled attributes set to initialize the fading edges from
4327      * @hide This is the real method; the public one is shimmed to be safe to call from apps.
4328      */
4329     protected void initializeFadingEdgeInternal(TypedArray a) {
4330         initScrollCache();
4331
4332         mScrollCache.fadingEdgeLength = a.getDimensionPixelSize(
4333                 R.styleable.View_fadingEdgeLength,
4334                 ViewConfiguration.get(mContext).getScaledFadingEdgeLength());
4335     }
4336
4337     /**
4338      * Returns the size of the vertical faded edges used to indicate that more
4339      * content in this view is visible.
4340      *
4341      * @return The size in pixels of the vertical faded edge or 0 if vertical
4342      *         faded edges are not enabled for this view.
4343      * @attr ref android.R.styleable#View_fadingEdgeLength
4344      */
4345     public int getVerticalFadingEdgeLength() {
4346         if (isVerticalFadingEdgeEnabled()) {
4347             ScrollabilityCache cache = mScrollCache;
4348             if (cache != null) {
4349                 return cache.fadingEdgeLength;
4350             }
4351         }
4352         return 0;
4353     }
4354
4355     /**
4356      * Set the size of the faded edge used to indicate that more content in this
4357      * view is available.  Will not change whether the fading edge is enabled; use
4358      * {@link #setVerticalFadingEdgeEnabled(boolean)} or
4359      * {@link #setHorizontalFadingEdgeEnabled(boolean)} to enable the fading edge
4360      * for the vertical or horizontal fading edges.
4361      *
4362      * @param length The size in pixels of the faded edge used to indicate that more
4363      *        content in this view is visible.
4364      */
4365     public void setFadingEdgeLength(int length) {
4366         initScrollCache();
4367         mScrollCache.fadingEdgeLength = length;
4368     }
4369
4370     /**
4371      * Returns the size of the horizontal faded edges used to indicate that more
4372      * content in this view is visible.
4373      *
4374      * @return The size in pixels of the horizontal faded edge or 0 if horizontal
4375      *         faded edges are not enabled for this view.
4376      * @attr ref android.R.styleable#View_fadingEdgeLength
4377      */
4378     public int getHorizontalFadingEdgeLength() {
4379         if (isHorizontalFadingEdgeEnabled()) {
4380             ScrollabilityCache cache = mScrollCache;
4381             if (cache != null) {
4382                 return cache.fadingEdgeLength;
4383             }
4384         }
4385         return 0;
4386     }
4387
4388     /**
4389      * Returns the width of the vertical scrollbar.
4390      *
4391      * @return The width in pixels of the vertical scrollbar or 0 if there
4392      *         is no vertical scrollbar.
4393      */
4394     public int getVerticalScrollbarWidth() {
4395         ScrollabilityCache cache = mScrollCache;
4396         if (cache != null) {
4397             ScrollBarDrawable scrollBar = cache.scrollBar;
4398             if (scrollBar != null) {
4399                 int size = scrollBar.getSize(true);
4400                 if (size <= 0) {
4401                     size = cache.scrollBarSize;
4402                 }
4403                 return size;
4404             }
4405             return 0;
4406         }
4407         return 0;
4408     }
4409
4410     /**
4411      * Returns the height of the horizontal scrollbar.
4412      *
4413      * @return The height in pixels of the horizontal scrollbar or 0 if
4414      *         there is no horizontal scrollbar.
4415      */
4416     protected int getHorizontalScrollbarHeight() {
4417         ScrollabilityCache cache = mScrollCache;
4418         if (cache != null) {
4419             ScrollBarDrawable scrollBar = cache.scrollBar;
4420             if (scrollBar != null) {
4421                 int size = scrollBar.getSize(false);
4422                 if (size <= 0) {
4423                     size = cache.scrollBarSize;
4424                 }
4425                 return size;
4426             }
4427             return 0;
4428         }
4429         return 0;
4430     }
4431
4432     /**
4433      * <p>
4434      * Initializes the scrollbars from a given set of styled attributes. This
4435      * method should be called by subclasses that need scrollbars and when an
4436      * instance of these subclasses is created programmatically rather than
4437      * being inflated from XML. This method is automatically called when the XML
4438      * is inflated.
4439      * </p>
4440      *
4441      * @param a the styled attributes set to initialize the scrollbars from
4442      */
4443     protected void initializeScrollbars(TypedArray a) {
4444         // It's not safe to use this method from apps. The parameter 'a' must have been obtained
4445         // using the View filter array which is not available to the SDK. As such, internal
4446         // framework usage now uses initializeScrollbarsInternal and we grab a default
4447         // TypedArray with the right filter instead here.
4448         TypedArray arr = mContext.obtainStyledAttributes(com.android.internal.R.styleable.View);
4449
4450         initializeScrollbarsInternal(arr);
4451
4452         // We ignored the method parameter. Recycle the one we actually did use.
4453         arr.recycle();
4454     }
4455
4456     /**
4457      * <p>
4458      * Initializes the scrollbars from a given set of styled attributes. This
4459      * method should be called by subclasses that need scrollbars and when an
4460      * instance of these subclasses is created programmatically rather than
4461      * being inflated from XML. This method is automatically called when the XML
4462      * is inflated.
4463      * </p>
4464      *
4465      * @param a the styled attributes set to initialize the scrollbars from
4466      * @hide
4467      */
4468     protected void initializeScrollbarsInternal(TypedArray a) {
4469         initScrollCache();
4470
4471         final ScrollabilityCache scrollabilityCache = mScrollCache;
4472
4473         if (scrollabilityCache.scrollBar == null) {
4474             scrollabilityCache.scrollBar = new ScrollBarDrawable();
4475         }
4476
4477         final boolean fadeScrollbars = a.getBoolean(R.styleable.View_fadeScrollbars, true);
4478
4479         if (!fadeScrollbars) {
4480             scrollabilityCache.state = ScrollabilityCache.ON;
4481         }
4482         scrollabilityCache.fadeScrollBars = fadeScrollbars;
4483
4484
4485         scrollabilityCache.scrollBarFadeDuration = a.getInt(
4486                 R.styleable.View_scrollbarFadeDuration, ViewConfiguration
4487                         .getScrollBarFadeDuration());
4488         scrollabilityCache.scrollBarDefaultDelayBeforeFade = a.getInt(
4489                 R.styleable.View_scrollbarDefaultDelayBeforeFade,
4490                 ViewConfiguration.getScrollDefaultDelay());
4491
4492
4493         scrollabilityCache.scrollBarSize = a.getDimensionPixelSize(
4494                 com.android.internal.R.styleable.View_scrollbarSize,
4495                 ViewConfiguration.get(mContext).getScaledScrollBarSize());
4496
4497         Drawable track = a.getDrawable(R.styleable.View_scrollbarTrackHorizontal);
4498         scrollabilityCache.scrollBar.setHorizontalTrackDrawable(track);
4499
4500         Drawable thumb = a.getDrawable(R.styleable.View_scrollbarThumbHorizontal);
4501         if (thumb != null) {
4502             scrollabilityCache.scrollBar.setHorizontalThumbDrawable(thumb);
4503         }
4504
4505         boolean alwaysDraw = a.getBoolean(R.styleable.View_scrollbarAlwaysDrawHorizontalTrack,
4506                 false);
4507         if (alwaysDraw) {
4508             scrollabilityCache.scrollBar.setAlwaysDrawHorizontalTrack(true);
4509         }
4510
4511         track = a.getDrawable(R.styleable.View_scrollbarTrackVertical);
4512         scrollabilityCache.scrollBar.setVerticalTrackDrawable(track);
4513
4514         thumb = a.getDrawable(R.styleable.View_scrollbarThumbVertical);
4515         if (thumb != null) {
4516             scrollabilityCache.scrollBar.setVerticalThumbDrawable(thumb);
4517         }
4518
4519         alwaysDraw = a.getBoolean(R.styleable.View_scrollbarAlwaysDrawVerticalTrack,
4520                 false);
4521         if (alwaysDraw) {
4522             scrollabilityCache.scrollBar.setAlwaysDrawVerticalTrack(true);
4523         }
4524
4525         // Apply layout direction to the new Drawables if needed
4526         final int layoutDirection = getLayoutDirection();
4527         if (track != null) {
4528             track.setLayoutDirection(layoutDirection);
4529         }
4530         if (thumb != null) {
4531             thumb.setLayoutDirection(layoutDirection);
4532         }
4533
4534         // Re-apply user/background padding so that scrollbar(s) get added
4535         resolvePadding();
4536     }
4537
4538     /**
4539      * <p>
4540      * Initalizes the scrollability cache if necessary.
4541      * </p>
4542      */
4543     private void initScrollCache() {
4544         if (mScrollCache == null) {
4545             mScrollCache = new ScrollabilityCache(ViewConfiguration.get(mContext), this);
4546         }
4547     }
4548
4549     private ScrollabilityCache getScrollCache() {
4550         initScrollCache();
4551         return mScrollCache;
4552     }
4553
4554     /**
4555      * Set the position of the vertical scroll bar. Should be one of
4556      * {@link #SCROLLBAR_POSITION_DEFAULT}, {@link #SCROLLBAR_POSITION_LEFT} or
4557      * {@link #SCROLLBAR_POSITION_RIGHT}.
4558      *
4559      * @param position Where the vertical scroll bar should be positioned.
4560      */
4561     public void setVerticalScrollbarPosition(int position) {
4562         if (mVerticalScrollbarPosition != position) {
4563             mVerticalScrollbarPosition = position;
4564             computeOpaqueFlags();
4565             resolvePadding();
4566         }
4567     }
4568
4569     /**
4570      * @return The position where the vertical scroll bar will show, if applicable.
4571      * @see #setVerticalScrollbarPosition(int)
4572      */
4573     public int getVerticalScrollbarPosition() {
4574         return mVerticalScrollbarPosition;
4575     }
4576
4577     ListenerInfo getListenerInfo() {
4578         if (mListenerInfo != null) {
4579             return mListenerInfo;
4580         }
4581         mListenerInfo = new ListenerInfo();
4582         return mListenerInfo;
4583     }
4584
4585     /**
4586      * Register a callback to be invoked when focus of this view changed.
4587      *
4588      * @param l The callback that will run.
4589      */
4590     public void setOnFocusChangeListener(OnFocusChangeListener l) {
4591         getListenerInfo().mOnFocusChangeListener = l;
4592     }
4593
4594     /**
4595      * Add a listener that will be called when the bounds of the view change due to
4596      * layout processing.
4597      *
4598      * @param listener The listener that will be called when layout bounds change.
4599      */
4600     public void addOnLayoutChangeListener(OnLayoutChangeListener listener) {
4601         ListenerInfo li = getListenerInfo();
4602         if (li.mOnLayoutChangeListeners == null) {
4603             li.mOnLayoutChangeListeners = new ArrayList<OnLayoutChangeListener>();
4604         }
4605         if (!li.mOnLayoutChangeListeners.contains(listener)) {
4606             li.mOnLayoutChangeListeners.add(listener);
4607         }
4608     }
4609
4610     /**
4611      * Remove a listener for layout changes.
4612      *
4613      * @param listener The listener for layout bounds change.
4614      */
4615     public void removeOnLayoutChangeListener(OnLayoutChangeListener listener) {
4616         ListenerInfo li = mListenerInfo;
4617         if (li == null || li.mOnLayoutChangeListeners == null) {
4618             return;
4619         }
4620         li.mOnLayoutChangeListeners.remove(listener);
4621     }
4622
4623     /**
4624      * Add a listener for attach state changes.
4625      *
4626      * This listener will be called whenever this view is attached or detached
4627      * from a window. Remove the listener using
4628      * {@link #removeOnAttachStateChangeListener(OnAttachStateChangeListener)}.
4629      *
4630      * @param listener Listener to attach
4631      * @see #removeOnAttachStateChangeListener(OnAttachStateChangeListener)
4632      */
4633     public void addOnAttachStateChangeListener(OnAttachStateChangeListener listener) {
4634         ListenerInfo li = getListenerInfo();
4635         if (li.mOnAttachStateChangeListeners == null) {
4636             li.mOnAttachStateChangeListeners
4637                     = new CopyOnWriteArrayList<OnAttachStateChangeListener>();
4638         }
4639         li.mOnAttachStateChangeListeners.add(listener);
4640     }
4641
4642     /**
4643      * Remove a listener for attach state changes. The listener will receive no further
4644      * notification of window attach/detach events.
4645      *
4646      * @param listener Listener to remove
4647      * @see #addOnAttachStateChangeListener(OnAttachStateChangeListener)
4648      */
4649     public void removeOnAttachStateChangeListener(OnAttachStateChangeListener listener) {
4650         ListenerInfo li = mListenerInfo;
4651         if (li == null || li.mOnAttachStateChangeListeners == null) {
4652             return;
4653         }
4654         li.mOnAttachStateChangeListeners.remove(listener);
4655     }
4656
4657     /**
4658      * Returns the focus-change callback registered for this view.
4659      *
4660      * @return The callback, or null if one is not registered.
4661      */
4662     public OnFocusChangeListener getOnFocusChangeListener() {
4663         ListenerInfo li = mListenerInfo;
4664         return li != null ? li.mOnFocusChangeListener : null;
4665     }
4666
4667     /**
4668      * Register a callback to be invoked when this view is clicked. If this view is not
4669      * clickable, it becomes clickable.
4670      *
4671      * @param l The callback that will run
4672      *
4673      * @see #setClickable(boolean)
4674      */
4675     public void setOnClickListener(OnClickListener l) {
4676         if (!isClickable()) {
4677             setClickable(true);
4678         }
4679         getListenerInfo().mOnClickListener = l;
4680     }
4681
4682     /**
4683      * Return whether this view has an attached OnClickListener.  Returns
4684      * true if there is a listener, false if there is none.
4685      */
4686     public boolean hasOnClickListeners() {
4687         ListenerInfo li = mListenerInfo;
4688         return (li != null && li.mOnClickListener != null);
4689     }
4690
4691     /**
4692      * Register a callback to be invoked when this view is clicked and held. If this view is not
4693      * long clickable, it becomes long clickable.
4694      *
4695      * @param l The callback that will run
4696      *
4697      * @see #setLongClickable(boolean)
4698      */
4699     public void setOnLongClickListener(OnLongClickListener l) {
4700         if (!isLongClickable()) {
4701             setLongClickable(true);
4702         }
4703         getListenerInfo().mOnLongClickListener = l;
4704     }
4705
4706     /**
4707      * Register a callback to be invoked when the context menu for this view is
4708      * being built. If this view is not long clickable, it becomes long clickable.
4709      *
4710      * @param l The callback that will run
4711      *
4712      */
4713     public void setOnCreateContextMenuListener(OnCreateContextMenuListener l) {
4714         if (!isLongClickable()) {
4715             setLongClickable(true);
4716         }
4717         getListenerInfo().mOnCreateContextMenuListener = l;
4718     }
4719
4720     /**
4721      * Call this view's OnClickListener, if it is defined.  Performs all normal
4722      * actions associated with clicking: reporting accessibility event, playing
4723      * a sound, etc.
4724      *
4725      * @return True there was an assigned OnClickListener that was called, false
4726      *         otherwise is returned.
4727      */
4728     public boolean performClick() {
4729         final boolean result;
4730         final ListenerInfo li = mListenerInfo;
4731         if (li != null && li.mOnClickListener != null) {
4732             playSoundEffect(SoundEffectConstants.CLICK);
4733             li.mOnClickListener.onClick(this);
4734             result = true;
4735         } else {
4736             result = false;
4737         }
4738
4739         sendAccessibilityEvent(AccessibilityEvent.TYPE_VIEW_CLICKED);
4740         return result;
4741     }
4742
4743     /**
4744      * Directly call any attached OnClickListener.  Unlike {@link #performClick()},
4745      * this only calls the listener, and does not do any associated clicking
4746      * actions like reporting an accessibility event.
4747      *
4748      * @return True there was an assigned OnClickListener that was called, false
4749      *         otherwise is returned.
4750      */
4751     public boolean callOnClick() {
4752         ListenerInfo li = mListenerInfo;
4753         if (li != null && li.mOnClickListener != null) {
4754             li.mOnClickListener.onClick(this);
4755             return true;
4756         }
4757         return false;
4758     }
4759
4760     /**
4761      * Call this view's OnLongClickListener, if it is defined. Invokes the context menu if the
4762      * OnLongClickListener did not consume the event.
4763      *
4764      * @return True if one of the above receivers consumed the event, false otherwise.
4765      */
4766     public boolean performLongClick() {
4767         sendAccessibilityEvent(AccessibilityEvent.TYPE_VIEW_LONG_CLICKED);
4768
4769         boolean handled = false;
4770         ListenerInfo li = mListenerInfo;
4771         if (li != null && li.mOnLongClickListener != null) {
4772             handled = li.mOnLongClickListener.onLongClick(View.this);
4773         }
4774         if (!handled) {
4775             handled = showContextMenu();
4776         }
4777         if (handled) {
4778             performHapticFeedback(HapticFeedbackConstants.LONG_PRESS);
4779         }
4780         return handled;
4781     }
4782
4783     /**
4784      * Performs button-related actions during a touch down event.
4785      *
4786      * @param event The event.
4787      * @return True if the down was consumed.
4788      *
4789      * @hide
4790      */
4791     protected boolean performButtonActionOnTouchDown(MotionEvent event) {
4792         if ((event.getButtonState() & MotionEvent.BUTTON_SECONDARY) != 0) {
4793             if (showContextMenu(event.getX(), event.getY(), event.getMetaState())) {
4794                 return true;
4795             }
4796         }
4797         return false;
4798     }
4799
4800     /**
4801      * Bring up the context menu for this view.
4802      *
4803      * @return Whether a context menu was displayed.
4804      */
4805     public boolean showContextMenu() {
4806         return getParent().showContextMenuForChild(this);
4807     }
4808
4809     /**
4810      * Bring up the context menu for this view, referring to the item under the specified point.
4811      *
4812      * @param x The referenced x coordinate.
4813      * @param y The referenced y coordinate.
4814      * @param metaState The keyboard modifiers that were pressed.
4815      * @return Whether a context menu was displayed.
4816      *
4817      * @hide
4818      */
4819     public boolean showContextMenu(float x, float y, int metaState) {
4820         return showContextMenu();
4821     }
4822
4823     /**
4824      * Start an action mode.
4825      *
4826      * @param callback Callback that will control the lifecycle of the action mode
4827      * @return The new action mode if it is started, null otherwise
4828      *
4829      * @see ActionMode
4830      */
4831     public ActionMode startActionMode(ActionMode.Callback callback) {
4832         ViewParent parent = getParent();
4833         if (parent == null) return null;
4834         return parent.startActionModeForChild(this, callback);
4835     }
4836
4837     /**
4838      * Register a callback to be invoked when a hardware key is pressed in this view.
4839      * Key presses in software input methods will generally not trigger the methods of
4840      * this listener.
4841      * @param l the key listener to attach to this view
4842      */
4843     public void setOnKeyListener(OnKeyListener l) {
4844         getListenerInfo().mOnKeyListener = l;
4845     }
4846
4847     /**
4848      * Register a callback to be invoked when a touch event is sent to this view.
4849      * @param l the touch listener to attach to this view
4850      */
4851     public void setOnTouchListener(OnTouchListener l) {
4852         getListenerInfo().mOnTouchListener = l;
4853     }
4854
4855     /**
4856      * Register a callback to be invoked when a generic motion event is sent to this view.
4857      * @param l the generic motion listener to attach to this view
4858      */
4859     public void setOnGenericMotionListener(OnGenericMotionListener l) {
4860         getListenerInfo().mOnGenericMotionListener = l;
4861     }
4862
4863     /**
4864      * Register a callback to be invoked when a hover event is sent to this view.
4865      * @param l the hover listener to attach to this view
4866      */
4867     public void setOnHoverListener(OnHoverListener l) {
4868         getListenerInfo().mOnHoverListener = l;
4869     }
4870
4871     /**
4872      * Register a drag event listener callback object for this View. The parameter is
4873      * an implementation of {@link android.view.View.OnDragListener}. To send a drag event to a
4874      * View, the system calls the
4875      * {@link android.view.View.OnDragListener#onDrag(View,DragEvent)} method.
4876      * @param l An implementation of {@link android.view.View.OnDragListener}.
4877      */
4878     public void setOnDragListener(OnDragListener l) {
4879         getListenerInfo().mOnDragListener = l;
4880     }
4881
4882     /**
4883      * Give this view focus. This will cause
4884      * {@link #onFocusChanged(boolean, int, android.graphics.Rect)} to be called.
4885      *
4886      * Note: this does not check whether this {@link View} should get focus, it just
4887      * gives it focus no matter what.  It should only be called internally by framework
4888      * code that knows what it is doing, namely {@link #requestFocus(int, Rect)}.
4889      *
4890      * @param direction values are {@link View#FOCUS_UP}, {@link View#FOCUS_DOWN},
4891      *        {@link View#FOCUS_LEFT} or {@link View#FOCUS_RIGHT}. This is the direction which
4892      *        focus moved when requestFocus() is called. It may not always
4893      *        apply, in which case use the default View.FOCUS_DOWN.
4894      * @param previouslyFocusedRect The rectangle of the view that had focus
4895      *        prior in this View's coordinate system.
4896      */
4897     void handleFocusGainInternal(@FocusRealDirection int direction, Rect previouslyFocusedRect) {
4898         if (DBG) {
4899             System.out.println(this + " requestFocus()");
4900         }
4901
4902         if ((mPrivateFlags & PFLAG_FOCUSED) == 0) {
4903             mPrivateFlags |= PFLAG_FOCUSED;
4904
4905             View oldFocus = (mAttachInfo != null) ? getRootView().findFocus() : null;
4906
4907             if (mParent != null) {
4908                 mParent.requestChildFocus(this, this);
4909             }
4910
4911             if (mAttachInfo != null) {
4912                 mAttachInfo.mTreeObserver.dispatchOnGlobalFocusChange(oldFocus, this);
4913             }
4914
4915             onFocusChanged(true, direction, previouslyFocusedRect);
4916             refreshDrawableState();
4917         }
4918     }
4919
4920     /**
4921      * Populates <code>outRect</code> with the hotspot bounds. By default,
4922      * the hotspot bounds are identical to the screen bounds.
4923      *
4924      * @param outRect rect to populate with hotspot bounds
4925      * @hide Only for internal use by views and widgets.
4926      */
4927     public void getHotspotBounds(Rect outRect) {
4928         final Drawable background = getBackground();
4929         if (background != null) {
4930             background.getHotspotBounds(outRect);
4931         } else {
4932             getBoundsOnScreen(outRect);
4933         }
4934     }
4935
4936     /**
4937      * Request that a rectangle of this view be visible on the screen,
4938      * scrolling if necessary just enough.
4939      *
4940      * <p>A View should call this if it maintains some notion of which part
4941      * of its content is interesting.  For example, a text editing view
4942      * should call this when its cursor moves.
4943      *
4944      * @param rectangle The rectangle.
4945      * @return Whether any parent scrolled.
4946      */
4947     public boolean requestRectangleOnScreen(Rect rectangle) {
4948         return requestRectangleOnScreen(rectangle, false);
4949     }
4950
4951     /**
4952      * Request that a rectangle of this view be visible on the screen,
4953      * scrolling if necessary just enough.
4954      *
4955      * <p>A View should call this if it maintains some notion of which part
4956      * of its content is interesting.  For example, a text editing view
4957      * should call this when its cursor moves.
4958      *
4959      * <p>When <code>immediate</code> is set to true, scrolling will not be
4960      * animated.
4961      *
4962      * @param rectangle The rectangle.
4963      * @param immediate True to forbid animated scrolling, false otherwise
4964      * @return Whether any parent scrolled.
4965      */
4966     public boolean requestRectangleOnScreen(Rect rectangle, boolean immediate) {
4967         if (mParent == null) {
4968             return false;
4969         }
4970
4971         View child = this;
4972
4973         RectF position = (mAttachInfo != null) ? mAttachInfo.mTmpTransformRect : new RectF();
4974         position.set(rectangle);
4975
4976         ViewParent parent = mParent;
4977         boolean scrolled = false;
4978         while (parent != null) {
4979             rectangle.set((int) position.left, (int) position.top,
4980                     (int) position.right, (int) position.bottom);
4981
4982             scrolled |= parent.requestChildRectangleOnScreen(child,
4983                     rectangle, immediate);
4984
4985             if (!child.hasIdentityMatrix()) {
4986                 child.getMatrix().mapRect(position);
4987             }
4988
4989             position.offset(child.mLeft, child.mTop);
4990
4991             if (!(parent instanceof View)) {
4992                 break;
4993             }
4994
4995             View parentView = (View) parent;
4996
4997             position.offset(-parentView.getScrollX(), -parentView.getScrollY());
4998
4999             child = parentView;
5000             parent = child.getParent();
5001         }
5002
5003         return scrolled;
5004     }
5005
5006     /**
5007      * Called when this view wants to give up focus. If focus is cleared
5008      * {@link #onFocusChanged(boolean, int, android.graphics.Rect)} is called.
5009      * <p>
5010      * <strong>Note:</strong> When a View clears focus the framework is trying
5011      * to give focus to the first focusable View from the top. Hence, if this
5012      * View is the first from the top that can take focus, then all callbacks
5013      * related to clearing focus will be invoked after wich the framework will
5014      * give focus to this view.
5015      * </p>
5016      */
5017     public void clearFocus() {
5018         if (DBG) {
5019             System.out.println(this + " clearFocus()");
5020         }
5021
5022         clearFocusInternal(null, true, true);
5023     }
5024
5025     /**
5026      * Clears focus from the view, optionally propagating the change up through
5027      * the parent hierarchy and requesting that the root view place new focus.
5028      *
5029      * @param propagate whether to propagate the change up through the parent
5030      *            hierarchy
5031      * @param refocus when propagate is true, specifies whether to request the
5032      *            root view place new focus
5033      */
5034     void clearFocusInternal(View focused, boolean propagate, boolean refocus) {
5035         if ((mPrivateFlags & PFLAG_FOCUSED) != 0) {
5036             mPrivateFlags &= ~PFLAG_FOCUSED;
5037
5038             if (propagate && mParent != null) {
5039                 mParent.clearChildFocus(this);
5040             }
5041
5042             onFocusChanged(false, 0, null);
5043             refreshDrawableState();
5044
5045             if (propagate && (!refocus || !rootViewRequestFocus())) {
5046                 notifyGlobalFocusCleared(this);
5047             }
5048         }
5049     }
5050
5051     void notifyGlobalFocusCleared(View oldFocus) {
5052         if (oldFocus != null && mAttachInfo != null) {
5053             mAttachInfo.mTreeObserver.dispatchOnGlobalFocusChange(oldFocus, null);
5054         }
5055     }
5056
5057     boolean rootViewRequestFocus() {
5058         final View root = getRootView();
5059         return root != null && root.requestFocus();
5060     }
5061
5062     /**
5063      * Called internally by the view system when a new view is getting focus.
5064      * This is what clears the old focus.
5065      * <p>
5066      * <b>NOTE:</b> The parent view's focused child must be updated manually
5067      * after calling this method. Otherwise, the view hierarchy may be left in
5068      * an inconstent state.
5069      */
5070     void unFocus(View focused) {
5071         if (DBG) {
5072             System.out.println(this + " unFocus()");
5073         }
5074
5075         clearFocusInternal(focused, false, false);
5076     }
5077
5078     /**
5079      * Returns true if this view has focus iteself, or is the ancestor of the
5080      * view that has focus.
5081      *
5082      * @return True if this view has or contains focus, false otherwise.
5083      */
5084     @ViewDebug.ExportedProperty(category = "focus")
5085     public boolean hasFocus() {
5086         return (mPrivateFlags & PFLAG_FOCUSED) != 0;
5087     }
5088
5089     /**
5090      * Returns true if this view is focusable or if it contains a reachable View
5091      * for which {@link #hasFocusable()} returns true. A "reachable hasFocusable()"
5092      * is a View whose parents do not block descendants focus.
5093      *
5094      * Only {@link #VISIBLE} views are considered focusable.
5095      *
5096      * @return True if the view is focusable or if the view contains a focusable
5097      *         View, false otherwise.
5098      *
5099      * @see ViewGroup#FOCUS_BLOCK_DESCENDANTS
5100      * @see ViewGroup#getTouchscreenBlocksFocus()
5101      */
5102     public boolean hasFocusable() {
5103         if (!isFocusableInTouchMode()) {
5104             for (ViewParent p = mParent; p instanceof ViewGroup; p = p.getParent()) {
5105                 final ViewGroup g = (ViewGroup) p;
5106                 if (g.shouldBlockFocusForTouchscreen()) {
5107                     return false;
5108                 }
5109             }
5110         }
5111         return (mViewFlags & VISIBILITY_MASK) == VISIBLE && isFocusable();
5112     }
5113
5114     /**
5115      * Called by the view system when the focus state of this view changes.
5116      * When the focus change event is caused by directional navigation, direction
5117      * and previouslyFocusedRect provide insight into where the focus is coming from.
5118      * When overriding, be sure to call up through to the super class so that
5119      * the standard focus handling will occur.
5120      *
5121      * @param gainFocus True if the View has focus; false otherwise.
5122      * @param direction The direction focus has moved when requestFocus()
5123      *                  is called to give this view focus. Values are
5124      *                  {@link #FOCUS_UP}, {@link #FOCUS_DOWN}, {@link #FOCUS_LEFT},
5125      *                  {@link #FOCUS_RIGHT}, {@link #FOCUS_FORWARD}, or {@link #FOCUS_BACKWARD}.
5126      *                  It may not always apply, in which case use the default.
5127      * @param previouslyFocusedRect The rectangle, in this view's coordinate
5128      *        system, of the previously focused view.  If applicable, this will be
5129      *        passed in as finer grained information about where the focus is coming
5130      *        from (in addition to direction).  Will be <code>null</code> otherwise.
5131      */
5132     protected void onFocusChanged(boolean gainFocus, @FocusDirection int direction,
5133             @Nullable Rect previouslyFocusedRect) {
5134         if (gainFocus) {
5135             sendAccessibilityEvent(AccessibilityEvent.TYPE_VIEW_FOCUSED);
5136         } else {
5137             notifyViewAccessibilityStateChangedIfNeeded(
5138                     AccessibilityEvent.CONTENT_CHANGE_TYPE_UNDEFINED);
5139         }
5140
5141         InputMethodManager imm = InputMethodManager.peekInstance();
5142         if (!gainFocus) {
5143             if (isPressed()) {
5144                 setPressed(false);
5145             }
5146             if (imm != null && mAttachInfo != null
5147                     && mAttachInfo.mHasWindowFocus) {
5148                 imm.focusOut(this);
5149             }
5150             onFocusLost();
5151         } else if (imm != null && mAttachInfo != null
5152                 && mAttachInfo.mHasWindowFocus) {
5153             imm.focusIn(this);
5154         }
5155
5156         invalidate(true);
5157         ListenerInfo li = mListenerInfo;
5158         if (li != null && li.mOnFocusChangeListener != null) {
5159             li.mOnFocusChangeListener.onFocusChange(this, gainFocus);
5160         }
5161
5162         if (mAttachInfo != null) {
5163             mAttachInfo.mKeyDispatchState.reset(this);
5164         }
5165     }
5166
5167     /**
5168      * Sends an accessibility event of the given type. If accessibility is
5169      * not enabled this method has no effect. The default implementation calls
5170      * {@link #onInitializeAccessibilityEvent(AccessibilityEvent)} first
5171      * to populate information about the event source (this View), then calls
5172      * {@link #dispatchPopulateAccessibilityEvent(AccessibilityEvent)} to
5173      * populate the text content of the event source including its descendants,
5174      * and last calls
5175      * {@link ViewParent#requestSendAccessibilityEvent(View, AccessibilityEvent)}
5176      * on its parent to resuest sending of the event to interested parties.
5177      * <p>
5178      * If an {@link AccessibilityDelegate} has been specified via calling
5179      * {@link #setAccessibilityDelegate(AccessibilityDelegate)} its
5180      * {@link AccessibilityDelegate#sendAccessibilityEvent(View, int)} is
5181      * responsible for handling this call.
5182      * </p>
5183      *
5184      * @param eventType The type of the event to send, as defined by several types from
5185      * {@link android.view.accessibility.AccessibilityEvent}, such as
5186      * {@link android.view.accessibility.AccessibilityEvent#TYPE_VIEW_CLICKED} or
5187      * {@link android.view.accessibility.AccessibilityEvent#TYPE_VIEW_HOVER_ENTER}.
5188      *
5189      * @see #onInitializeAccessibilityEvent(AccessibilityEvent)
5190      * @see #dispatchPopulateAccessibilityEvent(AccessibilityEvent)
5191      * @see ViewParent#requestSendAccessibilityEvent(View, AccessibilityEvent)
5192      * @see AccessibilityDelegate
5193      */
5194     public void sendAccessibilityEvent(int eventType) {
5195         if (mAccessibilityDelegate != null) {
5196             mAccessibilityDelegate.sendAccessibilityEvent(this, eventType);
5197         } else {
5198             sendAccessibilityEventInternal(eventType);
5199         }
5200     }
5201
5202     /**
5203      * Convenience method for sending a {@link AccessibilityEvent#TYPE_ANNOUNCEMENT}
5204      * {@link AccessibilityEvent} to make an announcement which is related to some
5205      * sort of a context change for which none of the events representing UI transitions
5206      * is a good fit. For example, announcing a new page in a book. If accessibility
5207      * is not enabled this method does nothing.
5208      *
5209      * @param text The announcement text.
5210      */
5211     public void announceForAccessibility(CharSequence text) {
5212         if (AccessibilityManager.getInstance(mContext).isEnabled() && mParent != null) {
5213             AccessibilityEvent event = AccessibilityEvent.obtain(
5214                     AccessibilityEvent.TYPE_ANNOUNCEMENT);
5215             onInitializeAccessibilityEvent(event);
5216             event.getText().add(text);
5217             event.setContentDescription(null);
5218             mParent.requestSendAccessibilityEvent(this, event);
5219         }
5220     }
5221
5222     /**
5223      * @see #sendAccessibilityEvent(int)
5224      *
5225      * Note: Called from the default {@link AccessibilityDelegate}.
5226      */
5227     void sendAccessibilityEventInternal(int eventType) {
5228         if (AccessibilityManager.getInstance(mContext).isEnabled()) {
5229             sendAccessibilityEventUnchecked(AccessibilityEvent.obtain(eventType));
5230         }
5231     }
5232
5233     /**
5234      * This method behaves exactly as {@link #sendAccessibilityEvent(int)} but
5235      * takes as an argument an empty {@link AccessibilityEvent} and does not
5236      * perform a check whether accessibility is enabled.
5237      * <p>
5238      * If an {@link AccessibilityDelegate} has been specified via calling
5239      * {@link #setAccessibilityDelegate(AccessibilityDelegate)} its
5240      * {@link AccessibilityDelegate#sendAccessibilityEventUnchecked(View, AccessibilityEvent)}
5241      * is responsible for handling this call.
5242      * </p>
5243      *
5244      * @param event The event to send.
5245      *
5246      * @see #sendAccessibilityEvent(int)
5247      */
5248     public void sendAccessibilityEventUnchecked(AccessibilityEvent event) {
5249         if (mAccessibilityDelegate != null) {
5250             mAccessibilityDelegate.sendAccessibilityEventUnchecked(this, event);
5251         } else {
5252             sendAccessibilityEventUncheckedInternal(event);
5253         }
5254     }
5255
5256     /**
5257      * @see #sendAccessibilityEventUnchecked(AccessibilityEvent)
5258      *
5259      * Note: Called from the default {@link AccessibilityDelegate}.
5260      */
5261     void sendAccessibilityEventUncheckedInternal(AccessibilityEvent event) {
5262         if (!isShown()) {
5263             return;
5264         }
5265         onInitializeAccessibilityEvent(event);
5266         // Only a subset of accessibility events populates text content.
5267         if ((event.getEventType() & POPULATING_ACCESSIBILITY_EVENT_TYPES) != 0) {
5268             dispatchPopulateAccessibilityEvent(event);
5269         }
5270         // In the beginning we called #isShown(), so we know that getParent() is not null.
5271         getParent().requestSendAccessibilityEvent(this, event);
5272     }
5273
5274     /**
5275      * Dispatches an {@link AccessibilityEvent} to the {@link View} first and then
5276      * to its children for adding their text content to the event. Note that the
5277      * event text is populated in a separate dispatch path since we add to the
5278      * event not only the text of the source but also the text of all its descendants.
5279      * A typical implementation will call
5280      * {@link #onPopulateAccessibilityEvent(AccessibilityEvent)} on the this view
5281      * and then call the {@link #dispatchPopulateAccessibilityEvent(AccessibilityEvent)}
5282      * on each child. Override this method if custom population of the event text
5283      * content is required.
5284      * <p>
5285      * If an {@link AccessibilityDelegate} has been specified via calling
5286      * {@link #setAccessibilityDelegate(AccessibilityDelegate)} its
5287      * {@link AccessibilityDelegate#dispatchPopulateAccessibilityEvent(View, AccessibilityEvent)}
5288      * is responsible for handling this call.
5289      * </p>
5290      * <p>
5291      * <em>Note:</em> Accessibility events of certain types are not dispatched for
5292      * populating the event text via this method. For details refer to {@link AccessibilityEvent}.
5293      * </p>
5294      *
5295      * @param event The event.
5296      *
5297      * @return True if the event population was completed.
5298      */
5299     public boolean dispatchPopulateAccessibilityEvent(AccessibilityEvent event) {
5300         if (mAccessibilityDelegate != null) {
5301             return mAccessibilityDelegate.dispatchPopulateAccessibilityEvent(this, event);
5302         } else {
5303             return dispatchPopulateAccessibilityEventInternal(event);
5304         }
5305     }
5306
5307     /**
5308      * @see #dispatchPopulateAccessibilityEvent(AccessibilityEvent)
5309      *
5310      * Note: Called from the default {@link AccessibilityDelegate}.
5311      */
5312     boolean dispatchPopulateAccessibilityEventInternal(AccessibilityEvent event) {
5313         onPopulateAccessibilityEvent(event);
5314         return false;
5315     }
5316
5317     /**
5318      * Called from {@link #dispatchPopulateAccessibilityEvent(AccessibilityEvent)}
5319      * giving a chance to this View to populate the accessibility event with its
5320      * text content. While this method is free to modify event
5321      * attributes other than text content, doing so should normally be performed in
5322      * {@link #onInitializeAccessibilityEvent(AccessibilityEvent)}.
5323      * <p>
5324      * Example: Adding formatted date string to an accessibility event in addition
5325      *          to the text added by the super implementation:
5326      * <pre> public void onPopulateAccessibilityEvent(AccessibilityEvent event) {
5327      *     super.onPopulateAccessibilityEvent(event);
5328      *     final int flags = DateUtils.FORMAT_SHOW_DATE | DateUtils.FORMAT_SHOW_WEEKDAY;
5329      *     String selectedDateUtterance = DateUtils.formatDateTime(mContext,
5330      *         mCurrentDate.getTimeInMillis(), flags);
5331      *     event.getText().add(selectedDateUtterance);
5332      * }</pre>
5333      * <p>
5334      * If an {@link AccessibilityDelegate} has been specified via calling
5335      * {@link #setAccessibilityDelegate(AccessibilityDelegate)} its
5336      * {@link AccessibilityDelegate#onPopulateAccessibilityEvent(View, AccessibilityEvent)}
5337      * is responsible for handling this call.
5338      * </p>
5339      * <p class="note"><strong>Note:</strong> Always call the super implementation before adding
5340      * information to the event, in case the default implementation has basic information to add.
5341      * </p>
5342      *
5343      * @param event The accessibility event which to populate.
5344      *
5345      * @see #sendAccessibilityEvent(int)
5346      * @see #dispatchPopulateAccessibilityEvent(AccessibilityEvent)
5347      */
5348     public void onPopulateAccessibilityEvent(AccessibilityEvent event) {
5349         if (mAccessibilityDelegate != null) {
5350             mAccessibilityDelegate.onPopulateAccessibilityEvent(this, event);
5351         } else {
5352             onPopulateAccessibilityEventInternal(event);
5353         }
5354     }
5355
5356     /**
5357      * @see #onPopulateAccessibilityEvent(AccessibilityEvent)
5358      *
5359      * Note: Called from the default {@link AccessibilityDelegate}.
5360      */
5361     void onPopulateAccessibilityEventInternal(AccessibilityEvent event) {
5362     }
5363
5364     /**
5365      * Initializes an {@link AccessibilityEvent} with information about
5366      * this View which is the event source. In other words, the source of
5367      * an accessibility event is the view whose state change triggered firing
5368      * the event.
5369      * <p>
5370      * Example: Setting the password property of an event in addition
5371      *          to properties set by the super implementation:
5372      * <pre> public void onInitializeAccessibilityEvent(AccessibilityEvent event) {
5373      *     super.onInitializeAccessibilityEvent(event);
5374      *     event.setPassword(true);
5375      * }</pre>
5376      * <p>
5377      * If an {@link AccessibilityDelegate} has been specified via calling
5378      * {@link #setAccessibilityDelegate(AccessibilityDelegate)} its
5379      * {@link AccessibilityDelegate#onInitializeAccessibilityEvent(View, AccessibilityEvent)}
5380      * is responsible for handling this call.
5381      * </p>
5382      * <p class="note"><strong>Note:</strong> Always call the super implementation before adding
5383      * information to the event, in case the default implementation has basic information to add.
5384      * </p>
5385      * @param event The event to initialize.
5386      *
5387      * @see #sendAccessibilityEvent(int)
5388      * @see #dispatchPopulateAccessibilityEvent(AccessibilityEvent)
5389      */
5390     public void onInitializeAccessibilityEvent(AccessibilityEvent event) {
5391         if (mAccessibilityDelegate != null) {
5392             mAccessibilityDelegate.onInitializeAccessibilityEvent(this, event);
5393         } else {
5394             onInitializeAccessibilityEventInternal(event);
5395         }
5396     }
5397
5398     /**
5399      * @see #onInitializeAccessibilityEvent(AccessibilityEvent)
5400      *
5401      * Note: Called from the default {@link AccessibilityDelegate}.
5402      */
5403     void onInitializeAccessibilityEventInternal(AccessibilityEvent event) {
5404         event.setSource(this);
5405         event.setClassName(View.class.getName());
5406         event.setPackageName(getContext().getPackageName());
5407         event.setEnabled(isEnabled());
5408         event.setContentDescription(mContentDescription);
5409
5410         switch (event.getEventType()) {
5411             case AccessibilityEvent.TYPE_VIEW_FOCUSED: {
5412                 ArrayList<View> focusablesTempList = (mAttachInfo != null)
5413                         ? mAttachInfo.mTempArrayList : new ArrayList<View>();
5414                 getRootView().addFocusables(focusablesTempList, View.FOCUS_FORWARD, FOCUSABLES_ALL);
5415                 event.setItemCount(focusablesTempList.size());
5416                 event.setCurrentItemIndex(focusablesTempList.indexOf(this));
5417                 if (mAttachInfo != null) {
5418                     focusablesTempList.clear();
5419                 }
5420             } break;
5421             case AccessibilityEvent.TYPE_VIEW_TEXT_SELECTION_CHANGED: {
5422                 CharSequence text = getIterableTextForAccessibility();
5423                 if (text != null && text.length() > 0) {
5424                     event.setFromIndex(getAccessibilitySelectionStart());
5425                     event.setToIndex(getAccessibilitySelectionEnd());
5426                     event.setItemCount(text.length());
5427                 }
5428             } break;
5429         }
5430     }
5431
5432     /**
5433      * Returns an {@link AccessibilityNodeInfo} representing this view from the
5434      * point of view of an {@link android.accessibilityservice.AccessibilityService}.
5435      * This method is responsible for obtaining an accessibility node info from a
5436      * pool of reusable instances and calling
5437      * {@link #onInitializeAccessibilityNodeInfo(AccessibilityNodeInfo)} on this view to
5438      * initialize the former.
5439      * <p>
5440      * Note: The client is responsible for recycling the obtained instance by calling
5441      *       {@link AccessibilityNodeInfo#recycle()} to minimize object creation.
5442      * </p>
5443      *
5444      * @return A populated {@link AccessibilityNodeInfo}.
5445      *
5446      * @see AccessibilityNodeInfo
5447      */
5448     public AccessibilityNodeInfo createAccessibilityNodeInfo() {
5449         if (mAccessibilityDelegate != null) {
5450             return mAccessibilityDelegate.createAccessibilityNodeInfo(this);
5451         } else {
5452             return createAccessibilityNodeInfoInternal();
5453         }
5454     }
5455
5456     /**
5457      * @see #createAccessibilityNodeInfo()
5458      */
5459     AccessibilityNodeInfo createAccessibilityNodeInfoInternal() {
5460         AccessibilityNodeProvider provider = getAccessibilityNodeProvider();
5461         if (provider != null) {
5462             return provider.createAccessibilityNodeInfo(View.NO_ID);
5463         } else {
5464             AccessibilityNodeInfo info = AccessibilityNodeInfo.obtain(this);
5465             onInitializeAccessibilityNodeInfo(info);
5466             return info;
5467         }
5468     }
5469
5470     /**
5471      * Initializes an {@link AccessibilityNodeInfo} with information about this view.
5472      * The base implementation sets:
5473      * <ul>
5474      *   <li>{@link AccessibilityNodeInfo#setParent(View)},</li>
5475      *   <li>{@link AccessibilityNodeInfo#setBoundsInParent(Rect)},</li>
5476      *   <li>{@link AccessibilityNodeInfo#setBoundsInScreen(Rect)},</li>
5477      *   <li>{@link AccessibilityNodeInfo#setPackageName(CharSequence)},</li>
5478      *   <li>{@link AccessibilityNodeInfo#setClassName(CharSequence)},</li>
5479      *   <li>{@link AccessibilityNodeInfo#setContentDescription(CharSequence)},</li>
5480      *   <li>{@link AccessibilityNodeInfo#setEnabled(boolean)},</li>
5481      *   <li>{@link AccessibilityNodeInfo#setClickable(boolean)},</li>
5482      *   <li>{@link AccessibilityNodeInfo#setFocusable(boolean)},</li>
5483      *   <li>{@link AccessibilityNodeInfo#setFocused(boolean)},</li>
5484      *   <li>{@link AccessibilityNodeInfo#setLongClickable(boolean)},</li>
5485      *   <li>{@link AccessibilityNodeInfo#setSelected(boolean)},</li>
5486      * </ul>
5487      * <p>
5488      * Subclasses should override this method, call the super implementation,
5489      * and set additional attributes.
5490      * </p>
5491      * <p>
5492      * If an {@link AccessibilityDelegate} has been specified via calling
5493      * {@link #setAccessibilityDelegate(AccessibilityDelegate)} its
5494      * {@link AccessibilityDelegate#onInitializeAccessibilityNodeInfo(View, AccessibilityNodeInfo)}
5495      * is responsible for handling this call.
5496      * </p>
5497      *
5498      * @param info The instance to initialize.
5499      */
5500     public void onInitializeAccessibilityNodeInfo(AccessibilityNodeInfo info) {
5501         if (mAccessibilityDelegate != null) {
5502             mAccessibilityDelegate.onInitializeAccessibilityNodeInfo(this, info);
5503         } else {
5504             onInitializeAccessibilityNodeInfoInternal(info);
5505         }
5506     }
5507
5508     /**
5509      * Gets the location of this view in screen coordintates.
5510      *
5511      * @param outRect The output location
5512      * @hide
5513      */
5514     public void getBoundsOnScreen(Rect outRect) {
5515         if (mAttachInfo == null) {
5516             return;
5517         }
5518
5519         RectF position = mAttachInfo.mTmpTransformRect;
5520         position.set(0, 0, mRight - mLeft, mBottom - mTop);
5521
5522         if (!hasIdentityMatrix()) {
5523             getMatrix().mapRect(position);
5524         }
5525
5526         position.offset(mLeft, mTop);
5527
5528         ViewParent parent = mParent;
5529         while (parent instanceof View) {
5530             View parentView = (View) parent;
5531
5532             position.offset(-parentView.mScrollX, -parentView.mScrollY);
5533
5534             if (!parentView.hasIdentityMatrix()) {
5535                 parentView.getMatrix().mapRect(position);
5536             }
5537
5538             position.offset(parentView.mLeft, parentView.mTop);
5539
5540             parent = parentView.mParent;
5541         }
5542
5543         if (parent instanceof ViewRootImpl) {
5544             ViewRootImpl viewRootImpl = (ViewRootImpl) parent;
5545             position.offset(0, -viewRootImpl.mCurScrollY);
5546         }
5547
5548         position.offset(mAttachInfo.mWindowLeft, mAttachInfo.mWindowTop);
5549
5550         outRect.set((int) (position.left + 0.5f), (int) (position.top + 0.5f),
5551                 (int) (position.right + 0.5f), (int) (position.bottom + 0.5f));
5552     }
5553
5554     /**
5555      * @see #onInitializeAccessibilityNodeInfo(AccessibilityNodeInfo)
5556      *
5557      * Note: Called from the default {@link AccessibilityDelegate}.
5558      */
5559     void onInitializeAccessibilityNodeInfoInternal(AccessibilityNodeInfo info) {
5560         Rect bounds = mAttachInfo.mTmpInvalRect;
5561
5562         getDrawingRect(bounds);
5563         info.setBoundsInParent(bounds);
5564
5565         getBoundsOnScreen(bounds);
5566         info.setBoundsInScreen(bounds);
5567
5568         ViewParent parent = getParentForAccessibility();
5569         if (parent instanceof View) {
5570             info.setParent((View) parent);
5571         }
5572
5573         if (mID != View.NO_ID) {
5574             View rootView = getRootView();
5575             if (rootView == null) {
5576                 rootView = this;
5577             }
5578             View label = rootView.findLabelForView(this, mID);
5579             if (label != null) {
5580                 info.setLabeledBy(label);
5581             }
5582
5583             if ((mAttachInfo.mAccessibilityFetchFlags
5584                     & AccessibilityNodeInfo.FLAG_REPORT_VIEW_IDS) != 0
5585                     && Resources.resourceHasPackage(mID)) {
5586                 try {
5587                     String viewId = getResources().getResourceName(mID);
5588                     info.setViewIdResourceName(viewId);
5589                 } catch (Resources.NotFoundException nfe) {
5590                     /* ignore */
5591                 }
5592             }
5593         }
5594
5595         if (mLabelForId != View.NO_ID) {
5596             View rootView = getRootView();
5597             if (rootView == null) {
5598                 rootView = this;
5599             }
5600             View labeled = rootView.findViewInsideOutShouldExist(this, mLabelForId);
5601             if (labeled != null) {
5602                 info.setLabelFor(labeled);
5603             }
5604         }
5605
5606         info.setVisibleToUser(isVisibleToUser());
5607
5608         info.setPackageName(mContext.getPackageName());
5609         info.setClassName(View.class.getName());
5610         info.setContentDescription(getContentDescription());
5611
5612         info.setEnabled(isEnabled());
5613         info.setClickable(isClickable());
5614         info.setFocusable(isFocusable());
5615         info.setFocused(isFocused());
5616         info.setAccessibilityFocused(isAccessibilityFocused());
5617         info.setSelected(isSelected());
5618         info.setLongClickable(isLongClickable());
5619         info.setLiveRegion(getAccessibilityLiveRegion());
5620
5621         // TODO: These make sense only if we are in an AdapterView but all
5622         // views can be selected. Maybe from accessibility perspective
5623         // we should report as selectable view in an AdapterView.
5624         info.addAction(AccessibilityNodeInfo.ACTION_SELECT);
5625         info.addAction(AccessibilityNodeInfo.ACTION_CLEAR_SELECTION);
5626
5627         if (isFocusable()) {
5628             if (isFocused()) {
5629                 info.addAction(AccessibilityNodeInfo.ACTION_CLEAR_FOCUS);
5630             } else {
5631                 info.addAction(AccessibilityNodeInfo.ACTION_FOCUS);
5632             }
5633         }
5634
5635         if (!isAccessibilityFocused()) {
5636             info.addAction(AccessibilityNodeInfo.ACTION_ACCESSIBILITY_FOCUS);
5637         } else {
5638             info.addAction(AccessibilityNodeInfo.ACTION_CLEAR_ACCESSIBILITY_FOCUS);
5639         }
5640
5641         if (isClickable() && isEnabled()) {
5642             info.addAction(AccessibilityNodeInfo.ACTION_CLICK);
5643         }
5644
5645         if (isLongClickable() && isEnabled()) {
5646             info.addAction(AccessibilityNodeInfo.ACTION_LONG_CLICK);
5647         }
5648
5649         CharSequence text = getIterableTextForAccessibility();
5650         if (text != null && text.length() > 0) {
5651             info.setTextSelection(getAccessibilitySelectionStart(), getAccessibilitySelectionEnd());
5652
5653             info.addAction(AccessibilityNodeInfo.ACTION_SET_SELECTION);
5654             info.addAction(AccessibilityNodeInfo.ACTION_NEXT_AT_MOVEMENT_GRANULARITY);
5655             info.addAction(AccessibilityNodeInfo.ACTION_PREVIOUS_AT_MOVEMENT_GRANULARITY);
5656             info.setMovementGranularities(AccessibilityNodeInfo.MOVEMENT_GRANULARITY_CHARACTER
5657                     | AccessibilityNodeInfo.MOVEMENT_GRANULARITY_WORD
5658                     | AccessibilityNodeInfo.MOVEMENT_GRANULARITY_PARAGRAPH);
5659         }
5660     }
5661
5662     private View findLabelForView(View view, int labeledId) {
5663         if (mMatchLabelForPredicate == null) {
5664             mMatchLabelForPredicate = new MatchLabelForPredicate();
5665         }
5666         mMatchLabelForPredicate.mLabeledId = labeledId;
5667         return findViewByPredicateInsideOut(view, mMatchLabelForPredicate);
5668     }
5669
5670     /**
5671      * Computes whether this view is visible to the user. Such a view is
5672      * attached, visible, all its predecessors are visible, it is not clipped
5673      * entirely by its predecessors, and has an alpha greater than zero.
5674      *
5675      * @return Whether the view is visible on the screen.
5676      *
5677      * @hide
5678      */
5679     protected boolean isVisibleToUser() {
5680         return isVisibleToUser(null);
5681     }
5682
5683     /**
5684      * Computes whether the given portion of this view is visible to the user.
5685      * Such a view is attached, visible, all its predecessors are visible,
5686      * has an alpha greater than zero, and the specified portion is not
5687      * clipped entirely by its predecessors.
5688      *
5689      * @param boundInView the portion of the view to test; coordinates should be relative; may be
5690      *                    <code>null</code>, and the entire view will be tested in this case.
5691      *                    When <code>true</code> is returned by the function, the actual visible
5692      *                    region will be stored in this parameter; that is, if boundInView is fully
5693      *                    contained within the view, no modification will be made, otherwise regions
5694      *                    outside of the visible area of the view will be clipped.
5695      *
5696      * @return Whether the specified portion of the view is visible on the screen.
5697      *
5698      * @hide
5699      */
5700     protected boolean isVisibleToUser(Rect boundInView) {
5701         if (mAttachInfo != null) {
5702             // Attached to invisible window means this view is not visible.
5703             if (mAttachInfo.mWindowVisibility != View.VISIBLE) {
5704                 return false;
5705             }
5706             // An invisible predecessor or one with alpha zero means
5707             // that this view is not visible to the user.
5708             Object current = this;
5709             while (current instanceof View) {
5710                 View view = (View) current;
5711                 // We have attach info so this view is attached and there is no
5712                 // need to check whether we reach to ViewRootImpl on the way up.
5713                 if (view.getAlpha() <= 0 || view.getTransitionAlpha() <= 0 ||
5714                         view.getVisibility() != VISIBLE) {
5715                     return false;
5716                 }
5717                 current = view.mParent;
5718             }
5719             // Check if the view is entirely covered by its predecessors.
5720             Rect visibleRect = mAttachInfo.mTmpInvalRect;
5721             Point offset = mAttachInfo.mPoint;
5722             if (!getGlobalVisibleRect(visibleRect, offset)) {
5723                 return false;
5724             }
5725             // Check if the visible portion intersects the rectangle of interest.
5726             if (boundInView != null) {
5727                 visibleRect.offset(-offset.x, -offset.y);
5728                 return boundInView.intersect(visibleRect);
5729             }
5730             return true;
5731         }
5732         return false;
5733     }
5734
5735     /**
5736      * Computes a point on which a sequence of a down/up event can be sent to
5737      * trigger clicking this view. This method is for the exclusive use by the
5738      * accessibility layer to determine where to send a click event in explore
5739      * by touch mode.
5740      *
5741      * @param interactiveRegion The interactive portion of this window.
5742      * @param outPoint The point to populate.
5743      * @return True of such a point exists.
5744      */
5745     boolean computeClickPointInScreenForAccessibility(Region interactiveRegion,
5746             Point outPoint) {
5747         // Since the interactive portion of the view is a region but as a view
5748         // may have a transformation matrix which cannot be applied to a
5749         // region we compute the view bounds rectangle and all interactive
5750         // predecessor's and sibling's (siblings of predecessors included)
5751         // rectangles that intersect the view bounds. At the
5752         // end if the view was partially covered by another interactive
5753         // view we compute the view's interactive region and pick a point
5754         // on its boundary path as regions do not offer APIs to get inner
5755         // points. Note that the the code is optimized to fail early and
5756         // avoid unnecessary allocations plus computations.
5757
5758         // The current approach has edge cases that may produce false
5759         // positives or false negatives. For example, a portion of the
5760         // view may be covered by an interactive descendant of a
5761         // predecessor, which we do not compute. Also a view may be handling
5762         // raw touch events instead registering click listeners, which
5763         // we cannot compute. Despite these limitations this approach will
5764         // work most of the time and it is a huge improvement over just
5765         // blindly sending the down and up events in the center of the
5766         // view.
5767
5768         // Cannot click on an unattached view.
5769         if (mAttachInfo == null) {
5770             return false;
5771         }
5772
5773         // Attached to an invisible window means this view is not visible.
5774         if (mAttachInfo.mWindowVisibility != View.VISIBLE) {
5775             return false;
5776         }
5777
5778         RectF bounds = mAttachInfo.mTmpTransformRect;
5779         bounds.set(0, 0, getWidth(), getHeight());
5780         List<RectF> intersections = mAttachInfo.mTmpRectList;
5781         intersections.clear();
5782
5783         if (mParent instanceof ViewGroup) {
5784             ViewGroup parentGroup = (ViewGroup) mParent;
5785             if (!parentGroup.translateBoundsAndIntersectionsInWindowCoordinates(
5786                     this, bounds, intersections)) {
5787                 intersections.clear();
5788                 return false;
5789             }
5790         }
5791
5792         // Take into account the window location.
5793         final int dx = mAttachInfo.mWindowLeft;
5794         final int dy = mAttachInfo.mWindowTop;
5795         bounds.offset(dx, dy);
5796         offsetRects(intersections, dx, dy);
5797
5798         if (intersections.isEmpty() && interactiveRegion == null) {
5799             outPoint.set((int) bounds.centerX(), (int) bounds.centerY());
5800         } else {
5801             // This view is partially covered by other views, then compute
5802             // the not covered region and pick a point on its boundary.
5803             Region region = new Region();
5804             region.set((int) bounds.left, (int) bounds.top,
5805                     (int) bounds.right, (int) bounds.bottom);
5806
5807             final int intersectionCount = intersections.size();
5808             for (int i = intersectionCount - 1; i >= 0; i--) {
5809                 RectF intersection = intersections.remove(i);
5810                 region.op((int) intersection.left, (int) intersection.top,
5811                         (int) intersection.right, (int) intersection.bottom,
5812                         Region.Op.DIFFERENCE);
5813             }
5814
5815             // If the view is completely covered, done.
5816             if (region.isEmpty()) {
5817                 return false;
5818             }
5819
5820             // Take into account the interactive portion of the window
5821             // as the rest is covered by other windows. If no such a region
5822             // then the whole window is interactive.
5823             if (interactiveRegion != null) {
5824                 region.op(interactiveRegion, Region.Op.INTERSECT);
5825             }
5826
5827             // If the view is completely covered, done.
5828             if (region.isEmpty()) {
5829                 return false;
5830             }
5831
5832             // Try a shortcut here.
5833             if (region.isRect()) {
5834                 Rect regionBounds = mAttachInfo.mTmpInvalRect;
5835                 region.getBounds(regionBounds);
5836                 outPoint.set(regionBounds.centerX(), regionBounds.centerY());
5837                 return true;
5838             }
5839
5840             // Get the a point on the region boundary path.
5841             Path path = region.getBoundaryPath();
5842             PathMeasure pathMeasure = new PathMeasure(path, false);
5843             final float[] coordinates = mAttachInfo.mTmpTransformLocation;
5844
5845             // Without loss of generality pick a point.
5846             final float point = pathMeasure.getLength() * 0.01f;
5847             if (!pathMeasure.getPosTan(point, coordinates, null)) {
5848                 return false;
5849             }
5850
5851             outPoint.set(Math.round(coordinates[0]), Math.round(coordinates[1]));
5852         }
5853
5854         return true;
5855     }
5856
5857     static void offsetRects(List<RectF> rects, float offsetX, float offsetY) {
5858         final int rectCount = rects.size();
5859         for (int i = 0; i < rectCount; i++) {
5860             RectF intersection = rects.get(i);
5861             intersection.offset(offsetX, offsetY);
5862         }
5863     }
5864
5865     /**
5866      * Returns the delegate for implementing accessibility support via
5867      * composition. For more details see {@link AccessibilityDelegate}.
5868      *
5869      * @return The delegate, or null if none set.
5870      *
5871      * @hide
5872      */
5873     public AccessibilityDelegate getAccessibilityDelegate() {
5874         return mAccessibilityDelegate;
5875     }
5876
5877     /**
5878      * Sets a delegate for implementing accessibility support via composition as
5879      * opposed to inheritance. The delegate's primary use is for implementing
5880      * backwards compatible widgets. For more details see {@link AccessibilityDelegate}.
5881      *
5882      * @param delegate The delegate instance.
5883      *
5884      * @see AccessibilityDelegate
5885      */
5886     public void setAccessibilityDelegate(AccessibilityDelegate delegate) {
5887         mAccessibilityDelegate = delegate;
5888     }
5889
5890     /**
5891      * Gets the provider for managing a virtual view hierarchy rooted at this View
5892      * and reported to {@link android.accessibilityservice.AccessibilityService}s
5893      * that explore the window content.
5894      * <p>
5895      * If this method returns an instance, this instance is responsible for managing
5896      * {@link AccessibilityNodeInfo}s describing the virtual sub-tree rooted at this
5897      * View including the one representing the View itself. Similarly the returned
5898      * instance is responsible for performing accessibility actions on any virtual
5899      * view or the root view itself.
5900      * </p>
5901      * <p>
5902      * If an {@link AccessibilityDelegate} has been specified via calling
5903      * {@link #setAccessibilityDelegate(AccessibilityDelegate)} its
5904      * {@link AccessibilityDelegate#getAccessibilityNodeProvider(View)}
5905      * is responsible for handling this call.
5906      * </p>
5907      *
5908      * @return The provider.
5909      *
5910      * @see AccessibilityNodeProvider
5911      */
5912     public AccessibilityNodeProvider getAccessibilityNodeProvider() {
5913         if (mAccessibilityDelegate != null) {
5914             return mAccessibilityDelegate.getAccessibilityNodeProvider(this);
5915         } else {
5916             return null;
5917         }
5918     }
5919
5920     /**
5921      * Gets the unique identifier of this view on the screen for accessibility purposes.
5922      * If this {@link View} is not attached to any window, {@value #NO_ID} is returned.
5923      *
5924      * @return The view accessibility id.
5925      *
5926      * @hide
5927      */
5928     public int getAccessibilityViewId() {
5929         if (mAccessibilityViewId == NO_ID) {
5930             mAccessibilityViewId = sNextAccessibilityViewId++;
5931         }
5932         return mAccessibilityViewId;
5933     }
5934
5935     /**
5936      * Gets the unique identifier of the window in which this View reseides.
5937      *
5938      * @return The window accessibility id.
5939      *
5940      * @hide
5941      */
5942     public int getAccessibilityWindowId() {
5943         return mAttachInfo != null ? mAttachInfo.mAccessibilityWindowId
5944                 : AccessibilityNodeInfo.UNDEFINED_ITEM_ID;
5945     }
5946
5947     /**
5948      * Gets the {@link View} description. It briefly describes the view and is
5949      * primarily used for accessibility support. Set this property to enable
5950      * better accessibility support for your application. This is especially
5951      * true for views that do not have textual representation (For example,
5952      * ImageButton).
5953      *
5954      * @return The content description.
5955      *
5956      * @attr ref android.R.styleable#View_contentDescription
5957      */
5958     @ViewDebug.ExportedProperty(category = "accessibility")
5959     public CharSequence getContentDescription() {
5960         return mContentDescription;
5961     }
5962
5963     /**
5964      * Sets the {@link View} description. It briefly describes the view and is
5965      * primarily used for accessibility support. Set this property to enable
5966      * better accessibility support for your application. This is especially
5967      * true for views that do not have textual representation (For example,
5968      * ImageButton).
5969      *
5970      * @param contentDescription The content description.
5971      *
5972      * @attr ref android.R.styleable#View_contentDescription
5973      */
5974     @RemotableViewMethod
5975     public void setContentDescription(CharSequence contentDescription) {
5976         if (mContentDescription == null) {
5977             if (contentDescription == null) {
5978                 return;
5979             }
5980         } else if (mContentDescription.equals(contentDescription)) {
5981             return;
5982         }
5983         mContentDescription = contentDescription;
5984         final boolean nonEmptyDesc = contentDescription != null && contentDescription.length() > 0;
5985         if (nonEmptyDesc && getImportantForAccessibility() == IMPORTANT_FOR_ACCESSIBILITY_AUTO) {
5986             setImportantForAccessibility(IMPORTANT_FOR_ACCESSIBILITY_YES);
5987             notifySubtreeAccessibilityStateChangedIfNeeded();
5988         } else {
5989             notifyViewAccessibilityStateChangedIfNeeded(
5990                     AccessibilityEvent.CONTENT_CHANGE_TYPE_CONTENT_DESCRIPTION);
5991         }
5992     }
5993
5994     /**
5995      * Gets the id of a view for which this view serves as a label for
5996      * accessibility purposes.
5997      *
5998      * @return The labeled view id.
5999      */
6000     @ViewDebug.ExportedProperty(category = "accessibility")
6001     public int getLabelFor() {
6002         return mLabelForId;
6003     }
6004
6005     /**
6006      * Sets the id of a view for which this view serves as a label for
6007      * accessibility purposes.
6008      *
6009      * @param id The labeled view id.
6010      */
6011     @RemotableViewMethod
6012     public void setLabelFor(int id) {
6013         mLabelForId = id;
6014         if (mLabelForId != View.NO_ID
6015                 && mID == View.NO_ID) {
6016             mID = generateViewId();
6017         }
6018     }
6019
6020     /**
6021      * Invoked whenever this view loses focus, either by losing window focus or by losing
6022      * focus within its window. This method can be used to clear any state tied to the
6023      * focus. For instance, if a button is held pressed with the trackball and the window
6024      * loses focus, this method can be used to cancel the press.
6025      *
6026      * Subclasses of View overriding this method should always call super.onFocusLost().
6027      *
6028      * @see #onFocusChanged(boolean, int, android.graphics.Rect)
6029      * @see #onWindowFocusChanged(boolean)
6030      *
6031      * @hide pending API council approval
6032      */
6033     protected void onFocusLost() {
6034         resetPressedState();
6035     }
6036
6037     private void resetPressedState() {
6038         if ((mViewFlags & ENABLED_MASK) == DISABLED) {
6039             return;
6040         }
6041
6042         if (isPressed()) {
6043             setPressed(false);
6044
6045             if (!mHasPerformedLongPress) {
6046                 removeLongPressCallback();
6047             }
6048         }
6049     }
6050
6051     /**
6052      * Returns true if this view has focus
6053      *
6054      * @return True if this view has focus, false otherwise.
6055      */
6056     @ViewDebug.ExportedProperty(category = "focus")
6057     public boolean isFocused() {
6058         return (mPrivateFlags & PFLAG_FOCUSED) != 0;
6059     }
6060
6061     /**
6062      * Find the view in the hierarchy rooted at this view that currently has
6063      * focus.
6064      *
6065      * @return The view that currently has focus, or null if no focused view can
6066      *         be found.
6067      */
6068     public View findFocus() {
6069         return (mPrivateFlags & PFLAG_FOCUSED) != 0 ? this : null;
6070     }
6071
6072     /**
6073      * Indicates whether this view is one of the set of scrollable containers in
6074      * its window.
6075      *
6076      * @return whether this view is one of the set of scrollable containers in
6077      * its window
6078      *
6079      * @attr ref android.R.styleable#View_isScrollContainer
6080      */
6081     public boolean isScrollContainer() {
6082         return (mPrivateFlags & PFLAG_SCROLL_CONTAINER_ADDED) != 0;
6083     }
6084
6085     /**
6086      * Change whether this view is one of the set of scrollable containers in
6087      * its window.  This will be used to determine whether the window can
6088      * resize or must pan when a soft input area is open -- scrollable
6089      * containers allow the window to use resize mode since the container
6090      * will appropriately shrink.
6091      *
6092      * @attr ref android.R.styleable#View_isScrollContainer
6093      */
6094     public void setScrollContainer(boolean isScrollContainer) {
6095         if (isScrollContainer) {
6096             if (mAttachInfo != null && (mPrivateFlags&PFLAG_SCROLL_CONTAINER_ADDED) == 0) {
6097                 mAttachInfo.mScrollContainers.add(this);
6098                 mPrivateFlags |= PFLAG_SCROLL_CONTAINER_ADDED;
6099             }
6100             mPrivateFlags |= PFLAG_SCROLL_CONTAINER;
6101         } else {
6102             if ((mPrivateFlags&PFLAG_SCROLL_CONTAINER_ADDED) != 0) {
6103                 mAttachInfo.mScrollContainers.remove(this);
6104             }
6105             mPrivateFlags &= ~(PFLAG_SCROLL_CONTAINER|PFLAG_SCROLL_CONTAINER_ADDED);
6106         }
6107     }
6108
6109     /**
6110      * Returns the quality of the drawing cache.
6111      *
6112      * @return One of {@link #DRAWING_CACHE_QUALITY_AUTO},
6113      *         {@link #DRAWING_CACHE_QUALITY_LOW}, or {@link #DRAWING_CACHE_QUALITY_HIGH}
6114      *
6115      * @see #setDrawingCacheQuality(int)
6116      * @see #setDrawingCacheEnabled(boolean)
6117      * @see #isDrawingCacheEnabled()
6118      *
6119      * @attr ref android.R.styleable#View_drawingCacheQuality
6120      */
6121     @DrawingCacheQuality
6122     public int getDrawingCacheQuality() {
6123         return mViewFlags & DRAWING_CACHE_QUALITY_MASK;
6124     }
6125
6126     /**
6127      * Set the drawing cache quality of this view. This value is used only when the
6128      * drawing cache is enabled
6129      *
6130      * @param quality One of {@link #DRAWING_CACHE_QUALITY_AUTO},
6131      *        {@link #DRAWING_CACHE_QUALITY_LOW}, or {@link #DRAWING_CACHE_QUALITY_HIGH}
6132      *
6133      * @see #getDrawingCacheQuality()
6134      * @see #setDrawingCacheEnabled(boolean)
6135      * @see #isDrawingCacheEnabled()
6136      *
6137      * @attr ref android.R.styleable#View_drawingCacheQuality
6138      */
6139     public void setDrawingCacheQuality(@DrawingCacheQuality int quality) {
6140         setFlags(quality, DRAWING_CACHE_QUALITY_MASK);
6141     }
6142
6143     /**
6144      * Returns whether the screen should remain on, corresponding to the current
6145      * value of {@link #KEEP_SCREEN_ON}.
6146      *
6147      * @return Returns true if {@link #KEEP_SCREEN_ON} is set.
6148      *
6149      * @see #setKeepScreenOn(boolean)
6150      *
6151      * @attr ref android.R.styleable#View_keepScreenOn
6152      */
6153     public boolean getKeepScreenOn() {
6154         return (mViewFlags & KEEP_SCREEN_ON) != 0;
6155     }
6156
6157     /**
6158      * Controls whether the screen should remain on, modifying the
6159      * value of {@link #KEEP_SCREEN_ON}.
6160      *
6161      * @param keepScreenOn Supply true to set {@link #KEEP_SCREEN_ON}.
6162      *
6163      * @see #getKeepScreenOn()
6164      *
6165      * @attr ref android.R.styleable#View_keepScreenOn
6166      */
6167     public void setKeepScreenOn(boolean keepScreenOn) {
6168         setFlags(keepScreenOn ? KEEP_SCREEN_ON : 0, KEEP_SCREEN_ON);
6169     }
6170
6171     /**
6172      * Gets the id of the view to use when the next focus is {@link #FOCUS_LEFT}.
6173      * @return The next focus ID, or {@link #NO_ID} if the framework should decide automatically.
6174      *
6175      * @attr ref android.R.styleable#View_nextFocusLeft
6176      */
6177     public int getNextFocusLeftId() {
6178         return mNextFocusLeftId;
6179     }
6180
6181     /**
6182      * Sets the id of the view to use when the next focus is {@link #FOCUS_LEFT}.
6183      * @param nextFocusLeftId The next focus ID, or {@link #NO_ID} if the framework should
6184      * decide automatically.
6185      *
6186      * @attr ref android.R.styleable#View_nextFocusLeft
6187      */
6188     public void setNextFocusLeftId(int nextFocusLeftId) {
6189         mNextFocusLeftId = nextFocusLeftId;
6190     }
6191
6192     /**
6193      * Gets the id of the view to use when the next focus is {@link #FOCUS_RIGHT}.
6194      * @return The next focus ID, or {@link #NO_ID} if the framework should decide automatically.
6195      *
6196      * @attr ref android.R.styleable#View_nextFocusRight
6197      */
6198     public int getNextFocusRightId() {
6199         return mNextFocusRightId;
6200     }
6201
6202     /**
6203      * Sets the id of the view to use when the next focus is {@link #FOCUS_RIGHT}.
6204      * @param nextFocusRightId The next focus ID, or {@link #NO_ID} if the framework should
6205      * decide automatically.
6206      *
6207      * @attr ref android.R.styleable#View_nextFocusRight
6208      */
6209     public void setNextFocusRightId(int nextFocusRightId) {
6210         mNextFocusRightId = nextFocusRightId;
6211     }
6212
6213     /**
6214      * Gets the id of the view to use when the next focus is {@link #FOCUS_UP}.
6215      * @return The next focus ID, or {@link #NO_ID} if the framework should decide automatically.
6216      *
6217      * @attr ref android.R.styleable#View_nextFocusUp
6218      */
6219     public int getNextFocusUpId() {
6220         return mNextFocusUpId;
6221     }
6222
6223     /**
6224      * Sets the id of the view to use when the next focus is {@link #FOCUS_UP}.
6225      * @param nextFocusUpId The next focus ID, or {@link #NO_ID} if the framework should
6226      * decide automatically.
6227      *
6228      * @attr ref android.R.styleable#View_nextFocusUp
6229      */
6230     public void setNextFocusUpId(int nextFocusUpId) {
6231         mNextFocusUpId = nextFocusUpId;
6232     }
6233
6234     /**
6235      * Gets the id of the view to use when the next focus is {@link #FOCUS_DOWN}.
6236      * @return The next focus ID, or {@link #NO_ID} if the framework should decide automatically.
6237      *
6238      * @attr ref android.R.styleable#View_nextFocusDown
6239      */
6240     public int getNextFocusDownId() {
6241         return mNextFocusDownId;
6242     }
6243
6244     /**
6245      * Sets the id of the view to use when the next focus is {@link #FOCUS_DOWN}.
6246      * @param nextFocusDownId The next focus ID, or {@link #NO_ID} if the framework should
6247      * decide automatically.
6248      *
6249      * @attr ref android.R.styleable#View_nextFocusDown
6250      */
6251     public void setNextFocusDownId(int nextFocusDownId) {
6252         mNextFocusDownId = nextFocusDownId;
6253     }
6254
6255     /**
6256      * Gets the id of the view to use when the next focus is {@link #FOCUS_FORWARD}.
6257      * @return The next focus ID, or {@link #NO_ID} if the framework should decide automatically.
6258      *
6259      * @attr ref android.R.styleable#View_nextFocusForward
6260      */
6261     public int getNextFocusForwardId() {
6262         return mNextFocusForwardId;
6263     }
6264
6265     /**
6266      * Sets the id of the view to use when the next focus is {@link #FOCUS_FORWARD}.
6267      * @param nextFocusForwardId The next focus ID, or {@link #NO_ID} if the framework should
6268      * decide automatically.
6269      *
6270      * @attr ref android.R.styleable#View_nextFocusForward
6271      */
6272     public void setNextFocusForwardId(int nextFocusForwardId) {
6273         mNextFocusForwardId = nextFocusForwardId;
6274     }
6275
6276     /**
6277      * Returns the visibility of this view and all of its ancestors
6278      *
6279      * @return True if this view and all of its ancestors are {@link #VISIBLE}
6280      */
6281     public boolean isShown() {
6282         View current = this;
6283         //noinspection ConstantConditions
6284         do {
6285             if ((current.mViewFlags & VISIBILITY_MASK) != VISIBLE) {
6286                 return false;
6287             }
6288             ViewParent parent = current.mParent;
6289             if (parent == null) {
6290                 return false; // We are not attached to the view root
6291             }
6292             if (!(parent instanceof View)) {
6293                 return true;
6294             }
6295             current = (View) parent;
6296         } while (current != null);
6297
6298         return false;
6299     }
6300
6301     /**
6302      * Called by the view hierarchy when the content insets for a window have
6303      * changed, to allow it to adjust its content to fit within those windows.
6304      * The content insets tell you the space that the status bar, input method,
6305      * and other system windows infringe on the application's window.
6306      *
6307      * <p>You do not normally need to deal with this function, since the default
6308      * window decoration given to applications takes care of applying it to the
6309      * content of the window.  If you use {@link #SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN}
6310      * or {@link #SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION} this will not be the case,
6311      * and your content can be placed under those system elements.  You can then
6312      * use this method within your view hierarchy if you have parts of your UI
6313      * which you would like to ensure are not being covered.
6314      *
6315      * <p>The default implementation of this method simply applies the content
6316      * insets to the view's padding, consuming that content (modifying the
6317      * insets to be 0), and returning true.  This behavior is off by default, but can
6318      * be enabled through {@link #setFitsSystemWindows(boolean)}.
6319      *
6320      * <p>This function's traversal down the hierarchy is depth-first.  The same content
6321      * insets object is propagated down the hierarchy, so any changes made to it will
6322      * be seen by all following views (including potentially ones above in
6323      * the hierarchy since this is a depth-first traversal).  The first view
6324      * that returns true will abort the entire traversal.
6325      *
6326      * <p>The default implementation works well for a situation where it is
6327      * used with a container that covers the entire window, allowing it to
6328      * apply the appropriate insets to its content on all edges.  If you need
6329      * a more complicated layout (such as two different views fitting system
6330      * windows, one on the top of the window, and one on the bottom),
6331      * you can override the method and handle the insets however you would like.
6332      * Note that the insets provided by the framework are always relative to the
6333      * far edges of the window, not accounting for the location of the called view
6334      * within that window.  (In fact when this method is called you do not yet know
6335      * where the layout will place the view, as it is done before layout happens.)
6336      *
6337      * <p>Note: unlike many View methods, there is no dispatch phase to this
6338      * call.  If you are overriding it in a ViewGroup and want to allow the
6339      * call to continue to your children, you must be sure to call the super
6340      * implementation.
6341      *
6342      * <p>Here is a sample layout that makes use of fitting system windows
6343      * to have controls for a video view placed inside of the window decorations
6344      * that it hides and shows.  This can be used with code like the second
6345      * sample (video player) shown in {@link #setSystemUiVisibility(int)}.
6346      *
6347      * {@sample development/samples/ApiDemos/res/layout/video_player.xml complete}
6348      *
6349      * @param insets Current content insets of the window.  Prior to
6350      * {@link android.os.Build.VERSION_CODES#JELLY_BEAN} you must not modify
6351      * the insets or else you and Android will be unhappy.
6352      *
6353      * @return {@code true} if this view applied the insets and it should not
6354      * continue propagating further down the hierarchy, {@code false} otherwise.
6355      * @see #getFitsSystemWindows()
6356      * @see #setFitsSystemWindows(boolean)
6357      * @see #setSystemUiVisibility(int)
6358      *
6359      * @deprecated As of API XX use {@link #dispatchApplyWindowInsets(WindowInsets)} to apply
6360      * insets to views. Views should override {@link #onApplyWindowInsets(WindowInsets)} or use
6361      * {@link #setOnApplyWindowInsetsListener(android.view.View.OnApplyWindowInsetsListener)}
6362      * to implement handling their own insets.
6363      */
6364     protected boolean fitSystemWindows(Rect insets) {
6365         if ((mPrivateFlags3 & PFLAG3_APPLYING_INSETS) == 0) {
6366             if (insets == null) {
6367                 // Null insets by definition have already been consumed.
6368                 // This call cannot apply insets since there are none to apply,
6369                 // so return false.
6370                 return false;
6371             }
6372             // If we're not in the process of dispatching the newer apply insets call,
6373             // that means we're not in the compatibility path. Dispatch into the newer
6374             // apply insets path and take things from there.
6375             try {
6376                 mPrivateFlags3 |= PFLAG3_FITTING_SYSTEM_WINDOWS;
6377                 return dispatchApplyWindowInsets(new WindowInsets(insets)).isConsumed();
6378             } finally {
6379                 mPrivateFlags3 &= ~PFLAG3_FITTING_SYSTEM_WINDOWS;
6380             }
6381         } else {
6382             // We're being called from the newer apply insets path.
6383             // Perform the standard fallback behavior.
6384             return fitSystemWindowsInt(insets);
6385         }
6386     }
6387
6388     private boolean fitSystemWindowsInt(Rect insets) {
6389         if ((mViewFlags & FITS_SYSTEM_WINDOWS) == FITS_SYSTEM_WINDOWS) {
6390             mUserPaddingStart = UNDEFINED_PADDING;
6391             mUserPaddingEnd = UNDEFINED_PADDING;
6392             Rect localInsets = sThreadLocal.get();
6393             if (localInsets == null) {
6394                 localInsets = new Rect();
6395                 sThreadLocal.set(localInsets);
6396             }
6397             boolean res = computeFitSystemWindows(insets, localInsets);
6398             mUserPaddingLeftInitial = localInsets.left;
6399             mUserPaddingRightInitial = localInsets.right;
6400             internalSetPadding(localInsets.left, localInsets.top,
6401                     localInsets.right, localInsets.bottom);
6402             return res;
6403         }
6404         return false;
6405     }
6406
6407     /**
6408      * Called when the view should apply {@link WindowInsets} according to its internal policy.
6409      *
6410      * <p>This method should be overridden by views that wish to apply a policy different from or
6411      * in addition to the default behavior. Clients that wish to force a view subtree
6412      * to apply insets should call {@link #dispatchApplyWindowInsets(WindowInsets)}.</p>
6413      *
6414      * <p>Clients may supply an {@link OnApplyWindowInsetsListener} to a view. If one is set
6415      * it will be called during dispatch instead of this method. The listener may optionally
6416      * call this method from its own implementation if it wishes to apply the view's default
6417      * insets policy in addition to its own.</p>
6418      *
6419      * <p>Implementations of this method should either return the insets parameter unchanged
6420      * or a new {@link WindowInsets} cloned from the supplied insets with any insets consumed
6421      * that this view applied itself. This allows new inset types added in future platform
6422      * versions to pass through existing implementations unchanged without being erroneously
6423      * consumed.</p>
6424      *
6425      * <p>By default if a view's {@link #setFitsSystemWindows(boolean) fitsSystemWindows}
6426      * property is set then the view will consume the system window insets and apply them
6427      * as padding for the view.</p>
6428      *
6429      * @param insets Insets to apply
6430      * @return The supplied insets with any applied insets consumed
6431      */
6432     public WindowInsets onApplyWindowInsets(WindowInsets insets) {
6433         if ((mPrivateFlags3 & PFLAG3_FITTING_SYSTEM_WINDOWS) == 0) {
6434             // We weren't called from within a direct call to fitSystemWindows,
6435             // call into it as a fallback in case we're in a class that overrides it
6436             // and has logic to perform.
6437             if (fitSystemWindows(insets.getSystemWindowInsets())) {
6438                 return insets.consumeSystemWindowInsets();
6439             }
6440         } else {
6441             // We were called from within a direct call to fitSystemWindows.
6442             if (fitSystemWindowsInt(insets.getSystemWindowInsets())) {
6443                 return insets.consumeSystemWindowInsets();
6444             }
6445         }
6446         return insets;
6447     }
6448
6449     /**
6450      * Set an {@link OnApplyWindowInsetsListener} to take over the policy for applying
6451      * window insets to this view. The listener's
6452      * {@link OnApplyWindowInsetsListener#onApplyWindowInsets(View, WindowInsets) onApplyWindowInsets}
6453      * method will be called instead of the view's
6454      * {@link #onApplyWindowInsets(WindowInsets) onApplyWindowInsets} method.
6455      *
6456      * @param listener Listener to set
6457      *
6458      * @see #onApplyWindowInsets(WindowInsets)
6459      */
6460     public void setOnApplyWindowInsetsListener(OnApplyWindowInsetsListener listener) {
6461         getListenerInfo().mOnApplyWindowInsetsListener = listener;
6462     }
6463
6464     /**
6465      * Request to apply the given window insets to this view or another view in its subtree.
6466      *
6467      * <p>This method should be called by clients wishing to apply insets corresponding to areas
6468      * obscured by window decorations or overlays. This can include the status and navigation bars,
6469      * action bars, input methods and more. New inset categories may be added in the future.
6470      * The method returns the insets provided minus any that were applied by this view or its
6471      * children.</p>
6472      *
6473      * <p>Clients wishing to provide custom behavior should override the
6474      * {@link #onApplyWindowInsets(WindowInsets)} method or alternatively provide a
6475      * {@link OnApplyWindowInsetsListener} via the
6476      * {@link #setOnApplyWindowInsetsListener(View.OnApplyWindowInsetsListener) setOnApplyWindowInsetsListener}
6477      * method.</p>
6478      *
6479      * <p>This method replaces the older {@link #fitSystemWindows(Rect) fitSystemWindows} method.
6480      * </p>
6481      *
6482      * @param insets Insets to apply
6483      * @return The provided insets minus the insets that were consumed
6484      */
6485     public WindowInsets dispatchApplyWindowInsets(WindowInsets insets) {
6486         try {
6487             mPrivateFlags3 |= PFLAG3_APPLYING_INSETS;
6488             if (mListenerInfo != null && mListenerInfo.mOnApplyWindowInsetsListener != null) {
6489                 return mListenerInfo.mOnApplyWindowInsetsListener.onApplyWindowInsets(this, insets);
6490             } else {
6491                 return onApplyWindowInsets(insets);
6492             }
6493         } finally {
6494             mPrivateFlags3 &= ~PFLAG3_APPLYING_INSETS;
6495         }
6496     }
6497
6498     /**
6499      * @hide Compute the insets that should be consumed by this view and the ones
6500      * that should propagate to those under it.
6501      */
6502     protected boolean computeFitSystemWindows(Rect inoutInsets, Rect outLocalInsets) {
6503         if ((mViewFlags & OPTIONAL_FITS_SYSTEM_WINDOWS) == 0
6504                 || mAttachInfo == null
6505                 || ((mAttachInfo.mSystemUiVisibility & SYSTEM_UI_LAYOUT_FLAGS) == 0
6506                         && !mAttachInfo.mOverscanRequested)) {
6507             outLocalInsets.set(inoutInsets);
6508             inoutInsets.set(0, 0, 0, 0);
6509             return true;
6510         } else {
6511             // The application wants to take care of fitting system window for
6512             // the content...  however we still need to take care of any overscan here.
6513             final Rect overscan = mAttachInfo.mOverscanInsets;
6514             outLocalInsets.set(overscan);
6515             inoutInsets.left -= overscan.left;
6516             inoutInsets.top -= overscan.top;
6517             inoutInsets.right -= overscan.right;
6518             inoutInsets.bottom -= overscan.bottom;
6519             return false;
6520         }
6521     }
6522
6523     /**
6524      * Sets whether or not this view should account for system screen decorations
6525      * such as the status bar and inset its content; that is, controlling whether
6526      * the default implementation of {@link #fitSystemWindows(Rect)} will be
6527      * executed.  See that method for more details.
6528      *
6529      * <p>Note that if you are providing your own implementation of
6530      * {@link #fitSystemWindows(Rect)}, then there is no need to set this
6531      * flag to true -- your implementation will be overriding the default
6532      * implementation that checks this flag.
6533      *
6534      * @param fitSystemWindows If true, then the default implementation of
6535      * {@link #fitSystemWindows(Rect)} will be executed.
6536      *
6537      * @attr ref android.R.styleable#View_fitsSystemWindows
6538      * @see #getFitsSystemWindows()
6539      * @see #fitSystemWindows(Rect)
6540      * @see #setSystemUiVisibility(int)
6541      */
6542     public void setFitsSystemWindows(boolean fitSystemWindows) {
6543         setFlags(fitSystemWindows ? FITS_SYSTEM_WINDOWS : 0, FITS_SYSTEM_WINDOWS);
6544     }
6545
6546     /**
6547      * Check for state of {@link #setFitsSystemWindows(boolean)}. If this method
6548      * returns {@code true}, the default implementation of {@link #fitSystemWindows(Rect)}
6549      * will be executed.
6550      *
6551      * @return {@code true} if the default implementation of
6552      * {@link #fitSystemWindows(Rect)} will be executed.
6553      *
6554      * @attr ref android.R.styleable#View_fitsSystemWindows
6555      * @see #setFitsSystemWindows(boolean)
6556      * @see #fitSystemWindows(Rect)
6557      * @see #setSystemUiVisibility(int)
6558      */
6559     public boolean getFitsSystemWindows() {
6560         return (mViewFlags & FITS_SYSTEM_WINDOWS) == FITS_SYSTEM_WINDOWS;
6561     }
6562
6563     /** @hide */
6564     public boolean fitsSystemWindows() {
6565         return getFitsSystemWindows();
6566     }
6567
6568     /**
6569      * Ask that a new dispatch of {@link #fitSystemWindows(Rect)} be performed.
6570      * @deprecated Use {@link #requestApplyInsets()} for newer platform versions.
6571      */
6572     public void requestFitSystemWindows() {
6573         if (mParent != null) {
6574             mParent.requestFitSystemWindows();
6575         }
6576     }
6577
6578     /**
6579      * Ask that a new dispatch of {@link #onApplyWindowInsets(WindowInsets)} be performed.
6580      */
6581     public void requestApplyInsets() {
6582         requestFitSystemWindows();
6583     }
6584
6585     /**
6586      * For use by PhoneWindow to make its own system window fitting optional.
6587      * @hide
6588      */
6589     public void makeOptionalFitsSystemWindows() {
6590         setFlags(OPTIONAL_FITS_SYSTEM_WINDOWS, OPTIONAL_FITS_SYSTEM_WINDOWS);
6591     }
6592
6593     /**
6594      * Returns the visibility status for this view.
6595      *
6596      * @return One of {@link #VISIBLE}, {@link #INVISIBLE}, or {@link #GONE}.
6597      * @attr ref android.R.styleable#View_visibility
6598      */
6599     @ViewDebug.ExportedProperty(mapping = {
6600         @ViewDebug.IntToString(from = VISIBLE,   to = "VISIBLE"),
6601         @ViewDebug.IntToString(from = INVISIBLE, to = "INVISIBLE"),
6602         @ViewDebug.IntToString(from = GONE,      to = "GONE")
6603     })
6604     @Visibility
6605     public int getVisibility() {
6606         return mViewFlags & VISIBILITY_MASK;
6607     }
6608
6609     /**
6610      * Set the enabled state of this view.
6611      *
6612      * @param visibility One of {@link #VISIBLE}, {@link #INVISIBLE}, or {@link #GONE}.
6613      * @attr ref android.R.styleable#View_visibility
6614      */
6615     @RemotableViewMethod
6616     public void setVisibility(@Visibility int visibility) {
6617         setFlags(visibility, VISIBILITY_MASK);
6618         if (mBackground != null) mBackground.setVisible(visibility == VISIBLE, false);
6619     }
6620
6621     /**
6622      * Returns the enabled status for this view. The interpretation of the
6623      * enabled state varies by subclass.
6624      *
6625      * @return True if this view is enabled, false otherwise.
6626      */
6627     @ViewDebug.ExportedProperty
6628     public boolean isEnabled() {
6629         return (mViewFlags & ENABLED_MASK) == ENABLED;
6630     }
6631
6632     /**
6633      * Set the enabled state of this view. The interpretation of the enabled
6634      * state varies by subclass.
6635      *
6636      * @param enabled True if this view is enabled, false otherwise.
6637      */
6638     @RemotableViewMethod
6639     public void setEnabled(boolean enabled) {
6640         if (enabled == isEnabled()) return;
6641
6642         setFlags(enabled ? ENABLED : DISABLED, ENABLED_MASK);
6643
6644         /*
6645          * The View most likely has to change its appearance, so refresh
6646          * the drawable state.
6647          */
6648         refreshDrawableState();
6649
6650         // Invalidate too, since the default behavior for views is to be
6651         // be drawn at 50% alpha rather than to change the drawable.
6652         invalidate(true);
6653
6654         if (!enabled) {
6655             cancelPendingInputEvents();
6656         }
6657     }
6658
6659     /**
6660      * Set whether this view can receive the focus.
6661      *
6662      * Setting this to false will also ensure that this view is not focusable
6663      * in touch mode.
6664      *
6665      * @param focusable If true, this view can receive the focus.
6666      *
6667      * @see #setFocusableInTouchMode(boolean)
6668      * @attr ref android.R.styleable#View_focusable
6669      */
6670     public void setFocusable(boolean focusable) {
6671         if (!focusable) {
6672             setFlags(0, FOCUSABLE_IN_TOUCH_MODE);
6673         }
6674         setFlags(focusable ? FOCUSABLE : NOT_FOCUSABLE, FOCUSABLE_MASK);
6675     }
6676
6677     /**
6678      * Set whether this view can receive focus while in touch mode.
6679      *
6680      * Setting this to true will also ensure that this view is focusable.
6681      *
6682      * @param focusableInTouchMode If true, this view can receive the focus while
6683      *   in touch mode.
6684      *
6685      * @see #setFocusable(boolean)
6686      * @attr ref android.R.styleable#View_focusableInTouchMode
6687      */
6688     public void setFocusableInTouchMode(boolean focusableInTouchMode) {
6689         // Focusable in touch mode should always be set before the focusable flag
6690         // otherwise, setting the focusable flag will trigger a focusableViewAvailable()
6691         // which, in touch mode, will not successfully request focus on this view
6692         // because the focusable in touch mode flag is not set
6693         setFlags(focusableInTouchMode ? FOCUSABLE_IN_TOUCH_MODE : 0, FOCUSABLE_IN_TOUCH_MODE);
6694         if (focusableInTouchMode) {
6695             setFlags(FOCUSABLE, FOCUSABLE_MASK);
6696         }
6697     }
6698
6699     /**
6700      * Set whether this view should have sound effects enabled for events such as
6701      * clicking and touching.
6702      *
6703      * <p>You may wish to disable sound effects for a view if you already play sounds,
6704      * for instance, a dial key that plays dtmf tones.
6705      *
6706      * @param soundEffectsEnabled whether sound effects are enabled for this view.
6707      * @see #isSoundEffectsEnabled()
6708      * @see #playSoundEffect(int)
6709      * @attr ref android.R.styleable#View_soundEffectsEnabled
6710      */
6711     public void setSoundEffectsEnabled(boolean soundEffectsEnabled) {
6712         setFlags(soundEffectsEnabled ? SOUND_EFFECTS_ENABLED: 0, SOUND_EFFECTS_ENABLED);
6713     }
6714
6715     /**
6716      * @return whether this view should have sound effects enabled for events such as
6717      *     clicking and touching.
6718      *
6719      * @see #setSoundEffectsEnabled(boolean)
6720      * @see #playSoundEffect(int)
6721      * @attr ref android.R.styleable#View_soundEffectsEnabled
6722      */
6723     @ViewDebug.ExportedProperty
6724     public boolean isSoundEffectsEnabled() {
6725         return SOUND_EFFECTS_ENABLED == (mViewFlags & SOUND_EFFECTS_ENABLED);
6726     }
6727
6728     /**
6729      * Set whether this view should have haptic feedback for events such as
6730      * long presses.
6731      *
6732      * <p>You may wish to disable haptic feedback if your view already controls
6733      * its own haptic feedback.
6734      *
6735      * @param hapticFeedbackEnabled whether haptic feedback enabled for this view.
6736      * @see #isHapticFeedbackEnabled()
6737      * @see #performHapticFeedback(int)
6738      * @attr ref android.R.styleable#View_hapticFeedbackEnabled
6739      */
6740     public void setHapticFeedbackEnabled(boolean hapticFeedbackEnabled) {
6741         setFlags(hapticFeedbackEnabled ? HAPTIC_FEEDBACK_ENABLED: 0, HAPTIC_FEEDBACK_ENABLED);
6742     }
6743
6744     /**
6745      * @return whether this view should have haptic feedback enabled for events
6746      * long presses.
6747      *
6748      * @see #setHapticFeedbackEnabled(boolean)
6749      * @see #performHapticFeedback(int)
6750      * @attr ref android.R.styleable#View_hapticFeedbackEnabled
6751      */
6752     @ViewDebug.ExportedProperty
6753     public boolean isHapticFeedbackEnabled() {
6754         return HAPTIC_FEEDBACK_ENABLED == (mViewFlags & HAPTIC_FEEDBACK_ENABLED);
6755     }
6756
6757     /**
6758      * Returns the layout direction for this view.
6759      *
6760      * @return One of {@link #LAYOUT_DIRECTION_LTR},
6761      *   {@link #LAYOUT_DIRECTION_RTL},
6762      *   {@link #LAYOUT_DIRECTION_INHERIT} or
6763      *   {@link #LAYOUT_DIRECTION_LOCALE}.
6764      *
6765      * @attr ref android.R.styleable#View_layoutDirection
6766      *
6767      * @hide
6768      */
6769     @ViewDebug.ExportedProperty(category = "layout", mapping = {
6770         @ViewDebug.IntToString(from = LAYOUT_DIRECTION_LTR,     to = "LTR"),
6771         @ViewDebug.IntToString(from = LAYOUT_DIRECTION_RTL,     to = "RTL"),
6772         @ViewDebug.IntToString(from = LAYOUT_DIRECTION_INHERIT, to = "INHERIT"),
6773         @ViewDebug.IntToString(from = LAYOUT_DIRECTION_LOCALE,  to = "LOCALE")
6774     })
6775     @LayoutDir
6776     public int getRawLayoutDirection() {
6777         return (mPrivateFlags2 & PFLAG2_LAYOUT_DIRECTION_MASK) >> PFLAG2_LAYOUT_DIRECTION_MASK_SHIFT;
6778     }
6779
6780     /**
6781      * Set the layout direction for this view. This will propagate a reset of layout direction
6782      * resolution to the view's children and resolve layout direction for this view.
6783      *
6784      * @param layoutDirection the layout direction to set. Should be one of:
6785      *
6786      * {@link #LAYOUT_DIRECTION_LTR},
6787      * {@link #LAYOUT_DIRECTION_RTL},
6788      * {@link #LAYOUT_DIRECTION_INHERIT},
6789      * {@link #LAYOUT_DIRECTION_LOCALE}.
6790      *
6791      * Resolution will be done if the value is set to LAYOUT_DIRECTION_INHERIT. The resolution
6792      * proceeds up the parent chain of the view to get the value. If there is no parent, then it
6793      * will return the default {@link #LAYOUT_DIRECTION_LTR}.
6794      *
6795      * @attr ref android.R.styleable#View_layoutDirection
6796      */
6797     @RemotableViewMethod
6798     public void setLayoutDirection(@LayoutDir int layoutDirection) {
6799         if (getRawLayoutDirection() != layoutDirection) {
6800             // Reset the current layout direction and the resolved one
6801             mPrivateFlags2 &= ~PFLAG2_LAYOUT_DIRECTION_MASK;
6802             resetRtlProperties();
6803             // Set the new layout direction (filtered)
6804             mPrivateFlags2 |=
6805                     ((layoutDirection << PFLAG2_LAYOUT_DIRECTION_MASK_SHIFT) & PFLAG2_LAYOUT_DIRECTION_MASK);
6806             // We need to resolve all RTL properties as they all depend on layout direction
6807             resolveRtlPropertiesIfNeeded();
6808             requestLayout();
6809             invalidate(true);
6810         }
6811     }
6812
6813     /**
6814      * Returns the resolved layout direction for this view.
6815      *
6816      * @return {@link #LAYOUT_DIRECTION_RTL} if the layout direction is RTL or returns
6817      * {@link #LAYOUT_DIRECTION_LTR} if the layout direction is not RTL.
6818      *
6819      * For compatibility, this will return {@link #LAYOUT_DIRECTION_LTR} if API version
6820      * is lower than {@link android.os.Build.VERSION_CODES#JELLY_BEAN_MR1}.
6821      *
6822      * @attr ref android.R.styleable#View_layoutDirection
6823      */
6824     @ViewDebug.ExportedProperty(category = "layout", mapping = {
6825         @ViewDebug.IntToString(from = LAYOUT_DIRECTION_LTR, to = "RESOLVED_DIRECTION_LTR"),
6826         @ViewDebug.IntToString(from = LAYOUT_DIRECTION_RTL, to = "RESOLVED_DIRECTION_RTL")
6827     })
6828     @ResolvedLayoutDir
6829     public int getLayoutDirection() {
6830         final int targetSdkVersion = getContext().getApplicationInfo().targetSdkVersion;
6831         if (targetSdkVersion < JELLY_BEAN_MR1) {
6832             mPrivateFlags2 |= PFLAG2_LAYOUT_DIRECTION_RESOLVED;
6833             return LAYOUT_DIRECTION_RESOLVED_DEFAULT;
6834         }
6835         return ((mPrivateFlags2 & PFLAG2_LAYOUT_DIRECTION_RESOLVED_RTL) ==
6836                 PFLAG2_LAYOUT_DIRECTION_RESOLVED_RTL) ? LAYOUT_DIRECTION_RTL : LAYOUT_DIRECTION_LTR;
6837     }
6838
6839     /**
6840      * Indicates whether or not this view's layout is right-to-left. This is resolved from
6841      * layout attribute and/or the inherited value from the parent
6842      *
6843      * @return true if the layout is right-to-left.
6844      *
6845      * @hide
6846      */
6847     @ViewDebug.ExportedProperty(category = "layout")
6848     public boolean isLayoutRtl() {
6849         return (getLayoutDirection() == LAYOUT_DIRECTION_RTL);
6850     }
6851
6852     /**
6853      * Indicates whether the view is currently tracking transient state that the
6854      * app should not need to concern itself with saving and restoring, but that
6855      * the framework should take special note to preserve when possible.
6856      *
6857      * <p>A view with transient state cannot be trivially rebound from an external
6858      * data source, such as an adapter binding item views in a list. This may be
6859      * because the view is performing an animation, tracking user selection
6860      * of content, or similar.</p>
6861      *
6862      * @return true if the view has transient state
6863      */
6864     @ViewDebug.ExportedProperty(category = "layout")
6865     public boolean hasTransientState() {
6866         return (mPrivateFlags2 & PFLAG2_HAS_TRANSIENT_STATE) == PFLAG2_HAS_TRANSIENT_STATE;
6867     }
6868
6869     /**
6870      * Set whether this view is currently tracking transient state that the
6871      * framework should attempt to preserve when possible. This flag is reference counted,
6872      * so every call to setHasTransientState(true) should be paired with a later call
6873      * to setHasTransientState(false).
6874      *
6875      * <p>A view with transient state cannot be trivially rebound from an external
6876      * data source, such as an adapter binding item views in a list. This may be
6877      * because the view is performing an animation, tracking user selection
6878      * of content, or similar.</p>
6879      *
6880      * @param hasTransientState true if this view has transient state
6881      */
6882     public void setHasTransientState(boolean hasTransientState) {
6883         mTransientStateCount = hasTransientState ? mTransientStateCount + 1 :
6884                 mTransientStateCount - 1;
6885         if (mTransientStateCount < 0) {
6886             mTransientStateCount = 0;
6887             Log.e(VIEW_LOG_TAG, "hasTransientState decremented below 0: " +
6888                     "unmatched pair of setHasTransientState calls");
6889         } else if ((hasTransientState && mTransientStateCount == 1) ||
6890                 (!hasTransientState && mTransientStateCount == 0)) {
6891             // update flag if we've just incremented up from 0 or decremented down to 0
6892             mPrivateFlags2 = (mPrivateFlags2 & ~PFLAG2_HAS_TRANSIENT_STATE) |
6893                     (hasTransientState ? PFLAG2_HAS_TRANSIENT_STATE : 0);
6894             if (mParent != null) {
6895                 try {
6896                     mParent.childHasTransientStateChanged(this, hasTransientState);
6897                 } catch (AbstractMethodError e) {
6898                     Log.e(VIEW_LOG_TAG, mParent.getClass().getSimpleName() +
6899                             " does not fully implement ViewParent", e);
6900                 }
6901             }
6902         }
6903     }
6904
6905     /**
6906      * Returns true if this view is currently attached to a window.
6907      */
6908     public boolean isAttachedToWindow() {
6909         return mAttachInfo != null;
6910     }
6911
6912     /**
6913      * Returns true if this view has been through at least one layout since it
6914      * was last attached to or detached from a window.
6915      */
6916     public boolean isLaidOut() {
6917         return (mPrivateFlags3 & PFLAG3_IS_LAID_OUT) == PFLAG3_IS_LAID_OUT;
6918     }
6919
6920     /**
6921      * If this view doesn't do any drawing on its own, set this flag to
6922      * allow further optimizations. By default, this flag is not set on
6923      * View, but could be set on some View subclasses such as ViewGroup.
6924      *
6925      * Typically, if you override {@link #onDraw(android.graphics.Canvas)}
6926      * you should clear this flag.
6927      *
6928      * @param willNotDraw whether or not this View draw on its own
6929      */
6930     public void setWillNotDraw(boolean willNotDraw) {
6931         setFlags(willNotDraw ? WILL_NOT_DRAW : 0, DRAW_MASK);
6932     }
6933
6934     /**
6935      * Returns whether or not this View draws on its own.
6936      *
6937      * @return true if this view has nothing to draw, false otherwise
6938      */
6939     @ViewDebug.ExportedProperty(category = "drawing")
6940     public boolean willNotDraw() {
6941         return (mViewFlags & DRAW_MASK) == WILL_NOT_DRAW;
6942     }
6943
6944     /**
6945      * When a View's drawing cache is enabled, drawing is redirected to an
6946      * offscreen bitmap. Some views, like an ImageView, must be able to
6947      * bypass this mechanism if they already draw a single bitmap, to avoid
6948      * unnecessary usage of the memory.
6949      *
6950      * @param willNotCacheDrawing true if this view does not cache its
6951      *        drawing, false otherwise
6952      */
6953     public void setWillNotCacheDrawing(boolean willNotCacheDrawing) {
6954         setFlags(willNotCacheDrawing ? WILL_NOT_CACHE_DRAWING : 0, WILL_NOT_CACHE_DRAWING);
6955     }
6956
6957     /**
6958      * Returns whether or not this View can cache its drawing or not.
6959      *
6960      * @return true if this view does not cache its drawing, false otherwise
6961      */
6962     @ViewDebug.ExportedProperty(category = "drawing")
6963     public boolean willNotCacheDrawing() {
6964         return (mViewFlags & WILL_NOT_CACHE_DRAWING) == WILL_NOT_CACHE_DRAWING;
6965     }
6966
6967     /**
6968      * Indicates whether this view reacts to click events or not.
6969      *
6970      * @return true if the view is clickable, false otherwise
6971      *
6972      * @see #setClickable(boolean)
6973      * @attr ref android.R.styleable#View_clickable
6974      */
6975     @ViewDebug.ExportedProperty
6976     public boolean isClickable() {
6977         return (mViewFlags & CLICKABLE) == CLICKABLE;
6978     }
6979
6980     /**
6981      * Enables or disables click events for this view. When a view
6982      * is clickable it will change its state to "pressed" on every click.
6983      * Subclasses should set the view clickable to visually react to
6984      * user's clicks.
6985      *
6986      * @param clickable true to make the view clickable, false otherwise
6987      *
6988      * @see #isClickable()
6989      * @attr ref android.R.styleable#View_clickable
6990      */
6991     public void setClickable(boolean clickable) {
6992         setFlags(clickable ? CLICKABLE : 0, CLICKABLE);
6993     }
6994
6995     /**
6996      * Indicates whether this view reacts to long click events or not.
6997      *
6998      * @return true if the view is long clickable, false otherwise
6999      *
7000      * @see #setLongClickable(boolean)
7001      * @attr ref android.R.styleable#View_longClickable
7002      */
7003     public boolean isLongClickable() {
7004         return (mViewFlags & LONG_CLICKABLE) == LONG_CLICKABLE;
7005     }
7006
7007     /**
7008      * Enables or disables long click events for this view. When a view is long
7009      * clickable it reacts to the user holding down the button for a longer
7010      * duration than a tap. This event can either launch the listener or a
7011      * context menu.
7012      *
7013      * @param longClickable true to make the view long clickable, false otherwise
7014      * @see #isLongClickable()
7015      * @attr ref android.R.styleable#View_longClickable
7016      */
7017     public void setLongClickable(boolean longClickable) {
7018         setFlags(longClickable ? LONG_CLICKABLE : 0, LONG_CLICKABLE);
7019     }
7020
7021     /**
7022      * Sets the pressed state for this view and provides a touch coordinate for
7023      * animation hinting.
7024      *
7025      * @param pressed Pass true to set the View's internal state to "pressed",
7026      *            or false to reverts the View's internal state from a
7027      *            previously set "pressed" state.
7028      * @param x The x coordinate of the touch that caused the press
7029      * @param y The y coordinate of the touch that caused the press
7030      */
7031     private void setPressed(boolean pressed, float x, float y) {
7032         if (pressed) {
7033             drawableHotspotChanged(x, y);
7034         }
7035
7036         setPressed(pressed);
7037     }
7038
7039     /**
7040      * Sets the pressed state for this view.
7041      *
7042      * @see #isClickable()
7043      * @see #setClickable(boolean)
7044      *
7045      * @param pressed Pass true to set the View's internal state to "pressed", or false to reverts
7046      *        the View's internal state from a previously set "pressed" state.
7047      */
7048     public void setPressed(boolean pressed) {
7049         final boolean needsRefresh = pressed != ((mPrivateFlags & PFLAG_PRESSED) == PFLAG_PRESSED);
7050
7051         if (pressed) {
7052             mPrivateFlags |= PFLAG_PRESSED;
7053         } else {
7054             mPrivateFlags &= ~PFLAG_PRESSED;
7055         }
7056
7057         if (needsRefresh) {
7058             refreshDrawableState();
7059         }
7060         dispatchSetPressed(pressed);
7061     }
7062
7063     /**
7064      * Dispatch setPressed to all of this View's children.
7065      *
7066      * @see #setPressed(boolean)
7067      *
7068      * @param pressed The new pressed state
7069      */
7070     protected void dispatchSetPressed(boolean pressed) {
7071     }
7072
7073     /**
7074      * Indicates whether the view is currently in pressed state. Unless
7075      * {@link #setPressed(boolean)} is explicitly called, only clickable views can enter
7076      * the pressed state.
7077      *
7078      * @see #setPressed(boolean)
7079      * @see #isClickable()
7080      * @see #setClickable(boolean)
7081      *
7082      * @return true if the view is currently pressed, false otherwise
7083      */
7084     @ViewDebug.ExportedProperty
7085     public boolean isPressed() {
7086         return (mPrivateFlags & PFLAG_PRESSED) == PFLAG_PRESSED;
7087     }
7088
7089     /**
7090      * Indicates whether this view will save its state (that is,
7091      * whether its {@link #onSaveInstanceState} method will be called).
7092      *
7093      * @return Returns true if the view state saving is enabled, else false.
7094      *
7095      * @see #setSaveEnabled(boolean)
7096      * @attr ref android.R.styleable#View_saveEnabled
7097      */
7098     public boolean isSaveEnabled() {
7099         return (mViewFlags & SAVE_DISABLED_MASK) != SAVE_DISABLED;
7100     }
7101
7102     /**
7103      * Controls whether the saving of this view's state is
7104      * enabled (that is, whether its {@link #onSaveInstanceState} method
7105      * will be called).  Note that even if freezing is enabled, the
7106      * view still must have an id assigned to it (via {@link #setId(int)})
7107      * for its state to be saved.  This flag can only disable the
7108      * saving of this view; any child views may still have their state saved.
7109      *
7110      * @param enabled Set to false to <em>disable</em> state saving, or true
7111      * (the default) to allow it.
7112      *
7113      * @see #isSaveEnabled()
7114      * @see #setId(int)
7115      * @see #onSaveInstanceState()
7116      * @attr ref android.R.styleable#View_saveEnabled
7117      */
7118     public void setSaveEnabled(boolean enabled) {
7119         setFlags(enabled ? 0 : SAVE_DISABLED, SAVE_DISABLED_MASK);
7120     }
7121
7122     /**
7123      * Gets whether the framework should discard touches when the view's
7124      * window is obscured by another visible window.
7125      * Refer to the {@link View} security documentation for more details.
7126      *
7127      * @return True if touch filtering is enabled.
7128      *
7129      * @see #setFilterTouchesWhenObscured(boolean)
7130      * @attr ref android.R.styleable#View_filterTouchesWhenObscured
7131      */
7132     @ViewDebug.ExportedProperty
7133     public boolean getFilterTouchesWhenObscured() {
7134         return (mViewFlags & FILTER_TOUCHES_WHEN_OBSCURED) != 0;
7135     }
7136
7137     /**
7138      * Sets whether the framework should discard touches when the view's
7139      * window is obscured by another visible window.
7140      * Refer to the {@link View} security documentation for more details.
7141      *
7142      * @param enabled True if touch filtering should be enabled.
7143      *
7144      * @see #getFilterTouchesWhenObscured
7145      * @attr ref android.R.styleable#View_filterTouchesWhenObscured
7146      */
7147     public void setFilterTouchesWhenObscured(boolean enabled) {
7148         setFlags(enabled ? FILTER_TOUCHES_WHEN_OBSCURED : 0,
7149                 FILTER_TOUCHES_WHEN_OBSCURED);
7150     }
7151
7152     /**
7153      * Indicates whether the entire hierarchy under this view will save its
7154      * state when a state saving traversal occurs from its parent.  The default
7155      * is true; if false, these views will not be saved unless
7156      * {@link #saveHierarchyState(SparseArray)} is called directly on this view.
7157      *
7158      * @return Returns true if the view state saving from parent is enabled, else false.
7159      *
7160      * @see #setSaveFromParentEnabled(boolean)
7161      */
7162     public boolean isSaveFromParentEnabled() {
7163         return (mViewFlags & PARENT_SAVE_DISABLED_MASK) != PARENT_SAVE_DISABLED;
7164     }
7165
7166     /**
7167      * Controls whether the entire hierarchy under this view will save its
7168      * state when a state saving traversal occurs from its parent.  The default
7169      * is true; if false, these views will not be saved unless
7170      * {@link #saveHierarchyState(SparseArray)} is called directly on this view.
7171      *
7172      * @param enabled Set to false to <em>disable</em> state saving, or true
7173      * (the default) to allow it.
7174      *
7175      * @see #isSaveFromParentEnabled()
7176      * @see #setId(int)
7177      * @see #onSaveInstanceState()
7178      */
7179     public void setSaveFromParentEnabled(boolean enabled) {
7180         setFlags(enabled ? 0 : PARENT_SAVE_DISABLED, PARENT_SAVE_DISABLED_MASK);
7181     }
7182
7183
7184     /**
7185      * Returns whether this View is able to take focus.
7186      *
7187      * @return True if this view can take focus, or false otherwise.
7188      * @attr ref android.R.styleable#View_focusable
7189      */
7190     @ViewDebug.ExportedProperty(category = "focus")
7191     public final boolean isFocusable() {
7192         return FOCUSABLE == (mViewFlags & FOCUSABLE_MASK);
7193     }
7194
7195     /**
7196      * When a view is focusable, it may not want to take focus when in touch mode.
7197      * For example, a button would like focus when the user is navigating via a D-pad
7198      * so that the user can click on it, but once the user starts touching the screen,
7199      * the button shouldn't take focus
7200      * @return Whether the view is focusable in touch mode.
7201      * @attr ref android.R.styleable#View_focusableInTouchMode
7202      */
7203     @ViewDebug.ExportedProperty
7204     public final boolean isFocusableInTouchMode() {
7205         return FOCUSABLE_IN_TOUCH_MODE == (mViewFlags & FOCUSABLE_IN_TOUCH_MODE);
7206     }
7207
7208     /**
7209      * Find the nearest view in the specified direction that can take focus.
7210      * This does not actually give focus to that view.
7211      *
7212      * @param direction One of FOCUS_UP, FOCUS_DOWN, FOCUS_LEFT, and FOCUS_RIGHT
7213      *
7214      * @return The nearest focusable in the specified direction, or null if none
7215      *         can be found.
7216      */
7217     public View focusSearch(@FocusRealDirection int direction) {
7218         if (mParent != null) {
7219             return mParent.focusSearch(this, direction);
7220         } else {
7221             return null;
7222         }
7223     }
7224
7225     /**
7226      * This method is the last chance for the focused view and its ancestors to
7227      * respond to an arrow key. This is called when the focused view did not
7228      * consume the key internally, nor could the view system find a new view in
7229      * the requested direction to give focus to.
7230      *
7231      * @param focused The currently focused view.
7232      * @param direction The direction focus wants to move. One of FOCUS_UP,
7233      *        FOCUS_DOWN, FOCUS_LEFT, and FOCUS_RIGHT.
7234      * @return True if the this view consumed this unhandled move.
7235      */
7236     public boolean dispatchUnhandledMove(View focused, @FocusRealDirection int direction) {
7237         return false;
7238     }
7239
7240     /**
7241      * If a user manually specified the next view id for a particular direction,
7242      * use the root to look up the view.
7243      * @param root The root view of the hierarchy containing this view.
7244      * @param direction One of FOCUS_UP, FOCUS_DOWN, FOCUS_LEFT, FOCUS_RIGHT, FOCUS_FORWARD,
7245      * or FOCUS_BACKWARD.
7246      * @return The user specified next view, or null if there is none.
7247      */
7248     View findUserSetNextFocus(View root, @FocusDirection int direction) {
7249         switch (direction) {
7250             case FOCUS_LEFT:
7251                 if (mNextFocusLeftId == View.NO_ID) return null;
7252                 return findViewInsideOutShouldExist(root, mNextFocusLeftId);
7253             case FOCUS_RIGHT:
7254                 if (mNextFocusRightId == View.NO_ID) return null;
7255                 return findViewInsideOutShouldExist(root, mNextFocusRightId);
7256             case FOCUS_UP:
7257                 if (mNextFocusUpId == View.NO_ID) return null;
7258                 return findViewInsideOutShouldExist(root, mNextFocusUpId);
7259             case FOCUS_DOWN:
7260                 if (mNextFocusDownId == View.NO_ID) return null;
7261                 return findViewInsideOutShouldExist(root, mNextFocusDownId);
7262             case FOCUS_FORWARD:
7263                 if (mNextFocusForwardId == View.NO_ID) return null;
7264                 return findViewInsideOutShouldExist(root, mNextFocusForwardId);
7265             case FOCUS_BACKWARD: {
7266                 if (mID == View.NO_ID) return null;
7267                 final int id = mID;
7268                 return root.findViewByPredicateInsideOut(this, new Predicate<View>() {
7269                     @Override
7270                     public boolean apply(View t) {
7271                         return t.mNextFocusForwardId == id;
7272                     }
7273                 });
7274             }
7275         }
7276         return null;
7277     }
7278
7279     private View findViewInsideOutShouldExist(View root, int id) {
7280         if (mMatchIdPredicate == null) {
7281             mMatchIdPredicate = new MatchIdPredicate();
7282         }
7283         mMatchIdPredicate.mId = id;
7284         View result = root.findViewByPredicateInsideOut(this, mMatchIdPredicate);
7285         if (result == null) {
7286             Log.w(VIEW_LOG_TAG, "couldn't find view with id " + id);
7287         }
7288         return result;
7289     }
7290
7291     /**
7292      * Find and return all focusable views that are descendants of this view,
7293      * possibly including this view if it is focusable itself.
7294      *
7295      * @param direction The direction of the focus
7296      * @return A list of focusable views
7297      */
7298     public ArrayList<View> getFocusables(@FocusDirection int direction) {
7299         ArrayList<View> result = new ArrayList<View>(24);
7300         addFocusables(result, direction);
7301         return result;
7302     }
7303
7304     /**
7305      * Add any focusable views that are descendants of this view (possibly
7306      * including this view if it is focusable itself) to views.  If we are in touch mode,
7307      * only add views that are also focusable in touch mode.
7308      *
7309      * @param views Focusable views found so far
7310      * @param direction The direction of the focus
7311      */
7312     public void addFocusables(ArrayList<View> views, @FocusDirection int direction) {
7313         addFocusables(views, direction, FOCUSABLES_TOUCH_MODE);
7314     }
7315
7316     /**
7317      * Adds any focusable views that are descendants of this view (possibly
7318      * including this view if it is focusable itself) to views. This method
7319      * adds all focusable views regardless if we are in touch mode or
7320      * only views focusable in touch mode if we are in touch mode or
7321      * only views that can take accessibility focus if accessibility is enabeld
7322      * depending on the focusable mode paramater.
7323      *
7324      * @param views Focusable views found so far or null if all we are interested is
7325      *        the number of focusables.
7326      * @param direction The direction of the focus.
7327      * @param focusableMode The type of focusables to be added.
7328      *
7329      * @see #FOCUSABLES_ALL
7330      * @see #FOCUSABLES_TOUCH_MODE
7331      */
7332     public void addFocusables(ArrayList<View> views, @FocusDirection int direction,
7333             @FocusableMode int focusableMode) {
7334         if (views == null) {
7335             return;
7336         }
7337         if (!isFocusable()) {
7338             return;
7339         }
7340         if ((focusableMode & FOCUSABLES_TOUCH_MODE) == FOCUSABLES_TOUCH_MODE
7341                 && isInTouchMode() && !isFocusableInTouchMode()) {
7342             return;
7343         }
7344         views.add(this);
7345     }
7346
7347     /**
7348      * Finds the Views that contain given text. The containment is case insensitive.
7349      * The search is performed by either the text that the View renders or the content
7350      * description that describes the view for accessibility purposes and the view does
7351      * not render or both. Clients can specify how the search is to be performed via
7352      * passing the {@link #FIND_VIEWS_WITH_TEXT} and
7353      * {@link #FIND_VIEWS_WITH_CONTENT_DESCRIPTION} flags.
7354      *
7355      * @param outViews The output list of matching Views.
7356      * @param searched The text to match against.
7357      *
7358      * @see #FIND_VIEWS_WITH_TEXT
7359      * @see #FIND_VIEWS_WITH_CONTENT_DESCRIPTION
7360      * @see #setContentDescription(CharSequence)
7361      */
7362     public void findViewsWithText(ArrayList<View> outViews, CharSequence searched,
7363             @FindViewFlags int flags) {
7364         if (getAccessibilityNodeProvider() != null) {
7365             if ((flags & FIND_VIEWS_WITH_ACCESSIBILITY_NODE_PROVIDERS) != 0) {
7366                 outViews.add(this);
7367             }
7368         } else if ((flags & FIND_VIEWS_WITH_CONTENT_DESCRIPTION) != 0
7369                 && (searched != null && searched.length() > 0)
7370                 && (mContentDescription != null && mContentDescription.length() > 0)) {
7371             String searchedLowerCase = searched.toString().toLowerCase();
7372             String contentDescriptionLowerCase = mContentDescription.toString().toLowerCase();
7373             if (contentDescriptionLowerCase.contains(searchedLowerCase)) {
7374                 outViews.add(this);
7375             }
7376         }
7377     }
7378
7379     /**
7380      * Find and return all touchable views that are descendants of this view,
7381      * possibly including this view if it is touchable itself.
7382      *
7383      * @return A list of touchable views
7384      */
7385     public ArrayList<View> getTouchables() {
7386         ArrayList<View> result = new ArrayList<View>();
7387         addTouchables(result);
7388         return result;
7389     }
7390
7391     /**
7392      * Add any touchable views that are descendants of this view (possibly
7393      * including this view if it is touchable itself) to views.
7394      *
7395      * @param views Touchable views found so far
7396      */
7397     public void addTouchables(ArrayList<View> views) {
7398         final int viewFlags = mViewFlags;
7399
7400         if (((viewFlags & CLICKABLE) == CLICKABLE || (viewFlags & LONG_CLICKABLE) == LONG_CLICKABLE)
7401                 && (viewFlags & ENABLED_MASK) == ENABLED) {
7402             views.add(this);
7403         }
7404     }
7405
7406     /**
7407      * Returns whether this View is accessibility focused.
7408      *
7409      * @return True if this View is accessibility focused.
7410      */
7411     public boolean isAccessibilityFocused() {
7412         return (mPrivateFlags2 & PFLAG2_ACCESSIBILITY_FOCUSED) != 0;
7413     }
7414
7415     /**
7416      * Call this to try to give accessibility focus to this view.
7417      *
7418      * A view will not actually take focus if {@link AccessibilityManager#isEnabled()}
7419      * returns false or the view is no visible or the view already has accessibility
7420      * focus.
7421      *
7422      * See also {@link #focusSearch(int)}, which is what you call to say that you
7423      * have focus, and you want your parent to look for the next one.
7424      *
7425      * @return Whether this view actually took accessibility focus.
7426      *
7427      * @hide
7428      */
7429     public boolean requestAccessibilityFocus() {
7430         AccessibilityManager manager = AccessibilityManager.getInstance(mContext);
7431         if (!manager.isEnabled() || !manager.isTouchExplorationEnabled()) {
7432             return false;
7433         }
7434         if ((mViewFlags & VISIBILITY_MASK) != VISIBLE) {
7435             return false;
7436         }
7437         if ((mPrivateFlags2 & PFLAG2_ACCESSIBILITY_FOCUSED) == 0) {
7438             mPrivateFlags2 |= PFLAG2_ACCESSIBILITY_FOCUSED;
7439             ViewRootImpl viewRootImpl = getViewRootImpl();
7440             if (viewRootImpl != null) {
7441                 viewRootImpl.setAccessibilityFocus(this, null);
7442             }
7443             invalidate();
7444             sendAccessibilityEvent(AccessibilityEvent.TYPE_VIEW_ACCESSIBILITY_FOCUSED);
7445             return true;
7446         }
7447         return false;
7448     }
7449
7450     /**
7451      * Call this to try to clear accessibility focus of this view.
7452      *
7453      * See also {@link #focusSearch(int)}, which is what you call to say that you
7454      * have focus, and you want your parent to look for the next one.
7455      *
7456      * @hide
7457      */
7458     public void clearAccessibilityFocus() {
7459         clearAccessibilityFocusNoCallbacks();
7460         // Clear the global reference of accessibility focus if this
7461         // view or any of its descendants had accessibility focus.
7462         ViewRootImpl viewRootImpl = getViewRootImpl();
7463         if (viewRootImpl != null) {
7464             View focusHost = viewRootImpl.getAccessibilityFocusedHost();
7465             if (focusHost != null && ViewRootImpl.isViewDescendantOf(focusHost, this)) {
7466                 viewRootImpl.setAccessibilityFocus(null, null);
7467             }
7468         }
7469     }
7470
7471     private void sendAccessibilityHoverEvent(int eventType) {
7472         // Since we are not delivering to a client accessibility events from not
7473         // important views (unless the clinet request that) we need to fire the
7474         // event from the deepest view exposed to the client. As a consequence if
7475         // the user crosses a not exposed view the client will see enter and exit
7476         // of the exposed predecessor followed by and enter and exit of that same
7477         // predecessor when entering and exiting the not exposed descendant. This
7478         // is fine since the client has a clear idea which view is hovered at the
7479         // price of a couple more events being sent. This is a simple and
7480         // working solution.
7481         View source = this;
7482         while (true) {
7483             if (source.includeForAccessibility()) {
7484                 source.sendAccessibilityEvent(eventType);
7485                 return;
7486             }
7487             ViewParent parent = source.getParent();
7488             if (parent instanceof View) {
7489                 source = (View) parent;
7490             } else {
7491                 return;
7492             }
7493         }
7494     }
7495
7496     /**
7497      * Clears accessibility focus without calling any callback methods
7498      * normally invoked in {@link #clearAccessibilityFocus()}. This method
7499      * is used for clearing accessibility focus when giving this focus to
7500      * another view.
7501      */
7502     void clearAccessibilityFocusNoCallbacks() {
7503         if ((mPrivateFlags2 & PFLAG2_ACCESSIBILITY_FOCUSED) != 0) {
7504             mPrivateFlags2 &= ~PFLAG2_ACCESSIBILITY_FOCUSED;
7505             invalidate();
7506             sendAccessibilityEvent(AccessibilityEvent.TYPE_VIEW_ACCESSIBILITY_FOCUS_CLEARED);
7507         }
7508     }
7509
7510     /**
7511      * Call this to try to give focus to a specific view or to one of its
7512      * descendants.
7513      *
7514      * A view will not actually take focus if it is not focusable ({@link #isFocusable} returns
7515      * false), or if it is focusable and it is not focusable in touch mode
7516      * ({@link #isFocusableInTouchMode}) while the device is in touch mode.
7517      *
7518      * See also {@link #focusSearch(int)}, which is what you call to say that you
7519      * have focus, and you want your parent to look for the next one.
7520      *
7521      * This is equivalent to calling {@link #requestFocus(int, Rect)} with arguments
7522      * {@link #FOCUS_DOWN} and <code>null</code>.
7523      *
7524      * @return Whether this view or one of its descendants actually took focus.
7525      */
7526     public final boolean requestFocus() {
7527         return requestFocus(View.FOCUS_DOWN);
7528     }
7529
7530     /**
7531      * Call this to try to give focus to a specific view or to one of its
7532      * descendants and give it a hint about what direction focus is heading.
7533      *
7534      * A view will not actually take focus if it is not focusable ({@link #isFocusable} returns
7535      * false), or if it is focusable and it is not focusable in touch mode
7536      * ({@link #isFocusableInTouchMode}) while the device is in touch mode.
7537      *
7538      * See also {@link #focusSearch(int)}, which is what you call to say that you
7539      * have focus, and you want your parent to look for the next one.
7540      *
7541      * This is equivalent to calling {@link #requestFocus(int, Rect)} with
7542      * <code>null</code> set for the previously focused rectangle.
7543      *
7544      * @param direction One of FOCUS_UP, FOCUS_DOWN, FOCUS_LEFT, and FOCUS_RIGHT
7545      * @return Whether this view or one of its descendants actually took focus.
7546      */
7547     public final boolean requestFocus(int direction) {
7548         return requestFocus(direction, null);
7549     }
7550
7551     /**
7552      * Call this to try to give focus to a specific view or to one of its descendants
7553      * and give it hints about the direction and a specific rectangle that the focus
7554      * is coming from.  The rectangle can help give larger views a finer grained hint
7555      * about where focus is coming from, and therefore, where to show selection, or
7556      * forward focus change internally.
7557      *
7558      * A view will not actually take focus if it is not focusable ({@link #isFocusable} returns
7559      * false), or if it is focusable and it is not focusable in touch mode
7560      * ({@link #isFocusableInTouchMode}) while the device is in touch mode.
7561      *
7562      * A View will not take focus if it is not visible.
7563      *
7564      * A View will not take focus if one of its parents has
7565      * {@link android.view.ViewGroup#getDescendantFocusability()} equal to
7566      * {@link ViewGroup#FOCUS_BLOCK_DESCENDANTS}.
7567      *
7568      * See also {@link #focusSearch(int)}, which is what you call to say that you
7569      * have focus, and you want your parent to look for the next one.
7570      *
7571      * You may wish to override this method if your custom {@link View} has an internal
7572      * {@link View} that it wishes to forward the request to.
7573      *
7574      * @param direction One of FOCUS_UP, FOCUS_DOWN, FOCUS_LEFT, and FOCUS_RIGHT
7575      * @param previouslyFocusedRect The rectangle (in this View's coordinate system)
7576      *        to give a finer grained hint about where focus is coming from.  May be null
7577      *        if there is no hint.
7578      * @return Whether this view or one of its descendants actually took focus.
7579      */
7580     public boolean requestFocus(int direction, Rect previouslyFocusedRect) {
7581         return requestFocusNoSearch(direction, previouslyFocusedRect);
7582     }
7583
7584     private boolean requestFocusNoSearch(int direction, Rect previouslyFocusedRect) {
7585         // need to be focusable
7586         if ((mViewFlags & FOCUSABLE_MASK) != FOCUSABLE ||
7587                 (mViewFlags & VISIBILITY_MASK) != VISIBLE) {
7588             return false;
7589         }
7590
7591         // need to be focusable in touch mode if in touch mode
7592         if (isInTouchMode() &&
7593             (FOCUSABLE_IN_TOUCH_MODE != (mViewFlags & FOCUSABLE_IN_TOUCH_MODE))) {
7594                return false;
7595         }
7596
7597         // need to not have any parents blocking us
7598         if (hasAncestorThatBlocksDescendantFocus()) {
7599             return false;
7600         }
7601
7602         handleFocusGainInternal(direction, previouslyFocusedRect);
7603         return true;
7604     }
7605
7606     /**
7607      * Call this to try to give focus to a specific view or to one of its descendants. This is a
7608      * special variant of {@link #requestFocus() } that will allow views that are not focuable in
7609      * touch mode to request focus when they are touched.
7610      *
7611      * @return Whether this view or one of its descendants actually took focus.
7612      *
7613      * @see #isInTouchMode()
7614      *
7615      */
7616     public final boolean requestFocusFromTouch() {
7617         // Leave touch mode if we need to
7618         if (isInTouchMode()) {
7619             ViewRootImpl viewRoot = getViewRootImpl();
7620             if (viewRoot != null) {
7621                 viewRoot.ensureTouchMode(false);
7622             }
7623         }
7624         return requestFocus(View.FOCUS_DOWN);
7625     }
7626
7627     /**
7628      * @return Whether any ancestor of this view blocks descendant focus.
7629      */
7630     private boolean hasAncestorThatBlocksDescendantFocus() {
7631         final boolean focusableInTouchMode = isFocusableInTouchMode();
7632         ViewParent ancestor = mParent;
7633         while (ancestor instanceof ViewGroup) {
7634             final ViewGroup vgAncestor = (ViewGroup) ancestor;
7635             if (vgAncestor.getDescendantFocusability() == ViewGroup.FOCUS_BLOCK_DESCENDANTS
7636                     || (!focusableInTouchMode && vgAncestor.shouldBlockFocusForTouchscreen())) {
7637                 return true;
7638             } else {
7639                 ancestor = vgAncestor.getParent();
7640             }
7641         }
7642         return false;
7643     }
7644
7645     /**
7646      * Gets the mode for determining whether this View is important for accessibility
7647      * which is if it fires accessibility events and if it is reported to
7648      * accessibility services that query the screen.
7649      *
7650      * @return The mode for determining whether a View is important for accessibility.
7651      *
7652      * @attr ref android.R.styleable#View_importantForAccessibility
7653      *
7654      * @see #IMPORTANT_FOR_ACCESSIBILITY_YES
7655      * @see #IMPORTANT_FOR_ACCESSIBILITY_NO
7656      * @see #IMPORTANT_FOR_ACCESSIBILITY_NO_HIDE_DESCENDANTS
7657      * @see #IMPORTANT_FOR_ACCESSIBILITY_AUTO
7658      */
7659     @ViewDebug.ExportedProperty(category = "accessibility", mapping = {
7660             @ViewDebug.IntToString(from = IMPORTANT_FOR_ACCESSIBILITY_AUTO, to = "auto"),
7661             @ViewDebug.IntToString(from = IMPORTANT_FOR_ACCESSIBILITY_YES, to = "yes"),
7662             @ViewDebug.IntToString(from = IMPORTANT_FOR_ACCESSIBILITY_NO, to = "no"),
7663             @ViewDebug.IntToString(from = IMPORTANT_FOR_ACCESSIBILITY_NO_HIDE_DESCENDANTS,
7664                     to = "noHideDescendants")
7665         })
7666     public int getImportantForAccessibility() {
7667         return (mPrivateFlags2 & PFLAG2_IMPORTANT_FOR_ACCESSIBILITY_MASK)
7668                 >> PFLAG2_IMPORTANT_FOR_ACCESSIBILITY_SHIFT;
7669     }
7670
7671     /**
7672      * Sets the live region mode for this view. This indicates to accessibility
7673      * services whether they should automatically notify the user about changes
7674      * to the view's content description or text, or to the content descriptions
7675      * or text of the view's children (where applicable).
7676      * <p>
7677      * For example, in a login screen with a TextView that displays an "incorrect
7678      * password" notification, that view should be marked as a live region with
7679      * mode {@link #ACCESSIBILITY_LIVE_REGION_POLITE}.
7680      * <p>
7681      * To disable change notifications for this view, use
7682      * {@link #ACCESSIBILITY_LIVE_REGION_NONE}. This is the default live region
7683      * mode for most views.
7684      * <p>
7685      * To indicate that the user should be notified of changes, use
7686      * {@link #ACCESSIBILITY_LIVE_REGION_POLITE}.
7687      * <p>
7688      * If the view's changes should interrupt ongoing speech and notify the user
7689      * immediately, use {@link #ACCESSIBILITY_LIVE_REGION_ASSERTIVE}.
7690      *
7691      * @param mode The live region mode for this view, one of:
7692      *        <ul>
7693      *        <li>{@link #ACCESSIBILITY_LIVE_REGION_NONE}
7694      *        <li>{@link #ACCESSIBILITY_LIVE_REGION_POLITE}
7695      *        <li>{@link #ACCESSIBILITY_LIVE_REGION_ASSERTIVE}
7696      *        </ul>
7697      * @attr ref android.R.styleable#View_accessibilityLiveRegion
7698      */
7699     public void setAccessibilityLiveRegion(int mode) {
7700         if (mode != getAccessibilityLiveRegion()) {
7701             mPrivateFlags2 &= ~PFLAG2_ACCESSIBILITY_LIVE_REGION_MASK;
7702             mPrivateFlags2 |= (mode << PFLAG2_ACCESSIBILITY_LIVE_REGION_SHIFT)
7703                     & PFLAG2_ACCESSIBILITY_LIVE_REGION_MASK;
7704             notifyViewAccessibilityStateChangedIfNeeded(
7705                     AccessibilityEvent.CONTENT_CHANGE_TYPE_UNDEFINED);
7706         }
7707     }
7708
7709     /**
7710      * Gets the live region mode for this View.
7711      *
7712      * @return The live region mode for the view.
7713      *
7714      * @attr ref android.R.styleable#View_accessibilityLiveRegion
7715      *
7716      * @see #setAccessibilityLiveRegion(int)
7717      */
7718     public int getAccessibilityLiveRegion() {
7719         return (mPrivateFlags2 & PFLAG2_ACCESSIBILITY_LIVE_REGION_MASK)
7720                 >> PFLAG2_ACCESSIBILITY_LIVE_REGION_SHIFT;
7721     }
7722
7723     /**
7724      * Sets how to determine whether this view is important for accessibility
7725      * which is if it fires accessibility events and if it is reported to
7726      * accessibility services that query the screen.
7727      *
7728      * @param mode How to determine whether this view is important for accessibility.
7729      *
7730      * @attr ref android.R.styleable#View_importantForAccessibility
7731      *
7732      * @see #IMPORTANT_FOR_ACCESSIBILITY_YES
7733      * @see #IMPORTANT_FOR_ACCESSIBILITY_NO
7734      * @see #IMPORTANT_FOR_ACCESSIBILITY_NO_HIDE_DESCENDANTS
7735      * @see #IMPORTANT_FOR_ACCESSIBILITY_AUTO
7736      */
7737     public void setImportantForAccessibility(int mode) {
7738         final int oldMode = getImportantForAccessibility();
7739         if (mode != oldMode) {
7740             // If we're moving between AUTO and another state, we might not need
7741             // to send a subtree changed notification. We'll store the computed
7742             // importance, since we'll need to check it later to make sure.
7743             final boolean maySkipNotify = oldMode == IMPORTANT_FOR_ACCESSIBILITY_AUTO
7744                     || mode == IMPORTANT_FOR_ACCESSIBILITY_AUTO;
7745             final boolean oldIncludeForAccessibility = maySkipNotify && includeForAccessibility();
7746             mPrivateFlags2 &= ~PFLAG2_IMPORTANT_FOR_ACCESSIBILITY_MASK;
7747             mPrivateFlags2 |= (mode << PFLAG2_IMPORTANT_FOR_ACCESSIBILITY_SHIFT)
7748                     & PFLAG2_IMPORTANT_FOR_ACCESSIBILITY_MASK;
7749             if (!maySkipNotify || oldIncludeForAccessibility != includeForAccessibility()) {
7750                 notifySubtreeAccessibilityStateChangedIfNeeded();
7751             } else {
7752                 notifyViewAccessibilityStateChangedIfNeeded(
7753                         AccessibilityEvent.CONTENT_CHANGE_TYPE_UNDEFINED);
7754             }
7755         }
7756     }
7757
7758     /**
7759      * Computes whether this view should be exposed for accessibility. In
7760      * general, views that are interactive or provide information are exposed
7761      * while views that serve only as containers are hidden.
7762      * <p>
7763      * If an ancestor of this view has importance
7764      * {@link #IMPORTANT_FOR_ACCESSIBILITY_NO_HIDE_DESCENDANTS}, this method
7765      * returns <code>false</code>.
7766      * <p>
7767      * Otherwise, the value is computed according to the view's
7768      * {@link #getImportantForAccessibility()} value:
7769      * <ol>
7770      * <li>{@link #IMPORTANT_FOR_ACCESSIBILITY_NO} or
7771      * {@link #IMPORTANT_FOR_ACCESSIBILITY_NO_HIDE_DESCENDANTS}, return <code>false
7772      * </code>
7773      * <li>{@link #IMPORTANT_FOR_ACCESSIBILITY_YES}, return <code>true</code>
7774      * <li>{@link #IMPORTANT_FOR_ACCESSIBILITY_AUTO}, return <code>true</code> if
7775      * view satisfies any of the following:
7776      * <ul>
7777      * <li>Is actionable, e.g. {@link #isClickable()},
7778      * {@link #isLongClickable()}, or {@link #isFocusable()}
7779      * <li>Has an {@link AccessibilityDelegate}
7780      * <li>Has an interaction listener, e.g. {@link OnTouchListener},
7781      * {@link OnKeyListener}, etc.
7782      * <li>Is an accessibility live region, e.g.
7783      * {@link #getAccessibilityLiveRegion()} is not
7784      * {@link #ACCESSIBILITY_LIVE_REGION_NONE}.
7785      * </ul>
7786      * </ol>
7787      *
7788      * @return Whether the view is exposed for accessibility.
7789      * @see #setImportantForAccessibility(int)
7790      * @see #getImportantForAccessibility()
7791      */
7792     public boolean isImportantForAccessibility() {
7793         final int mode = (mPrivateFlags2 & PFLAG2_IMPORTANT_FOR_ACCESSIBILITY_MASK)
7794                 >> PFLAG2_IMPORTANT_FOR_ACCESSIBILITY_SHIFT;
7795         if (mode == IMPORTANT_FOR_ACCESSIBILITY_NO
7796                 || mode == IMPORTANT_FOR_ACCESSIBILITY_NO_HIDE_DESCENDANTS) {
7797             return false;
7798         }
7799
7800         // Check parent mode to ensure we're not hidden.
7801         ViewParent parent = mParent;
7802         while (parent instanceof View) {
7803             if (((View) parent).getImportantForAccessibility()
7804                     == IMPORTANT_FOR_ACCESSIBILITY_NO_HIDE_DESCENDANTS) {
7805                 return false;
7806             }
7807             parent = parent.getParent();
7808         }
7809
7810         return mode == IMPORTANT_FOR_ACCESSIBILITY_YES || isActionableForAccessibility()
7811                 || hasListenersForAccessibility() || getAccessibilityNodeProvider() != null
7812                 || getAccessibilityLiveRegion() != ACCESSIBILITY_LIVE_REGION_NONE;
7813     }
7814
7815     /**
7816      * Gets the parent for accessibility purposes. Note that the parent for
7817      * accessibility is not necessary the immediate parent. It is the first
7818      * predecessor that is important for accessibility.
7819      *
7820      * @return The parent for accessibility purposes.
7821      */
7822     public ViewParent getParentForAccessibility() {
7823         if (mParent instanceof View) {
7824             View parentView = (View) mParent;
7825             if (parentView.includeForAccessibility()) {
7826                 return mParent;
7827             } else {
7828                 return mParent.getParentForAccessibility();
7829             }
7830         }
7831         return null;
7832     }
7833
7834     /**
7835      * Adds the children of a given View for accessibility. Since some Views are
7836      * not important for accessibility the children for accessibility are not
7837      * necessarily direct children of the view, rather they are the first level of
7838      * descendants important for accessibility.
7839      *
7840      * @param children The list of children for accessibility.
7841      */
7842     public void addChildrenForAccessibility(ArrayList<View> children) {
7843
7844     }
7845
7846     /**
7847      * Whether to regard this view for accessibility. A view is regarded for
7848      * accessibility if it is important for accessibility or the querying
7849      * accessibility service has explicitly requested that view not
7850      * important for accessibility are regarded.
7851      *
7852      * @return Whether to regard the view for accessibility.
7853      *
7854      * @hide
7855      */
7856     public boolean includeForAccessibility() {
7857         if (mAttachInfo != null) {
7858             return (mAttachInfo.mAccessibilityFetchFlags
7859                     & AccessibilityNodeInfo.FLAG_INCLUDE_NOT_IMPORTANT_VIEWS) != 0
7860                     || isImportantForAccessibility();
7861         }
7862         return false;
7863     }
7864
7865     /**
7866      * Returns whether the View is considered actionable from
7867      * accessibility perspective. Such view are important for
7868      * accessibility.
7869      *
7870      * @return True if the view is actionable for accessibility.
7871      *
7872      * @hide
7873      */
7874     public boolean isActionableForAccessibility() {
7875         return (isClickable() || isLongClickable() || isFocusable());
7876     }
7877
7878     /**
7879      * Returns whether the View has registered callbacks which makes it
7880      * important for accessibility.
7881      *
7882      * @return True if the view is actionable for accessibility.
7883      */
7884     private boolean hasListenersForAccessibility() {
7885         ListenerInfo info = getListenerInfo();
7886         return mTouchDelegate != null || info.mOnKeyListener != null
7887                 || info.mOnTouchListener != null || info.mOnGenericMotionListener != null
7888                 || info.mOnHoverListener != null || info.mOnDragListener != null;
7889     }
7890
7891     /**
7892      * Notifies that the accessibility state of this view changed. The change
7893      * is local to this view and does not represent structural changes such
7894      * as children and parent. For example, the view became focusable. The
7895      * notification is at at most once every
7896      * {@link ViewConfiguration#getSendRecurringAccessibilityEventsInterval()}
7897      * to avoid unnecessary load to the system. Also once a view has a pending
7898      * notification this method is a NOP until the notification has been sent.
7899      *
7900      * @hide
7901      */
7902     public void notifyViewAccessibilityStateChangedIfNeeded(int changeType) {
7903         if (!AccessibilityManager.getInstance(mContext).isEnabled()) {
7904             return;
7905         }
7906         if (mSendViewStateChangedAccessibilityEvent == null) {
7907             mSendViewStateChangedAccessibilityEvent =
7908                     new SendViewStateChangedAccessibilityEvent();
7909         }
7910         mSendViewStateChangedAccessibilityEvent.runOrPost(changeType);
7911     }
7912
7913     /**
7914      * Notifies that the accessibility state of this view changed. The change
7915      * is *not* local to this view and does represent structural changes such
7916      * as children and parent. For example, the view size changed. The
7917      * notification is at at most once every
7918      * {@link ViewConfiguration#getSendRecurringAccessibilityEventsInterval()}
7919      * to avoid unnecessary load to the system. Also once a view has a pending
7920      * notification this method is a NOP until the notification has been sent.
7921      *
7922      * @hide
7923      */
7924     public void notifySubtreeAccessibilityStateChangedIfNeeded() {
7925         if (!AccessibilityManager.getInstance(mContext).isEnabled()) {
7926             return;
7927         }
7928         if ((mPrivateFlags2 & PFLAG2_SUBTREE_ACCESSIBILITY_STATE_CHANGED) == 0) {
7929             mPrivateFlags2 |= PFLAG2_SUBTREE_ACCESSIBILITY_STATE_CHANGED;
7930             if (mParent != null) {
7931                 try {
7932                     mParent.notifySubtreeAccessibilityStateChanged(
7933                             this, this, AccessibilityEvent.CONTENT_CHANGE_TYPE_SUBTREE);
7934                 } catch (AbstractMethodError e) {
7935                     Log.e(VIEW_LOG_TAG, mParent.getClass().getSimpleName() +
7936                             " does not fully implement ViewParent", e);
7937                 }
7938             }
7939         }
7940     }
7941
7942     /**
7943      * Reset the flag indicating the accessibility state of the subtree rooted
7944      * at this view changed.
7945      */
7946     void resetSubtreeAccessibilityStateChanged() {
7947         mPrivateFlags2 &= ~PFLAG2_SUBTREE_ACCESSIBILITY_STATE_CHANGED;
7948     }
7949
7950     /**
7951      * Performs the specified accessibility action on the view. For
7952      * possible accessibility actions look at {@link AccessibilityNodeInfo}.
7953      * <p>
7954      * If an {@link AccessibilityDelegate} has been specified via calling
7955      * {@link #setAccessibilityDelegate(AccessibilityDelegate)} its
7956      * {@link AccessibilityDelegate#performAccessibilityAction(View, int, Bundle)}
7957      * is responsible for handling this call.
7958      * </p>
7959      *
7960      * @param action The action to perform.
7961      * @param arguments Optional action arguments.
7962      * @return Whether the action was performed.
7963      */
7964     public boolean performAccessibilityAction(int action, Bundle arguments) {
7965       if (mAccessibilityDelegate != null) {
7966           return mAccessibilityDelegate.performAccessibilityAction(this, action, arguments);
7967       } else {
7968           return performAccessibilityActionInternal(action, arguments);
7969       }
7970     }
7971
7972    /**
7973     * @see #performAccessibilityAction(int, Bundle)
7974     *
7975     * Note: Called from the default {@link AccessibilityDelegate}.
7976     */
7977     boolean performAccessibilityActionInternal(int action, Bundle arguments) {
7978         switch (action) {
7979             case AccessibilityNodeInfo.ACTION_CLICK: {
7980                 if (isClickable()) {
7981                     performClick();
7982                     return true;
7983                 }
7984             } break;
7985             case AccessibilityNodeInfo.ACTION_LONG_CLICK: {
7986                 if (isLongClickable()) {
7987                     performLongClick();
7988                     return true;
7989                 }
7990             } break;
7991             case AccessibilityNodeInfo.ACTION_FOCUS: {
7992                 if (!hasFocus()) {
7993                     // Get out of touch mode since accessibility
7994                     // wants to move focus around.
7995                     getViewRootImpl().ensureTouchMode(false);
7996                     return requestFocus();
7997                 }
7998             } break;
7999             case AccessibilityNodeInfo.ACTION_CLEAR_FOCUS: {
8000                 if (hasFocus()) {
8001                     clearFocus();
8002                     return !isFocused();
8003                 }
8004             } break;
8005             case AccessibilityNodeInfo.ACTION_SELECT: {
8006                 if (!isSelected()) {
8007                     setSelected(true);
8008                     return isSelected();
8009                 }
8010             } break;
8011             case AccessibilityNodeInfo.ACTION_CLEAR_SELECTION: {
8012                 if (isSelected()) {
8013                     setSelected(false);
8014                     return !isSelected();
8015                 }
8016             } break;
8017             case AccessibilityNodeInfo.ACTION_ACCESSIBILITY_FOCUS: {
8018                 if (!isAccessibilityFocused()) {
8019                     return requestAccessibilityFocus();
8020                 }
8021             } break;
8022             case AccessibilityNodeInfo.ACTION_CLEAR_ACCESSIBILITY_FOCUS: {
8023                 if (isAccessibilityFocused()) {
8024                     clearAccessibilityFocus();
8025                     return true;
8026                 }
8027             } break;
8028             case AccessibilityNodeInfo.ACTION_NEXT_AT_MOVEMENT_GRANULARITY: {
8029                 if (arguments != null) {
8030                     final int granularity = arguments.getInt(
8031                             AccessibilityNodeInfo.ACTION_ARGUMENT_MOVEMENT_GRANULARITY_INT);
8032                     final boolean extendSelection = arguments.getBoolean(
8033                             AccessibilityNodeInfo.ACTION_ARGUMENT_EXTEND_SELECTION_BOOLEAN);
8034                     return traverseAtGranularity(granularity, true, extendSelection);
8035                 }
8036             } break;
8037             case AccessibilityNodeInfo.ACTION_PREVIOUS_AT_MOVEMENT_GRANULARITY: {
8038                 if (arguments != null) {
8039                     final int granularity = arguments.getInt(
8040                             AccessibilityNodeInfo.ACTION_ARGUMENT_MOVEMENT_GRANULARITY_INT);
8041                     final boolean extendSelection = arguments.getBoolean(
8042                             AccessibilityNodeInfo.ACTION_ARGUMENT_EXTEND_SELECTION_BOOLEAN);
8043                     return traverseAtGranularity(granularity, false, extendSelection);
8044                 }
8045             } break;
8046             case AccessibilityNodeInfo.ACTION_SET_SELECTION: {
8047                 CharSequence text = getIterableTextForAccessibility();
8048                 if (text == null) {
8049                     return false;
8050                 }
8051                 final int start = (arguments != null) ? arguments.getInt(
8052                         AccessibilityNodeInfo.ACTION_ARGUMENT_SELECTION_START_INT, -1) : -1;
8053                 final int end = (arguments != null) ? arguments.getInt(
8054                 AccessibilityNodeInfo.ACTION_ARGUMENT_SELECTION_END_INT, -1) : -1;
8055                 // Only cursor position can be specified (selection length == 0)
8056                 if ((getAccessibilitySelectionStart() != start
8057                         || getAccessibilitySelectionEnd() != end)
8058                         && (start == end)) {
8059                     setAccessibilitySelection(start, end);
8060                     notifyViewAccessibilityStateChangedIfNeeded(
8061                             AccessibilityEvent.CONTENT_CHANGE_TYPE_UNDEFINED);
8062                     return true;
8063                 }
8064             } break;
8065         }
8066         return false;
8067     }
8068
8069     private boolean traverseAtGranularity(int granularity, boolean forward,
8070             boolean extendSelection) {
8071         CharSequence text = getIterableTextForAccessibility();
8072         if (text == null || text.length() == 0) {
8073             return false;
8074         }
8075         TextSegmentIterator iterator = getIteratorForGranularity(granularity);
8076         if (iterator == null) {
8077             return false;
8078         }
8079         int current = getAccessibilitySelectionEnd();
8080         if (current == ACCESSIBILITY_CURSOR_POSITION_UNDEFINED) {
8081             current = forward ? 0 : text.length();
8082         }
8083         final int[] range = forward ? iterator.following(current) : iterator.preceding(current);
8084         if (range == null) {
8085             return false;
8086         }
8087         final int segmentStart = range[0];
8088         final int segmentEnd = range[1];
8089         int selectionStart;
8090         int selectionEnd;
8091         if (extendSelection && isAccessibilitySelectionExtendable()) {
8092             selectionStart = getAccessibilitySelectionStart();
8093             if (selectionStart == ACCESSIBILITY_CURSOR_POSITION_UNDEFINED) {
8094                 selectionStart = forward ? segmentStart : segmentEnd;
8095             }
8096             selectionEnd = forward ? segmentEnd : segmentStart;
8097         } else {
8098             selectionStart = selectionEnd= forward ? segmentEnd : segmentStart;
8099         }
8100         setAccessibilitySelection(selectionStart, selectionEnd);
8101         final int action = forward ? AccessibilityNodeInfo.ACTION_NEXT_AT_MOVEMENT_GRANULARITY
8102                 : AccessibilityNodeInfo.ACTION_PREVIOUS_AT_MOVEMENT_GRANULARITY;
8103         sendViewTextTraversedAtGranularityEvent(action, granularity, segmentStart, segmentEnd);
8104         return true;
8105     }
8106
8107     /**
8108      * Gets the text reported for accessibility purposes.
8109      *
8110      * @return The accessibility text.
8111      *
8112      * @hide
8113      */
8114     public CharSequence getIterableTextForAccessibility() {
8115         return getContentDescription();
8116     }
8117
8118     /**
8119      * Gets whether accessibility selection can be extended.
8120      *
8121      * @return If selection is extensible.
8122      *
8123      * @hide
8124      */
8125     public boolean isAccessibilitySelectionExtendable() {
8126         return false;
8127     }
8128
8129     /**
8130      * @hide
8131      */
8132     public int getAccessibilitySelectionStart() {
8133         return mAccessibilityCursorPosition;
8134     }
8135
8136     /**
8137      * @hide
8138      */
8139     public int getAccessibilitySelectionEnd() {
8140         return getAccessibilitySelectionStart();
8141     }
8142
8143     /**
8144      * @hide
8145      */
8146     public void setAccessibilitySelection(int start, int end) {
8147         if (start ==  end && end == mAccessibilityCursorPosition) {
8148             return;
8149         }
8150         if (start >= 0 && start == end && end <= getIterableTextForAccessibility().length()) {
8151             mAccessibilityCursorPosition = start;
8152         } else {
8153             mAccessibilityCursorPosition = ACCESSIBILITY_CURSOR_POSITION_UNDEFINED;
8154         }
8155         sendAccessibilityEvent(AccessibilityEvent.TYPE_VIEW_TEXT_SELECTION_CHANGED);
8156     }
8157
8158     private void sendViewTextTraversedAtGranularityEvent(int action, int granularity,
8159             int fromIndex, int toIndex) {
8160         if (mParent == null) {
8161             return;
8162         }
8163         AccessibilityEvent event = AccessibilityEvent.obtain(
8164                 AccessibilityEvent.TYPE_VIEW_TEXT_TRAVERSED_AT_MOVEMENT_GRANULARITY);
8165         onInitializeAccessibilityEvent(event);
8166         onPopulateAccessibilityEvent(event);
8167         event.setFromIndex(fromIndex);
8168         event.setToIndex(toIndex);
8169         event.setAction(action);
8170         event.setMovementGranularity(granularity);
8171         mParent.requestSendAccessibilityEvent(this, event);
8172     }
8173
8174     /**
8175      * @hide
8176      */
8177     public TextSegmentIterator getIteratorForGranularity(int granularity) {
8178         switch (granularity) {
8179             case AccessibilityNodeInfo.MOVEMENT_GRANULARITY_CHARACTER: {
8180                 CharSequence text = getIterableTextForAccessibility();
8181                 if (text != null && text.length() > 0) {
8182                     CharacterTextSegmentIterator iterator =
8183                         CharacterTextSegmentIterator.getInstance(
8184                                 mContext.getResources().getConfiguration().locale);
8185                     iterator.initialize(text.toString());
8186                     return iterator;
8187                 }
8188             } break;
8189             case AccessibilityNodeInfo.MOVEMENT_GRANULARITY_WORD: {
8190                 CharSequence text = getIterableTextForAccessibility();
8191                 if (text != null && text.length() > 0) {
8192                     WordTextSegmentIterator iterator =
8193                         WordTextSegmentIterator.getInstance(
8194                                 mContext.getResources().getConfiguration().locale);
8195                     iterator.initialize(text.toString());
8196                     return iterator;
8197                 }
8198             } break;
8199             case AccessibilityNodeInfo.MOVEMENT_GRANULARITY_PARAGRAPH: {
8200                 CharSequence text = getIterableTextForAccessibility();
8201                 if (text != null && text.length() > 0) {
8202                     ParagraphTextSegmentIterator iterator =
8203                         ParagraphTextSegmentIterator.getInstance();
8204                     iterator.initialize(text.toString());
8205                     return iterator;
8206                 }
8207             } break;
8208         }
8209         return null;
8210     }
8211
8212     /**
8213      * @hide
8214      */
8215     public void dispatchStartTemporaryDetach() {
8216         onStartTemporaryDetach();
8217     }
8218
8219     /**
8220      * This is called when a container is going to temporarily detach a child, with
8221      * {@link ViewGroup#detachViewFromParent(View) ViewGroup.detachViewFromParent}.
8222      * It will either be followed by {@link #onFinishTemporaryDetach()} or
8223      * {@link #onDetachedFromWindow()} when the container is done.
8224      */
8225     public void onStartTemporaryDetach() {
8226         removeUnsetPressCallback();
8227         mPrivateFlags |= PFLAG_CANCEL_NEXT_UP_EVENT;
8228     }
8229
8230     /**
8231      * @hide
8232      */
8233     public void dispatchFinishTemporaryDetach() {
8234         onFinishTemporaryDetach();
8235     }
8236
8237     /**
8238      * Called after {@link #onStartTemporaryDetach} when the container is done
8239      * changing the view.
8240      */
8241     public void onFinishTemporaryDetach() {
8242     }
8243
8244     /**
8245      * Return the global {@link KeyEvent.DispatcherState KeyEvent.DispatcherState}
8246      * for this view's window.  Returns null if the view is not currently attached
8247      * to the window.  Normally you will not need to use this directly, but
8248      * just use the standard high-level event callbacks like
8249      * {@link #onKeyDown(int, KeyEvent)}.
8250      */
8251     public KeyEvent.DispatcherState getKeyDispatcherState() {
8252         return mAttachInfo != null ? mAttachInfo.mKeyDispatchState : null;
8253     }
8254
8255     /**
8256      * Dispatch a key event before it is processed by any input method
8257      * associated with the view hierarchy.  This can be used to intercept
8258      * key events in special situations before the IME consumes them; a
8259      * typical example would be handling the BACK key to update the application's
8260      * UI instead of allowing the IME to see it and close itself.
8261      *
8262      * @param event The key event to be dispatched.
8263      * @return True if the event was handled, false otherwise.
8264      */
8265     public boolean dispatchKeyEventPreIme(KeyEvent event) {
8266         return onKeyPreIme(event.getKeyCode(), event);
8267     }
8268
8269     /**
8270      * Dispatch a key event to the next view on the focus path. This path runs
8271      * from the top of the view tree down to the currently focused view. If this
8272      * view has focus, it will dispatch to itself. Otherwise it will dispatch
8273      * the next node down the focus path. This method also fires any key
8274      * listeners.
8275      *
8276      * @param event The key event to be dispatched.
8277      * @return True if the event was handled, false otherwise.
8278      */
8279     public boolean dispatchKeyEvent(KeyEvent event) {
8280         if (mInputEventConsistencyVerifier != null) {
8281             mInputEventConsistencyVerifier.onKeyEvent(event, 0);
8282         }
8283
8284         // Give any attached key listener a first crack at the event.
8285         //noinspection SimplifiableIfStatement
8286         ListenerInfo li = mListenerInfo;
8287         if (li != null && li.mOnKeyListener != null && (mViewFlags & ENABLED_MASK) == ENABLED
8288                 && li.mOnKeyListener.onKey(this, event.getKeyCode(), event)) {
8289             return true;
8290         }
8291
8292         if (event.dispatch(this, mAttachInfo != null
8293                 ? mAttachInfo.mKeyDispatchState : null, this)) {
8294             return true;
8295         }
8296
8297         if (mInputEventConsistencyVerifier != null) {
8298             mInputEventConsistencyVerifier.onUnhandledEvent(event, 0);
8299         }
8300         return false;
8301     }
8302
8303     /**
8304      * Dispatches a key shortcut event.
8305      *
8306      * @param event The key event to be dispatched.
8307      * @return True if the event was handled by the view, false otherwise.
8308      */
8309     public boolean dispatchKeyShortcutEvent(KeyEvent event) {
8310         return onKeyShortcut(event.getKeyCode(), event);
8311     }
8312
8313     /**
8314      * Pass the touch screen motion event down to the target view, or this
8315      * view if it is the target.
8316      *
8317      * @param event The motion event to be dispatched.
8318      * @return True if the event was handled by the view, false otherwise.
8319      */
8320     public boolean dispatchTouchEvent(MotionEvent event) {
8321         boolean result = false;
8322
8323         if (mInputEventConsistencyVerifier != null) {
8324             mInputEventConsistencyVerifier.onTouchEvent(event, 0);
8325         }
8326
8327         final int actionMasked = event.getActionMasked();
8328         if (actionMasked == MotionEvent.ACTION_DOWN) {
8329             // Defensive cleanup for new gesture
8330             stopNestedScroll();
8331         }
8332
8333         if (onFilterTouchEventForSecurity(event)) {
8334             //noinspection SimplifiableIfStatement
8335             ListenerInfo li = mListenerInfo;
8336             if (li != null && li.mOnTouchListener != null
8337                     && (mViewFlags & ENABLED_MASK) == ENABLED
8338                     && li.mOnTouchListener.onTouch(this, event)) {
8339                 result = true;
8340             }
8341
8342             if (!result && onTouchEvent(event)) {
8343                 result = true;
8344             }
8345         }
8346
8347         if (!result && mInputEventConsistencyVerifier != null) {
8348             mInputEventConsistencyVerifier.onUnhandledEvent(event, 0);
8349         }
8350
8351         // Clean up after nested scrolls if this is the end of a gesture;
8352         // also cancel it if we tried an ACTION_DOWN but we didn't want the rest
8353         // of the gesture.
8354         if (actionMasked == MotionEvent.ACTION_UP ||
8355                 actionMasked == MotionEvent.ACTION_CANCEL ||
8356                 (actionMasked == MotionEvent.ACTION_DOWN && !result)) {
8357             stopNestedScroll();
8358         }
8359
8360         return result;
8361     }
8362
8363     /**
8364      * Filter the touch event to apply security policies.
8365      *
8366      * @param event The motion event to be filtered.
8367      * @return True if the event should be dispatched, false if the event should be dropped.
8368      *
8369      * @see #getFilterTouchesWhenObscured
8370      */
8371     public boolean onFilterTouchEventForSecurity(MotionEvent event) {
8372         //noinspection RedundantIfStatement
8373         if ((mViewFlags & FILTER_TOUCHES_WHEN_OBSCURED) != 0
8374                 && (event.getFlags() & MotionEvent.FLAG_WINDOW_IS_OBSCURED) != 0) {
8375             // Window is obscured, drop this touch.
8376             return false;
8377         }
8378         return true;
8379     }
8380
8381     /**
8382      * Pass a trackball motion event down to the focused view.
8383      *
8384      * @param event The motion event to be dispatched.
8385      * @return True if the event was handled by the view, false otherwise.
8386      */
8387     public boolean dispatchTrackballEvent(MotionEvent event) {
8388         if (mInputEventConsistencyVerifier != null) {
8389             mInputEventConsistencyVerifier.onTrackballEvent(event, 0);
8390         }
8391
8392         return onTrackballEvent(event);
8393     }
8394
8395     /**
8396      * Dispatch a generic motion event.
8397      * <p>
8398      * Generic motion events with source class {@link InputDevice#SOURCE_CLASS_POINTER}
8399      * are delivered to the view under the pointer.  All other generic motion events are
8400      * delivered to the focused view.  Hover events are handled specially and are delivered
8401      * to {@link #onHoverEvent(MotionEvent)}.
8402      * </p>
8403      *
8404      * @param event The motion event to be dispatched.
8405      * @return True if the event was handled by the view, false otherwise.
8406      */
8407     public boolean dispatchGenericMotionEvent(MotionEvent event) {
8408         if (mInputEventConsistencyVerifier != null) {
8409             mInputEventConsistencyVerifier.onGenericMotionEvent(event, 0);
8410         }
8411
8412         final int source = event.getSource();
8413         if ((source & InputDevice.SOURCE_CLASS_POINTER) != 0) {
8414             final int action = event.getAction();
8415             if (action == MotionEvent.ACTION_HOVER_ENTER
8416                     || action == MotionEvent.ACTION_HOVER_MOVE
8417                     || action == MotionEvent.ACTION_HOVER_EXIT) {
8418                 if (dispatchHoverEvent(event)) {
8419                     return true;
8420                 }
8421             } else if (dispatchGenericPointerEvent(event)) {
8422                 return true;
8423             }
8424         } else if (dispatchGenericFocusedEvent(event)) {
8425             return true;
8426         }
8427
8428         if (dispatchGenericMotionEventInternal(event)) {
8429             return true;
8430         }
8431
8432         if (mInputEventConsistencyVerifier != null) {
8433             mInputEventConsistencyVerifier.onUnhandledEvent(event, 0);
8434         }
8435         return false;
8436     }
8437
8438     private boolean dispatchGenericMotionEventInternal(MotionEvent event) {
8439         //noinspection SimplifiableIfStatement
8440         ListenerInfo li = mListenerInfo;
8441         if (li != null && li.mOnGenericMotionListener != null
8442                 && (mViewFlags & ENABLED_MASK) == ENABLED
8443                 && li.mOnGenericMotionListener.onGenericMotion(this, event)) {
8444             return true;
8445         }
8446
8447         if (onGenericMotionEvent(event)) {
8448             return true;
8449         }
8450
8451         if (mInputEventConsistencyVerifier != null) {
8452             mInputEventConsistencyVerifier.onUnhandledEvent(event, 0);
8453         }
8454         return false;
8455     }
8456
8457     /**
8458      * Dispatch a hover event.
8459      * <p>
8460      * Do not call this method directly.
8461      * Call {@link #dispatchGenericMotionEvent(MotionEvent)} instead.
8462      * </p>
8463      *
8464      * @param event The motion event to be dispatched.
8465      * @return True if the event was handled by the view, false otherwise.
8466      */
8467     protected boolean dispatchHoverEvent(MotionEvent event) {
8468         ListenerInfo li = mListenerInfo;
8469         //noinspection SimplifiableIfStatement
8470         if (li != null && li.mOnHoverListener != null
8471                 && (mViewFlags & ENABLED_MASK) == ENABLED
8472                 && li.mOnHoverListener.onHover(this, event)) {
8473             return true;
8474         }
8475
8476         return onHoverEvent(event);
8477     }
8478
8479     /**
8480      * Returns true if the view has a child to which it has recently sent
8481      * {@link MotionEvent#ACTION_HOVER_ENTER}.  If this view is hovered and
8482      * it does not have a hovered child, then it must be the innermost hovered view.
8483      * @hide
8484      */
8485     protected boolean hasHoveredChild() {
8486         return false;
8487     }
8488
8489     /**
8490      * Dispatch a generic motion event to the view under the first pointer.
8491      * <p>
8492      * Do not call this method directly.
8493      * Call {@link #dispatchGenericMotionEvent(MotionEvent)} instead.
8494      * </p>
8495      *
8496      * @param event The motion event to be dispatched.
8497      * @return True if the event was handled by the view, false otherwise.
8498      */
8499     protected boolean dispatchGenericPointerEvent(MotionEvent event) {
8500         return false;
8501     }
8502
8503     /**
8504      * Dispatch a generic motion event to the currently focused view.
8505      * <p>
8506      * Do not call this method directly.
8507      * Call {@link #dispatchGenericMotionEvent(MotionEvent)} instead.
8508      * </p>
8509      *
8510      * @param event The motion event to be dispatched.
8511      * @return True if the event was handled by the view, false otherwise.
8512      */
8513     protected boolean dispatchGenericFocusedEvent(MotionEvent event) {
8514         return false;
8515     }
8516
8517     /**
8518      * Dispatch a pointer event.
8519      * <p>
8520      * Dispatches touch related pointer events to {@link #onTouchEvent(MotionEvent)} and all
8521      * other events to {@link #onGenericMotionEvent(MotionEvent)}.  This separation of concerns
8522      * reinforces the invariant that {@link #onTouchEvent(MotionEvent)} is really about touches
8523      * and should not be expected to handle other pointing device features.
8524      * </p>
8525      *
8526      * @param event The motion event to be dispatched.
8527      * @return True if the event was handled by the view, false otherwise.
8528      * @hide
8529      */
8530     public final boolean dispatchPointerEvent(MotionEvent event) {
8531         if (event.isTouchEvent()) {
8532             return dispatchTouchEvent(event);
8533         } else {
8534             return dispatchGenericMotionEvent(event);
8535         }
8536     }
8537
8538     /**
8539      * Called when the window containing this view gains or loses window focus.
8540      * ViewGroups should override to route to their children.
8541      *
8542      * @param hasFocus True if the window containing this view now has focus,
8543      *        false otherwise.
8544      */
8545     public void dispatchWindowFocusChanged(boolean hasFocus) {
8546         onWindowFocusChanged(hasFocus);
8547     }
8548
8549     /**
8550      * Called when the window containing this view gains or loses focus.  Note
8551      * that this is separate from view focus: to receive key events, both
8552      * your view and its window must have focus.  If a window is displayed
8553      * on top of yours that takes input focus, then your own window will lose
8554      * focus but the view focus will remain unchanged.
8555      *
8556      * @param hasWindowFocus True if the window containing this view now has
8557      *        focus, false otherwise.
8558      */
8559     public void onWindowFocusChanged(boolean hasWindowFocus) {
8560         InputMethodManager imm = InputMethodManager.peekInstance();
8561         if (!hasWindowFocus) {
8562             if (isPressed()) {
8563                 setPressed(false);
8564             }
8565             if (imm != null && (mPrivateFlags & PFLAG_FOCUSED) != 0) {
8566                 imm.focusOut(this);
8567             }
8568             removeLongPressCallback();
8569             removeTapCallback();
8570             onFocusLost();
8571         } else if (imm != null && (mPrivateFlags & PFLAG_FOCUSED) != 0) {
8572             imm.focusIn(this);
8573         }
8574         refreshDrawableState();
8575     }
8576
8577     /**
8578      * Returns true if this view is in a window that currently has window focus.
8579      * Note that this is not the same as the view itself having focus.
8580      *
8581      * @return True if this view is in a window that currently has window focus.
8582      */
8583     public boolean hasWindowFocus() {
8584         return mAttachInfo != null && mAttachInfo.mHasWindowFocus;
8585     }
8586
8587     /**
8588      * Dispatch a view visibility change down the view hierarchy.
8589      * ViewGroups should override to route to their children.
8590      * @param changedView The view whose visibility changed. Could be 'this' or
8591      * an ancestor view.
8592      * @param visibility The new visibility of changedView: {@link #VISIBLE},
8593      * {@link #INVISIBLE} or {@link #GONE}.
8594      */
8595     protected void dispatchVisibilityChanged(@NonNull View changedView,
8596             @Visibility int visibility) {
8597         onVisibilityChanged(changedView, visibility);
8598     }
8599
8600     /**
8601      * Called when the visibility of the view or an ancestor of the view is changed.
8602      * @param changedView The view whose visibility changed. Could be 'this' or
8603      * an ancestor view.
8604      * @param visibility The new visibility of changedView: {@link #VISIBLE},
8605      * {@link #INVISIBLE} or {@link #GONE}.
8606      */
8607     protected void onVisibilityChanged(@NonNull View changedView, @Visibility int visibility) {
8608         if (visibility == VISIBLE) {
8609             if (mAttachInfo != null) {
8610                 initialAwakenScrollBars();
8611             } else {
8612                 mPrivateFlags |= PFLAG_AWAKEN_SCROLL_BARS_ON_ATTACH;
8613             }
8614         }
8615     }
8616
8617     /**
8618      * Dispatch a hint about whether this view is displayed. For instance, when
8619      * a View moves out of the screen, it might receives a display hint indicating
8620      * the view is not displayed. Applications should not <em>rely</em> on this hint
8621      * as there is no guarantee that they will receive one.
8622      *
8623      * @param hint A hint about whether or not this view is displayed:
8624      * {@link #VISIBLE} or {@link #INVISIBLE}.
8625      */
8626     public void dispatchDisplayHint(@Visibility int hint) {
8627         onDisplayHint(hint);
8628     }
8629
8630     /**
8631      * Gives this view a hint about whether is displayed or not. For instance, when
8632      * a View moves out of the screen, it might receives a display hint indicating
8633      * the view is not displayed. Applications should not <em>rely</em> on this hint
8634      * as there is no guarantee that they will receive one.
8635      *
8636      * @param hint A hint about whether or not this view is displayed:
8637      * {@link #VISIBLE} or {@link #INVISIBLE}.
8638      */
8639     protected void onDisplayHint(@Visibility int hint) {
8640     }
8641
8642     /**
8643      * Dispatch a window visibility change down the view hierarchy.
8644      * ViewGroups should override to route to their children.
8645      *
8646      * @param visibility The new visibility of the window.
8647      *
8648      * @see #onWindowVisibilityChanged(int)
8649      */
8650     public void dispatchWindowVisibilityChanged(@Visibility int visibility) {
8651         onWindowVisibilityChanged(visibility);
8652     }
8653
8654     /**
8655      * Called when the window containing has change its visibility
8656      * (between {@link #GONE}, {@link #INVISIBLE}, and {@link #VISIBLE}).  Note
8657      * that this tells you whether or not your window is being made visible
8658      * to the window manager; this does <em>not</em> tell you whether or not
8659      * your window is obscured by other windows on the screen, even if it
8660      * is itself visible.
8661      *
8662      * @param visibility The new visibility of the window.
8663      */
8664     protected void onWindowVisibilityChanged(@Visibility int visibility) {
8665         if (visibility == VISIBLE) {
8666             initialAwakenScrollBars();
8667         }
8668     }
8669
8670     /**
8671      * Returns the current visibility of the window this view is attached to
8672      * (either {@link #GONE}, {@link #INVISIBLE}, or {@link #VISIBLE}).
8673      *
8674      * @return Returns the current visibility of the view's window.
8675      */
8676     @Visibility
8677     public int getWindowVisibility() {
8678         return mAttachInfo != null ? mAttachInfo.mWindowVisibility : GONE;
8679     }
8680
8681     /**
8682      * Retrieve the overall visible display size in which the window this view is
8683      * attached to has been positioned in.  This takes into account screen
8684      * decorations above the window, for both cases where the window itself
8685      * is being position inside of them or the window is being placed under
8686      * then and covered insets are used for the window to position its content
8687      * inside.  In effect, this tells you the available area where content can
8688      * be placed and remain visible to users.
8689      *
8690      * <p>This function requires an IPC back to the window manager to retrieve
8691      * the requested information, so should not be used in performance critical
8692      * code like drawing.
8693      *
8694      * @param outRect Filled in with the visible display frame.  If the view
8695      * is not attached to a window, this is simply the raw display size.
8696      */
8697     public void getWindowVisibleDisplayFrame(Rect outRect) {
8698         if (mAttachInfo != null) {
8699             try {
8700                 mAttachInfo.mSession.getDisplayFrame(mAttachInfo.mWindow, outRect);
8701             } catch (RemoteException e) {
8702                 return;
8703             }
8704             // XXX This is really broken, and probably all needs to be done
8705             // in the window manager, and we need to know more about whether
8706             // we want the area behind or in front of the IME.
8707             final Rect insets = mAttachInfo.mVisibleInsets;
8708             outRect.left += insets.left;
8709             outRect.top += insets.top;
8710             outRect.right -= insets.right;
8711             outRect.bottom -= insets.bottom;
8712             return;
8713         }
8714         // The view is not attached to a display so we don't have a context.
8715         // Make a best guess about the display size.
8716         Display d = DisplayManagerGlobal.getInstance().getRealDisplay(Display.DEFAULT_DISPLAY);
8717         d.getRectSize(outRect);
8718     }
8719
8720     /**
8721      * Dispatch a notification about a resource configuration change down
8722      * the view hierarchy.
8723      * ViewGroups should override to route to their children.
8724      *
8725      * @param newConfig The new resource configuration.
8726      *
8727      * @see #onConfigurationChanged(android.content.res.Configuration)
8728      */
8729     public void dispatchConfigurationChanged(Configuration newConfig) {
8730         onConfigurationChanged(newConfig);
8731     }
8732
8733     /**
8734      * Called when the current configuration of the resources being used
8735      * by the application have changed.  You can use this to decide when
8736      * to reload resources that can changed based on orientation and other
8737      * configuration characterstics.  You only need to use this if you are
8738      * not relying on the normal {@link android.app.Activity} mechanism of
8739      * recreating the activity instance upon a configuration change.
8740      *
8741      * @param newConfig The new resource configuration.
8742      */
8743     protected void onConfigurationChanged(Configuration newConfig) {
8744     }
8745
8746     /**
8747      * Private function to aggregate all per-view attributes in to the view
8748      * root.
8749      */
8750     void dispatchCollectViewAttributes(AttachInfo attachInfo, int visibility) {
8751         performCollectViewAttributes(attachInfo, visibility);
8752     }
8753
8754     void performCollectViewAttributes(AttachInfo attachInfo, int visibility) {
8755         if ((visibility & VISIBILITY_MASK) == VISIBLE) {
8756             if ((mViewFlags & KEEP_SCREEN_ON) == KEEP_SCREEN_ON) {
8757                 attachInfo.mKeepScreenOn = true;
8758             }
8759             attachInfo.mSystemUiVisibility |= mSystemUiVisibility;
8760             ListenerInfo li = mListenerInfo;
8761             if (li != null && li.mOnSystemUiVisibilityChangeListener != null) {
8762                 attachInfo.mHasSystemUiListeners = true;
8763             }
8764         }
8765     }
8766
8767     void needGlobalAttributesUpdate(boolean force) {
8768         final AttachInfo ai = mAttachInfo;
8769         if (ai != null && !ai.mRecomputeGlobalAttributes) {
8770             if (force || ai.mKeepScreenOn || (ai.mSystemUiVisibility != 0)
8771                     || ai.mHasSystemUiListeners) {
8772                 ai.mRecomputeGlobalAttributes = true;
8773             }
8774         }
8775     }
8776
8777     /**
8778      * Returns whether the device is currently in touch mode.  Touch mode is entered
8779      * once the user begins interacting with the device by touch, and affects various
8780      * things like whether focus is always visible to the user.
8781      *
8782      * @return Whether the device is in touch mode.
8783      */
8784     @ViewDebug.ExportedProperty
8785     public boolean isInTouchMode() {
8786         if (mAttachInfo != null) {
8787             return mAttachInfo.mInTouchMode;
8788         } else {
8789             return ViewRootImpl.isInTouchMode();
8790         }
8791     }
8792
8793     /**
8794      * Returns the context the view is running in, through which it can
8795      * access the current theme, resources, etc.
8796      *
8797      * @return The view's Context.
8798      */
8799     @ViewDebug.CapturedViewProperty
8800     public final Context getContext() {
8801         return mContext;
8802     }
8803
8804     /**
8805      * Handle a key event before it is processed by any input method
8806      * associated with the view hierarchy.  This can be used to intercept
8807      * key events in special situations before the IME consumes them; a
8808      * typical example would be handling the BACK key to update the application's
8809      * UI instead of allowing the IME to see it and close itself.
8810      *
8811      * @param keyCode The value in event.getKeyCode().
8812      * @param event Description of the key event.
8813      * @return If you handled the event, return true. If you want to allow the
8814      *         event to be handled by the next receiver, return false.
8815      */
8816     public boolean onKeyPreIme(int keyCode, KeyEvent event) {
8817         return false;
8818     }
8819
8820     /**
8821      * Default implementation of {@link KeyEvent.Callback#onKeyDown(int, KeyEvent)
8822      * KeyEvent.Callback.onKeyDown()}: perform press of the view
8823      * when {@link KeyEvent#KEYCODE_DPAD_CENTER} or {@link KeyEvent#KEYCODE_ENTER}
8824      * is released, if the view is enabled and clickable.
8825      *
8826      * <p>Key presses in software keyboards will generally NOT trigger this listener,
8827      * although some may elect to do so in some situations. Do not rely on this to
8828      * catch software key presses.
8829      *
8830      * @param keyCode A key code that represents the button pressed, from
8831      *                {@link android.view.KeyEvent}.
8832      * @param event   The KeyEvent object that defines the button action.
8833      */
8834     public boolean onKeyDown(int keyCode, KeyEvent event) {
8835         boolean result = false;
8836
8837         if (KeyEvent.isConfirmKey(keyCode)) {
8838             if ((mViewFlags & ENABLED_MASK) == DISABLED) {
8839                 return true;
8840             }
8841             // Long clickable items don't necessarily have to be clickable
8842             if (((mViewFlags & CLICKABLE) == CLICKABLE ||
8843                     (mViewFlags & LONG_CLICKABLE) == LONG_CLICKABLE) &&
8844                     (event.getRepeatCount() == 0)) {
8845                 setPressed(true);
8846                 checkForLongClick(0);
8847                 return true;
8848             }
8849         }
8850         return result;
8851     }
8852
8853     /**
8854      * Default implementation of {@link KeyEvent.Callback#onKeyLongPress(int, KeyEvent)
8855      * KeyEvent.Callback.onKeyLongPress()}: always returns false (doesn't handle
8856      * the event).
8857      * <p>Key presses in software keyboards will generally NOT trigger this listener,
8858      * although some may elect to do so in some situations. Do not rely on this to
8859      * catch software key presses.
8860      */
8861     public boolean onKeyLongPress(int keyCode, KeyEvent event) {
8862         return false;
8863     }
8864
8865     /**
8866      * Default implementation of {@link KeyEvent.Callback#onKeyUp(int, KeyEvent)
8867      * KeyEvent.Callback.onKeyUp()}: perform clicking of the view
8868      * when {@link KeyEvent#KEYCODE_DPAD_CENTER} or
8869      * {@link KeyEvent#KEYCODE_ENTER} is released.
8870      * <p>Key presses in software keyboards will generally NOT trigger this listener,
8871      * although some may elect to do so in some situations. Do not rely on this to
8872      * catch software key presses.
8873      *
8874      * @param keyCode A key code that represents the button pressed, from
8875      *                {@link android.view.KeyEvent}.
8876      * @param event   The KeyEvent object that defines the button action.
8877      */
8878     public boolean onKeyUp(int keyCode, KeyEvent event) {
8879         if (KeyEvent.isConfirmKey(keyCode)) {
8880             if ((mViewFlags & ENABLED_MASK) == DISABLED) {
8881                 return true;
8882             }
8883             if ((mViewFlags & CLICKABLE) == CLICKABLE && isPressed()) {
8884                 setPressed(false);
8885
8886                 if (!mHasPerformedLongPress) {
8887                     // This is a tap, so remove the longpress check
8888                     removeLongPressCallback();
8889                     return performClick();
8890                 }
8891             }
8892         }
8893         return false;
8894     }
8895
8896     /**
8897      * Default implementation of {@link KeyEvent.Callback#onKeyMultiple(int, int, KeyEvent)
8898      * KeyEvent.Callback.onKeyMultiple()}: always returns false (doesn't handle
8899      * the event).
8900      * <p>Key presses in software keyboards will generally NOT trigger this listener,
8901      * although some may elect to do so in some situations. Do not rely on this to
8902      * catch software key presses.
8903      *
8904      * @param keyCode     A key code that represents the button pressed, from
8905      *                    {@link android.view.KeyEvent}.
8906      * @param repeatCount The number of times the action was made.
8907      * @param event       The KeyEvent object that defines the button action.
8908      */
8909     public boolean onKeyMultiple(int keyCode, int repeatCount, KeyEvent event) {
8910         return false;
8911     }
8912
8913     /**
8914      * Called on the focused view when a key shortcut event is not handled.
8915      * Override this method to implement local key shortcuts for the View.
8916      * Key shortcuts can also be implemented by setting the
8917      * {@link MenuItem#setShortcut(char, char) shortcut} property of menu items.
8918      *
8919      * @param keyCode The value in event.getKeyCode().
8920      * @param event Description of the key event.
8921      * @return If you handled the event, return true. If you want to allow the
8922      *         event to be handled by the next receiver, return false.
8923      */
8924     public boolean onKeyShortcut(int keyCode, KeyEvent event) {
8925         return false;
8926     }
8927
8928     /**
8929      * Check whether the called view is a text editor, in which case it
8930      * would make sense to automatically display a soft input window for
8931      * it.  Subclasses should override this if they implement
8932      * {@link #onCreateInputConnection(EditorInfo)} to return true if
8933      * a call on that method would return a non-null InputConnection, and
8934      * they are really a first-class editor that the user would normally
8935      * start typing on when the go into a window containing your view.
8936      *
8937      * <p>The default implementation always returns false.  This does
8938      * <em>not</em> mean that its {@link #onCreateInputConnection(EditorInfo)}
8939      * will not be called or the user can not otherwise perform edits on your
8940      * view; it is just a hint to the system that this is not the primary
8941      * purpose of this view.
8942      *
8943      * @return Returns true if this view is a text editor, else false.
8944      */
8945     public boolean onCheckIsTextEditor() {
8946         return false;
8947     }
8948
8949     /**
8950      * Create a new InputConnection for an InputMethod to interact
8951      * with the view.  The default implementation returns null, since it doesn't
8952      * support input methods.  You can override this to implement such support.
8953      * This is only needed for views that take focus and text input.
8954      *
8955      * <p>When implementing this, you probably also want to implement
8956      * {@link #onCheckIsTextEditor()} to indicate you will return a
8957      * non-null InputConnection.</p>
8958      *
8959      * <p>Also, take good care to fill in the {@link android.view.inputmethod.EditorInfo}
8960      * object correctly and in its entirety, so that the connected IME can rely
8961      * on its values. For example, {@link android.view.inputmethod.EditorInfo#initialSelStart}
8962      * and  {@link android.view.inputmethod.EditorInfo#initialSelEnd} members
8963      * must be filled in with the correct cursor position for IMEs to work correctly
8964      * with your application.</p>
8965      *
8966      * @param outAttrs Fill in with attribute information about the connection.
8967      */
8968     public InputConnection onCreateInputConnection(EditorInfo outAttrs) {
8969         return null;
8970     }
8971
8972     /**
8973      * Called by the {@link android.view.inputmethod.InputMethodManager}
8974      * when a view who is not the current
8975      * input connection target is trying to make a call on the manager.  The
8976      * default implementation returns false; you can override this to return
8977      * true for certain views if you are performing InputConnection proxying
8978      * to them.
8979      * @param view The View that is making the InputMethodManager call.
8980      * @return Return true to allow the call, false to reject.
8981      */
8982     public boolean checkInputConnectionProxy(View view) {
8983         return false;
8984     }
8985
8986     /**
8987      * Show the context menu for this view. It is not safe to hold on to the
8988      * menu after returning from this method.
8989      *
8990      * You should normally not overload this method. Overload
8991      * {@link #onCreateContextMenu(ContextMenu)} or define an
8992      * {@link OnCreateContextMenuListener} to add items to the context menu.
8993      *
8994      * @param menu The context menu to populate
8995      */
8996     public void createContextMenu(ContextMenu menu) {
8997         ContextMenuInfo menuInfo = getContextMenuInfo();
8998
8999         // Sets the current menu info so all items added to menu will have
9000         // my extra info set.
9001         ((MenuBuilder)menu).setCurrentMenuInfo(menuInfo);
9002
9003         onCreateContextMenu(menu);
9004         ListenerInfo li = mListenerInfo;
9005         if (li != null && li.mOnCreateContextMenuListener != null) {
9006             li.mOnCreateContextMenuListener.onCreateContextMenu(menu, this, menuInfo);
9007         }
9008
9009         // Clear the extra information so subsequent items that aren't mine don't
9010         // have my extra info.
9011         ((MenuBuilder)menu).setCurrentMenuInfo(null);
9012
9013         if (mParent != null) {
9014             mParent.createContextMenu(menu);
9015         }
9016     }
9017
9018     /**
9019      * Views should implement this if they have extra information to associate
9020      * with the context menu. The return result is supplied as a parameter to
9021      * the {@link OnCreateContextMenuListener#onCreateContextMenu(ContextMenu, View, ContextMenuInfo)}
9022      * callback.
9023      *
9024      * @return Extra information about the item for which the context menu
9025      *         should be shown. This information will vary across different
9026      *         subclasses of View.
9027      */
9028     protected ContextMenuInfo getContextMenuInfo() {
9029         return null;
9030     }
9031
9032     /**
9033      * Views should implement this if the view itself is going to add items to
9034      * the context menu.
9035      *
9036      * @param menu the context menu to populate
9037      */
9038     protected void onCreateContextMenu(ContextMenu menu) {
9039     }
9040
9041     /**
9042      * Implement this method to handle trackball motion events.  The
9043      * <em>relative</em> movement of the trackball since the last event
9044      * can be retrieve with {@link MotionEvent#getX MotionEvent.getX()} and
9045      * {@link MotionEvent#getY MotionEvent.getY()}.  These are normalized so
9046      * that a movement of 1 corresponds to the user pressing one DPAD key (so
9047      * they will often be fractional values, representing the more fine-grained
9048      * movement information available from a trackball).
9049      *
9050      * @param event The motion event.
9051      * @return True if the event was handled, false otherwise.
9052      */
9053     public boolean onTrackballEvent(MotionEvent event) {
9054         return false;
9055     }
9056
9057     /**
9058      * Implement this method to handle generic motion events.
9059      * <p>
9060      * Generic motion events describe joystick movements, mouse hovers, track pad
9061      * touches, scroll wheel movements and other input events.  The
9062      * {@link MotionEvent#getSource() source} of the motion event specifies
9063      * the class of input that was received.  Implementations of this method
9064      * must examine the bits in the source before processing the event.
9065      * The following code example shows how this is done.
9066      * </p><p>
9067      * Generic motion events with source class {@link InputDevice#SOURCE_CLASS_POINTER}
9068      * are delivered to the view under the pointer.  All other generic motion events are
9069      * delivered to the focused view.
9070      * </p>
9071      * <pre> public boolean onGenericMotionEvent(MotionEvent event) {
9072      *     if (event.isFromSource(InputDevice.SOURCE_CLASS_JOYSTICK)) {
9073      *         if (event.getAction() == MotionEvent.ACTION_MOVE) {
9074      *             // process the joystick movement...
9075      *             return true;
9076      *         }
9077      *     }
9078      *     if (event.isFromSource(InputDevice.SOURCE_CLASS_POINTER)) {
9079      *         switch (event.getAction()) {
9080      *             case MotionEvent.ACTION_HOVER_MOVE:
9081      *                 // process the mouse hover movement...
9082      *                 return true;
9083      *             case MotionEvent.ACTION_SCROLL:
9084      *                 // process the scroll wheel movement...
9085      *                 return true;
9086      *         }
9087      *     }
9088      *     return super.onGenericMotionEvent(event);
9089      * }</pre>
9090      *
9091      * @param event The generic motion event being processed.
9092      * @return True if the event was handled, false otherwise.
9093      */
9094     public boolean onGenericMotionEvent(MotionEvent event) {
9095         return false;
9096     }
9097
9098     /**
9099      * Implement this method to handle hover events.
9100      * <p>
9101      * This method is called whenever a pointer is hovering into, over, or out of the
9102      * bounds of a view and the view is not currently being touched.
9103      * Hover events are represented as pointer events with action
9104      * {@link MotionEvent#ACTION_HOVER_ENTER}, {@link MotionEvent#ACTION_HOVER_MOVE},
9105      * or {@link MotionEvent#ACTION_HOVER_EXIT}.
9106      * </p>
9107      * <ul>
9108      * <li>The view receives a hover event with action {@link MotionEvent#ACTION_HOVER_ENTER}
9109      * when the pointer enters the bounds of the view.</li>
9110      * <li>The view receives a hover event with action {@link MotionEvent#ACTION_HOVER_MOVE}
9111      * when the pointer has already entered the bounds of the view and has moved.</li>
9112      * <li>The view receives a hover event with action {@link MotionEvent#ACTION_HOVER_EXIT}
9113      * when the pointer has exited the bounds of the view or when the pointer is
9114      * about to go down due to a button click, tap, or similar user action that
9115      * causes the view to be touched.</li>
9116      * </ul>
9117      * <p>
9118      * The view should implement this method to return true to indicate that it is
9119      * handling the hover event, such as by changing its drawable state.
9120      * </p><p>
9121      * The default implementation calls {@link #setHovered} to update the hovered state
9122      * of the view when a hover enter or hover exit event is received, if the view
9123      * is enabled and is clickable.  The default implementation also sends hover
9124      * accessibility events.
9125      * </p>
9126      *
9127      * @param event The motion event that describes the hover.
9128      * @return True if the view handled the hover event.
9129      *
9130      * @see #isHovered
9131      * @see #setHovered
9132      * @see #onHoverChanged
9133      */
9134     public boolean onHoverEvent(MotionEvent event) {
9135         // The root view may receive hover (or touch) events that are outside the bounds of
9136         // the window.  This code ensures that we only send accessibility events for
9137         // hovers that are actually within the bounds of the root view.
9138         final int action = event.getActionMasked();
9139         if (!mSendingHoverAccessibilityEvents) {
9140             if ((action == MotionEvent.ACTION_HOVER_ENTER
9141                     || action == MotionEvent.ACTION_HOVER_MOVE)
9142                     && !hasHoveredChild()
9143                     && pointInView(event.getX(), event.getY())) {
9144                 sendAccessibilityHoverEvent(AccessibilityEvent.TYPE_VIEW_HOVER_ENTER);
9145                 mSendingHoverAccessibilityEvents = true;
9146             }
9147         } else {
9148             if (action == MotionEvent.ACTION_HOVER_EXIT
9149                     || (action == MotionEvent.ACTION_MOVE
9150                             && !pointInView(event.getX(), event.getY()))) {
9151                 mSendingHoverAccessibilityEvents = false;
9152                 sendAccessibilityHoverEvent(AccessibilityEvent.TYPE_VIEW_HOVER_EXIT);
9153             }
9154         }
9155
9156         if (isHoverable()) {
9157             switch (action) {
9158                 case MotionEvent.ACTION_HOVER_ENTER:
9159                     setHovered(true);
9160                     break;
9161                 case MotionEvent.ACTION_HOVER_EXIT:
9162                     setHovered(false);
9163                     break;
9164             }
9165
9166             // Dispatch the event to onGenericMotionEvent before returning true.
9167             // This is to provide compatibility with existing applications that
9168             // handled HOVER_MOVE events in onGenericMotionEvent and that would
9169             // break because of the new default handling for hoverable views
9170             // in onHoverEvent.
9171             // Note that onGenericMotionEvent will be called by default when
9172             // onHoverEvent returns false (refer to dispatchGenericMotionEvent).
9173             dispatchGenericMotionEventInternal(event);
9174             // The event was already handled by calling setHovered(), so always
9175             // return true.
9176             return true;
9177         }
9178
9179         return false;
9180     }
9181
9182     /**
9183      * Returns true if the view should handle {@link #onHoverEvent}
9184      * by calling {@link #setHovered} to change its hovered state.
9185      *
9186      * @return True if the view is hoverable.
9187      */
9188     private boolean isHoverable() {
9189         final int viewFlags = mViewFlags;
9190         if ((viewFlags & ENABLED_MASK) == DISABLED) {
9191             return false;
9192         }
9193
9194         return (viewFlags & CLICKABLE) == CLICKABLE
9195                 || (viewFlags & LONG_CLICKABLE) == LONG_CLICKABLE;
9196     }
9197
9198     /**
9199      * Returns true if the view is currently hovered.
9200      *
9201      * @return True if the view is currently hovered.
9202      *
9203      * @see #setHovered
9204      * @see #onHoverChanged
9205      */
9206     @ViewDebug.ExportedProperty
9207     public boolean isHovered() {
9208         return (mPrivateFlags & PFLAG_HOVERED) != 0;
9209     }
9210
9211     /**
9212      * Sets whether the view is currently hovered.
9213      * <p>
9214      * Calling this method also changes the drawable state of the view.  This
9215      * enables the view to react to hover by using different drawable resources
9216      * to change its appearance.
9217      * </p><p>
9218      * The {@link #onHoverChanged} method is called when the hovered state changes.
9219      * </p>
9220      *
9221      * @param hovered True if the view is hovered.
9222      *
9223      * @see #isHovered
9224      * @see #onHoverChanged
9225      */
9226     public void setHovered(boolean hovered) {
9227         if (hovered) {
9228             if ((mPrivateFlags & PFLAG_HOVERED) == 0) {
9229                 mPrivateFlags |= PFLAG_HOVERED;
9230                 refreshDrawableState();
9231                 onHoverChanged(true);
9232             }
9233         } else {
9234             if ((mPrivateFlags & PFLAG_HOVERED) != 0) {
9235                 mPrivateFlags &= ~PFLAG_HOVERED;
9236                 refreshDrawableState();
9237                 onHoverChanged(false);
9238             }
9239         }
9240     }
9241
9242     /**
9243      * Implement this method to handle hover state changes.
9244      * <p>
9245      * This method is called whenever the hover state changes as a result of a
9246      * call to {@link #setHovered}.
9247      * </p>
9248      *
9249      * @param hovered The current hover state, as returned by {@link #isHovered}.
9250      *
9251      * @see #isHovered
9252      * @see #setHovered
9253      */
9254     public void onHoverChanged(boolean hovered) {
9255     }
9256
9257     /**
9258      * Implement this method to handle touch screen motion events.
9259      * <p>
9260      * If this method is used to detect click actions, it is recommended that
9261      * the actions be performed by implementing and calling
9262      * {@link #performClick()}. This will ensure consistent system behavior,
9263      * including:
9264      * <ul>
9265      * <li>obeying click sound preferences
9266      * <li>dispatching OnClickListener calls
9267      * <li>handling {@link AccessibilityNodeInfo#ACTION_CLICK ACTION_CLICK} when
9268      * accessibility features are enabled
9269      * </ul>
9270      *
9271      * @param event The motion event.
9272      * @return True if the event was handled, false otherwise.
9273      */
9274     public boolean onTouchEvent(MotionEvent event) {
9275         final float x = event.getX();
9276         final float y = event.getY();
9277         final int viewFlags = mViewFlags;
9278
9279         if ((viewFlags & ENABLED_MASK) == DISABLED) {
9280             if (event.getAction() == MotionEvent.ACTION_UP && (mPrivateFlags & PFLAG_PRESSED) != 0) {
9281                 setPressed(false);
9282             }
9283             // A disabled view that is clickable still consumes the touch
9284             // events, it just doesn't respond to them.
9285             return (((viewFlags & CLICKABLE) == CLICKABLE ||
9286                     (viewFlags & LONG_CLICKABLE) == LONG_CLICKABLE));
9287         }
9288
9289         if (mTouchDelegate != null) {
9290             if (mTouchDelegate.onTouchEvent(event)) {
9291                 return true;
9292             }
9293         }
9294
9295         if (((viewFlags & CLICKABLE) == CLICKABLE ||
9296                 (viewFlags & LONG_CLICKABLE) == LONG_CLICKABLE)) {
9297             switch (event.getAction()) {
9298                 case MotionEvent.ACTION_UP:
9299                     boolean prepressed = (mPrivateFlags & PFLAG_PREPRESSED) != 0;
9300                     if ((mPrivateFlags & PFLAG_PRESSED) != 0 || prepressed) {
9301                         // take focus if we don't have it already and we should in
9302                         // touch mode.
9303                         boolean focusTaken = false;
9304                         if (isFocusable() && isFocusableInTouchMode() && !isFocused()) {
9305                             focusTaken = requestFocus();
9306                         }
9307
9308                         if (prepressed) {
9309                             // The button is being released before we actually
9310                             // showed it as pressed.  Make it show the pressed
9311                             // state now (before scheduling the click) to ensure
9312                             // the user sees it.
9313                             setPressed(true, x, y);
9314                        }
9315
9316                         if (!mHasPerformedLongPress) {
9317                             // This is a tap, so remove the longpress check
9318                             removeLongPressCallback();
9319
9320                             // Only perform take click actions if we were in the pressed state
9321                             if (!focusTaken) {
9322                                 // Use a Runnable and post this rather than calling
9323                                 // performClick directly. This lets other visual state
9324                                 // of the view update before click actions start.
9325                                 if (mPerformClick == null) {
9326                                     mPerformClick = new PerformClick();
9327                                 }
9328                                 if (!post(mPerformClick)) {
9329                                     performClick();
9330                                 }
9331                             }
9332                         }
9333
9334                         if (mUnsetPressedState == null) {
9335                             mUnsetPressedState = new UnsetPressedState();
9336                         }
9337
9338                         if (prepressed) {
9339                             postDelayed(mUnsetPressedState,
9340                                     ViewConfiguration.getPressedStateDuration());
9341                         } else if (!post(mUnsetPressedState)) {
9342                             // If the post failed, unpress right now
9343                             mUnsetPressedState.run();
9344                         }
9345
9346                         removeTapCallback();
9347                     }
9348                     break;
9349
9350                 case MotionEvent.ACTION_DOWN:
9351                     mHasPerformedLongPress = false;
9352
9353                     if (performButtonActionOnTouchDown(event)) {
9354                         break;
9355                     }
9356
9357                     // Walk up the hierarchy to determine if we're inside a scrolling container.
9358                     boolean isInScrollingContainer = isInScrollingContainer();
9359
9360                     // For views inside a scrolling container, delay the pressed feedback for
9361                     // a short period in case this is a scroll.
9362                     if (isInScrollingContainer) {
9363                         mPrivateFlags |= PFLAG_PREPRESSED;
9364                         if (mPendingCheckForTap == null) {
9365                             mPendingCheckForTap = new CheckForTap();
9366                         }
9367                         mPendingCheckForTap.x = event.getX();
9368                         mPendingCheckForTap.y = event.getY();
9369                         postDelayed(mPendingCheckForTap, ViewConfiguration.getTapTimeout());
9370                     } else {
9371                         // Not inside a scrolling container, so show the feedback right away
9372                         setPressed(true, x, y);
9373                         checkForLongClick(0);
9374                     }
9375                     break;
9376
9377                 case MotionEvent.ACTION_CANCEL:
9378                     setPressed(false);
9379                     removeTapCallback();
9380                     removeLongPressCallback();
9381                     break;
9382
9383                 case MotionEvent.ACTION_MOVE:
9384                     drawableHotspotChanged(x, y);
9385
9386                     // Be lenient about moving outside of buttons
9387                     if (!pointInView(x, y, mTouchSlop)) {
9388                         // Outside button
9389                         removeTapCallback();
9390                         if ((mPrivateFlags & PFLAG_PRESSED) != 0) {
9391                             // Remove any future long press/tap checks
9392                             removeLongPressCallback();
9393
9394                             setPressed(false);
9395                         }
9396                     }
9397                     break;
9398             }
9399
9400             return true;
9401         }
9402
9403         return false;
9404     }
9405
9406     /**
9407      * @hide
9408      */
9409     public boolean isInScrollingContainer() {
9410         ViewParent p = getParent();
9411         while (p != null && p instanceof ViewGroup) {
9412             if (((ViewGroup) p).shouldDelayChildPressedState()) {
9413                 return true;
9414             }
9415             p = p.getParent();
9416         }
9417         return false;
9418     }
9419
9420     /**
9421      * Remove the longpress detection timer.
9422      */
9423     private void removeLongPressCallback() {
9424         if (mPendingCheckForLongPress != null) {
9425           removeCallbacks(mPendingCheckForLongPress);
9426         }
9427     }
9428
9429     /**
9430      * Remove the pending click action
9431      */
9432     private void removePerformClickCallback() {
9433         if (mPerformClick != null) {
9434             removeCallbacks(mPerformClick);
9435         }
9436     }
9437
9438     /**
9439      * Remove the prepress detection timer.
9440      */
9441     private void removeUnsetPressCallback() {
9442         if ((mPrivateFlags & PFLAG_PRESSED) != 0 && mUnsetPressedState != null) {
9443             setPressed(false);
9444             removeCallbacks(mUnsetPressedState);
9445         }
9446     }
9447
9448     /**
9449      * Remove the tap detection timer.
9450      */
9451     private void removeTapCallback() {
9452         if (mPendingCheckForTap != null) {
9453             mPrivateFlags &= ~PFLAG_PREPRESSED;
9454             removeCallbacks(mPendingCheckForTap);
9455         }
9456     }
9457
9458     /**
9459      * Cancels a pending long press.  Your subclass can use this if you
9460      * want the context menu to come up if the user presses and holds
9461      * at the same place, but you don't want it to come up if they press
9462      * and then move around enough to cause scrolling.
9463      */
9464     public void cancelLongPress() {
9465         removeLongPressCallback();
9466
9467         /*
9468          * The prepressed state handled by the tap callback is a display
9469          * construct, but the tap callback will post a long press callback
9470          * less its own timeout. Remove it here.
9471          */
9472         removeTapCallback();
9473     }
9474
9475     /**
9476      * Remove the pending callback for sending a
9477      * {@link AccessibilityEvent#TYPE_VIEW_SCROLLED} accessibility event.
9478      */
9479     private void removeSendViewScrolledAccessibilityEventCallback() {
9480         if (mSendViewScrolledAccessibilityEvent != null) {
9481             removeCallbacks(mSendViewScrolledAccessibilityEvent);
9482             mSendViewScrolledAccessibilityEvent.mIsPending = false;
9483         }
9484     }
9485
9486     /**
9487      * Sets the TouchDelegate for this View.
9488      */
9489     public void setTouchDelegate(TouchDelegate delegate) {
9490         mTouchDelegate = delegate;
9491     }
9492
9493     /**
9494      * Gets the TouchDelegate for this View.
9495      */
9496     public TouchDelegate getTouchDelegate() {
9497         return mTouchDelegate;
9498     }
9499
9500     /**
9501      * Request unbuffered dispatch of the given stream of MotionEvents to this View.
9502      *
9503      * Until this View receives a corresponding {@link MotionEvent#ACTION_UP}, ask that the input
9504      * system not batch {@link MotionEvent}s but instead deliver them as soon as they're
9505      * available. This method should only be called for touch events.
9506      *
9507      * <p class="note">This api is not intended for most applications. Buffered dispatch
9508      * provides many of benefits, and just requesting unbuffered dispatch on most MotionEvent
9509      * streams will not improve your input latency. Side effects include: increased latency,
9510      * jittery scrolls and inability to take advantage of system resampling. Talk to your input
9511      * professional to see if {@link #requestUnbufferedDispatch(MotionEvent)} is right for
9512      * you.</p>
9513      */
9514     public final void requestUnbufferedDispatch(MotionEvent event) {
9515         final int action = event.getAction();
9516         if (mAttachInfo == null
9517                 || action != MotionEvent.ACTION_DOWN && action != MotionEvent.ACTION_MOVE
9518                 || !event.isTouchEvent()) {
9519             return;
9520         }
9521         mAttachInfo.mUnbufferedDispatchRequested = true;
9522     }
9523
9524     /**
9525      * Set flags controlling behavior of this view.
9526      *
9527      * @param flags Constant indicating the value which should be set
9528      * @param mask Constant indicating the bit range that should be changed
9529      */
9530     void setFlags(int flags, int mask) {
9531         final boolean accessibilityEnabled =
9532                 AccessibilityManager.getInstance(mContext).isEnabled();
9533         final boolean oldIncludeForAccessibility = accessibilityEnabled && includeForAccessibility();
9534
9535         int old = mViewFlags;
9536         mViewFlags = (mViewFlags & ~mask) | (flags & mask);
9537
9538         int changed = mViewFlags ^ old;
9539         if (changed == 0) {
9540             return;
9541         }
9542         int privateFlags = mPrivateFlags;
9543
9544         /* Check if the FOCUSABLE bit has changed */
9545         if (((changed & FOCUSABLE_MASK) != 0) &&
9546                 ((privateFlags & PFLAG_HAS_BOUNDS) !=0)) {
9547             if (((old & FOCUSABLE_MASK) == FOCUSABLE)
9548                     && ((privateFlags & PFLAG_FOCUSED) != 0)) {
9549                 /* Give up focus if we are no longer focusable */
9550                 clearFocus();
9551             } else if (((old & FOCUSABLE_MASK) == NOT_FOCUSABLE)
9552                     && ((privateFlags & PFLAG_FOCUSED) == 0)) {
9553                 /*
9554                  * Tell the view system that we are now available to take focus
9555                  * if no one else already has it.
9556                  */
9557                 if (mParent != null) mParent.focusableViewAvailable(this);
9558             }
9559         }
9560
9561         final int newVisibility = flags & VISIBILITY_MASK;
9562         if (newVisibility == VISIBLE) {
9563             if ((changed & VISIBILITY_MASK) != 0) {
9564                 /*
9565                  * If this view is becoming visible, invalidate it in case it changed while
9566                  * it was not visible. Marking it drawn ensures that the invalidation will
9567                  * go through.
9568                  */
9569                 mPrivateFlags |= PFLAG_DRAWN;
9570                 invalidate(true);
9571
9572                 needGlobalAttributesUpdate(true);
9573
9574                 // a view becoming visible is worth notifying the parent
9575                 // about in case nothing has focus.  even if this specific view
9576                 // isn't focusable, it may contain something that is, so let
9577                 // the root view try to give this focus if nothing else does.
9578                 if ((mParent != null) && (mBottom > mTop) && (mRight > mLeft)) {
9579                     mParent.focusableViewAvailable(this);
9580                 }
9581             }
9582         }
9583
9584         /* Check if the GONE bit has changed */
9585         if ((changed & GONE) != 0) {
9586             needGlobalAttributesUpdate(false);
9587             requestLayout();
9588
9589             if (((mViewFlags & VISIBILITY_MASK) == GONE)) {
9590                 if (hasFocus()) clearFocus();
9591                 clearAccessibilityFocus();
9592                 destroyDrawingCache();
9593                 if (mParent instanceof View) {
9594                     // GONE views noop invalidation, so invalidate the parent
9595                     ((View) mParent).invalidate(true);
9596                 }
9597                 // Mark the view drawn to ensure that it gets invalidated properly the next
9598                 // time it is visible and gets invalidated
9599                 mPrivateFlags |= PFLAG_DRAWN;
9600             }
9601             if (mAttachInfo != null) {
9602                 mAttachInfo.mViewVisibilityChanged = true;
9603             }
9604         }
9605
9606         /* Check if the VISIBLE bit has changed */
9607         if ((changed & INVISIBLE) != 0) {
9608             needGlobalAttributesUpdate(false);
9609             /*
9610              * If this view is becoming invisible, set the DRAWN flag so that
9611              * the next invalidate() will not be skipped.
9612              */
9613             mPrivateFlags |= PFLAG_DRAWN;
9614
9615             if (((mViewFlags & VISIBILITY_MASK) == INVISIBLE)) {
9616                 // root view becoming invisible shouldn't clear focus and accessibility focus
9617                 if (getRootView() != this) {
9618                     if (hasFocus()) clearFocus();
9619                     clearAccessibilityFocus();
9620                 }
9621             }
9622             if (mAttachInfo != null) {
9623                 mAttachInfo.mViewVisibilityChanged = true;
9624             }
9625         }
9626
9627         if ((changed & VISIBILITY_MASK) != 0) {
9628             // If the view is invisible, cleanup its display list to free up resources
9629             if (newVisibility != VISIBLE && mAttachInfo != null) {
9630                 cleanupDraw();
9631             }
9632
9633             if (mParent instanceof ViewGroup) {
9634                 ((ViewGroup) mParent).onChildVisibilityChanged(this,
9635                         (changed & VISIBILITY_MASK), newVisibility);
9636                 ((View) mParent).invalidate(true);
9637             } else if (mParent != null) {
9638                 mParent.invalidateChild(this, null);
9639             }
9640             dispatchVisibilityChanged(this, newVisibility);
9641
9642             notifySubtreeAccessibilityStateChangedIfNeeded();
9643         }
9644
9645         if ((changed & WILL_NOT_CACHE_DRAWING) != 0) {
9646             destroyDrawingCache();
9647         }
9648
9649         if ((changed & DRAWING_CACHE_ENABLED) != 0) {
9650             destroyDrawingCache();
9651             mPrivateFlags &= ~PFLAG_DRAWING_CACHE_VALID;
9652             invalidateParentCaches();
9653         }
9654
9655         if ((changed & DRAWING_CACHE_QUALITY_MASK) != 0) {
9656             destroyDrawingCache();
9657             mPrivateFlags &= ~PFLAG_DRAWING_CACHE_VALID;
9658         }
9659
9660         if ((changed & DRAW_MASK) != 0) {
9661             if ((mViewFlags & WILL_NOT_DRAW) != 0) {
9662                 if (mBackground != null) {
9663                     mPrivateFlags &= ~PFLAG_SKIP_DRAW;
9664                     mPrivateFlags |= PFLAG_ONLY_DRAWS_BACKGROUND;
9665                 } else {
9666                     mPrivateFlags |= PFLAG_SKIP_DRAW;
9667                 }
9668             } else {
9669                 mPrivateFlags &= ~PFLAG_SKIP_DRAW;
9670             }
9671             requestLayout();
9672             invalidate(true);
9673         }
9674
9675         if ((changed & KEEP_SCREEN_ON) != 0) {
9676             if (mParent != null && mAttachInfo != null && !mAttachInfo.mRecomputeGlobalAttributes) {
9677                 mParent.recomputeViewAttributes(this);
9678             }
9679         }
9680
9681         if (accessibilityEnabled) {
9682             if ((changed & FOCUSABLE_MASK) != 0 || (changed & VISIBILITY_MASK) != 0
9683                     || (changed & CLICKABLE) != 0 || (changed & LONG_CLICKABLE) != 0) {
9684                 if (oldIncludeForAccessibility != includeForAccessibility()) {
9685                     notifySubtreeAccessibilityStateChangedIfNeeded();
9686                 } else {
9687                     notifyViewAccessibilityStateChangedIfNeeded(
9688                             AccessibilityEvent.CONTENT_CHANGE_TYPE_UNDEFINED);
9689                 }
9690             } else if ((changed & ENABLED_MASK) != 0) {
9691                 notifyViewAccessibilityStateChangedIfNeeded(
9692                         AccessibilityEvent.CONTENT_CHANGE_TYPE_UNDEFINED);
9693             }
9694         }
9695     }
9696
9697     /**
9698      * Change the view's z order in the tree, so it's on top of other sibling
9699      * views. This ordering change may affect layout, if the parent container
9700      * uses an order-dependent layout scheme (e.g., LinearLayout). Prior
9701      * to {@link android.os.Build.VERSION_CODES#KITKAT} this
9702      * method should be followed by calls to {@link #requestLayout()} and
9703      * {@link View#invalidate()} on the view's parent to force the parent to redraw
9704      * with the new child ordering.
9705      *
9706      * @see ViewGroup#bringChildToFront(View)
9707      */
9708     public void bringToFront() {
9709         if (mParent != null) {
9710             mParent.bringChildToFront(this);
9711         }
9712     }
9713
9714     /**
9715      * This is called in response to an internal scroll in this view (i.e., the
9716      * view scrolled its own contents). This is typically as a result of
9717      * {@link #scrollBy(int, int)} or {@link #scrollTo(int, int)} having been
9718      * called.
9719      *
9720      * @param l Current horizontal scroll origin.
9721      * @param t Current vertical scroll origin.
9722      * @param oldl Previous horizontal scroll origin.
9723      * @param oldt Previous vertical scroll origin.
9724      */
9725     protected void onScrollChanged(int l, int t, int oldl, int oldt) {
9726         if (AccessibilityManager.getInstance(mContext).isEnabled()) {
9727             postSendViewScrolledAccessibilityEventCallback();
9728         }
9729
9730         mBackgroundSizeChanged = true;
9731
9732         final AttachInfo ai = mAttachInfo;
9733         if (ai != null) {
9734             ai.mViewScrollChanged = true;
9735         }
9736     }
9737
9738     /**
9739      * Interface definition for a callback to be invoked when the layout bounds of a view
9740      * changes due to layout processing.
9741      */
9742     public interface OnLayoutChangeListener {
9743         /**
9744          * Called when the layout bounds of a view changes due to layout processing.
9745          *
9746          * @param v The view whose bounds have changed.
9747          * @param left The new value of the view's left property.
9748          * @param top The new value of the view's top property.
9749          * @param right The new value of the view's right property.
9750          * @param bottom The new value of the view's bottom property.
9751          * @param oldLeft The previous value of the view's left property.
9752          * @param oldTop The previous value of the view's top property.
9753          * @param oldRight The previous value of the view's right property.
9754          * @param oldBottom The previous value of the view's bottom property.
9755          */
9756         void onLayoutChange(View v, int left, int top, int right, int bottom,
9757             int oldLeft, int oldTop, int oldRight, int oldBottom);
9758     }
9759
9760     /**
9761      * This is called during layout when the size of this view has changed. If
9762      * you were just added to the view hierarchy, you're called with the old
9763      * values of 0.
9764      *
9765      * @param w Current width of this view.
9766      * @param h Current height of this view.
9767      * @param oldw Old width of this view.
9768      * @param oldh Old height of this view.
9769      */
9770     protected void onSizeChanged(int w, int h, int oldw, int oldh) {
9771     }
9772
9773     /**
9774      * Called by draw to draw the child views. This may be overridden
9775      * by derived classes to gain control just before its children are drawn
9776      * (but after its own view has been drawn).
9777      * @param canvas the canvas on which to draw the view
9778      */
9779     protected void dispatchDraw(Canvas canvas) {
9780
9781     }
9782
9783     /**
9784      * Gets the parent of this view. Note that the parent is a
9785      * ViewParent and not necessarily a View.
9786      *
9787      * @return Parent of this view.
9788      */
9789     public final ViewParent getParent() {
9790         return mParent;
9791     }
9792
9793     /**
9794      * Set the horizontal scrolled position of your view. This will cause a call to
9795      * {@link #onScrollChanged(int, int, int, int)} and the view will be
9796      * invalidated.
9797      * @param value the x position to scroll to
9798      */
9799     public void setScrollX(int value) {
9800         scrollTo(value, mScrollY);
9801     }
9802
9803     /**
9804      * Set the vertical scrolled position of your view. This will cause a call to
9805      * {@link #onScrollChanged(int, int, int, int)} and the view will be
9806      * invalidated.
9807      * @param value the y position to scroll to
9808      */
9809     public void setScrollY(int value) {
9810         scrollTo(mScrollX, value);
9811     }
9812
9813     /**
9814      * Return the scrolled left position of this view. This is the left edge of
9815      * the displayed part of your view. You do not need to draw any pixels
9816      * farther left, since those are outside of the frame of your view on
9817      * screen.
9818      *
9819      * @return The left edge of the displayed part of your view, in pixels.
9820      */
9821     public final int getScrollX() {
9822         return mScrollX;
9823     }
9824
9825     /**
9826      * Return the scrolled top position of this view. This is the top edge of
9827      * the displayed part of your view. You do not need to draw any pixels above
9828      * it, since those are outside of the frame of your view on screen.
9829      *
9830      * @return The top edge of the displayed part of your view, in pixels.
9831      */
9832     public final int getScrollY() {
9833         return mScrollY;
9834     }
9835
9836     /**
9837      * Return the width of the your view.
9838      *
9839      * @return The width of your view, in pixels.
9840      */
9841     @ViewDebug.ExportedProperty(category = "layout")
9842     public final int getWidth() {
9843         return mRight - mLeft;
9844     }
9845
9846     /**
9847      * Return the height of your view.
9848      *
9849      * @return The height of your view, in pixels.
9850      */
9851     @ViewDebug.ExportedProperty(category = "layout")
9852     public final int getHeight() {
9853         return mBottom - mTop;
9854     }
9855
9856     /**
9857      * Return the visible drawing bounds of your view. Fills in the output
9858      * rectangle with the values from getScrollX(), getScrollY(),
9859      * getWidth(), and getHeight(). These bounds do not account for any
9860      * transformation properties currently set on the view, such as
9861      * {@link #setScaleX(float)} or {@link #setRotation(float)}.
9862      *
9863      * @param outRect The (scrolled) drawing bounds of the view.
9864      */
9865     public void getDrawingRect(Rect outRect) {
9866         outRect.left = mScrollX;
9867         outRect.top = mScrollY;
9868         outRect.right = mScrollX + (mRight - mLeft);
9869         outRect.bottom = mScrollY + (mBottom - mTop);
9870     }
9871
9872     /**
9873      * Like {@link #getMeasuredWidthAndState()}, but only returns the
9874      * raw width component (that is the result is masked by
9875      * {@link #MEASURED_SIZE_MASK}).
9876      *
9877      * @return The raw measured width of this view.
9878      */
9879     public final int getMeasuredWidth() {
9880         return mMeasuredWidth & MEASURED_SIZE_MASK;
9881     }
9882
9883     /**
9884      * Return the full width measurement information for this view as computed
9885      * by the most recent call to {@link #measure(int, int)}.  This result is a bit mask
9886      * as defined by {@link #MEASURED_SIZE_MASK} and {@link #MEASURED_STATE_TOO_SMALL}.
9887      * This should be used during measurement and layout calculations only. Use
9888      * {@link #getWidth()} to see how wide a view is after layout.
9889      *
9890      * @return The measured width of this view as a bit mask.
9891      */
9892     public final int getMeasuredWidthAndState() {
9893         return mMeasuredWidth;
9894     }
9895
9896     /**
9897      * Like {@link #getMeasuredHeightAndState()}, but only returns the
9898      * raw width component (that is the result is masked by
9899      * {@link #MEASURED_SIZE_MASK}).
9900      *
9901      * @return The raw measured height of this view.
9902      */
9903     public final int getMeasuredHeight() {
9904         return mMeasuredHeight & MEASURED_SIZE_MASK;
9905     }
9906
9907     /**
9908      * Return the full height measurement information for this view as computed
9909      * by the most recent call to {@link #measure(int, int)}.  This result is a bit mask
9910      * as defined by {@link #MEASURED_SIZE_MASK} and {@link #MEASURED_STATE_TOO_SMALL}.
9911      * This should be used during measurement and layout calculations only. Use
9912      * {@link #getHeight()} to see how wide a view is after layout.
9913      *
9914      * @return The measured width of this view as a bit mask.
9915      */
9916     public final int getMeasuredHeightAndState() {
9917         return mMeasuredHeight;
9918     }
9919
9920     /**
9921      * Return only the state bits of {@link #getMeasuredWidthAndState()}
9922      * and {@link #getMeasuredHeightAndState()}, combined into one integer.
9923      * The width component is in the regular bits {@link #MEASURED_STATE_MASK}
9924      * and the height component is at the shifted bits
9925      * {@link #MEASURED_HEIGHT_STATE_SHIFT}>>{@link #MEASURED_STATE_MASK}.
9926      */
9927     public final int getMeasuredState() {
9928         return (mMeasuredWidth&MEASURED_STATE_MASK)
9929                 | ((mMeasuredHeight>>MEASURED_HEIGHT_STATE_SHIFT)
9930                         & (MEASURED_STATE_MASK>>MEASURED_HEIGHT_STATE_SHIFT));
9931     }
9932
9933     /**
9934      * The transform matrix of this view, which is calculated based on the current
9935      * rotation, scale, and pivot properties.
9936      *
9937      * @see #getRotation()
9938      * @see #getScaleX()
9939      * @see #getScaleY()
9940      * @see #getPivotX()
9941      * @see #getPivotY()
9942      * @return The current transform matrix for the view
9943      */
9944     public Matrix getMatrix() {
9945         ensureTransformationInfo();
9946         final Matrix matrix = mTransformationInfo.mMatrix;
9947         mRenderNode.getMatrix(matrix);
9948         return matrix;
9949     }
9950
9951     /**
9952      * Returns true if the transform matrix is the identity matrix.
9953      * Recomputes the matrix if necessary.
9954      *
9955      * @return True if the transform matrix is the identity matrix, false otherwise.
9956      */
9957     final boolean hasIdentityMatrix() {
9958         return mRenderNode.hasIdentityMatrix();
9959     }
9960
9961     void ensureTransformationInfo() {
9962         if (mTransformationInfo == null) {
9963             mTransformationInfo = new TransformationInfo();
9964         }
9965     }
9966
9967    /**
9968      * Utility method to retrieve the inverse of the current mMatrix property.
9969      * We cache the matrix to avoid recalculating it when transform properties
9970      * have not changed.
9971      *
9972      * @return The inverse of the current matrix of this view.
9973      * @hide
9974      */
9975     public final Matrix getInverseMatrix() {
9976         ensureTransformationInfo();
9977         if (mTransformationInfo.mInverseMatrix == null) {
9978             mTransformationInfo.mInverseMatrix = new Matrix();
9979         }
9980         final Matrix matrix = mTransformationInfo.mInverseMatrix;
9981         mRenderNode.getInverseMatrix(matrix);
9982         return matrix;
9983     }
9984
9985     /**
9986      * Gets the distance along the Z axis from the camera to this view.
9987      *
9988      * @see #setCameraDistance(float)
9989      *
9990      * @return The distance along the Z axis.
9991      */
9992     public float getCameraDistance() {
9993         final float dpi = mResources.getDisplayMetrics().densityDpi;
9994         return -(mRenderNode.getCameraDistance() * dpi);
9995     }
9996
9997     /**
9998      * <p>Sets the distance along the Z axis (orthogonal to the X/Y plane on which
9999      * views are drawn) from the camera to this view. The camera's distance
10000      * affects 3D transformations, for instance rotations around the X and Y
10001      * axis. If the rotationX or rotationY properties are changed and this view is
10002      * large (more than half the size of the screen), it is recommended to always
10003      * use a camera distance that's greater than the height (X axis rotation) or
10004      * the width (Y axis rotation) of this view.</p>
10005      *
10006      * <p>The distance of the camera from the view plane can have an affect on the
10007      * perspective distortion of the view when it is rotated around the x or y axis.
10008      * For example, a large distance will result in a large viewing angle, and there
10009      * will not be much perspective distortion of the view as it rotates. A short
10010      * distance may cause much more perspective distortion upon rotation, and can
10011      * also result in some drawing artifacts if the rotated view ends up partially
10012      * behind the camera (which is why the recommendation is to use a distance at
10013      * least as far as the size of the view, if the view is to be rotated.)</p>
10014      *
10015      * <p>The distance is expressed in "depth pixels." The default distance depends
10016      * on the screen density. For instance, on a medium density display, the
10017      * default distance is 1280. On a high density display, the default distance
10018      * is 1920.</p>
10019      *
10020      * <p>If you want to specify a distance that leads to visually consistent
10021      * results across various densities, use the following formula:</p>
10022      * <pre>
10023      * float scale = context.getResources().getDisplayMetrics().density;
10024      * view.setCameraDistance(distance * scale);
10025      * </pre>
10026      *
10027      * <p>The density scale factor of a high density display is 1.5,
10028      * and 1920 = 1280 * 1.5.</p>
10029      *
10030      * @param distance The distance in "depth pixels", if negative the opposite
10031      *        value is used
10032      *
10033      * @see #setRotationX(float)
10034      * @see #setRotationY(float)
10035      */
10036     public void setCameraDistance(float distance) {
10037         final float dpi = mResources.getDisplayMetrics().densityDpi;
10038
10039         invalidateViewProperty(true, false);
10040         mRenderNode.setCameraDistance(-Math.abs(distance) / dpi);
10041         invalidateViewProperty(false, false);
10042
10043         invalidateParentIfNeededAndWasQuickRejected();
10044     }
10045
10046     /**
10047      * The degrees that the view is rotated around the pivot point.
10048      *
10049      * @see #setRotation(float)
10050      * @see #getPivotX()
10051      * @see #getPivotY()
10052      *
10053      * @return The degrees of rotation.
10054      */
10055     @ViewDebug.ExportedProperty(category = "drawing")
10056     public float getRotation() {
10057         return mRenderNode.getRotation();
10058     }
10059
10060     /**
10061      * Sets the degrees that the view is rotated around the pivot point. Increasing values
10062      * result in clockwise rotation.
10063      *
10064      * @param rotation The degrees of rotation.
10065      *
10066      * @see #getRotation()
10067      * @see #getPivotX()
10068      * @see #getPivotY()
10069      * @see #setRotationX(float)
10070      * @see #setRotationY(float)
10071      *
10072      * @attr ref android.R.styleable#View_rotation
10073      */
10074     public void setRotation(float rotation) {
10075         if (rotation != getRotation()) {
10076             // Double-invalidation is necessary to capture view's old and new areas
10077             invalidateViewProperty(true, false);
10078             mRenderNode.setRotation(rotation);
10079             invalidateViewProperty(false, true);
10080
10081             invalidateParentIfNeededAndWasQuickRejected();
10082             notifySubtreeAccessibilityStateChangedIfNeeded();
10083         }
10084     }
10085
10086     /**
10087      * The degrees that the view is rotated around the vertical axis through the pivot point.
10088      *
10089      * @see #getPivotX()
10090      * @see #getPivotY()
10091      * @see #setRotationY(float)
10092      *
10093      * @return The degrees of Y rotation.
10094      */
10095     @ViewDebug.ExportedProperty(category = "drawing")
10096     public float getRotationY() {
10097         return mRenderNode.getRotationY();
10098     }
10099
10100     /**
10101      * Sets the degrees that the view is rotated around the vertical axis through the pivot point.
10102      * Increasing values result in counter-clockwise rotation from the viewpoint of looking
10103      * down the y axis.
10104      *
10105      * When rotating large views, it is recommended to adjust the camera distance
10106      * accordingly. Refer to {@link #setCameraDistance(float)} for more information.
10107      *
10108      * @param rotationY The degrees of Y rotation.
10109      *
10110      * @see #getRotationY()
10111      * @see #getPivotX()
10112      * @see #getPivotY()
10113      * @see #setRotation(float)
10114      * @see #setRotationX(float)
10115      * @see #setCameraDistance(float)
10116      *
10117      * @attr ref android.R.styleable#View_rotationY
10118      */
10119     public void setRotationY(float rotationY) {
10120         if (rotationY != getRotationY()) {
10121             invalidateViewProperty(true, false);
10122             mRenderNode.setRotationY(rotationY);
10123             invalidateViewProperty(false, true);
10124
10125             invalidateParentIfNeededAndWasQuickRejected();
10126             notifySubtreeAccessibilityStateChangedIfNeeded();
10127         }
10128     }
10129
10130     /**
10131      * The degrees that the view is rotated around the horizontal axis through the pivot point.
10132      *
10133      * @see #getPivotX()
10134      * @see #getPivotY()
10135      * @see #setRotationX(float)
10136      *
10137      * @return The degrees of X rotation.
10138      */
10139     @ViewDebug.ExportedProperty(category = "drawing")
10140     public float getRotationX() {
10141         return mRenderNode.getRotationX();
10142     }
10143
10144     /**
10145      * Sets the degrees that the view is rotated around the horizontal axis through the pivot point.
10146      * Increasing values result in clockwise rotation from the viewpoint of looking down the
10147      * x axis.
10148      *
10149      * When rotating large views, it is recommended to adjust the camera distance
10150      * accordingly. Refer to {@link #setCameraDistance(float)} for more information.
10151      *
10152      * @param rotationX The degrees of X rotation.
10153      *
10154      * @see #getRotationX()
10155      * @see #getPivotX()
10156      * @see #getPivotY()
10157      * @see #setRotation(float)
10158      * @see #setRotationY(float)
10159      * @see #setCameraDistance(float)
10160      *
10161      * @attr ref android.R.styleable#View_rotationX
10162      */
10163     public void setRotationX(float rotationX) {
10164         if (rotationX != getRotationX()) {
10165             invalidateViewProperty(true, false);
10166             mRenderNode.setRotationX(rotationX);
10167             invalidateViewProperty(false, true);
10168
10169             invalidateParentIfNeededAndWasQuickRejected();
10170             notifySubtreeAccessibilityStateChangedIfNeeded();
10171         }
10172     }
10173
10174     /**
10175      * The amount that the view is scaled in x around the pivot point, as a proportion of
10176      * the view's unscaled width. A value of 1, the default, means that no scaling is applied.
10177      *
10178      * <p>By default, this is 1.0f.
10179      *
10180      * @see #getPivotX()
10181      * @see #getPivotY()
10182      * @return The scaling factor.
10183      */
10184     @ViewDebug.ExportedProperty(category = "drawing")
10185     public float getScaleX() {
10186         return mRenderNode.getScaleX();
10187     }
10188
10189     /**
10190      * Sets the amount that the view is scaled in x around the pivot point, as a proportion of
10191      * the view's unscaled width. A value of 1 means that no scaling is applied.
10192      *
10193      * @param scaleX The scaling factor.
10194      * @see #getPivotX()
10195      * @see #getPivotY()
10196      *
10197      * @attr ref android.R.styleable#View_scaleX
10198      */
10199     public void setScaleX(float scaleX) {
10200         if (scaleX != getScaleX()) {
10201             invalidateViewProperty(true, false);
10202             mRenderNode.setScaleX(scaleX);
10203             invalidateViewProperty(false, true);
10204
10205             invalidateParentIfNeededAndWasQuickRejected();
10206             notifySubtreeAccessibilityStateChangedIfNeeded();
10207         }
10208     }
10209
10210     /**
10211      * The amount that the view is scaled in y around the pivot point, as a proportion of
10212      * the view's unscaled height. A value of 1, the default, means that no scaling is applied.
10213      *
10214      * <p>By default, this is 1.0f.
10215      *
10216      * @see #getPivotX()
10217      * @see #getPivotY()
10218      * @return The scaling factor.
10219      */
10220     @ViewDebug.ExportedProperty(category = "drawing")
10221     public float getScaleY() {
10222         return mRenderNode.getScaleY();
10223     }
10224
10225     /**
10226      * Sets the amount that the view is scaled in Y around the pivot point, as a proportion of
10227      * the view's unscaled width. A value of 1 means that no scaling is applied.
10228      *
10229      * @param scaleY The scaling factor.
10230      * @see #getPivotX()
10231      * @see #getPivotY()
10232      *
10233      * @attr ref android.R.styleable#View_scaleY
10234      */
10235     public void setScaleY(float scaleY) {
10236         if (scaleY != getScaleY()) {
10237             invalidateViewProperty(true, false);
10238             mRenderNode.setScaleY(scaleY);
10239             invalidateViewProperty(false, true);
10240
10241             invalidateParentIfNeededAndWasQuickRejected();
10242             notifySubtreeAccessibilityStateChangedIfNeeded();
10243         }
10244     }
10245
10246     /**
10247      * The x location of the point around which the view is {@link #setRotation(float) rotated}
10248      * and {@link #setScaleX(float) scaled}.
10249      *
10250      * @see #getRotation()
10251      * @see #getScaleX()
10252      * @see #getScaleY()
10253      * @see #getPivotY()
10254      * @return The x location of the pivot point.
10255      *
10256      * @attr ref android.R.styleable#View_transformPivotX
10257      */
10258     @ViewDebug.ExportedProperty(category = "drawing")
10259     public float getPivotX() {
10260         return mRenderNode.getPivotX();
10261     }
10262
10263     /**
10264      * Sets the x location of the point around which the view is
10265      * {@link #setRotation(float) rotated} and {@link #setScaleX(float) scaled}.
10266      * By default, the pivot point is centered on the object.
10267      * Setting this property disables this behavior and causes the view to use only the
10268      * explicitly set pivotX and pivotY values.
10269      *
10270      * @param pivotX The x location of the pivot point.
10271      * @see #getRotation()
10272      * @see #getScaleX()
10273      * @see #getScaleY()
10274      * @see #getPivotY()
10275      *
10276      * @attr ref android.R.styleable#View_transformPivotX
10277      */
10278     public void setPivotX(float pivotX) {
10279         if (!mRenderNode.isPivotExplicitlySet() || pivotX != getPivotX()) {
10280             invalidateViewProperty(true, false);
10281             mRenderNode.setPivotX(pivotX);
10282             invalidateViewProperty(false, true);
10283
10284             invalidateParentIfNeededAndWasQuickRejected();
10285         }
10286     }
10287
10288     /**
10289      * The y location of the point around which the view is {@link #setRotation(float) rotated}
10290      * and {@link #setScaleY(float) scaled}.
10291      *
10292      * @see #getRotation()
10293      * @see #getScaleX()
10294      * @see #getScaleY()
10295      * @see #getPivotY()
10296      * @return The y location of the pivot point.
10297      *
10298      * @attr ref android.R.styleable#View_transformPivotY
10299      */
10300     @ViewDebug.ExportedProperty(category = "drawing")
10301     public float getPivotY() {
10302         return mRenderNode.getPivotY();
10303     }
10304
10305     /**
10306      * Sets the y location of the point around which the view is {@link #setRotation(float) rotated}
10307      * and {@link #setScaleY(float) scaled}. By default, the pivot point is centered on the object.
10308      * Setting this property disables this behavior and causes the view to use only the
10309      * explicitly set pivotX and pivotY values.
10310      *
10311      * @param pivotY The y location of the pivot point.
10312      * @see #getRotation()
10313      * @see #getScaleX()
10314      * @see #getScaleY()
10315      * @see #getPivotY()
10316      *
10317      * @attr ref android.R.styleable#View_transformPivotY
10318      */
10319     public void setPivotY(float pivotY) {
10320         if (!mRenderNode.isPivotExplicitlySet() || pivotY != getPivotY()) {
10321             invalidateViewProperty(true, false);
10322             mRenderNode.setPivotY(pivotY);
10323             invalidateViewProperty(false, true);
10324
10325             invalidateParentIfNeededAndWasQuickRejected();
10326         }
10327     }
10328
10329     /**
10330      * The opacity of the view. This is a value from 0 to 1, where 0 means the view is
10331      * completely transparent and 1 means the view is completely opaque.
10332      *
10333      * <p>By default this is 1.0f.
10334      * @return The opacity of the view.
10335      */
10336     @ViewDebug.ExportedProperty(category = "drawing")
10337     public float getAlpha() {
10338         return mTransformationInfo != null ? mTransformationInfo.mAlpha : 1;
10339     }
10340
10341     /**
10342      * Returns whether this View has content which overlaps.
10343      *
10344      * <p>This function, intended to be overridden by specific View types, is an optimization when
10345      * alpha is set on a view. If rendering overlaps in a view with alpha < 1, that view is drawn to
10346      * an offscreen buffer and then composited into place, which can be expensive. If the view has
10347      * no overlapping rendering, the view can draw each primitive with the appropriate alpha value
10348      * directly. An example of overlapping rendering is a TextView with a background image, such as
10349      * a Button. An example of non-overlapping rendering is a TextView with no background, or an
10350      * ImageView with only the foreground image. The default implementation returns true; subclasses
10351      * should override if they have cases which can be optimized.</p>
10352      *
10353      * <p>The current implementation of the saveLayer and saveLayerAlpha methods in {@link Canvas}
10354      * necessitates that a View return true if it uses the methods internally without passing the
10355      * {@link Canvas#CLIP_TO_LAYER_SAVE_FLAG}.</p>
10356      *
10357      * @return true if the content in this view might overlap, false otherwise.
10358      */
10359     @ViewDebug.ExportedProperty(category = "drawing")
10360     public boolean hasOverlappingRendering() {
10361         return true;
10362     }
10363
10364     /**
10365      * <p>Sets the opacity of the view. This is a value from 0 to 1, where 0 means the view is
10366      * completely transparent and 1 means the view is completely opaque.</p>
10367      *
10368      * <p> Note that setting alpha to a translucent value (0 < alpha < 1) can have significant
10369      * performance implications, especially for large views. It is best to use the alpha property
10370      * sparingly and transiently, as in the case of fading animations.</p>
10371      *
10372      * <p>For a view with a frequently changing alpha, such as during a fading animation, it is
10373      * strongly recommended for performance reasons to either override
10374      * {@link #hasOverlappingRendering()} to return false if appropriate, or setting a
10375      * {@link #setLayerType(int, android.graphics.Paint) layer type} on the view.</p>
10376      *
10377      * <p>If this view overrides {@link #onSetAlpha(int)} to return true, then this view is
10378      * responsible for applying the opacity itself.</p>
10379      *
10380      * <p>Note that if the view is backed by a
10381      * {@link #setLayerType(int, android.graphics.Paint) layer} and is associated with a
10382      * {@link #setLayerPaint(android.graphics.Paint) layer paint}, setting an alpha value less than
10383      * 1.0 will supercede the alpha of the layer paint.</p>
10384      *
10385      * @param alpha The opacity of the view.
10386      *
10387      * @see #hasOverlappingRendering()
10388      * @see #setLayerType(int, android.graphics.Paint)
10389      *
10390      * @attr ref android.R.styleable#View_alpha
10391      */
10392     public void setAlpha(float alpha) {
10393         ensureTransformationInfo();
10394         if (mTransformationInfo.mAlpha != alpha) {
10395             mTransformationInfo.mAlpha = alpha;
10396             if (onSetAlpha((int) (alpha * 255))) {
10397                 mPrivateFlags |= PFLAG_ALPHA_SET;
10398                 // subclass is handling alpha - don't optimize rendering cache invalidation
10399                 invalidateParentCaches();
10400                 invalidate(true);
10401             } else {
10402                 mPrivateFlags &= ~PFLAG_ALPHA_SET;
10403                 invalidateViewProperty(true, false);
10404                 mRenderNode.setAlpha(getFinalAlpha());
10405                 notifyViewAccessibilityStateChangedIfNeeded(
10406                         AccessibilityEvent.CONTENT_CHANGE_TYPE_UNDEFINED);
10407             }
10408         }
10409     }
10410
10411     /**
10412      * Faster version of setAlpha() which performs the same steps except there are
10413      * no calls to invalidate(). The caller of this function should perform proper invalidation
10414      * on the parent and this object. The return value indicates whether the subclass handles
10415      * alpha (the return value for onSetAlpha()).
10416      *
10417      * @param alpha The new value for the alpha property
10418      * @return true if the View subclass handles alpha (the return value for onSetAlpha()) and
10419      *         the new value for the alpha property is different from the old value
10420      */
10421     boolean setAlphaNoInvalidation(float alpha) {
10422         ensureTransformationInfo();
10423         if (mTransformationInfo.mAlpha != alpha) {
10424             mTransformationInfo.mAlpha = alpha;
10425             boolean subclassHandlesAlpha = onSetAlpha((int) (alpha * 255));
10426             if (subclassHandlesAlpha) {
10427                 mPrivateFlags |= PFLAG_ALPHA_SET;
10428                 return true;
10429             } else {
10430                 mPrivateFlags &= ~PFLAG_ALPHA_SET;
10431                 mRenderNode.setAlpha(getFinalAlpha());
10432             }
10433         }
10434         return false;
10435     }
10436
10437     /**
10438      * This property is hidden and intended only for use by the Fade transition, which
10439      * animates it to produce a visual translucency that does not side-effect (or get
10440      * affected by) the real alpha property. This value is composited with the other
10441      * alpha value (and the AlphaAnimation value, when that is present) to produce
10442      * a final visual translucency result, which is what is passed into the DisplayList.
10443      *
10444      * @hide
10445      */
10446     public void setTransitionAlpha(float alpha) {
10447         ensureTransformationInfo();
10448         if (mTransformationInfo.mTransitionAlpha != alpha) {
10449             mTransformationInfo.mTransitionAlpha = alpha;
10450             mPrivateFlags &= ~PFLAG_ALPHA_SET;
10451             invalidateViewProperty(true, false);
10452             mRenderNode.setAlpha(getFinalAlpha());
10453         }
10454     }
10455
10456     /**
10457      * Calculates the visual alpha of this view, which is a combination of the actual
10458      * alpha value and the transitionAlpha value (if set).
10459      */
10460     private float getFinalAlpha() {
10461         if (mTransformationInfo != null) {
10462             return mTransformationInfo.mAlpha * mTransformationInfo.mTransitionAlpha;
10463         }
10464         return 1;
10465     }
10466
10467     /**
10468      * This property is hidden and intended only for use by the Fade transition, which
10469      * animates it to produce a visual translucency that does not side-effect (or get
10470      * affected by) the real alpha property. This value is composited with the other
10471      * alpha value (and the AlphaAnimation value, when that is present) to produce
10472      * a final visual translucency result, which is what is passed into the DisplayList.
10473      *
10474      * @hide
10475      */
10476     @ViewDebug.ExportedProperty(category = "drawing")
10477     public float getTransitionAlpha() {
10478         return mTransformationInfo != null ? mTransformationInfo.mTransitionAlpha : 1;
10479     }
10480
10481     /**
10482      * Top position of this view relative to its parent.
10483      *
10484      * @return The top of this view, in pixels.
10485      */
10486     @ViewDebug.CapturedViewProperty
10487     public final int getTop() {
10488         return mTop;
10489     }
10490
10491     /**
10492      * Sets the top position of this view relative to its parent. This method is meant to be called
10493      * by the layout system and should not generally be called otherwise, because the property
10494      * may be changed at any time by the layout.
10495      *
10496      * @param top The top of this view, in pixels.
10497      */
10498     public final void setTop(int top) {
10499         if (top != mTop) {
10500             final boolean matrixIsIdentity = hasIdentityMatrix();
10501             if (matrixIsIdentity) {
10502                 if (mAttachInfo != null) {
10503                     int minTop;
10504                     int yLoc;
10505                     if (top < mTop) {
10506                         minTop = top;
10507                         yLoc = top - mTop;
10508                     } else {
10509                         minTop = mTop;
10510                         yLoc = 0;
10511                     }
10512                     invalidate(0, yLoc, mRight - mLeft, mBottom - minTop);
10513                 }
10514             } else {
10515                 // Double-invalidation is necessary to capture view's old and new areas
10516                 invalidate(true);
10517             }
10518
10519             int width = mRight - mLeft;
10520             int oldHeight = mBottom - mTop;
10521
10522             mTop = top;
10523             mRenderNode.setTop(mTop);
10524
10525             sizeChange(width, mBottom - mTop, width, oldHeight);
10526
10527             if (!matrixIsIdentity) {
10528                 mPrivateFlags |= PFLAG_DRAWN; // force another invalidation with the new orientation
10529                 invalidate(true);
10530             }
10531             mBackgroundSizeChanged = true;
10532             invalidateParentIfNeeded();
10533             if ((mPrivateFlags2 & PFLAG2_VIEW_QUICK_REJECTED) == PFLAG2_VIEW_QUICK_REJECTED) {
10534                 // View was rejected last time it was drawn by its parent; this may have changed
10535                 invalidateParentIfNeeded();
10536             }
10537         }
10538     }
10539
10540     /**
10541      * Bottom position of this view relative to its parent.
10542      *
10543      * @return The bottom of this view, in pixels.
10544      */
10545     @ViewDebug.CapturedViewProperty
10546     public final int getBottom() {
10547         return mBottom;
10548     }
10549
10550     /**
10551      * True if this view has changed since the last time being drawn.
10552      *
10553      * @return The dirty state of this view.
10554      */
10555     public boolean isDirty() {
10556         return (mPrivateFlags & PFLAG_DIRTY_MASK) != 0;
10557     }
10558
10559     /**
10560      * Sets the bottom position of this view relative to its parent. This method is meant to be
10561      * called by the layout system and should not generally be called otherwise, because the
10562      * property may be changed at any time by the layout.
10563      *
10564      * @param bottom The bottom of this view, in pixels.
10565      */
10566     public final void setBottom(int bottom) {
10567         if (bottom != mBottom) {
10568             final boolean matrixIsIdentity = hasIdentityMatrix();
10569             if (matrixIsIdentity) {
10570                 if (mAttachInfo != null) {
10571                     int maxBottom;
10572                     if (bottom < mBottom) {
10573                         maxBottom = mBottom;
10574                     } else {
10575                         maxBottom = bottom;
10576                     }
10577                     invalidate(0, 0, mRight - mLeft, maxBottom - mTop);
10578                 }
10579             } else {
10580                 // Double-invalidation is necessary to capture view's old and new areas
10581                 invalidate(true);
10582             }
10583
10584             int width = mRight - mLeft;
10585             int oldHeight = mBottom - mTop;
10586
10587             mBottom = bottom;
10588             mRenderNode.setBottom(mBottom);
10589
10590             sizeChange(width, mBottom - mTop, width, oldHeight);
10591
10592             if (!matrixIsIdentity) {
10593                 mPrivateFlags |= PFLAG_DRAWN; // force another invalidation with the new orientation
10594                 invalidate(true);
10595             }
10596             mBackgroundSizeChanged = true;
10597             invalidateParentIfNeeded();
10598             if ((mPrivateFlags2 & PFLAG2_VIEW_QUICK_REJECTED) == PFLAG2_VIEW_QUICK_REJECTED) {
10599                 // View was rejected last time it was drawn by its parent; this may have changed
10600                 invalidateParentIfNeeded();
10601             }
10602         }
10603     }
10604
10605     /**
10606      * Left position of this view relative to its parent.
10607      *
10608      * @return The left edge of this view, in pixels.
10609      */
10610     @ViewDebug.CapturedViewProperty
10611     public final int getLeft() {
10612         return mLeft;
10613     }
10614
10615     /**
10616      * Sets the left position of this view relative to its parent. This method is meant to be called
10617      * by the layout system and should not generally be called otherwise, because the property
10618      * may be changed at any time by the layout.
10619      *
10620      * @param left The left of this view, in pixels.
10621      */
10622     public final void setLeft(int left) {
10623         if (left != mLeft) {
10624             final boolean matrixIsIdentity = hasIdentityMatrix();
10625             if (matrixIsIdentity) {
10626                 if (mAttachInfo != null) {
10627                     int minLeft;
10628                     int xLoc;
10629                     if (left < mLeft) {
10630                         minLeft = left;
10631                         xLoc = left - mLeft;
10632                     } else {
10633                         minLeft = mLeft;
10634                         xLoc = 0;
10635                     }
10636                     invalidate(xLoc, 0, mRight - minLeft, mBottom - mTop);
10637                 }
10638             } else {
10639                 // Double-invalidation is necessary to capture view's old and new areas
10640                 invalidate(true);
10641             }
10642
10643             int oldWidth = mRight - mLeft;
10644             int height = mBottom - mTop;
10645
10646             mLeft = left;
10647             mRenderNode.setLeft(left);
10648
10649             sizeChange(mRight - mLeft, height, oldWidth, height);
10650
10651             if (!matrixIsIdentity) {
10652                 mPrivateFlags |= PFLAG_DRAWN; // force another invalidation with the new orientation
10653                 invalidate(true);
10654             }
10655             mBackgroundSizeChanged = true;
10656             invalidateParentIfNeeded();
10657             if ((mPrivateFlags2 & PFLAG2_VIEW_QUICK_REJECTED) == PFLAG2_VIEW_QUICK_REJECTED) {
10658                 // View was rejected last time it was drawn by its parent; this may have changed
10659                 invalidateParentIfNeeded();
10660             }
10661         }
10662     }
10663
10664     /**
10665      * Right position of this view relative to its parent.
10666      *
10667      * @return The right edge of this view, in pixels.
10668      */
10669     @ViewDebug.CapturedViewProperty
10670     public final int getRight() {
10671         return mRight;
10672     }
10673
10674     /**
10675      * Sets the right position of this view relative to its parent. This method is meant to be called
10676      * by the layout system and should not generally be called otherwise, because the property
10677      * may be changed at any time by the layout.
10678      *
10679      * @param right The right of this view, in pixels.
10680      */
10681     public final void setRight(int right) {
10682         if (right != mRight) {
10683             final boolean matrixIsIdentity = hasIdentityMatrix();
10684             if (matrixIsIdentity) {
10685                 if (mAttachInfo != null) {
10686                     int maxRight;
10687                     if (right < mRight) {
10688                         maxRight = mRight;
10689                     } else {
10690                         maxRight = right;
10691                     }
10692                     invalidate(0, 0, maxRight - mLeft, mBottom - mTop);
10693                 }
10694             } else {
10695                 // Double-invalidation is necessary to capture view's old and new areas
10696                 invalidate(true);
10697             }
10698
10699             int oldWidth = mRight - mLeft;
10700             int height = mBottom - mTop;
10701
10702             mRight = right;
10703             mRenderNode.setRight(mRight);
10704
10705             sizeChange(mRight - mLeft, height, oldWidth, height);
10706
10707             if (!matrixIsIdentity) {
10708                 mPrivateFlags |= PFLAG_DRAWN; // force another invalidation with the new orientation
10709                 invalidate(true);
10710             }
10711             mBackgroundSizeChanged = true;
10712             invalidateParentIfNeeded();
10713             if ((mPrivateFlags2 & PFLAG2_VIEW_QUICK_REJECTED) == PFLAG2_VIEW_QUICK_REJECTED) {
10714                 // View was rejected last time it was drawn by its parent; this may have changed
10715                 invalidateParentIfNeeded();
10716             }
10717         }
10718     }
10719
10720     /**
10721      * The visual x position of this view, in pixels. This is equivalent to the
10722      * {@link #setTranslationX(float) translationX} property plus the current
10723      * {@link #getLeft() left} property.
10724      *
10725      * @return The visual x position of this view, in pixels.
10726      */
10727     @ViewDebug.ExportedProperty(category = "drawing")
10728     public float getX() {
10729         return mLeft + getTranslationX();
10730     }
10731
10732     /**
10733      * Sets the visual x position of this view, in pixels. This is equivalent to setting the
10734      * {@link #setTranslationX(float) translationX} property to be the difference between
10735      * the x value passed in and the current {@link #getLeft() left} property.
10736      *
10737      * @param x The visual x position of this view, in pixels.
10738      */
10739     public void setX(float x) {
10740         setTranslationX(x - mLeft);
10741     }
10742
10743     /**
10744      * The visual y position of this view, in pixels. This is equivalent to the
10745      * {@link #setTranslationY(float) translationY} property plus the current
10746      * {@link #getTop() top} property.
10747      *
10748      * @return The visual y position of this view, in pixels.
10749      */
10750     @ViewDebug.ExportedProperty(category = "drawing")
10751     public float getY() {
10752         return mTop + getTranslationY();
10753     }
10754
10755     /**
10756      * Sets the visual y position of this view, in pixels. This is equivalent to setting the
10757      * {@link #setTranslationY(float) translationY} property to be the difference between
10758      * the y value passed in and the current {@link #getTop() top} property.
10759      *
10760      * @param y The visual y position of this view, in pixels.
10761      */
10762     public void setY(float y) {
10763         setTranslationY(y - mTop);
10764     }
10765
10766     /**
10767      * The visual z position of this view, in pixels. This is equivalent to the
10768      * {@link #setTranslationZ(float) translationZ} property plus the current
10769      * {@link #getElevation() elevation} property.
10770      *
10771      * @return The visual z position of this view, in pixels.
10772      */
10773     @ViewDebug.ExportedProperty(category = "drawing")
10774     public float getZ() {
10775         return getElevation() + getTranslationZ();
10776     }
10777
10778     /**
10779      * Sets the visual z position of this view, in pixels. This is equivalent to setting the
10780      * {@link #setTranslationZ(float) translationZ} property to be the difference between
10781      * the x value passed in and the current {@link #getElevation() elevation} property.
10782      *
10783      * @param z The visual z position of this view, in pixels.
10784      */
10785     public void setZ(float z) {
10786         setTranslationZ(z - getElevation());
10787     }
10788
10789     /**
10790      * The base elevation of this view relative to its parent, in pixels.
10791      *
10792      * @return The base depth position of the view, in pixels.
10793      */
10794     @ViewDebug.ExportedProperty(category = "drawing")
10795     public float getElevation() {
10796         return mRenderNode.getElevation();
10797     }
10798
10799     /**
10800      * Sets the base elevation of this view, in pixels.
10801      *
10802      * @attr ref android.R.styleable#View_elevation
10803      */
10804     public void setElevation(float elevation) {
10805         if (elevation != getElevation()) {
10806             invalidateViewProperty(true, false);
10807             mRenderNode.setElevation(elevation);
10808             invalidateViewProperty(false, true);
10809
10810             invalidateParentIfNeededAndWasQuickRejected();
10811         }
10812     }
10813
10814     /**
10815      * The horizontal location of this view relative to its {@link #getLeft() left} position.
10816      * This position is post-layout, in addition to wherever the object's
10817      * layout placed it.
10818      *
10819      * @return The horizontal position of this view relative to its left position, in pixels.
10820      */
10821     @ViewDebug.ExportedProperty(category = "drawing")
10822     public float getTranslationX() {
10823         return mRenderNode.getTranslationX();
10824     }
10825
10826     /**
10827      * Sets the horizontal location of this view relative to its {@link #getLeft() left} position.
10828      * This effectively positions the object post-layout, in addition to wherever the object's
10829      * layout placed it.
10830      *
10831      * @param translationX The horizontal position of this view relative to its left position,
10832      * in pixels.
10833      *
10834      * @attr ref android.R.styleable#View_translationX
10835      */
10836     public void setTranslationX(float translationX) {
10837         if (translationX != getTranslationX()) {
10838             invalidateViewProperty(true, false);
10839             mRenderNode.setTranslationX(translationX);
10840             invalidateViewProperty(false, true);
10841
10842             invalidateParentIfNeededAndWasQuickRejected();
10843             notifySubtreeAccessibilityStateChangedIfNeeded();
10844         }
10845     }
10846
10847     /**
10848      * The vertical location of this view relative to its {@link #getTop() top} position.
10849      * This position is post-layout, in addition to wherever the object's
10850      * layout placed it.
10851      *
10852      * @return The vertical position of this view relative to its top position,
10853      * in pixels.
10854      */
10855     @ViewDebug.ExportedProperty(category = "drawing")
10856     public float getTranslationY() {
10857         return mRenderNode.getTranslationY();
10858     }
10859
10860     /**
10861      * Sets the vertical location of this view relative to its {@link #getTop() top} position.
10862      * This effectively positions the object post-layout, in addition to wherever the object's
10863      * layout placed it.
10864      *
10865      * @param translationY The vertical position of this view relative to its top position,
10866      * in pixels.
10867      *
10868      * @attr ref android.R.styleable#View_translationY
10869      */
10870     public void setTranslationY(float translationY) {
10871         if (translationY != getTranslationY()) {
10872             invalidateViewProperty(true, false);
10873             mRenderNode.setTranslationY(translationY);
10874             invalidateViewProperty(false, true);
10875
10876             invalidateParentIfNeededAndWasQuickRejected();
10877         }
10878     }
10879
10880     /**
10881      * The depth location of this view relative to its {@link #getElevation() elevation}.
10882      *
10883      * @return The depth of this view relative to its elevation.
10884      */
10885     @ViewDebug.ExportedProperty(category = "drawing")
10886     public float getTranslationZ() {
10887         return mRenderNode.getTranslationZ();
10888     }
10889
10890     /**
10891      * Sets the depth location of this view relative to its {@link #getElevation() elevation}.
10892      *
10893      * @attr ref android.R.styleable#View_translationZ
10894      */
10895     public void setTranslationZ(float translationZ) {
10896         if (translationZ != getTranslationZ()) {
10897             invalidateViewProperty(true, false);
10898             mRenderNode.setTranslationZ(translationZ);
10899             invalidateViewProperty(false, true);
10900
10901             invalidateParentIfNeededAndWasQuickRejected();
10902         }
10903     }
10904
10905     /** @hide */
10906     public void setAnimationMatrix(Matrix matrix) {
10907         invalidateViewProperty(true, false);
10908         mRenderNode.setAnimationMatrix(matrix);
10909         invalidateViewProperty(false, true);
10910
10911         invalidateParentIfNeededAndWasQuickRejected();
10912     }
10913
10914     /**
10915      * Returns the current StateListAnimator if exists.
10916      *
10917      * @return StateListAnimator or null if it does not exists
10918      * @see    #setStateListAnimator(android.animation.StateListAnimator)
10919      */
10920     public StateListAnimator getStateListAnimator() {
10921         return mStateListAnimator;
10922     }
10923
10924     /**
10925      * Attaches the provided StateListAnimator to this View.
10926      * <p>
10927      * Any previously attached StateListAnimator will be detached.
10928      *
10929      * @param stateListAnimator The StateListAnimator to update the view
10930      * @see {@link android.animation.StateListAnimator}
10931      */
10932     public void setStateListAnimator(StateListAnimator stateListAnimator) {
10933         if (mStateListAnimator == stateListAnimator) {
10934             return;
10935         }
10936         if (mStateListAnimator != null) {
10937             mStateListAnimator.setTarget(null);
10938         }
10939         mStateListAnimator = stateListAnimator;
10940         if (stateListAnimator != null) {
10941             stateListAnimator.setTarget(this);
10942             if (isAttachedToWindow()) {
10943                 stateListAnimator.setState(getDrawableState());
10944             }
10945         }
10946     }
10947
10948     /**
10949      * Returns whether the Outline should be used to clip the contents of the View.
10950      * <p>
10951      * Note that this flag will only be respected if the View's Outline returns true from
10952      * {@link Outline#canClip()}.
10953      *
10954      * @see #setOutlineProvider(ViewOutlineProvider)
10955      * @see #setClipToOutline(boolean)
10956      */
10957     public final boolean getClipToOutline() {
10958         return mRenderNode.getClipToOutline();
10959     }
10960
10961     /**
10962      * Sets whether the View's Outline should be used to clip the contents of the View.
10963      * <p>
10964      * Only a single non-rectangular clip can be applied on a View at any time.
10965      * Circular clips from a {@link ViewAnimationUtils#createCircularReveal(View, int, int, float, float)
10966      * circular reveal} animation take priority over Outline clipping, and
10967      * child Outline clipping takes priority over Outline clipping done by a
10968      * parent.
10969      * <p>
10970      * Note that this flag will only be respected if the View's Outline returns true from
10971      * {@link Outline#canClip()}.
10972      *
10973      * @see #setOutlineProvider(ViewOutlineProvider)
10974      * @see #getClipToOutline()
10975      */
10976     public void setClipToOutline(boolean clipToOutline) {
10977         damageInParent();
10978         if (getClipToOutline() != clipToOutline) {
10979             mRenderNode.setClipToOutline(clipToOutline);
10980         }
10981     }
10982
10983     // correspond to the enum values of View_outlineProvider
10984     private static final int PROVIDER_BACKGROUND = 0;
10985     private static final int PROVIDER_NONE = 1;
10986     private static final int PROVIDER_BOUNDS = 2;
10987     private static final int PROVIDER_PADDED_BOUNDS = 3;
10988     private void setOutlineProviderFromAttribute(int providerInt) {
10989         switch (providerInt) {
10990             case PROVIDER_BACKGROUND:
10991                 setOutlineProvider(ViewOutlineProvider.BACKGROUND);
10992                 break;
10993             case PROVIDER_NONE:
10994                 setOutlineProvider(null);
10995                 break;
10996             case PROVIDER_BOUNDS:
10997                 setOutlineProvider(ViewOutlineProvider.BOUNDS);
10998                 break;
10999             case PROVIDER_PADDED_BOUNDS:
11000                 setOutlineProvider(ViewOutlineProvider.PADDED_BOUNDS);
11001                 break;
11002         }
11003     }
11004
11005     /**
11006      * Sets the {@link ViewOutlineProvider} of the view, which generates the Outline that defines
11007      * the shape of the shadow it casts, and enables outline clipping.
11008      * <p>
11009      * The default ViewOutlineProvider, {@link ViewOutlineProvider#BACKGROUND}, queries the Outline
11010      * from the View's background drawable, via {@link Drawable#getOutline(Outline)}. Changing the
11011      * outline provider with this method allows this behavior to be overridden.
11012      * <p>
11013      * If the ViewOutlineProvider is null, if querying it for an outline returns false,
11014      * or if the produced Outline is {@link Outline#isEmpty()}, shadows will not be cast.
11015      * <p>
11016      * Only outlines that return true from {@link Outline#canClip()} may be used for clipping.
11017      *
11018      * @see #setClipToOutline(boolean)
11019      * @see #getClipToOutline()
11020      * @see #getOutlineProvider()
11021      */
11022     public void setOutlineProvider(ViewOutlineProvider provider) {
11023         mOutlineProvider = provider;
11024         invalidateOutline();
11025     }
11026
11027     /**
11028      * Returns the current {@link ViewOutlineProvider} of the view, which generates the Outline
11029      * that defines the shape of the shadow it casts, and enables outline clipping.
11030      *
11031      * @see #setOutlineProvider(ViewOutlineProvider)
11032      */
11033     public ViewOutlineProvider getOutlineProvider() {
11034         return mOutlineProvider;
11035     }
11036
11037     /**
11038      * Called to rebuild this View's Outline from its {@link ViewOutlineProvider outline provider}
11039      *
11040      * @see #setOutlineProvider(ViewOutlineProvider)
11041      */
11042     public void invalidateOutline() {
11043         // Unattached views ignore this signal, and outline is recomputed in onAttachedToWindow()
11044         if (mAttachInfo == null) return;
11045
11046         if (mOutlineProvider == null) {
11047             // no provider, remove outline
11048             mRenderNode.setOutline(null);
11049         } else {
11050             final Outline outline = mAttachInfo.mTmpOutline;
11051             outline.setEmpty();
11052             outline.setAlpha(1.0f);
11053
11054             mOutlineProvider.getOutline(this, outline);
11055             mRenderNode.setOutline(outline);
11056         }
11057
11058         notifySubtreeAccessibilityStateChangedIfNeeded();
11059         invalidateViewProperty(false, false);
11060     }
11061
11062     /**
11063      * HierarchyViewer only
11064      *
11065      * @hide
11066      */
11067     @ViewDebug.ExportedProperty(category = "drawing")
11068     public boolean hasShadow() {
11069         return mRenderNode.hasShadow();
11070     }
11071
11072
11073     /** @hide */
11074     public void setRevealClip(boolean shouldClip, float x, float y, float radius) {
11075         mRenderNode.setRevealClip(shouldClip, x, y, radius);
11076         invalidateViewProperty(false, false);
11077     }
11078
11079     /**
11080      * Hit rectangle in parent's coordinates
11081      *
11082      * @param outRect The hit rectangle of the view.
11083      */
11084     public void getHitRect(Rect outRect) {
11085         if (hasIdentityMatrix() || mAttachInfo == null) {
11086             outRect.set(mLeft, mTop, mRight, mBottom);
11087         } else {
11088             final RectF tmpRect = mAttachInfo.mTmpTransformRect;
11089             tmpRect.set(0, 0, getWidth(), getHeight());
11090             getMatrix().mapRect(tmpRect); // TODO: mRenderNode.mapRect(tmpRect)
11091             outRect.set((int) tmpRect.left + mLeft, (int) tmpRect.top + mTop,
11092                     (int) tmpRect.right + mLeft, (int) tmpRect.bottom + mTop);
11093         }
11094     }
11095
11096     /**
11097      * Determines whether the given point, in local coordinates is inside the view.
11098      */
11099     /*package*/ final boolean pointInView(float localX, float localY) {
11100         return localX >= 0 && localX < (mRight - mLeft)
11101                 && localY >= 0 && localY < (mBottom - mTop);
11102     }
11103
11104     /**
11105      * Utility method to determine whether the given point, in local coordinates,
11106      * is inside the view, where the area of the view is expanded by the slop factor.
11107      * This method is called while processing touch-move events to determine if the event
11108      * is still within the view.
11109      *
11110      * @hide
11111      */
11112     public boolean pointInView(float localX, float localY, float slop) {
11113         return localX >= -slop && localY >= -slop && localX < ((mRight - mLeft) + slop) &&
11114                 localY < ((mBottom - mTop) + slop);
11115     }
11116
11117     /**
11118      * When a view has focus and the user navigates away from it, the next view is searched for
11119      * starting from the rectangle filled in by this method.
11120      *
11121      * By default, the rectangle is the {@link #getDrawingRect(android.graphics.Rect)})
11122      * of the view.  However, if your view maintains some idea of internal selection,
11123      * such as a cursor, or a selected row or column, you should override this method and
11124      * fill in a more specific rectangle.
11125      *
11126      * @param r The rectangle to fill in, in this view's coordinates.
11127      */
11128     public void getFocusedRect(Rect r) {
11129         getDrawingRect(r);
11130     }
11131
11132     /**
11133      * If some part of this view is not clipped by any of its parents, then
11134      * return that area in r in global (root) coordinates. To convert r to local
11135      * coordinates (without taking possible View rotations into account), offset
11136      * it by -globalOffset (e.g. r.offset(-globalOffset.x, -globalOffset.y)).
11137      * If the view is completely clipped or translated out, return false.
11138      *
11139      * @param r If true is returned, r holds the global coordinates of the
11140      *        visible portion of this view.
11141      * @param globalOffset If true is returned, globalOffset holds the dx,dy
11142      *        between this view and its root. globalOffet may be null.
11143      * @return true if r is non-empty (i.e. part of the view is visible at the
11144      *         root level.
11145      */
11146     public boolean getGlobalVisibleRect(Rect r, Point globalOffset) {
11147         int width = mRight - mLeft;
11148         int height = mBottom - mTop;
11149         if (width > 0 && height > 0) {
11150             r.set(0, 0, width, height);
11151             if (globalOffset != null) {
11152                 globalOffset.set(-mScrollX, -mScrollY);
11153             }
11154             return mParent == null || mParent.getChildVisibleRect(this, r, globalOffset);
11155         }
11156         return false;
11157     }
11158
11159     public final boolean getGlobalVisibleRect(Rect r) {
11160         return getGlobalVisibleRect(r, null);
11161     }
11162
11163     public final boolean getLocalVisibleRect(Rect r) {
11164         final Point offset = mAttachInfo != null ? mAttachInfo.mPoint : new Point();
11165         if (getGlobalVisibleRect(r, offset)) {
11166             r.offset(-offset.x, -offset.y); // make r local
11167             return true;
11168         }
11169         return false;
11170     }
11171
11172     /**
11173      * Offset this view's vertical location by the specified number of pixels.
11174      *
11175      * @param offset the number of pixels to offset the view by
11176      */
11177     public void offsetTopAndBottom(int offset) {
11178         if (offset != 0) {
11179             final boolean matrixIsIdentity = hasIdentityMatrix();
11180             if (matrixIsIdentity) {
11181                 if (isHardwareAccelerated()) {
11182                     invalidateViewProperty(false, false);
11183                 } else {
11184                     final ViewParent p = mParent;
11185                     if (p != null && mAttachInfo != null) {
11186                         final Rect r = mAttachInfo.mTmpInvalRect;
11187                         int minTop;
11188                         int maxBottom;
11189                         int yLoc;
11190                         if (offset < 0) {
11191                             minTop = mTop + offset;
11192                             maxBottom = mBottom;
11193                             yLoc = offset;
11194                         } else {
11195                             minTop = mTop;
11196                             maxBottom = mBottom + offset;
11197                             yLoc = 0;
11198                         }
11199                         r.set(0, yLoc, mRight - mLeft, maxBottom - minTop);
11200                         p.invalidateChild(this, r);
11201                     }
11202                 }
11203             } else {
11204                 invalidateViewProperty(false, false);
11205             }
11206
11207             mTop += offset;
11208             mBottom += offset;
11209             mRenderNode.offsetTopAndBottom(offset);
11210             if (isHardwareAccelerated()) {
11211                 invalidateViewProperty(false, false);
11212             } else {
11213                 if (!matrixIsIdentity) {
11214                     invalidateViewProperty(false, true);
11215                 }
11216                 invalidateParentIfNeeded();
11217             }
11218             notifySubtreeAccessibilityStateChangedIfNeeded();
11219         }
11220     }
11221
11222     /**
11223      * Offset this view's horizontal location by the specified amount of pixels.
11224      *
11225      * @param offset the number of pixels to offset the view by
11226      */
11227     public void offsetLeftAndRight(int offset) {
11228         if (offset != 0) {
11229             final boolean matrixIsIdentity = hasIdentityMatrix();
11230             if (matrixIsIdentity) {
11231                 if (isHardwareAccelerated()) {
11232                     invalidateViewProperty(false, false);
11233                 } else {
11234                     final ViewParent p = mParent;
11235                     if (p != null && mAttachInfo != null) {
11236                         final Rect r = mAttachInfo.mTmpInvalRect;
11237                         int minLeft;
11238                         int maxRight;
11239                         if (offset < 0) {
11240                             minLeft = mLeft + offset;
11241                             maxRight = mRight;
11242                         } else {
11243                             minLeft = mLeft;
11244                             maxRight = mRight + offset;
11245                         }
11246                         r.set(0, 0, maxRight - minLeft, mBottom - mTop);
11247                         p.invalidateChild(this, r);
11248                     }
11249                 }
11250             } else {
11251                 invalidateViewProperty(false, false);
11252             }
11253
11254             mLeft += offset;
11255             mRight += offset;
11256             mRenderNode.offsetLeftAndRight(offset);
11257             if (isHardwareAccelerated()) {
11258                 invalidateViewProperty(false, false);
11259             } else {
11260                 if (!matrixIsIdentity) {
11261                     invalidateViewProperty(false, true);
11262                 }
11263                 invalidateParentIfNeeded();
11264             }
11265             notifySubtreeAccessibilityStateChangedIfNeeded();
11266         }
11267     }
11268
11269     /**
11270      * Get the LayoutParams associated with this view. All views should have
11271      * layout parameters. These supply parameters to the <i>parent</i> of this
11272      * view specifying how it should be arranged. There are many subclasses of
11273      * ViewGroup.LayoutParams, and these correspond to the different subclasses
11274      * of ViewGroup that are responsible for arranging their children.
11275      *
11276      * This method may return null if this View is not attached to a parent
11277      * ViewGroup or {@link #setLayoutParams(android.view.ViewGroup.LayoutParams)}
11278      * was not invoked successfully. When a View is attached to a parent
11279      * ViewGroup, this method must not return null.
11280      *
11281      * @return The LayoutParams associated with this view, or null if no
11282      *         parameters have been set yet
11283      */
11284     @ViewDebug.ExportedProperty(deepExport = true, prefix = "layout_")
11285     public ViewGroup.LayoutParams getLayoutParams() {
11286         return mLayoutParams;
11287     }
11288
11289     /**
11290      * Set the layout parameters associated with this view. These supply
11291      * parameters to the <i>parent</i> of this view specifying how it should be
11292      * arranged. There are many subclasses of ViewGroup.LayoutParams, and these
11293      * correspond to the different subclasses of ViewGroup that are responsible
11294      * for arranging their children.
11295      *
11296      * @param params The layout parameters for this view, cannot be null
11297      */
11298     public void setLayoutParams(ViewGroup.LayoutParams params) {
11299         if (params == null) {
11300             throw new NullPointerException("Layout parameters cannot be null");
11301         }
11302         mLayoutParams = params;
11303         resolveLayoutParams();
11304         if (mParent instanceof ViewGroup) {
11305             ((ViewGroup) mParent).onSetLayoutParams(this, params);
11306         }
11307         requestLayout();
11308     }
11309
11310     /**
11311      * Resolve the layout parameters depending on the resolved layout direction
11312      *
11313      * @hide
11314      */
11315     public void resolveLayoutParams() {
11316         if (mLayoutParams != null) {
11317             mLayoutParams.resolveLayoutDirection(getLayoutDirection());
11318         }
11319     }
11320
11321     /**
11322      * Set the scrolled position of your view. This will cause a call to
11323      * {@link #onScrollChanged(int, int, int, int)} and the view will be
11324      * invalidated.
11325      * @param x the x position to scroll to
11326      * @param y the y position to scroll to
11327      */
11328     public void scrollTo(int x, int y) {
11329         if (mScrollX != x || mScrollY != y) {
11330             int oldX = mScrollX;
11331             int oldY = mScrollY;
11332             mScrollX = x;
11333             mScrollY = y;
11334             invalidateParentCaches();
11335             onScrollChanged(mScrollX, mScrollY, oldX, oldY);
11336             if (!awakenScrollBars()) {
11337                 postInvalidateOnAnimation();
11338             }
11339         }
11340     }
11341
11342     /**
11343      * Move the scrolled position of your view. This will cause a call to
11344      * {@link #onScrollChanged(int, int, int, int)} and the view will be
11345      * invalidated.
11346      * @param x the amount of pixels to scroll by horizontally
11347      * @param y the amount of pixels to scroll by vertically
11348      */
11349     public void scrollBy(int x, int y) {
11350         scrollTo(mScrollX + x, mScrollY + y);
11351     }
11352
11353     /**
11354      * <p>Trigger the scrollbars to draw. When invoked this method starts an
11355      * animation to fade the scrollbars out after a default delay. If a subclass
11356      * provides animated scrolling, the start delay should equal the duration
11357      * of the scrolling animation.</p>
11358      *
11359      * <p>The animation starts only if at least one of the scrollbars is
11360      * enabled, as specified by {@link #isHorizontalScrollBarEnabled()} and
11361      * {@link #isVerticalScrollBarEnabled()}. When the animation is started,
11362      * this method returns true, and false otherwise. If the animation is
11363      * started, this method calls {@link #invalidate()}; in that case the
11364      * caller should not call {@link #invalidate()}.</p>
11365      *
11366      * <p>This method should be invoked every time a subclass directly updates
11367      * the scroll parameters.</p>
11368      *
11369      * <p>This method is automatically invoked by {@link #scrollBy(int, int)}
11370      * and {@link #scrollTo(int, int)}.</p>
11371      *
11372      * @return true if the animation is played, false otherwise
11373      *
11374      * @see #awakenScrollBars(int)
11375      * @see #scrollBy(int, int)
11376      * @see #scrollTo(int, int)
11377      * @see #isHorizontalScrollBarEnabled()
11378      * @see #isVerticalScrollBarEnabled()
11379      * @see #setHorizontalScrollBarEnabled(boolean)
11380      * @see #setVerticalScrollBarEnabled(boolean)
11381      */
11382     protected boolean awakenScrollBars() {
11383         return mScrollCache != null &&
11384                 awakenScrollBars(mScrollCache.scrollBarDefaultDelayBeforeFade, true);
11385     }
11386
11387     /**
11388      * Trigger the scrollbars to draw.
11389      * This method differs from awakenScrollBars() only in its default duration.
11390      * initialAwakenScrollBars() will show the scroll bars for longer than
11391      * usual to give the user more of a chance to notice them.
11392      *
11393      * @return true if the animation is played, false otherwise.
11394      */
11395     private boolean initialAwakenScrollBars() {
11396         return mScrollCache != null &&
11397                 awakenScrollBars(mScrollCache.scrollBarDefaultDelayBeforeFade * 4, true);
11398     }
11399
11400     /**
11401      * <p>
11402      * Trigger the scrollbars to draw. When invoked this method starts an
11403      * animation to fade the scrollbars out after a fixed delay. If a subclass
11404      * provides animated scrolling, the start delay should equal the duration of
11405      * the scrolling animation.
11406      * </p>
11407      *
11408      * <p>
11409      * The animation starts only if at least one of the scrollbars is enabled,
11410      * as specified by {@link #isHorizontalScrollBarEnabled()} and
11411      * {@link #isVerticalScrollBarEnabled()}. When the animation is started,
11412      * this method returns true, and false otherwise. If the animation is
11413      * started, this method calls {@link #invalidate()}; in that case the caller
11414      * should not call {@link #invalidate()}.
11415      * </p>
11416      *
11417      * <p>
11418      * This method should be invoked everytime a subclass directly updates the
11419      * scroll parameters.
11420      * </p>
11421      *
11422      * @param startDelay the delay, in milliseconds, after which the animation
11423      *        should start; when the delay is 0, the animation starts
11424      *        immediately
11425      * @return true if the animation is played, false otherwise
11426      *
11427      * @see #scrollBy(int, int)
11428      * @see #scrollTo(int, int)
11429      * @see #isHorizontalScrollBarEnabled()
11430      * @see #isVerticalScrollBarEnabled()
11431      * @see #setHorizontalScrollBarEnabled(boolean)
11432      * @see #setVerticalScrollBarEnabled(boolean)
11433      */
11434     protected boolean awakenScrollBars(int startDelay) {
11435         return awakenScrollBars(startDelay, true);
11436     }
11437
11438     /**
11439      * <p>
11440      * Trigger the scrollbars to draw. When invoked this method starts an
11441      * animation to fade the scrollbars out after a fixed delay. If a subclass
11442      * provides animated scrolling, the start delay should equal the duration of
11443      * the scrolling animation.
11444      * </p>
11445      *
11446      * <p>
11447      * The animation starts only if at least one of the scrollbars is enabled,
11448      * as specified by {@link #isHorizontalScrollBarEnabled()} and
11449      * {@link #isVerticalScrollBarEnabled()}. When the animation is started,
11450      * this method returns true, and false otherwise. If the animation is
11451      * started, this method calls {@link #invalidate()} if the invalidate parameter
11452      * is set to true; in that case the caller
11453      * should not call {@link #invalidate()}.
11454      * </p>
11455      *
11456      * <p>
11457      * This method should be invoked everytime a subclass directly updates the
11458      * scroll parameters.
11459      * </p>
11460      *
11461      * @param startDelay the delay, in milliseconds, after which the animation
11462      *        should start; when the delay is 0, the animation starts
11463      *        immediately
11464      *
11465      * @param invalidate Wheter this method should call invalidate
11466      *
11467      * @return true if the animation is played, false otherwise
11468      *
11469      * @see #scrollBy(int, int)
11470      * @see #scrollTo(int, int)
11471      * @see #isHorizontalScrollBarEnabled()
11472      * @see #isVerticalScrollBarEnabled()
11473      * @see #setHorizontalScrollBarEnabled(boolean)
11474      * @see #setVerticalScrollBarEnabled(boolean)
11475      */
11476     protected boolean awakenScrollBars(int startDelay, boolean invalidate) {
11477         final ScrollabilityCache scrollCache = mScrollCache;
11478
11479         if (scrollCache == null || !scrollCache.fadeScrollBars) {
11480             return false;
11481         }
11482
11483         if (scrollCache.scrollBar == null) {
11484             scrollCache.scrollBar = new ScrollBarDrawable();
11485         }
11486
11487         if (isHorizontalScrollBarEnabled() || isVerticalScrollBarEnabled()) {
11488
11489             if (invalidate) {
11490                 // Invalidate to show the scrollbars
11491                 postInvalidateOnAnimation();
11492             }
11493
11494             if (scrollCache.state == ScrollabilityCache.OFF) {
11495                 // FIXME: this is copied from WindowManagerService.
11496                 // We should get this value from the system when it
11497                 // is possible to do so.
11498                 final int KEY_REPEAT_FIRST_DELAY = 750;
11499                 startDelay = Math.max(KEY_REPEAT_FIRST_DELAY, startDelay);
11500             }
11501
11502             // Tell mScrollCache when we should start fading. This may
11503             // extend the fade start time if one was already scheduled
11504             long fadeStartTime = AnimationUtils.currentAnimationTimeMillis() + startDelay;
11505             scrollCache.fadeStartTime = fadeStartTime;
11506             scrollCache.state = ScrollabilityCache.ON;
11507
11508             // Schedule our fader to run, unscheduling any old ones first
11509             if (mAttachInfo != null) {
11510                 mAttachInfo.mHandler.removeCallbacks(scrollCache);
11511                 mAttachInfo.mHandler.postAtTime(scrollCache, fadeStartTime);
11512             }
11513
11514             return true;
11515         }
11516
11517         return false;
11518     }
11519
11520     /**
11521      * Do not invalidate views which are not visible and which are not running an animation. They
11522      * will not get drawn and they should not set dirty flags as if they will be drawn
11523      */
11524     private boolean skipInvalidate() {
11525         return (mViewFlags & VISIBILITY_MASK) != VISIBLE && mCurrentAnimation == null &&
11526                 (!(mParent instanceof ViewGroup) ||
11527                         !((ViewGroup) mParent).isViewTransitioning(this));
11528     }
11529
11530     /**
11531      * Mark the area defined by dirty as needing to be drawn. If the view is
11532      * visible, {@link #onDraw(android.graphics.Canvas)} will be called at some
11533      * point in the future.
11534      * <p>
11535      * This must be called from a UI thread. To call from a non-UI thread, call
11536      * {@link #postInvalidate()}.
11537      * <p>
11538      * <b>WARNING:</b> In API 19 and below, this method may be destructive to
11539      * {@code dirty}.
11540      *
11541      * @param dirty the rectangle representing the bounds of the dirty region
11542      */
11543     public void invalidate(Rect dirty) {
11544         final int scrollX = mScrollX;
11545         final int scrollY = mScrollY;
11546         invalidateInternal(dirty.left - scrollX, dirty.top - scrollY,
11547                 dirty.right - scrollX, dirty.bottom - scrollY, true, false);
11548     }
11549
11550     /**
11551      * Mark the area defined by the rect (l,t,r,b) as needing to be drawn. The
11552      * coordinates of the dirty rect are relative to the view. If the view is
11553      * visible, {@link #onDraw(android.graphics.Canvas)} will be called at some
11554      * point in the future.
11555      * <p>
11556      * This must be called from a UI thread. To call from a non-UI thread, call
11557      * {@link #postInvalidate()}.
11558      *
11559      * @param l the left position of the dirty region
11560      * @param t the top position of the dirty region
11561      * @param r the right position of the dirty region
11562      * @param b the bottom position of the dirty region
11563      */
11564     public void invalidate(int l, int t, int r, int b) {
11565         final int scrollX = mScrollX;
11566         final int scrollY = mScrollY;
11567         invalidateInternal(l - scrollX, t - scrollY, r - scrollX, b - scrollY, true, false);
11568     }
11569
11570     /**
11571      * Invalidate the whole view. If the view is visible,
11572      * {@link #onDraw(android.graphics.Canvas)} will be called at some point in
11573      * the future.
11574      * <p>
11575      * This must be called from a UI thread. To call from a non-UI thread, call
11576      * {@link #postInvalidate()}.
11577      */
11578     public void invalidate() {
11579         invalidate(true);
11580     }
11581
11582     /**
11583      * This is where the invalidate() work actually happens. A full invalidate()
11584      * causes the drawing cache to be invalidated, but this function can be
11585      * called with invalidateCache set to false to skip that invalidation step
11586      * for cases that do not need it (for example, a component that remains at
11587      * the same dimensions with the same content).
11588      *
11589      * @param invalidateCache Whether the drawing cache for this view should be
11590      *            invalidated as well. This is usually true for a full
11591      *            invalidate, but may be set to false if the View's contents or
11592      *            dimensions have not changed.
11593      */
11594     void invalidate(boolean invalidateCache) {
11595         invalidateInternal(0, 0, mRight - mLeft, mBottom - mTop, invalidateCache, true);
11596     }
11597
11598     void invalidateInternal(int l, int t, int r, int b, boolean invalidateCache,
11599             boolean fullInvalidate) {
11600         if (mGhostView != null) {
11601             mGhostView.invalidate(invalidateCache);
11602             return;
11603         }
11604
11605         if (skipInvalidate()) {
11606             return;
11607         }
11608
11609         if ((mPrivateFlags & (PFLAG_DRAWN | PFLAG_HAS_BOUNDS)) == (PFLAG_DRAWN | PFLAG_HAS_BOUNDS)
11610                 || (invalidateCache && (mPrivateFlags & PFLAG_DRAWING_CACHE_VALID) == PFLAG_DRAWING_CACHE_VALID)
11611                 || (mPrivateFlags & PFLAG_INVALIDATED) != PFLAG_INVALIDATED
11612                 || (fullInvalidate && isOpaque() != mLastIsOpaque)) {
11613             if (fullInvalidate) {
11614                 mLastIsOpaque = isOpaque();
11615                 mPrivateFlags &= ~PFLAG_DRAWN;
11616             }
11617
11618             mPrivateFlags |= PFLAG_DIRTY;
11619
11620             if (invalidateCache) {
11621                 mPrivateFlags |= PFLAG_INVALIDATED;
11622                 mPrivateFlags &= ~PFLAG_DRAWING_CACHE_VALID;
11623             }
11624
11625             // Propagate the damage rectangle to the parent view.
11626             final AttachInfo ai = mAttachInfo;
11627             final ViewParent p = mParent;
11628             if (p != null && ai != null && l < r && t < b) {
11629                 final Rect damage = ai.mTmpInvalRect;
11630                 damage.set(l, t, r, b);
11631                 p.invalidateChild(this, damage);
11632             }
11633
11634             // Damage the entire projection receiver, if necessary.
11635             if (mBackground != null && mBackground.isProjected()) {
11636                 final View receiver = getProjectionReceiver();
11637                 if (receiver != null) {
11638                     receiver.damageInParent();
11639                 }
11640             }
11641
11642             // Damage the entire IsolatedZVolume receiving this view's shadow.
11643             if (isHardwareAccelerated() && getZ() != 0) {
11644                 damageShadowReceiver();
11645             }
11646         }
11647     }
11648
11649     /**
11650      * @return this view's projection receiver, or {@code null} if none exists
11651      */
11652     private View getProjectionReceiver() {
11653         ViewParent p = getParent();
11654         while (p != null && p instanceof View) {
11655             final View v = (View) p;
11656             if (v.isProjectionReceiver()) {
11657                 return v;
11658             }
11659             p = p.getParent();
11660         }
11661
11662         return null;
11663     }
11664
11665     /**
11666      * @return whether the view is a projection receiver
11667      */
11668     private boolean isProjectionReceiver() {
11669         return mBackground != null;
11670     }
11671
11672     /**
11673      * Damage area of the screen that can be covered by this View's shadow.
11674      *
11675      * This method will guarantee that any changes to shadows cast by a View
11676      * are damaged on the screen for future redraw.
11677      */
11678     private void damageShadowReceiver() {
11679         final AttachInfo ai = mAttachInfo;
11680         if (ai != null) {
11681             ViewParent p = getParent();
11682             if (p != null && p instanceof ViewGroup) {
11683                 final ViewGroup vg = (ViewGroup) p;
11684                 vg.damageInParent();
11685             }
11686         }
11687     }
11688
11689     /**
11690      * Quick invalidation for View property changes (alpha, translationXY, etc.). We don't want to
11691      * set any flags or handle all of the cases handled by the default invalidation methods.
11692      * Instead, we just want to schedule a traversal in ViewRootImpl with the appropriate
11693      * dirty rect. This method calls into fast invalidation methods in ViewGroup that
11694      * walk up the hierarchy, transforming the dirty rect as necessary.
11695      *
11696      * The method also handles normal invalidation logic if display list properties are not
11697      * being used in this view. The invalidateParent and forceRedraw flags are used by that
11698      * backup approach, to handle these cases used in the various property-setting methods.
11699      *
11700      * @param invalidateParent Force a call to invalidateParentCaches() if display list properties
11701      * are not being used in this view
11702      * @param forceRedraw Mark the view as DRAWN to force the invalidation to propagate, if display
11703      * list properties are not being used in this view
11704      */
11705     void invalidateViewProperty(boolean invalidateParent, boolean forceRedraw) {
11706         if (!isHardwareAccelerated()
11707                 || !mRenderNode.isValid()
11708                 || (mPrivateFlags & PFLAG_DRAW_ANIMATION) != 0) {
11709             if (invalidateParent) {
11710                 invalidateParentCaches();
11711             }
11712             if (forceRedraw) {
11713                 mPrivateFlags |= PFLAG_DRAWN; // force another invalidation with the new orientation
11714             }
11715             invalidate(false);
11716         } else {
11717             damageInParent();
11718         }
11719         if (isHardwareAccelerated() && invalidateParent && getZ() != 0) {
11720             damageShadowReceiver();
11721         }
11722     }
11723
11724     /**
11725      * Tells the parent view to damage this view's bounds.
11726      *
11727      * @hide
11728      */
11729     protected void damageInParent() {
11730         final AttachInfo ai = mAttachInfo;
11731         final ViewParent p = mParent;
11732         if (p != null && ai != null) {
11733             final Rect r = ai.mTmpInvalRect;
11734             r.set(0, 0, mRight - mLeft, mBottom - mTop);
11735             if (mParent instanceof ViewGroup) {
11736                 ((ViewGroup) mParent).damageChild(this, r);
11737             } else {
11738                 mParent.invalidateChild(this, r);
11739             }
11740         }
11741     }
11742
11743     /**
11744      * Utility method to transform a given Rect by the current matrix of this view.
11745      */
11746     void transformRect(final Rect rect) {
11747         if (!getMatrix().isIdentity()) {
11748             RectF boundingRect = mAttachInfo.mTmpTransformRect;
11749             boundingRect.set(rect);
11750             getMatrix().mapRect(boundingRect);
11751             rect.set((int) Math.floor(boundingRect.left),
11752                     (int) Math.floor(boundingRect.top),
11753                     (int) Math.ceil(boundingRect.right),
11754                     (int) Math.ceil(boundingRect.bottom));
11755         }
11756     }
11757
11758     /**
11759      * Used to indicate that the parent of this view should clear its caches. This functionality
11760      * is used to force the parent to rebuild its display list (when hardware-accelerated),
11761      * which is necessary when various parent-managed properties of the view change, such as
11762      * alpha, translationX/Y, scrollX/Y, scaleX/Y, and rotation/X/Y. This method only
11763      * clears the parent caches and does not causes an invalidate event.
11764      *
11765      * @hide
11766      */
11767     protected void invalidateParentCaches() {
11768         if (mParent instanceof View) {
11769             ((View) mParent).mPrivateFlags |= PFLAG_INVALIDATED;
11770         }
11771     }
11772
11773     /**
11774      * Used to indicate that the parent of this view should be invalidated. This functionality
11775      * is used to force the parent to rebuild its display list (when hardware-accelerated),
11776      * which is necessary when various parent-managed properties of the view change, such as
11777      * alpha, translationX/Y, scrollX/Y, scaleX/Y, and rotation/X/Y. This method will propagate
11778      * an invalidation event to the parent.
11779      *
11780      * @hide
11781      */
11782     protected void invalidateParentIfNeeded() {
11783         if (isHardwareAccelerated() && mParent instanceof View) {
11784             ((View) mParent).invalidate(true);
11785         }
11786     }
11787
11788     /**
11789      * @hide
11790      */
11791     protected void invalidateParentIfNeededAndWasQuickRejected() {
11792         if ((mPrivateFlags2 & PFLAG2_VIEW_QUICK_REJECTED) != 0) {
11793             // View was rejected last time it was drawn by its parent; this may have changed
11794             invalidateParentIfNeeded();
11795         }
11796     }
11797
11798     /**
11799      * Indicates whether this View is opaque. An opaque View guarantees that it will
11800      * draw all the pixels overlapping its bounds using a fully opaque color.
11801      *
11802      * Subclasses of View should override this method whenever possible to indicate
11803      * whether an instance is opaque. Opaque Views are treated in a special way by
11804      * the View hierarchy, possibly allowing it to perform optimizations during
11805      * invalidate/draw passes.
11806      *
11807      * @return True if this View is guaranteed to be fully opaque, false otherwise.
11808      */
11809     @ViewDebug.ExportedProperty(category = "drawing")
11810     public boolean isOpaque() {
11811         return (mPrivateFlags & PFLAG_OPAQUE_MASK) == PFLAG_OPAQUE_MASK &&
11812                 getFinalAlpha() >= 1.0f;
11813     }
11814
11815     /**
11816      * @hide
11817      */
11818     protected void computeOpaqueFlags() {
11819         // Opaque if:
11820         //   - Has a background
11821         //   - Background is opaque
11822         //   - Doesn't have scrollbars or scrollbars overlay
11823
11824         if (mBackground != null && mBackground.getOpacity() == PixelFormat.OPAQUE) {
11825             mPrivateFlags |= PFLAG_OPAQUE_BACKGROUND;
11826         } else {
11827             mPrivateFlags &= ~PFLAG_OPAQUE_BACKGROUND;
11828         }
11829
11830         final int flags = mViewFlags;
11831         if (((flags & SCROLLBARS_VERTICAL) == 0 && (flags & SCROLLBARS_HORIZONTAL) == 0) ||
11832                 (flags & SCROLLBARS_STYLE_MASK) == SCROLLBARS_INSIDE_OVERLAY ||
11833                 (flags & SCROLLBARS_STYLE_MASK) == SCROLLBARS_OUTSIDE_OVERLAY) {
11834             mPrivateFlags |= PFLAG_OPAQUE_SCROLLBARS;
11835         } else {
11836             mPrivateFlags &= ~PFLAG_OPAQUE_SCROLLBARS;
11837         }
11838     }
11839
11840     /**
11841      * @hide
11842      */
11843     protected boolean hasOpaqueScrollbars() {
11844         return (mPrivateFlags & PFLAG_OPAQUE_SCROLLBARS) == PFLAG_OPAQUE_SCROLLBARS;
11845     }
11846
11847     /**
11848      * @return A handler associated with the thread running the View. This
11849      * handler can be used to pump events in the UI events queue.
11850      */
11851     public Handler getHandler() {
11852         final AttachInfo attachInfo = mAttachInfo;
11853         if (attachInfo != null) {
11854             return attachInfo.mHandler;
11855         }
11856         return null;
11857     }
11858
11859     /**
11860      * Gets the view root associated with the View.
11861      * @return The view root, or null if none.
11862      * @hide
11863      */
11864     public ViewRootImpl getViewRootImpl() {
11865         if (mAttachInfo != null) {
11866             return mAttachInfo.mViewRootImpl;
11867         }
11868         return null;
11869     }
11870
11871     /**
11872      * @hide
11873      */
11874     public HardwareRenderer getHardwareRenderer() {
11875         return mAttachInfo != null ? mAttachInfo.mHardwareRenderer : null;
11876     }
11877
11878     /**
11879      * <p>Causes the Runnable to be added to the message queue.
11880      * The runnable will be run on the user interface thread.</p>
11881      *
11882      * @param action The Runnable that will be executed.
11883      *
11884      * @return Returns true if the Runnable was successfully placed in to the
11885      *         message queue.  Returns false on failure, usually because the
11886      *         looper processing the message queue is exiting.
11887      *
11888      * @see #postDelayed
11889      * @see #removeCallbacks
11890      */
11891     public boolean post(Runnable action) {
11892         final AttachInfo attachInfo = mAttachInfo;
11893         if (attachInfo != null) {
11894             return attachInfo.mHandler.post(action);
11895         }
11896         // Assume that post will succeed later
11897         ViewRootImpl.getRunQueue().post(action);
11898         return true;
11899     }
11900
11901     /**
11902      * <p>Causes the Runnable to be added to the message queue, to be run
11903      * after the specified amount of time elapses.
11904      * The runnable will be run on the user interface thread.</p>
11905      *
11906      * @param action The Runnable that will be executed.
11907      * @param delayMillis The delay (in milliseconds) until the Runnable
11908      *        will be executed.
11909      *
11910      * @return true if the Runnable was successfully placed in to the
11911      *         message queue.  Returns false on failure, usually because the
11912      *         looper processing the message queue is exiting.  Note that a
11913      *         result of true does not mean the Runnable will be processed --
11914      *         if the looper is quit before the delivery time of the message
11915      *         occurs then the message will be dropped.
11916      *
11917      * @see #post
11918      * @see #removeCallbacks
11919      */
11920     public boolean postDelayed(Runnable action, long delayMillis) {
11921         final AttachInfo attachInfo = mAttachInfo;
11922         if (attachInfo != null) {
11923             return attachInfo.mHandler.postDelayed(action, delayMillis);
11924         }
11925         // Assume that post will succeed later
11926         ViewRootImpl.getRunQueue().postDelayed(action, delayMillis);
11927         return true;
11928     }
11929
11930     /**
11931      * <p>Causes the Runnable to execute on the next animation time step.
11932      * The runnable will be run on the user interface thread.</p>
11933      *
11934      * @param action The Runnable that will be executed.
11935      *
11936      * @see #postOnAnimationDelayed
11937      * @see #removeCallbacks
11938      */
11939     public void postOnAnimation(Runnable action) {
11940         final AttachInfo attachInfo = mAttachInfo;
11941         if (attachInfo != null) {
11942             attachInfo.mViewRootImpl.mChoreographer.postCallback(
11943                     Choreographer.CALLBACK_ANIMATION, action, null);
11944         } else {
11945             // Assume that post will succeed later
11946             ViewRootImpl.getRunQueue().post(action);
11947         }
11948     }
11949
11950     /**
11951      * <p>Causes the Runnable to execute on the next animation time step,
11952      * after the specified amount of time elapses.
11953      * The runnable will be run on the user interface thread.</p>
11954      *
11955      * @param action The Runnable that will be executed.
11956      * @param delayMillis The delay (in milliseconds) until the Runnable
11957      *        will be executed.
11958      *
11959      * @see #postOnAnimation
11960      * @see #removeCallbacks
11961      */
11962     public void postOnAnimationDelayed(Runnable action, long delayMillis) {
11963         final AttachInfo attachInfo = mAttachInfo;
11964         if (attachInfo != null) {
11965             attachInfo.mViewRootImpl.mChoreographer.postCallbackDelayed(
11966                     Choreographer.CALLBACK_ANIMATION, action, null, delayMillis);
11967         } else {
11968             // Assume that post will succeed later
11969             ViewRootImpl.getRunQueue().postDelayed(action, delayMillis);
11970         }
11971     }
11972
11973     /**
11974      * <p>Removes the specified Runnable from the message queue.</p>
11975      *
11976      * @param action The Runnable to remove from the message handling queue
11977      *
11978      * @return true if this view could ask the Handler to remove the Runnable,
11979      *         false otherwise. When the returned value is true, the Runnable
11980      *         may or may not have been actually removed from the message queue
11981      *         (for instance, if the Runnable was not in the queue already.)
11982      *
11983      * @see #post
11984      * @see #postDelayed
11985      * @see #postOnAnimation
11986      * @see #postOnAnimationDelayed
11987      */
11988     public boolean removeCallbacks(Runnable action) {
11989         if (action != null) {
11990             final AttachInfo attachInfo = mAttachInfo;
11991             if (attachInfo != null) {
11992                 attachInfo.mHandler.removeCallbacks(action);
11993                 attachInfo.mViewRootImpl.mChoreographer.removeCallbacks(
11994                         Choreographer.CALLBACK_ANIMATION, action, null);
11995             }
11996             // Assume that post will succeed later
11997             ViewRootImpl.getRunQueue().removeCallbacks(action);
11998         }
11999         return true;
12000     }
12001
12002     /**
12003      * <p>Cause an invalidate to happen on a subsequent cycle through the event loop.
12004      * Use this to invalidate the View from a non-UI thread.</p>
12005      *
12006      * <p>This method can be invoked from outside of the UI thread
12007      * only when this View is attached to a window.</p>
12008      *
12009      * @see #invalidate()
12010      * @see #postInvalidateDelayed(long)
12011      */
12012     public void postInvalidate() {
12013         postInvalidateDelayed(0);
12014     }
12015
12016     /**
12017      * <p>Cause an invalidate of the specified area to happen on a subsequent cycle
12018      * through the event loop. Use this to invalidate the View from a non-UI thread.</p>
12019      *
12020      * <p>This method can be invoked from outside of the UI thread
12021      * only when this View is attached to a window.</p>
12022      *
12023      * @param left The left coordinate of the rectangle to invalidate.
12024      * @param top The top coordinate of the rectangle to invalidate.
12025      * @param right The right coordinate of the rectangle to invalidate.
12026      * @param bottom The bottom coordinate of the rectangle to invalidate.
12027      *
12028      * @see #invalidate(int, int, int, int)
12029      * @see #invalidate(Rect)
12030      * @see #postInvalidateDelayed(long, int, int, int, int)
12031      */
12032     public void postInvalidate(int left, int top, int right, int bottom) {
12033         postInvalidateDelayed(0, left, top, right, bottom);
12034     }
12035
12036     /**
12037      * <p>Cause an invalidate to happen on a subsequent cycle through the event
12038      * loop. Waits for the specified amount of time.</p>
12039      *
12040      * <p>This method can be invoked from outside of the UI thread
12041      * only when this View is attached to a window.</p>
12042      *
12043      * @param delayMilliseconds the duration in milliseconds to delay the
12044      *         invalidation by
12045      *
12046      * @see #invalidate()
12047      * @see #postInvalidate()
12048      */
12049     public void postInvalidateDelayed(long delayMilliseconds) {
12050         // We try only with the AttachInfo because there's no point in invalidating
12051         // if we are not attached to our window
12052         final AttachInfo attachInfo = mAttachInfo;
12053         if (attachInfo != null) {
12054             attachInfo.mViewRootImpl.dispatchInvalidateDelayed(this, delayMilliseconds);
12055         }
12056     }
12057
12058     /**
12059      * <p>Cause an invalidate of the specified area to happen on a subsequent cycle
12060      * through the event loop. Waits for the specified amount of time.</p>
12061      *
12062      * <p>This method can be invoked from outside of the UI thread
12063      * only when this View is attached to a window.</p>
12064      *
12065      * @param delayMilliseconds the duration in milliseconds to delay the
12066      *         invalidation by
12067      * @param left The left coordinate of the rectangle to invalidate.
12068      * @param top The top coordinate of the rectangle to invalidate.
12069      * @param right The right coordinate of the rectangle to invalidate.
12070      * @param bottom The bottom coordinate of the rectangle to invalidate.
12071      *
12072      * @see #invalidate(int, int, int, int)
12073      * @see #invalidate(Rect)
12074      * @see #postInvalidate(int, int, int, int)
12075      */
12076     public void postInvalidateDelayed(long delayMilliseconds, int left, int top,
12077             int right, int bottom) {
12078
12079         // We try only with the AttachInfo because there's no point in invalidating
12080         // if we are not attached to our window
12081         final AttachInfo attachInfo = mAttachInfo;
12082         if (attachInfo != null) {
12083             final AttachInfo.InvalidateInfo info = AttachInfo.InvalidateInfo.obtain();
12084             info.target = this;
12085             info.left = left;
12086             info.top = top;
12087             info.right = right;
12088             info.bottom = bottom;
12089
12090             attachInfo.mViewRootImpl.dispatchInvalidateRectDelayed(info, delayMilliseconds);
12091         }
12092     }
12093
12094     /**
12095      * <p>Cause an invalidate to happen on the next animation time step, typically the
12096      * next display frame.</p>
12097      *
12098      * <p>This method can be invoked from outside of the UI thread
12099      * only when this View is attached to a window.</p>
12100      *
12101      * @see #invalidate()
12102      */
12103     public void postInvalidateOnAnimation() {
12104         // We try only with the AttachInfo because there's no point in invalidating
12105         // if we are not attached to our window
12106         final AttachInfo attachInfo = mAttachInfo;
12107         if (attachInfo != null) {
12108             attachInfo.mViewRootImpl.dispatchInvalidateOnAnimation(this);
12109         }
12110     }
12111
12112     /**
12113      * <p>Cause an invalidate of the specified area to happen on the next animation
12114      * time step, typically the next display frame.</p>
12115      *
12116      * <p>This method can be invoked from outside of the UI thread
12117      * only when this View is attached to a window.</p>
12118      *
12119      * @param left The left coordinate of the rectangle to invalidate.
12120      * @param top The top coordinate of the rectangle to invalidate.
12121      * @param right The right coordinate of the rectangle to invalidate.
12122      * @param bottom The bottom coordinate of the rectangle to invalidate.
12123      *
12124      * @see #invalidate(int, int, int, int)
12125      * @see #invalidate(Rect)
12126      */
12127     public void postInvalidateOnAnimation(int left, int top, int right, int bottom) {
12128         // We try only with the AttachInfo because there's no point in invalidating
12129         // if we are not attached to our window
12130         final AttachInfo attachInfo = mAttachInfo;
12131         if (attachInfo != null) {
12132             final AttachInfo.InvalidateInfo info = AttachInfo.InvalidateInfo.obtain();
12133             info.target = this;
12134             info.left = left;
12135             info.top = top;
12136             info.right = right;
12137             info.bottom = bottom;
12138
12139             attachInfo.mViewRootImpl.dispatchInvalidateRectOnAnimation(info);
12140         }
12141     }
12142
12143     /**
12144      * Post a callback to send a {@link AccessibilityEvent#TYPE_VIEW_SCROLLED} event.
12145      * This event is sent at most once every
12146      * {@link ViewConfiguration#getSendRecurringAccessibilityEventsInterval()}.
12147      */
12148     private void postSendViewScrolledAccessibilityEventCallback() {
12149         if (mSendViewScrolledAccessibilityEvent == null) {
12150             mSendViewScrolledAccessibilityEvent = new SendViewScrolledAccessibilityEvent();
12151         }
12152         if (!mSendViewScrolledAccessibilityEvent.mIsPending) {
12153             mSendViewScrolledAccessibilityEvent.mIsPending = true;
12154             postDelayed(mSendViewScrolledAccessibilityEvent,
12155                     ViewConfiguration.getSendRecurringAccessibilityEventsInterval());
12156         }
12157     }
12158
12159     /**
12160      * Called by a parent to request that a child update its values for mScrollX
12161      * and mScrollY if necessary. This will typically be done if the child is
12162      * animating a scroll using a {@link android.widget.Scroller Scroller}
12163      * object.
12164      */
12165     public void computeScroll() {
12166     }
12167
12168     /**
12169      * <p>Indicate whether the horizontal edges are faded when the view is
12170      * scrolled horizontally.</p>
12171      *
12172      * @return true if the horizontal edges should are faded on scroll, false
12173      *         otherwise
12174      *
12175      * @see #setHorizontalFadingEdgeEnabled(boolean)
12176      *
12177      * @attr ref android.R.styleable#View_requiresFadingEdge
12178      */
12179     public boolean isHorizontalFadingEdgeEnabled() {
12180         return (mViewFlags & FADING_EDGE_HORIZONTAL) == FADING_EDGE_HORIZONTAL;
12181     }
12182
12183     /**
12184      * <p>Define whether the horizontal edges should be faded when this view
12185      * is scrolled horizontally.</p>
12186      *
12187      * @param horizontalFadingEdgeEnabled true if the horizontal edges should
12188      *                                    be faded when the view is scrolled
12189      *                                    horizontally
12190      *
12191      * @see #isHorizontalFadingEdgeEnabled()
12192      *
12193      * @attr ref android.R.styleable#View_requiresFadingEdge
12194      */
12195     public void setHorizontalFadingEdgeEnabled(boolean horizontalFadingEdgeEnabled) {
12196         if (isHorizontalFadingEdgeEnabled() != horizontalFadingEdgeEnabled) {
12197             if (horizontalFadingEdgeEnabled) {
12198                 initScrollCache();
12199             }
12200
12201             mViewFlags ^= FADING_EDGE_HORIZONTAL;
12202         }
12203     }
12204
12205     /**
12206      * <p>Indicate whether the vertical edges are faded when the view is
12207      * scrolled horizontally.</p>
12208      *
12209      * @return true if the vertical edges should are faded on scroll, false
12210      *         otherwise
12211      *
12212      * @see #setVerticalFadingEdgeEnabled(boolean)
12213      *
12214      * @attr ref android.R.styleable#View_requiresFadingEdge
12215      */
12216     public boolean isVerticalFadingEdgeEnabled() {
12217         return (mViewFlags & FADING_EDGE_VERTICAL) == FADING_EDGE_VERTICAL;
12218     }
12219
12220     /**
12221      * <p>Define whether the vertical edges should be faded when this view
12222      * is scrolled vertically.</p>
12223      *
12224      * @param verticalFadingEdgeEnabled true if the vertical edges should
12225      *                                  be faded when the view is scrolled
12226      *                                  vertically
12227      *
12228      * @see #isVerticalFadingEdgeEnabled()
12229      *
12230      * @attr ref android.R.styleable#View_requiresFadingEdge
12231      */
12232     public void setVerticalFadingEdgeEnabled(boolean verticalFadingEdgeEnabled) {
12233         if (isVerticalFadingEdgeEnabled() != verticalFadingEdgeEnabled) {
12234             if (verticalFadingEdgeEnabled) {
12235                 initScrollCache();
12236             }
12237
12238             mViewFlags ^= FADING_EDGE_VERTICAL;
12239         }
12240     }
12241
12242     /**
12243      * Returns the strength, or intensity, of the top faded edge. The strength is
12244      * a value between 0.0 (no fade) and 1.0 (full fade). The default implementation
12245      * returns 0.0 or 1.0 but no value in between.
12246      *
12247      * Subclasses should override this method to provide a smoother fade transition
12248      * when scrolling occurs.
12249      *
12250      * @return the intensity of the top fade as a float between 0.0f and 1.0f
12251      */
12252     protected float getTopFadingEdgeStrength() {
12253         return computeVerticalScrollOffset() > 0 ? 1.0f : 0.0f;
12254     }
12255
12256     /**
12257      * Returns the strength, or intensity, of the bottom faded edge. The strength is
12258      * a value between 0.0 (no fade) and 1.0 (full fade). The default implementation
12259      * returns 0.0 or 1.0 but no value in between.
12260      *
12261      * Subclasses should override this method to provide a smoother fade transition
12262      * when scrolling occurs.
12263      *
12264      * @return the intensity of the bottom fade as a float between 0.0f and 1.0f
12265      */
12266     protected float getBottomFadingEdgeStrength() {
12267         return computeVerticalScrollOffset() + computeVerticalScrollExtent() <
12268                 computeVerticalScrollRange() ? 1.0f : 0.0f;
12269     }
12270
12271     /**
12272      * Returns the strength, or intensity, of the left faded edge. The strength is
12273      * a value between 0.0 (no fade) and 1.0 (full fade). The default implementation
12274      * returns 0.0 or 1.0 but no value in between.
12275      *
12276      * Subclasses should override this method to provide a smoother fade transition
12277      * when scrolling occurs.
12278      *
12279      * @return the intensity of the left fade as a float between 0.0f and 1.0f
12280      */
12281     protected float getLeftFadingEdgeStrength() {
12282         return computeHorizontalScrollOffset() > 0 ? 1.0f : 0.0f;
12283     }
12284
12285     /**
12286      * Returns the strength, or intensity, of the right faded edge. The strength is
12287      * a value between 0.0 (no fade) and 1.0 (full fade). The default implementation
12288      * returns 0.0 or 1.0 but no value in between.
12289      *
12290      * Subclasses should override this method to provide a smoother fade transition
12291      * when scrolling occurs.
12292      *
12293      * @return the intensity of the right fade as a float between 0.0f and 1.0f
12294      */
12295     protected float getRightFadingEdgeStrength() {
12296         return computeHorizontalScrollOffset() + computeHorizontalScrollExtent() <
12297                 computeHorizontalScrollRange() ? 1.0f : 0.0f;
12298     }
12299
12300     /**
12301      * <p>Indicate whether the horizontal scrollbar should be drawn or not. The
12302      * scrollbar is not drawn by default.</p>
12303      *
12304      * @return true if the horizontal scrollbar should be painted, false
12305      *         otherwise
12306      *
12307      * @see #setHorizontalScrollBarEnabled(boolean)
12308      */
12309     public boolean isHorizontalScrollBarEnabled() {
12310         return (mViewFlags & SCROLLBARS_HORIZONTAL) == SCROLLBARS_HORIZONTAL;
12311     }
12312
12313     /**
12314      * <p>Define whether the horizontal scrollbar should be drawn or not. The
12315      * scrollbar is not drawn by default.</p>
12316      *
12317      * @param horizontalScrollBarEnabled true if the horizontal scrollbar should
12318      *                                   be painted
12319      *
12320      * @see #isHorizontalScrollBarEnabled()
12321      */
12322     public void setHorizontalScrollBarEnabled(boolean horizontalScrollBarEnabled) {
12323         if (isHorizontalScrollBarEnabled() != horizontalScrollBarEnabled) {
12324             mViewFlags ^= SCROLLBARS_HORIZONTAL;
12325             computeOpaqueFlags();
12326             resolvePadding();
12327         }
12328     }
12329
12330     /**
12331      * <p>Indicate whether the vertical scrollbar should be drawn or not. The
12332      * scrollbar is not drawn by default.</p>
12333      *
12334      * @return true if the vertical scrollbar should be painted, false
12335      *         otherwise
12336      *
12337      * @see #setVerticalScrollBarEnabled(boolean)
12338      */
12339     public boolean isVerticalScrollBarEnabled() {
12340         return (mViewFlags & SCROLLBARS_VERTICAL) == SCROLLBARS_VERTICAL;
12341     }
12342
12343     /**
12344      * <p>Define whether the vertical scrollbar should be drawn or not. The
12345      * scrollbar is not drawn by default.</p>
12346      *
12347      * @param verticalScrollBarEnabled true if the vertical scrollbar should
12348      *                                 be painted
12349      *
12350      * @see #isVerticalScrollBarEnabled()
12351      */
12352     public void setVerticalScrollBarEnabled(boolean verticalScrollBarEnabled) {
12353         if (isVerticalScrollBarEnabled() != verticalScrollBarEnabled) {
12354             mViewFlags ^= SCROLLBARS_VERTICAL;
12355             computeOpaqueFlags();
12356             resolvePadding();
12357         }
12358     }
12359
12360     /**
12361      * @hide
12362      */
12363     protected void recomputePadding() {
12364         internalSetPadding(mUserPaddingLeft, mPaddingTop, mUserPaddingRight, mUserPaddingBottom);
12365     }
12366
12367     /**
12368      * Define whether scrollbars will fade when the view is not scrolling.
12369      *
12370      * @param fadeScrollbars wheter to enable fading
12371      *
12372      * @attr ref android.R.styleable#View_fadeScrollbars
12373      */
12374     public void setScrollbarFadingEnabled(boolean fadeScrollbars) {
12375         initScrollCache();
12376         final ScrollabilityCache scrollabilityCache = mScrollCache;
12377         scrollabilityCache.fadeScrollBars = fadeScrollbars;
12378         if (fadeScrollbars) {
12379             scrollabilityCache.state = ScrollabilityCache.OFF;
12380         } else {
12381             scrollabilityCache.state = ScrollabilityCache.ON;
12382         }
12383     }
12384
12385     /**
12386      *
12387      * Returns true if scrollbars will fade when this view is not scrolling
12388      *
12389      * @return true if scrollbar fading is enabled
12390      *
12391      * @attr ref android.R.styleable#View_fadeScrollbars
12392      */
12393     public boolean isScrollbarFadingEnabled() {
12394         return mScrollCache != null && mScrollCache.fadeScrollBars;
12395     }
12396
12397     /**
12398      *
12399      * Returns the delay before scrollbars fade.
12400      *
12401      * @return the delay before scrollbars fade
12402      *
12403      * @attr ref android.R.styleable#View_scrollbarDefaultDelayBeforeFade
12404      */
12405     public int getScrollBarDefaultDelayBeforeFade() {
12406         return mScrollCache == null ? ViewConfiguration.getScrollDefaultDelay() :
12407                 mScrollCache.scrollBarDefaultDelayBeforeFade;
12408     }
12409
12410     /**
12411      * Define the delay before scrollbars fade.
12412      *
12413      * @param scrollBarDefaultDelayBeforeFade - the delay before scrollbars fade
12414      *
12415      * @attr ref android.R.styleable#View_scrollbarDefaultDelayBeforeFade
12416      */
12417     public void setScrollBarDefaultDelayBeforeFade(int scrollBarDefaultDelayBeforeFade) {
12418         getScrollCache().scrollBarDefaultDelayBeforeFade = scrollBarDefaultDelayBeforeFade;
12419     }
12420
12421     /**
12422      *
12423      * Returns the scrollbar fade duration.
12424      *
12425      * @return the scrollbar fade duration
12426      *
12427      * @attr ref android.R.styleable#View_scrollbarFadeDuration
12428      */
12429     public int getScrollBarFadeDuration() {
12430         return mScrollCache == null ? ViewConfiguration.getScrollBarFadeDuration() :
12431                 mScrollCache.scrollBarFadeDuration;
12432     }
12433
12434     /**
12435      * Define the scrollbar fade duration.
12436      *
12437      * @param scrollBarFadeDuration - the scrollbar fade duration
12438      *
12439      * @attr ref android.R.styleable#View_scrollbarFadeDuration
12440      */
12441     public void setScrollBarFadeDuration(int scrollBarFadeDuration) {
12442         getScrollCache().scrollBarFadeDuration = scrollBarFadeDuration;
12443     }
12444
12445     /**
12446      *
12447      * Returns the scrollbar size.
12448      *
12449      * @return the scrollbar size
12450      *
12451      * @attr ref android.R.styleable#View_scrollbarSize
12452      */
12453     public int getScrollBarSize() {
12454         return mScrollCache == null ? ViewConfiguration.get(mContext).getScaledScrollBarSize() :
12455                 mScrollCache.scrollBarSize;
12456     }
12457
12458     /**
12459      * Define the scrollbar size.
12460      *
12461      * @param scrollBarSize - the scrollbar size
12462      *
12463      * @attr ref android.R.styleable#View_scrollbarSize
12464      */
12465     public void setScrollBarSize(int scrollBarSize) {
12466         getScrollCache().scrollBarSize = scrollBarSize;
12467     }
12468
12469     /**
12470      * <p>Specify the style of the scrollbars. The scrollbars can be overlaid or
12471      * inset. When inset, they add to the padding of the view. And the scrollbars
12472      * can be drawn inside the padding area or on the edge of the view. For example,
12473      * if a view has a background drawable and you want to draw the scrollbars
12474      * inside the padding specified by the drawable, you can use
12475      * SCROLLBARS_INSIDE_OVERLAY or SCROLLBARS_INSIDE_INSET. If you want them to
12476      * appear at the edge of the view, ignoring the padding, then you can use
12477      * SCROLLBARS_OUTSIDE_OVERLAY or SCROLLBARS_OUTSIDE_INSET.</p>
12478      * @param style the style of the scrollbars. Should be one of
12479      * SCROLLBARS_INSIDE_OVERLAY, SCROLLBARS_INSIDE_INSET,
12480      * SCROLLBARS_OUTSIDE_OVERLAY or SCROLLBARS_OUTSIDE_INSET.
12481      * @see #SCROLLBARS_INSIDE_OVERLAY
12482      * @see #SCROLLBARS_INSIDE_INSET
12483      * @see #SCROLLBARS_OUTSIDE_OVERLAY
12484      * @see #SCROLLBARS_OUTSIDE_INSET
12485      *
12486      * @attr ref android.R.styleable#View_scrollbarStyle
12487      */
12488     public void setScrollBarStyle(@ScrollBarStyle int style) {
12489         if (style != (mViewFlags & SCROLLBARS_STYLE_MASK)) {
12490             mViewFlags = (mViewFlags & ~SCROLLBARS_STYLE_MASK) | (style & SCROLLBARS_STYLE_MASK);
12491             computeOpaqueFlags();
12492             resolvePadding();
12493         }
12494     }
12495
12496     /**
12497      * <p>Returns the current scrollbar style.</p>
12498      * @return the current scrollbar style
12499      * @see #SCROLLBARS_INSIDE_OVERLAY
12500      * @see #SCROLLBARS_INSIDE_INSET
12501      * @see #SCROLLBARS_OUTSIDE_OVERLAY
12502      * @see #SCROLLBARS_OUTSIDE_INSET
12503      *
12504      * @attr ref android.R.styleable#View_scrollbarStyle
12505      */
12506     @ViewDebug.ExportedProperty(mapping = {
12507             @ViewDebug.IntToString(from = SCROLLBARS_INSIDE_OVERLAY, to = "INSIDE_OVERLAY"),
12508             @ViewDebug.IntToString(from = SCROLLBARS_INSIDE_INSET, to = "INSIDE_INSET"),
12509             @ViewDebug.IntToString(from = SCROLLBARS_OUTSIDE_OVERLAY, to = "OUTSIDE_OVERLAY"),
12510             @ViewDebug.IntToString(from = SCROLLBARS_OUTSIDE_INSET, to = "OUTSIDE_INSET")
12511     })
12512     @ScrollBarStyle
12513     public int getScrollBarStyle() {
12514         return mViewFlags & SCROLLBARS_STYLE_MASK;
12515     }
12516
12517     /**
12518      * <p>Compute the horizontal range that the horizontal scrollbar
12519      * represents.</p>
12520      *
12521      * <p>The range is expressed in arbitrary units that must be the same as the
12522      * units used by {@link #computeHorizontalScrollExtent()} and
12523      * {@link #computeHorizontalScrollOffset()}.</p>
12524      *
12525      * <p>The default range is the drawing width of this view.</p>
12526      *
12527      * @return the total horizontal range represented by the horizontal
12528      *         scrollbar
12529      *
12530      * @see #computeHorizontalScrollExtent()
12531      * @see #computeHorizontalScrollOffset()
12532      * @see android.widget.ScrollBarDrawable
12533      */
12534     protected int computeHorizontalScrollRange() {
12535         return getWidth();
12536     }
12537
12538     /**
12539      * <p>Compute the horizontal offset of the horizontal scrollbar's thumb
12540      * within the horizontal range. This value is used to compute the position
12541      * of the thumb within the scrollbar's track.</p>
12542      *
12543      * <p>The range is expressed in arbitrary units that must be the same as the
12544      * units used by {@link #computeHorizontalScrollRange()} and
12545      * {@link #computeHorizontalScrollExtent()}.</p>
12546      *
12547      * <p>The default offset is the scroll offset of this view.</p>
12548      *
12549      * @return the horizontal offset of the scrollbar's thumb
12550      *
12551      * @see #computeHorizontalScrollRange()
12552      * @see #computeHorizontalScrollExtent()
12553      * @see android.widget.ScrollBarDrawable
12554      */
12555     protected int computeHorizontalScrollOffset() {
12556         return mScrollX;
12557     }
12558
12559     /**
12560      * <p>Compute the horizontal extent of the horizontal scrollbar's thumb
12561      * within the horizontal range. This value is used to compute the length
12562      * of the thumb within the scrollbar's track.</p>
12563      *
12564      * <p>The range is expressed in arbitrary units that must be the same as the
12565      * units used by {@link #computeHorizontalScrollRange()} and
12566      * {@link #computeHorizontalScrollOffset()}.</p>
12567      *
12568      * <p>The default extent is the drawing width of this view.</p>
12569      *
12570      * @return the horizontal extent of the scrollbar's thumb
12571      *
12572      * @see #computeHorizontalScrollRange()
12573      * @see #computeHorizontalScrollOffset()
12574      * @see android.widget.ScrollBarDrawable
12575      */
12576     protected int computeHorizontalScrollExtent() {
12577         return getWidth();
12578     }
12579
12580     /**
12581      * <p>Compute the vertical range that the vertical scrollbar represents.</p>
12582      *
12583      * <p>The range is expressed in arbitrary units that must be the same as the
12584      * units used by {@link #computeVerticalScrollExtent()} and
12585      * {@link #computeVerticalScrollOffset()}.</p>
12586      *
12587      * @return the total vertical range represented by the vertical scrollbar
12588      *
12589      * <p>The default range is the drawing height of this view.</p>
12590      *
12591      * @see #computeVerticalScrollExtent()
12592      * @see #computeVerticalScrollOffset()
12593      * @see android.widget.ScrollBarDrawable
12594      */
12595     protected int computeVerticalScrollRange() {
12596         return getHeight();
12597     }
12598
12599     /**
12600      * <p>Compute the vertical offset of the vertical scrollbar's thumb
12601      * within the horizontal range. This value is used to compute the position
12602      * of the thumb within the scrollbar's track.</p>
12603      *
12604      * <p>The range is expressed in arbitrary units that must be the same as the
12605      * units used by {@link #computeVerticalScrollRange()} and
12606      * {@link #computeVerticalScrollExtent()}.</p>
12607      *
12608      * <p>The default offset is the scroll offset of this view.</p>
12609      *
12610      * @return the vertical offset of the scrollbar's thumb
12611      *
12612      * @see #computeVerticalScrollRange()
12613      * @see #computeVerticalScrollExtent()
12614      * @see android.widget.ScrollBarDrawable
12615      */
12616     protected int computeVerticalScrollOffset() {
12617         return mScrollY;
12618     }
12619
12620     /**
12621      * <p>Compute the vertical extent of the vertical scrollbar's thumb
12622      * within the vertical range. This value is used to compute the length
12623      * of the thumb within the scrollbar's track.</p>
12624      *
12625      * <p>The range is expressed in arbitrary units that must be the same as the
12626      * units used by {@link #computeVerticalScrollRange()} and
12627      * {@link #computeVerticalScrollOffset()}.</p>
12628      *
12629      * <p>The default extent is the drawing height of this view.</p>
12630      *
12631      * @return the vertical extent of the scrollbar's thumb
12632      *
12633      * @see #computeVerticalScrollRange()
12634      * @see #computeVerticalScrollOffset()
12635      * @see android.widget.ScrollBarDrawable
12636      */
12637     protected int computeVerticalScrollExtent() {
12638         return getHeight();
12639     }
12640
12641     /**
12642      * Check if this view can be scrolled horizontally in a certain direction.
12643      *
12644      * @param direction Negative to check scrolling left, positive to check scrolling right.
12645      * @return true if this view can be scrolled in the specified direction, false otherwise.
12646      */
12647     public boolean canScrollHorizontally(int direction) {
12648         final int offset = computeHorizontalScrollOffset();
12649         final int range = computeHorizontalScrollRange() - computeHorizontalScrollExtent();
12650         if (range == 0) return false;
12651         if (direction < 0) {
12652             return offset > 0;
12653         } else {
12654             return offset < range - 1;
12655         }
12656     }
12657
12658     /**
12659      * Check if this view can be scrolled vertically in a certain direction.
12660      *
12661      * @param direction Negative to check scrolling up, positive to check scrolling down.
12662      * @return true if this view can be scrolled in the specified direction, false otherwise.
12663      */
12664     public boolean canScrollVertically(int direction) {
12665         final int offset = computeVerticalScrollOffset();
12666         final int range = computeVerticalScrollRange() - computeVerticalScrollExtent();
12667         if (range == 0) return false;
12668         if (direction < 0) {
12669             return offset > 0;
12670         } else {
12671             return offset < range - 1;
12672         }
12673     }
12674
12675     /**
12676      * <p>Request the drawing of the horizontal and the vertical scrollbar. The
12677      * scrollbars are painted only if they have been awakened first.</p>
12678      *
12679      * @param canvas the canvas on which to draw the scrollbars
12680      *
12681      * @see #awakenScrollBars(int)
12682      */
12683     protected final void onDrawScrollBars(Canvas canvas) {
12684         // scrollbars are drawn only when the animation is running
12685         final ScrollabilityCache cache = mScrollCache;
12686         if (cache != null) {
12687
12688             int state = cache.state;
12689
12690             if (state == ScrollabilityCache.OFF) {
12691                 return;
12692             }
12693
12694             boolean invalidate = false;
12695
12696             if (state == ScrollabilityCache.FADING) {
12697                 // We're fading -- get our fade interpolation
12698                 if (cache.interpolatorValues == null) {
12699                     cache.interpolatorValues = new float[1];
12700                 }
12701
12702                 float[] values = cache.interpolatorValues;
12703
12704                 // Stops the animation if we're done
12705                 if (cache.scrollBarInterpolator.timeToValues(values) ==
12706                         Interpolator.Result.FREEZE_END) {
12707                     cache.state = ScrollabilityCache.OFF;
12708                 } else {
12709                     cache.scrollBar.setAlpha(Math.round(values[0]));
12710                 }
12711
12712                 // This will make the scroll bars inval themselves after
12713                 // drawing. We only want this when we're fading so that
12714                 // we prevent excessive redraws
12715                 invalidate = true;
12716             } else {
12717                 // We're just on -- but we may have been fading before so
12718                 // reset alpha
12719                 cache.scrollBar.setAlpha(255);
12720             }
12721
12722
12723             final int viewFlags = mViewFlags;
12724
12725             final boolean drawHorizontalScrollBar =
12726                 (viewFlags & SCROLLBARS_HORIZONTAL) == SCROLLBARS_HORIZONTAL;
12727             final boolean drawVerticalScrollBar =
12728                 (viewFlags & SCROLLBARS_VERTICAL) == SCROLLBARS_VERTICAL
12729                 && !isVerticalScrollBarHidden();
12730
12731             if (drawVerticalScrollBar || drawHorizontalScrollBar) {
12732                 final int width = mRight - mLeft;
12733                 final int height = mBottom - mTop;
12734
12735                 final ScrollBarDrawable scrollBar = cache.scrollBar;
12736
12737                 final int scrollX = mScrollX;
12738                 final int scrollY = mScrollY;
12739                 final int inside = (viewFlags & SCROLLBARS_OUTSIDE_MASK) == 0 ? ~0 : 0;
12740
12741                 int left;
12742                 int top;
12743                 int right;
12744                 int bottom;
12745
12746                 if (drawHorizontalScrollBar) {
12747                     int size = scrollBar.getSize(false);
12748                     if (size <= 0) {
12749                         size = cache.scrollBarSize;
12750                     }
12751
12752                     scrollBar.setParameters(computeHorizontalScrollRange(),
12753                                             computeHorizontalScrollOffset(),
12754                                             computeHorizontalScrollExtent(), false);
12755                     final int verticalScrollBarGap = drawVerticalScrollBar ?
12756                             getVerticalScrollbarWidth() : 0;
12757                     top = scrollY + height - size - (mUserPaddingBottom & inside);
12758                     left = scrollX + (mPaddingLeft & inside);
12759                     right = scrollX + width - (mUserPaddingRight & inside) - verticalScrollBarGap;
12760                     bottom = top + size;
12761                     onDrawHorizontalScrollBar(canvas, scrollBar, left, top, right, bottom);
12762                     if (invalidate) {
12763                         invalidate(left, top, right, bottom);
12764                     }
12765                 }
12766
12767                 if (drawVerticalScrollBar) {
12768                     int size = scrollBar.getSize(true);
12769                     if (size <= 0) {
12770                         size = cache.scrollBarSize;
12771                     }
12772
12773                     scrollBar.setParameters(computeVerticalScrollRange(),
12774                                             computeVerticalScrollOffset(),
12775                                             computeVerticalScrollExtent(), true);
12776                     int verticalScrollbarPosition = mVerticalScrollbarPosition;
12777                     if (verticalScrollbarPosition == SCROLLBAR_POSITION_DEFAULT) {
12778                         verticalScrollbarPosition = isLayoutRtl() ?
12779                                 SCROLLBAR_POSITION_LEFT : SCROLLBAR_POSITION_RIGHT;
12780                     }
12781                     switch (verticalScrollbarPosition) {
12782                         default:
12783                         case SCROLLBAR_POSITION_RIGHT:
12784                             left = scrollX + width - size - (mUserPaddingRight & inside);
12785                             break;
12786                         case SCROLLBAR_POSITION_LEFT:
12787                             left = scrollX + (mUserPaddingLeft & inside);
12788                             break;
12789                     }
12790                     top = scrollY + (mPaddingTop & inside);
12791                     right = left + size;
12792                     bottom = scrollY + height - (mUserPaddingBottom & inside);
12793                     onDrawVerticalScrollBar(canvas, scrollBar, left, top, right, bottom);
12794                     if (invalidate) {
12795                         invalidate(left, top, right, bottom);
12796                     }
12797                 }
12798             }
12799         }
12800     }
12801
12802     /**
12803      * Override this if the vertical scrollbar needs to be hidden in a subclass, like when
12804      * FastScroller is visible.
12805      * @return whether to temporarily hide the vertical scrollbar
12806      * @hide
12807      */
12808     protected boolean isVerticalScrollBarHidden() {
12809         return false;
12810     }
12811
12812     /**
12813      * <p>Draw the horizontal scrollbar if
12814      * {@link #isHorizontalScrollBarEnabled()} returns true.</p>
12815      *
12816      * @param canvas the canvas on which to draw the scrollbar
12817      * @param scrollBar the scrollbar's drawable
12818      *
12819      * @see #isHorizontalScrollBarEnabled()
12820      * @see #computeHorizontalScrollRange()
12821      * @see #computeHorizontalScrollExtent()
12822      * @see #computeHorizontalScrollOffset()
12823      * @see android.widget.ScrollBarDrawable
12824      * @hide
12825      */
12826     protected void onDrawHorizontalScrollBar(Canvas canvas, Drawable scrollBar,
12827             int l, int t, int r, int b) {
12828         scrollBar.setBounds(l, t, r, b);
12829         scrollBar.draw(canvas);
12830     }
12831
12832     /**
12833      * <p>Draw the vertical scrollbar if {@link #isVerticalScrollBarEnabled()}
12834      * returns true.</p>
12835      *
12836      * @param canvas the canvas on which to draw the scrollbar
12837      * @param scrollBar the scrollbar's drawable
12838      *
12839      * @see #isVerticalScrollBarEnabled()
12840      * @see #computeVerticalScrollRange()
12841      * @see #computeVerticalScrollExtent()
12842      * @see #computeVerticalScrollOffset()
12843      * @see android.widget.ScrollBarDrawable
12844      * @hide
12845      */
12846     protected void onDrawVerticalScrollBar(Canvas canvas, Drawable scrollBar,
12847             int l, int t, int r, int b) {
12848         scrollBar.setBounds(l, t, r, b);
12849         scrollBar.draw(canvas);
12850     }
12851
12852     /**
12853      * Implement this to do your drawing.
12854      *
12855      * @param canvas the canvas on which the background will be drawn
12856      */
12857     protected void onDraw(Canvas canvas) {
12858     }
12859
12860     /*
12861      * Caller is responsible for calling requestLayout if necessary.
12862      * (This allows addViewInLayout to not request a new layout.)
12863      */
12864     void assignParent(ViewParent parent) {
12865         if (mParent == null) {
12866             mParent = parent;
12867         } else if (parent == null) {
12868             mParent = null;
12869         } else {
12870             throw new RuntimeException("view " + this + " being added, but"
12871                     + " it already has a parent");
12872         }
12873     }
12874
12875     /**
12876      * This is called when the view is attached to a window.  At this point it
12877      * has a Surface and will start drawing.  Note that this function is
12878      * guaranteed to be called before {@link #onDraw(android.graphics.Canvas)},
12879      * however it may be called any time before the first onDraw -- including
12880      * before or after {@link #onMeasure(int, int)}.
12881      *
12882      * @see #onDetachedFromWindow()
12883      */
12884     protected void onAttachedToWindow() {
12885         if ((mPrivateFlags & PFLAG_REQUEST_TRANSPARENT_REGIONS) != 0) {
12886             mParent.requestTransparentRegion(this);
12887         }
12888
12889         if ((mPrivateFlags & PFLAG_AWAKEN_SCROLL_BARS_ON_ATTACH) != 0) {
12890             initialAwakenScrollBars();
12891             mPrivateFlags &= ~PFLAG_AWAKEN_SCROLL_BARS_ON_ATTACH;
12892         }
12893
12894         mPrivateFlags3 &= ~PFLAG3_IS_LAID_OUT;
12895
12896         jumpDrawablesToCurrentState();
12897
12898         resetSubtreeAccessibilityStateChanged();
12899
12900         invalidateOutline();
12901
12902         if (isFocused()) {
12903             InputMethodManager imm = InputMethodManager.peekInstance();
12904             imm.focusIn(this);
12905         }
12906     }
12907
12908     /**
12909      * Resolve all RTL related properties.
12910      *
12911      * @return true if resolution of RTL properties has been done
12912      *
12913      * @hide
12914      */
12915     public boolean resolveRtlPropertiesIfNeeded() {
12916         if (!needRtlPropertiesResolution()) return false;
12917
12918         // Order is important here: LayoutDirection MUST be resolved first
12919         if (!isLayoutDirectionResolved()) {
12920             resolveLayoutDirection();
12921             resolveLayoutParams();
12922         }
12923         // ... then we can resolve the others properties depending on the resolved LayoutDirection.
12924         if (!isTextDirectionResolved()) {
12925             resolveTextDirection();
12926         }
12927         if (!isTextAlignmentResolved()) {
12928             resolveTextAlignment();
12929         }
12930         // Should resolve Drawables before Padding because we need the layout direction of the
12931         // Drawable to correctly resolve Padding.
12932         if (!isDrawablesResolved()) {
12933             resolveDrawables();
12934         }
12935         if (!isPaddingResolved()) {
12936             resolvePadding();
12937         }
12938         onRtlPropertiesChanged(getLayoutDirection());
12939         return true;
12940     }
12941
12942     /**
12943      * Reset resolution of all RTL related properties.
12944      *
12945      * @hide
12946      */
12947     public void resetRtlProperties() {
12948         resetResolvedLayoutDirection();
12949         resetResolvedTextDirection();
12950         resetResolvedTextAlignment();
12951         resetResolvedPadding();
12952         resetResolvedDrawables();
12953     }
12954
12955     /**
12956      * @see #onScreenStateChanged(int)
12957      */
12958     void dispatchScreenStateChanged(int screenState) {
12959         onScreenStateChanged(screenState);
12960     }
12961
12962     /**
12963      * This method is called whenever the state of the screen this view is
12964      * attached to changes. A state change will usually occurs when the screen
12965      * turns on or off (whether it happens automatically or the user does it
12966      * manually.)
12967      *
12968      * @param screenState The new state of the screen. Can be either
12969      *                    {@link #SCREEN_STATE_ON} or {@link #SCREEN_STATE_OFF}
12970      */
12971     public void onScreenStateChanged(int screenState) {
12972     }
12973
12974     /**
12975      * Return true if the application tag in the AndroidManifest has set "supportRtl" to true
12976      */
12977     private boolean hasRtlSupport() {
12978         return mContext.getApplicationInfo().hasRtlSupport();
12979     }
12980
12981     /**
12982      * Return true if we are in RTL compatibility mode (either before Jelly Bean MR1 or
12983      * RTL not supported)
12984      */
12985     private boolean isRtlCompatibilityMode() {
12986         final int targetSdkVersion = getContext().getApplicationInfo().targetSdkVersion;
12987         return targetSdkVersion < JELLY_BEAN_MR1 || !hasRtlSupport();
12988     }
12989
12990     /**
12991      * @return true if RTL properties need resolution.
12992      *
12993      */
12994     private boolean needRtlPropertiesResolution() {
12995         return (mPrivateFlags2 & ALL_RTL_PROPERTIES_RESOLVED) != ALL_RTL_PROPERTIES_RESOLVED;
12996     }
12997
12998     /**
12999      * Called when any RTL property (layout direction or text direction or text alignment) has
13000      * been changed.
13001      *
13002      * Subclasses need to override this method to take care of cached information that depends on the
13003      * resolved layout direction, or to inform child views that inherit their layout direction.
13004      *
13005      * The default implementation does nothing.
13006      *
13007      * @param layoutDirection the direction of the layout
13008      *
13009      * @see #LAYOUT_DIRECTION_LTR
13010      * @see #LAYOUT_DIRECTION_RTL
13011      */
13012     public void onRtlPropertiesChanged(@ResolvedLayoutDir int layoutDirection) {
13013     }
13014
13015     /**
13016      * Resolve and cache the layout direction. LTR is set initially. This is implicitly supposing
13017      * that the parent directionality can and will be resolved before its children.
13018      *
13019      * @return true if resolution has been done, false otherwise.
13020      *
13021      * @hide
13022      */
13023     public boolean resolveLayoutDirection() {
13024         // Clear any previous layout direction resolution
13025         mPrivateFlags2 &= ~PFLAG2_LAYOUT_DIRECTION_RESOLVED_MASK;
13026
13027         if (hasRtlSupport()) {
13028             // Set resolved depending on layout direction
13029             switch ((mPrivateFlags2 & PFLAG2_LAYOUT_DIRECTION_MASK) >>
13030                     PFLAG2_LAYOUT_DIRECTION_MASK_SHIFT) {
13031                 case LAYOUT_DIRECTION_INHERIT:
13032                     // We cannot resolve yet. LTR is by default and let the resolution happen again
13033                     // later to get the correct resolved value
13034                     if (!canResolveLayoutDirection()) return false;
13035
13036                     // Parent has not yet resolved, LTR is still the default
13037                     try {
13038                         if (!mParent.isLayoutDirectionResolved()) return false;
13039
13040                         if (mParent.getLayoutDirection() == LAYOUT_DIRECTION_RTL) {
13041                             mPrivateFlags2 |= PFLAG2_LAYOUT_DIRECTION_RESOLVED_RTL;
13042                         }
13043                     } catch (AbstractMethodError e) {
13044                         Log.e(VIEW_LOG_TAG, mParent.getClass().getSimpleName() +
13045                                 " does not fully implement ViewParent", e);
13046                     }
13047                     break;
13048                 case LAYOUT_DIRECTION_RTL:
13049                     mPrivateFlags2 |= PFLAG2_LAYOUT_DIRECTION_RESOLVED_RTL;
13050                     break;
13051                 case LAYOUT_DIRECTION_LOCALE:
13052                     if((LAYOUT_DIRECTION_RTL ==
13053                             TextUtils.getLayoutDirectionFromLocale(Locale.getDefault()))) {
13054                         mPrivateFlags2 |= PFLAG2_LAYOUT_DIRECTION_RESOLVED_RTL;
13055                     }
13056                     break;
13057                 default:
13058                     // Nothing to do, LTR by default
13059             }
13060         }
13061
13062         // Set to resolved
13063         mPrivateFlags2 |= PFLAG2_LAYOUT_DIRECTION_RESOLVED;
13064         return true;
13065     }
13066
13067     /**
13068      * Check if layout direction resolution can be done.
13069      *
13070      * @return true if layout direction resolution can be done otherwise return false.
13071      */
13072     public boolean canResolveLayoutDirection() {
13073         switch (getRawLayoutDirection()) {
13074             case LAYOUT_DIRECTION_INHERIT:
13075                 if (mParent != null) {
13076                     try {
13077                         return mParent.canResolveLayoutDirection();
13078                     } catch (AbstractMethodError e) {
13079                         Log.e(VIEW_LOG_TAG, mParent.getClass().getSimpleName() +
13080                                 " does not fully implement ViewParent", e);
13081                     }
13082                 }
13083                 return false;
13084
13085             default:
13086                 return true;
13087         }
13088     }
13089
13090     /**
13091      * Reset the resolved layout direction. Layout direction will be resolved during a call to
13092      * {@link #onMeasure(int, int)}.
13093      *
13094      * @hide
13095      */
13096     public void resetResolvedLayoutDirection() {
13097         // Reset the current resolved bits
13098         mPrivateFlags2 &= ~PFLAG2_LAYOUT_DIRECTION_RESOLVED_MASK;
13099     }
13100
13101     /**
13102      * @return true if the layout direction is inherited.
13103      *
13104      * @hide
13105      */
13106     public boolean isLayoutDirectionInherited() {
13107         return (getRawLayoutDirection() == LAYOUT_DIRECTION_INHERIT);
13108     }
13109
13110     /**
13111      * @return true if layout direction has been resolved.
13112      */
13113     public boolean isLayoutDirectionResolved() {
13114         return (mPrivateFlags2 & PFLAG2_LAYOUT_DIRECTION_RESOLVED) == PFLAG2_LAYOUT_DIRECTION_RESOLVED;
13115     }
13116
13117     /**
13118      * Return if padding has been resolved
13119      *
13120      * @hide
13121      */
13122     boolean isPaddingResolved() {
13123         return (mPrivateFlags2 & PFLAG2_PADDING_RESOLVED) == PFLAG2_PADDING_RESOLVED;
13124     }
13125
13126     /**
13127      * Resolves padding depending on layout direction, if applicable, and
13128      * recomputes internal padding values to adjust for scroll bars.
13129      *
13130      * @hide
13131      */
13132     public void resolvePadding() {
13133         final int resolvedLayoutDirection = getLayoutDirection();
13134
13135         if (!isRtlCompatibilityMode()) {
13136             // Post Jelly Bean MR1 case: we need to take the resolved layout direction into account.
13137             // If start / end padding are defined, they will be resolved (hence overriding) to
13138             // left / right or right / left depending on the resolved layout direction.
13139             // If start / end padding are not defined, use the left / right ones.
13140             if (mBackground != null && (!mLeftPaddingDefined || !mRightPaddingDefined)) {
13141                 Rect padding = sThreadLocal.get();
13142                 if (padding == null) {
13143                     padding = new Rect();
13144                     sThreadLocal.set(padding);
13145                 }
13146                 mBackground.getPadding(padding);
13147                 if (!mLeftPaddingDefined) {
13148                     mUserPaddingLeftInitial = padding.left;
13149                 }
13150                 if (!mRightPaddingDefined) {
13151                     mUserPaddingRightInitial = padding.right;
13152                 }
13153             }
13154             switch (resolvedLayoutDirection) {
13155                 case LAYOUT_DIRECTION_RTL:
13156                     if (mUserPaddingStart != UNDEFINED_PADDING) {
13157                         mUserPaddingRight = mUserPaddingStart;
13158                     } else {
13159                         mUserPaddingRight = mUserPaddingRightInitial;
13160                     }
13161                     if (mUserPaddingEnd != UNDEFINED_PADDING) {
13162                         mUserPaddingLeft = mUserPaddingEnd;
13163                     } else {
13164                         mUserPaddingLeft = mUserPaddingLeftInitial;
13165                     }
13166                     break;
13167                 case LAYOUT_DIRECTION_LTR:
13168                 default:
13169                     if (mUserPaddingStart != UNDEFINED_PADDING) {
13170                         mUserPaddingLeft = mUserPaddingStart;
13171                     } else {
13172                         mUserPaddingLeft = mUserPaddingLeftInitial;
13173                     }
13174                     if (mUserPaddingEnd != UNDEFINED_PADDING) {
13175                         mUserPaddingRight = mUserPaddingEnd;
13176                     } else {
13177                         mUserPaddingRight = mUserPaddingRightInitial;
13178                     }
13179             }
13180
13181             mUserPaddingBottom = (mUserPaddingBottom >= 0) ? mUserPaddingBottom : mPaddingBottom;
13182         }
13183
13184         internalSetPadding(mUserPaddingLeft, mPaddingTop, mUserPaddingRight, mUserPaddingBottom);
13185         onRtlPropertiesChanged(resolvedLayoutDirection);
13186
13187         mPrivateFlags2 |= PFLAG2_PADDING_RESOLVED;
13188     }
13189
13190     /**
13191      * Reset the resolved layout direction.
13192      *
13193      * @hide
13194      */
13195     public void resetResolvedPadding() {
13196         mPrivateFlags2 &= ~PFLAG2_PADDING_RESOLVED;
13197     }
13198
13199     /**
13200      * This is called when the view is detached from a window.  At this point it
13201      * no longer has a surface for drawing.
13202      *
13203      * @see #onAttachedToWindow()
13204      */
13205     protected void onDetachedFromWindow() {
13206     }
13207
13208     /**
13209      * This is a framework-internal mirror of onDetachedFromWindow() that's called
13210      * after onDetachedFromWindow().
13211      *
13212      * If you override this you *MUST* call super.onDetachedFromWindowInternal()!
13213      * The super method should be called at the end of the overriden method to ensure
13214      * subclasses are destroyed first
13215      *
13216      * @hide
13217      */
13218     protected void onDetachedFromWindowInternal() {
13219         mPrivateFlags &= ~PFLAG_CANCEL_NEXT_UP_EVENT;
13220         mPrivateFlags3 &= ~PFLAG3_IS_LAID_OUT;
13221
13222         removeUnsetPressCallback();
13223         removeLongPressCallback();
13224         removePerformClickCallback();
13225         removeSendViewScrolledAccessibilityEventCallback();
13226         stopNestedScroll();
13227
13228         // Anything that started animating right before detach should already
13229         // be in its final state when re-attached.
13230         jumpDrawablesToCurrentState();
13231
13232         destroyDrawingCache();
13233
13234         cleanupDraw();
13235         mCurrentAnimation = null;
13236     }
13237
13238     private void cleanupDraw() {
13239         resetDisplayList();
13240         if (mAttachInfo != null) {
13241             mAttachInfo.mViewRootImpl.cancelInvalidate(this);
13242         }
13243     }
13244
13245     void invalidateInheritedLayoutMode(int layoutModeOfRoot) {
13246     }
13247
13248     /**
13249      * @return The number of times this view has been attached to a window
13250      */
13251     protected int getWindowAttachCount() {
13252         return mWindowAttachCount;
13253     }
13254
13255     /**
13256      * Retrieve a unique token identifying the window this view is attached to.
13257      * @return Return the window's token for use in
13258      * {@link WindowManager.LayoutParams#token WindowManager.LayoutParams.token}.
13259      */
13260     public IBinder getWindowToken() {
13261         return mAttachInfo != null ? mAttachInfo.mWindowToken : null;
13262     }
13263
13264     /**
13265      * Retrieve the {@link WindowId} for the window this view is
13266      * currently attached to.
13267      */
13268     public WindowId getWindowId() {
13269         if (mAttachInfo == null) {
13270             return null;
13271         }
13272         if (mAttachInfo.mWindowId == null) {
13273             try {
13274                 mAttachInfo.mIWindowId = mAttachInfo.mSession.getWindowId(
13275                         mAttachInfo.mWindowToken);
13276                 mAttachInfo.mWindowId = new WindowId(
13277                         mAttachInfo.mIWindowId);
13278             } catch (RemoteException e) {
13279             }
13280         }
13281         return mAttachInfo.mWindowId;
13282     }
13283
13284     /**
13285      * Retrieve a unique token identifying the top-level "real" window of
13286      * the window that this view is attached to.  That is, this is like
13287      * {@link #getWindowToken}, except if the window this view in is a panel
13288      * window (attached to another containing window), then the token of
13289      * the containing window is returned instead.
13290      *
13291      * @return Returns the associated window token, either
13292      * {@link #getWindowToken()} or the containing window's token.
13293      */
13294     public IBinder getApplicationWindowToken() {
13295         AttachInfo ai = mAttachInfo;
13296         if (ai != null) {
13297             IBinder appWindowToken = ai.mPanelParentWindowToken;
13298             if (appWindowToken == null) {
13299                 appWindowToken = ai.mWindowToken;
13300             }
13301             return appWindowToken;
13302         }
13303         return null;
13304     }
13305
13306     /**
13307      * Gets the logical display to which the view's window has been attached.
13308      *
13309      * @return The logical display, or null if the view is not currently attached to a window.
13310      */
13311     public Display getDisplay() {
13312         return mAttachInfo != null ? mAttachInfo.mDisplay : null;
13313     }
13314
13315     /**
13316      * Retrieve private session object this view hierarchy is using to
13317      * communicate with the window manager.
13318      * @return the session object to communicate with the window manager
13319      */
13320     /*package*/ IWindowSession getWindowSession() {
13321         return mAttachInfo != null ? mAttachInfo.mSession : null;
13322     }
13323
13324     /**
13325      * @param info the {@link android.view.View.AttachInfo} to associated with
13326      *        this view
13327      */
13328     void dispatchAttachedToWindow(AttachInfo info, int visibility) {
13329         //System.out.println("Attached! " + this);
13330         mAttachInfo = info;
13331         if (mOverlay != null) {
13332             mOverlay.getOverlayView().dispatchAttachedToWindow(info, visibility);
13333         }
13334         mWindowAttachCount++;
13335         // We will need to evaluate the drawable state at least once.
13336         mPrivateFlags |= PFLAG_DRAWABLE_STATE_DIRTY;
13337         if (mFloatingTreeObserver != null) {
13338             info.mTreeObserver.merge(mFloatingTreeObserver);
13339             mFloatingTreeObserver = null;
13340         }
13341         if ((mPrivateFlags&PFLAG_SCROLL_CONTAINER) != 0) {
13342             mAttachInfo.mScrollContainers.add(this);
13343             mPrivateFlags |= PFLAG_SCROLL_CONTAINER_ADDED;
13344         }
13345         performCollectViewAttributes(mAttachInfo, visibility);
13346         onAttachedToWindow();
13347
13348         ListenerInfo li = mListenerInfo;
13349         final CopyOnWriteArrayList<OnAttachStateChangeListener> listeners =
13350                 li != null ? li.mOnAttachStateChangeListeners : null;
13351         if (listeners != null && listeners.size() > 0) {
13352             // NOTE: because of the use of CopyOnWriteArrayList, we *must* use an iterator to
13353             // perform the dispatching. The iterator is a safe guard against listeners that
13354             // could mutate the list by calling the various add/remove methods. This prevents
13355             // the array from being modified while we iterate it.
13356             for (OnAttachStateChangeListener listener : listeners) {
13357                 listener.onViewAttachedToWindow(this);
13358             }
13359         }
13360
13361         int vis = info.mWindowVisibility;
13362         if (vis != GONE) {
13363             onWindowVisibilityChanged(vis);
13364         }
13365         if ((mPrivateFlags&PFLAG_DRAWABLE_STATE_DIRTY) != 0) {
13366             // If nobody has evaluated the drawable state yet, then do it now.
13367             refreshDrawableState();
13368         }
13369         needGlobalAttributesUpdate(false);
13370     }
13371
13372     void dispatchDetachedFromWindow() {
13373         AttachInfo info = mAttachInfo;
13374         if (info != null) {
13375             int vis = info.mWindowVisibility;
13376             if (vis != GONE) {
13377                 onWindowVisibilityChanged(GONE);
13378             }
13379         }
13380
13381         onDetachedFromWindow();
13382         onDetachedFromWindowInternal();
13383
13384         ListenerInfo li = mListenerInfo;
13385         final CopyOnWriteArrayList<OnAttachStateChangeListener> listeners =
13386                 li != null ? li.mOnAttachStateChangeListeners : null;
13387         if (listeners != null && listeners.size() > 0) {
13388             // NOTE: because of the use of CopyOnWriteArrayList, we *must* use an iterator to
13389             // perform the dispatching. The iterator is a safe guard against listeners that
13390             // could mutate the list by calling the various add/remove methods. This prevents
13391             // the array from being modified while we iterate it.
13392             for (OnAttachStateChangeListener listener : listeners) {
13393                 listener.onViewDetachedFromWindow(this);
13394             }
13395         }
13396
13397         if ((mPrivateFlags & PFLAG_SCROLL_CONTAINER_ADDED) != 0) {
13398             mAttachInfo.mScrollContainers.remove(this);
13399             mPrivateFlags &= ~PFLAG_SCROLL_CONTAINER_ADDED;
13400         }
13401
13402         mAttachInfo = null;
13403         if (mOverlay != null) {
13404             mOverlay.getOverlayView().dispatchDetachedFromWindow();
13405         }
13406     }
13407
13408     /**
13409      * Cancel any deferred high-level input events that were previously posted to the event queue.
13410      *
13411      * <p>Many views post high-level events such as click handlers to the event queue
13412      * to run deferred in order to preserve a desired user experience - clearing visible
13413      * pressed states before executing, etc. This method will abort any events of this nature
13414      * that are currently in flight.</p>
13415      *
13416      * <p>Custom views that generate their own high-level deferred input events should override
13417      * {@link #onCancelPendingInputEvents()} and remove those pending events from the queue.</p>
13418      *
13419      * <p>This will also cancel pending input events for any child views.</p>
13420      *
13421      * <p>Note that this may not be sufficient as a debouncing strategy for clicks in all cases.
13422      * This will not impact newer events posted after this call that may occur as a result of
13423      * lower-level input events still waiting in the queue. If you are trying to prevent
13424      * double-submitted  events for the duration of some sort of asynchronous transaction
13425      * you should also take other steps to protect against unexpected double inputs e.g. calling
13426      * {@link #setEnabled(boolean) setEnabled(false)} and re-enabling the view when
13427      * the transaction completes, tracking already submitted transaction IDs, etc.</p>
13428      */
13429     public final void cancelPendingInputEvents() {
13430         dispatchCancelPendingInputEvents();
13431     }
13432
13433     /**
13434      * Called by {@link #cancelPendingInputEvents()} to cancel input events in flight.
13435      * Overridden by ViewGroup to dispatch. Package scoped to prevent app-side meddling.
13436      */
13437     void dispatchCancelPendingInputEvents() {
13438         mPrivateFlags3 &= ~PFLAG3_CALLED_SUPER;
13439         onCancelPendingInputEvents();
13440         if ((mPrivateFlags3 & PFLAG3_CALLED_SUPER) != PFLAG3_CALLED_SUPER) {
13441             throw new SuperNotCalledException("View " + getClass().getSimpleName() +
13442                     " did not call through to super.onCancelPendingInputEvents()");
13443         }
13444     }
13445
13446     /**
13447      * Called as the result of a call to {@link #cancelPendingInputEvents()} on this view or
13448      * a parent view.
13449      *
13450      * <p>This method is responsible for removing any pending high-level input events that were
13451      * posted to the event queue to run later. Custom view classes that post their own deferred
13452      * high-level events via {@link #post(Runnable)}, {@link #postDelayed(Runnable, long)} or
13453      * {@link android.os.Handler} should override this method, call
13454      * <code>super.onCancelPendingInputEvents()</code> and remove those callbacks as appropriate.
13455      * </p>
13456      */
13457     public void onCancelPendingInputEvents() {
13458         removePerformClickCallback();
13459         cancelLongPress();
13460         mPrivateFlags3 |= PFLAG3_CALLED_SUPER;
13461     }
13462
13463     /**
13464      * Store this view hierarchy's frozen state into the given container.
13465      *
13466      * @param container The SparseArray in which to save the view's state.
13467      *
13468      * @see #restoreHierarchyState(android.util.SparseArray)
13469      * @see #dispatchSaveInstanceState(android.util.SparseArray)
13470      * @see #onSaveInstanceState()
13471      */
13472     public void saveHierarchyState(SparseArray<Parcelable> container) {
13473         dispatchSaveInstanceState(container);
13474     }
13475
13476     /**
13477      * Called by {@link #saveHierarchyState(android.util.SparseArray)} to store the state for
13478      * this view and its children. May be overridden to modify how freezing happens to a
13479      * view's children; for example, some views may want to not store state for their children.
13480      *
13481      * @param container The SparseArray in which to save the view's state.
13482      *
13483      * @see #dispatchRestoreInstanceState(android.util.SparseArray)
13484      * @see #saveHierarchyState(android.util.SparseArray)
13485      * @see #onSaveInstanceState()
13486      */
13487     protected void dispatchSaveInstanceState(SparseArray<Parcelable> container) {
13488         if (mID != NO_ID && (mViewFlags & SAVE_DISABLED_MASK) == 0) {
13489             mPrivateFlags &= ~PFLAG_SAVE_STATE_CALLED;
13490             Parcelable state = onSaveInstanceState();
13491             if ((mPrivateFlags & PFLAG_SAVE_STATE_CALLED) == 0) {
13492                 throw new IllegalStateException(
13493                         "Derived class did not call super.onSaveInstanceState()");
13494             }
13495             if (state != null) {
13496                 // Log.i("View", "Freezing #" + Integer.toHexString(mID)
13497                 // + ": " + state);
13498                 container.put(mID, state);
13499             }
13500         }
13501     }
13502
13503     /**
13504      * Hook allowing a view to generate a representation of its internal state
13505      * that can later be used to create a new instance with that same state.
13506      * This state should only contain information that is not persistent or can
13507      * not be reconstructed later. For example, you will never store your
13508      * current position on screen because that will be computed again when a
13509      * new instance of the view is placed in its view hierarchy.
13510      * <p>
13511      * Some examples of things you may store here: the current cursor position
13512      * in a text view (but usually not the text itself since that is stored in a
13513      * content provider or other persistent storage), the currently selected
13514      * item in a list view.
13515      *
13516      * @return Returns a Parcelable object containing the view's current dynamic
13517      *         state, or null if there is nothing interesting to save. The
13518      *         default implementation returns null.
13519      * @see #onRestoreInstanceState(android.os.Parcelable)
13520      * @see #saveHierarchyState(android.util.SparseArray)
13521      * @see #dispatchSaveInstanceState(android.util.SparseArray)
13522      * @see #setSaveEnabled(boolean)
13523      */
13524     protected Parcelable onSaveInstanceState() {
13525         mPrivateFlags |= PFLAG_SAVE_STATE_CALLED;
13526         return BaseSavedState.EMPTY_STATE;
13527     }
13528
13529     /**
13530      * Restore this view hierarchy's frozen state from the given container.
13531      *
13532      * @param container The SparseArray which holds previously frozen states.
13533      *
13534      * @see #saveHierarchyState(android.util.SparseArray)
13535      * @see #dispatchRestoreInstanceState(android.util.SparseArray)
13536      * @see #onRestoreInstanceState(android.os.Parcelable)
13537      */
13538     public void restoreHierarchyState(SparseArray<Parcelable> container) {
13539         dispatchRestoreInstanceState(container);
13540     }
13541
13542     /**
13543      * Called by {@link #restoreHierarchyState(android.util.SparseArray)} to retrieve the
13544      * state for this view and its children. May be overridden to modify how restoring
13545      * happens to a view's children; for example, some views may want to not store state
13546      * for their children.
13547      *
13548      * @param container The SparseArray which holds previously saved state.
13549      *
13550      * @see #dispatchSaveInstanceState(android.util.SparseArray)
13551      * @see #restoreHierarchyState(android.util.SparseArray)
13552      * @see #onRestoreInstanceState(android.os.Parcelable)
13553      */
13554     protected void dispatchRestoreInstanceState(SparseArray<Parcelable> container) {
13555         if (mID != NO_ID) {
13556             Parcelable state = container.get(mID);
13557             if (state != null) {
13558                 // Log.i("View", "Restoreing #" + Integer.toHexString(mID)
13559                 // + ": " + state);
13560                 mPrivateFlags &= ~PFLAG_SAVE_STATE_CALLED;
13561                 onRestoreInstanceState(state);
13562                 if ((mPrivateFlags & PFLAG_SAVE_STATE_CALLED) == 0) {
13563                     throw new IllegalStateException(
13564                             "Derived class did not call super.onRestoreInstanceState()");
13565                 }
13566             }
13567         }
13568     }
13569
13570     /**
13571      * Hook allowing a view to re-apply a representation of its internal state that had previously
13572      * been generated by {@link #onSaveInstanceState}. This function will never be called with a
13573      * null state.
13574      *
13575      * @param state The frozen state that had previously been returned by
13576      *        {@link #onSaveInstanceState}.
13577      *
13578      * @see #onSaveInstanceState()
13579      * @see #restoreHierarchyState(android.util.SparseArray)
13580      * @see #dispatchRestoreInstanceState(android.util.SparseArray)
13581      */
13582     protected void onRestoreInstanceState(Parcelable state) {
13583         mPrivateFlags |= PFLAG_SAVE_STATE_CALLED;
13584         if (state != BaseSavedState.EMPTY_STATE && state != null) {
13585             throw new IllegalArgumentException("Wrong state class, expecting View State but "
13586                     + "received " + state.getClass().toString() + " instead. This usually happens "
13587                     + "when two views of different type have the same id in the same hierarchy. "
13588                     + "This view's id is " + ViewDebug.resolveId(mContext, getId()) + ". Make sure "
13589                     + "other views do not use the same id.");
13590         }
13591     }
13592
13593     /**
13594      * <p>Return the time at which the drawing of the view hierarchy started.</p>
13595      *
13596      * @return the drawing start time in milliseconds
13597      */
13598     public long getDrawingTime() {
13599         return mAttachInfo != null ? mAttachInfo.mDrawingTime : 0;
13600     }
13601
13602     /**
13603      * <p>Enables or disables the duplication of the parent's state into this view. When
13604      * duplication is enabled, this view gets its drawable state from its parent rather
13605      * than from its own internal properties.</p>
13606      *
13607      * <p>Note: in the current implementation, setting this property to true after the
13608      * view was added to a ViewGroup might have no effect at all. This property should
13609      * always be used from XML or set to true before adding this view to a ViewGroup.</p>
13610      *
13611      * <p>Note: if this view's parent addStateFromChildren property is enabled and this
13612      * property is enabled, an exception will be thrown.</p>
13613      *
13614      * <p>Note: if the child view uses and updates additionnal states which are unknown to the
13615      * parent, these states should not be affected by this method.</p>
13616      *
13617      * @param enabled True to enable duplication of the parent's drawable state, false
13618      *                to disable it.
13619      *
13620      * @see #getDrawableState()
13621      * @see #isDuplicateParentStateEnabled()
13622      */
13623     public void setDuplicateParentStateEnabled(boolean enabled) {
13624         setFlags(enabled ? DUPLICATE_PARENT_STATE : 0, DUPLICATE_PARENT_STATE);
13625     }
13626
13627     /**
13628      * <p>Indicates whether this duplicates its drawable state from its parent.</p>
13629      *
13630      * @return True if this view's drawable state is duplicated from the parent,
13631      *         false otherwise
13632      *
13633      * @see #getDrawableState()
13634      * @see #setDuplicateParentStateEnabled(boolean)
13635      */
13636     public boolean isDuplicateParentStateEnabled() {
13637         return (mViewFlags & DUPLICATE_PARENT_STATE) == DUPLICATE_PARENT_STATE;
13638     }
13639
13640     /**
13641      * <p>Specifies the type of layer backing this view. The layer can be
13642      * {@link #LAYER_TYPE_NONE}, {@link #LAYER_TYPE_SOFTWARE} or
13643      * {@link #LAYER_TYPE_HARDWARE}.</p>
13644      *
13645      * <p>A layer is associated with an optional {@link android.graphics.Paint}
13646      * instance that controls how the layer is composed on screen. The following
13647      * properties of the paint are taken into account when composing the layer:</p>
13648      * <ul>
13649      * <li>{@link android.graphics.Paint#getAlpha() Translucency (alpha)}</li>
13650      * <li>{@link android.graphics.Paint#getXfermode() Blending mode}</li>
13651      * <li>{@link android.graphics.Paint#getColorFilter() Color filter}</li>
13652      * </ul>
13653      *
13654      * <p>If this view has an alpha value set to < 1.0 by calling
13655      * {@link #setAlpha(float)}, the alpha value of the layer's paint is superceded
13656      * by this view's alpha value.</p>
13657      *
13658      * <p>Refer to the documentation of {@link #LAYER_TYPE_NONE},
13659      * {@link #LAYER_TYPE_SOFTWARE} and {@link #LAYER_TYPE_HARDWARE}
13660      * for more information on when and how to use layers.</p>
13661      *
13662      * @param layerType The type of layer to use with this view, must be one of
13663      *        {@link #LAYER_TYPE_NONE}, {@link #LAYER_TYPE_SOFTWARE} or
13664      *        {@link #LAYER_TYPE_HARDWARE}
13665      * @param paint The paint used to compose the layer. This argument is optional
13666      *        and can be null. It is ignored when the layer type is
13667      *        {@link #LAYER_TYPE_NONE}
13668      *
13669      * @see #getLayerType()
13670      * @see #LAYER_TYPE_NONE
13671      * @see #LAYER_TYPE_SOFTWARE
13672      * @see #LAYER_TYPE_HARDWARE
13673      * @see #setAlpha(float)
13674      *
13675      * @attr ref android.R.styleable#View_layerType
13676      */
13677     public void setLayerType(int layerType, Paint paint) {
13678         if (layerType < LAYER_TYPE_NONE || layerType > LAYER_TYPE_HARDWARE) {
13679             throw new IllegalArgumentException("Layer type can only be one of: LAYER_TYPE_NONE, "
13680                     + "LAYER_TYPE_SOFTWARE or LAYER_TYPE_HARDWARE");
13681         }
13682
13683         boolean typeChanged = mRenderNode.setLayerType(layerType);
13684
13685         if (!typeChanged) {
13686             setLayerPaint(paint);
13687             return;
13688         }
13689
13690         // Destroy any previous software drawing cache if needed
13691         if (mLayerType == LAYER_TYPE_SOFTWARE) {
13692             destroyDrawingCache();
13693         }
13694
13695         mLayerType = layerType;
13696         final boolean layerDisabled = (mLayerType == LAYER_TYPE_NONE);
13697         mLayerPaint = layerDisabled ? null : (paint == null ? new Paint() : paint);
13698         mRenderNode.setLayerPaint(mLayerPaint);
13699
13700         // draw() behaves differently if we are on a layer, so we need to
13701         // invalidate() here
13702         invalidateParentCaches();
13703         invalidate(true);
13704     }
13705
13706     /**
13707      * Updates the {@link Paint} object used with the current layer (used only if the current
13708      * layer type is not set to {@link #LAYER_TYPE_NONE}). Changed properties of the Paint
13709      * provided to {@link #setLayerType(int, android.graphics.Paint)} will be used the next time
13710      * the View is redrawn, but {@link #setLayerPaint(android.graphics.Paint)} must be called to
13711      * ensure that the view gets redrawn immediately.
13712      *
13713      * <p>A layer is associated with an optional {@link android.graphics.Paint}
13714      * instance that controls how the layer is composed on screen. The following
13715      * properties of the paint are taken into account when composing the layer:</p>
13716      * <ul>
13717      * <li>{@link android.graphics.Paint#getAlpha() Translucency (alpha)}</li>
13718      * <li>{@link android.graphics.Paint#getXfermode() Blending mode}</li>
13719      * <li>{@link android.graphics.Paint#getColorFilter() Color filter}</li>
13720      * </ul>
13721      *
13722      * <p>If this view has an alpha value set to < 1.0 by calling {@link #setAlpha(float)}, the
13723      * alpha value of the layer's paint is superceded by this view's alpha value.</p>
13724      *
13725      * @param paint The paint used to compose the layer. This argument is optional
13726      *        and can be null. It is ignored when the layer type is
13727      *        {@link #LAYER_TYPE_NONE}
13728      *
13729      * @see #setLayerType(int, android.graphics.Paint)
13730      */
13731     public void setLayerPaint(Paint paint) {
13732         int layerType = getLayerType();
13733         if (layerType != LAYER_TYPE_NONE) {
13734             mLayerPaint = paint == null ? new Paint() : paint;
13735             if (layerType == LAYER_TYPE_HARDWARE) {
13736                 if (mRenderNode.setLayerPaint(mLayerPaint)) {
13737                     invalidateViewProperty(false, false);
13738                 }
13739             } else {
13740                 invalidate();
13741             }
13742         }
13743     }
13744
13745     /**
13746      * Indicates whether this view has a static layer. A view with layer type
13747      * {@link #LAYER_TYPE_NONE} is a static layer. Other types of layers are
13748      * dynamic.
13749      */
13750     boolean hasStaticLayer() {
13751         return true;
13752     }
13753
13754     /**
13755      * Indicates what type of layer is currently associated with this view. By default
13756      * a view does not have a layer, and the layer type is {@link #LAYER_TYPE_NONE}.
13757      * Refer to the documentation of {@link #setLayerType(int, android.graphics.Paint)}
13758      * for more information on the different types of layers.
13759      *
13760      * @return {@link #LAYER_TYPE_NONE}, {@link #LAYER_TYPE_SOFTWARE} or
13761      *         {@link #LAYER_TYPE_HARDWARE}
13762      *
13763      * @see #setLayerType(int, android.graphics.Paint)
13764      * @see #buildLayer()
13765      * @see #LAYER_TYPE_NONE
13766      * @see #LAYER_TYPE_SOFTWARE
13767      * @see #LAYER_TYPE_HARDWARE
13768      */
13769     public int getLayerType() {
13770         return mLayerType;
13771     }
13772
13773     /**
13774      * Forces this view's layer to be created and this view to be rendered
13775      * into its layer. If this view's layer type is set to {@link #LAYER_TYPE_NONE},
13776      * invoking this method will have no effect.
13777      *
13778      * This method can for instance be used to render a view into its layer before
13779      * starting an animation. If this view is complex, rendering into the layer
13780      * before starting the animation will avoid skipping frames.
13781      *
13782      * @throws IllegalStateException If this view is not attached to a window
13783      *
13784      * @see #setLayerType(int, android.graphics.Paint)
13785      */
13786     public void buildLayer() {
13787         if (mLayerType == LAYER_TYPE_NONE) return;
13788
13789         final AttachInfo attachInfo = mAttachInfo;
13790         if (attachInfo == null) {
13791             throw new IllegalStateException("This view must be attached to a window first");
13792         }
13793
13794         if (getWidth() == 0 || getHeight() == 0) {
13795             return;
13796         }
13797
13798         switch (mLayerType) {
13799             case LAYER_TYPE_HARDWARE:
13800                 updateDisplayListIfDirty();
13801                 if (attachInfo.mHardwareRenderer != null && mRenderNode.isValid()) {
13802                     attachInfo.mHardwareRenderer.buildLayer(mRenderNode);
13803                 }
13804                 break;
13805             case LAYER_TYPE_SOFTWARE:
13806                 buildDrawingCache(true);
13807                 break;
13808         }
13809     }
13810
13811     /**
13812      * If this View draws with a HardwareLayer, returns it.
13813      * Otherwise returns null
13814      *
13815      * TODO: Only TextureView uses this, can we eliminate it?
13816      */
13817     HardwareLayer getHardwareLayer() {
13818         return null;
13819     }
13820
13821     /**
13822      * Destroys all hardware rendering resources. This method is invoked
13823      * when the system needs to reclaim resources. Upon execution of this
13824      * method, you should free any OpenGL resources created by the view.
13825      *
13826      * Note: you <strong>must</strong> call
13827      * <code>super.destroyHardwareResources()</code> when overriding
13828      * this method.
13829      *
13830      * @hide
13831      */
13832     protected void destroyHardwareResources() {
13833         // Although the Layer will be destroyed by RenderNode, we want to release
13834         // the staging display list, which is also a signal to RenderNode that it's
13835         // safe to free its copy of the display list as it knows that we will
13836         // push an updated DisplayList if we try to draw again
13837         resetDisplayList();
13838     }
13839
13840     /**
13841      * <p>Enables or disables the drawing cache. When the drawing cache is enabled, the next call
13842      * to {@link #getDrawingCache()} or {@link #buildDrawingCache()} will draw the view in a
13843      * bitmap. Calling {@link #draw(android.graphics.Canvas)} will not draw from the cache when
13844      * the cache is enabled. To benefit from the cache, you must request the drawing cache by
13845      * calling {@link #getDrawingCache()} and draw it on screen if the returned bitmap is not
13846      * null.</p>
13847      *
13848      * <p>Enabling the drawing cache is similar to
13849      * {@link #setLayerType(int, android.graphics.Paint) setting a layer} when hardware
13850      * acceleration is turned off. When hardware acceleration is turned on, enabling the
13851      * drawing cache has no effect on rendering because the system uses a different mechanism
13852      * for acceleration which ignores the flag. If you want to use a Bitmap for the view, even
13853      * when hardware acceleration is enabled, see {@link #setLayerType(int, android.graphics.Paint)}
13854      * for information on how to enable software and hardware layers.</p>
13855      *
13856      * <p>This API can be used to manually generate
13857      * a bitmap copy of this view, by setting the flag to <code>true</code> and calling
13858      * {@link #getDrawingCache()}.</p>
13859      *
13860      * @param enabled true to enable the drawing cache, false otherwise
13861      *
13862      * @see #isDrawingCacheEnabled()
13863      * @see #getDrawingCache()
13864      * @see #buildDrawingCache()
13865      * @see #setLayerType(int, android.graphics.Paint)
13866      */
13867     public void setDrawingCacheEnabled(boolean enabled) {
13868         mCachingFailed = false;
13869         setFlags(enabled ? DRAWING_CACHE_ENABLED : 0, DRAWING_CACHE_ENABLED);
13870     }
13871
13872     /**
13873      * <p>Indicates whether the drawing cache is enabled for this view.</p>
13874      *
13875      * @return true if the drawing cache is enabled
13876      *
13877      * @see #setDrawingCacheEnabled(boolean)
13878      * @see #getDrawingCache()
13879      */
13880     @ViewDebug.ExportedProperty(category = "drawing")
13881     public boolean isDrawingCacheEnabled() {
13882         return (mViewFlags & DRAWING_CACHE_ENABLED) == DRAWING_CACHE_ENABLED;
13883     }
13884
13885     /**
13886      * Debugging utility which recursively outputs the dirty state of a view and its
13887      * descendants.
13888      *
13889      * @hide
13890      */
13891     @SuppressWarnings({"UnusedDeclaration"})
13892     public void outputDirtyFlags(String indent, boolean clear, int clearMask) {
13893         Log.d("View", indent + this + "             DIRTY(" + (mPrivateFlags & View.PFLAG_DIRTY_MASK) +
13894                 ") DRAWN(" + (mPrivateFlags & PFLAG_DRAWN) + ")" + " CACHE_VALID(" +
13895                 (mPrivateFlags & View.PFLAG_DRAWING_CACHE_VALID) +
13896                 ") INVALIDATED(" + (mPrivateFlags & PFLAG_INVALIDATED) + ")");
13897         if (clear) {
13898             mPrivateFlags &= clearMask;
13899         }
13900         if (this instanceof ViewGroup) {
13901             ViewGroup parent = (ViewGroup) this;
13902             final int count = parent.getChildCount();
13903             for (int i = 0; i < count; i++) {
13904                 final View child = parent.getChildAt(i);
13905                 child.outputDirtyFlags(indent + "  ", clear, clearMask);
13906             }
13907         }
13908     }
13909
13910     /**
13911      * This method is used by ViewGroup to cause its children to restore or recreate their
13912      * display lists. It is called by getDisplayList() when the parent ViewGroup does not need
13913      * to recreate its own display list, which would happen if it went through the normal
13914      * draw/dispatchDraw mechanisms.
13915      *
13916      * @hide
13917      */
13918     protected void dispatchGetDisplayList() {}
13919
13920     /**
13921      * A view that is not attached or hardware accelerated cannot create a display list.
13922      * This method checks these conditions and returns the appropriate result.
13923      *
13924      * @return true if view has the ability to create a display list, false otherwise.
13925      *
13926      * @hide
13927      */
13928     public boolean canHaveDisplayList() {
13929         return !(mAttachInfo == null || mAttachInfo.mHardwareRenderer == null);
13930     }
13931
13932     private void updateDisplayListIfDirty() {
13933         final RenderNode renderNode = mRenderNode;
13934         if (!canHaveDisplayList()) {
13935             // can't populate RenderNode, don't try
13936             return;
13937         }
13938
13939         if ((mPrivateFlags & PFLAG_DRAWING_CACHE_VALID) == 0
13940                 || !renderNode.isValid()
13941                 || (mRecreateDisplayList)) {
13942             // Don't need to recreate the display list, just need to tell our
13943             // children to restore/recreate theirs
13944             if (renderNode.isValid()
13945                     && !mRecreateDisplayList) {
13946                 mPrivateFlags |= PFLAG_DRAWN | PFLAG_DRAWING_CACHE_VALID;
13947                 mPrivateFlags &= ~PFLAG_DIRTY_MASK;
13948                 dispatchGetDisplayList();
13949
13950                 return; // no work needed
13951             }
13952
13953             // If we got here, we're recreating it. Mark it as such to ensure that
13954             // we copy in child display lists into ours in drawChild()
13955             mRecreateDisplayList = true;
13956
13957             int width = mRight - mLeft;
13958             int height = mBottom - mTop;
13959             int layerType = getLayerType();
13960
13961             final HardwareCanvas canvas = renderNode.start(width, height);
13962             canvas.setHighContrastText(mAttachInfo.mHighContrastText);
13963
13964             try {
13965                 final HardwareLayer layer = getHardwareLayer();
13966                 if (layer != null && layer.isValid()) {
13967                     canvas.drawHardwareLayer(layer, 0, 0, mLayerPaint);
13968                 } else if (layerType == LAYER_TYPE_SOFTWARE) {
13969                     buildDrawingCache(true);
13970                     Bitmap cache = getDrawingCache(true);
13971                     if (cache != null) {
13972                         canvas.drawBitmap(cache, 0, 0, mLayerPaint);
13973                     }
13974                 } else {
13975                     computeScroll();
13976
13977                     canvas.translate(-mScrollX, -mScrollY);
13978                     mPrivateFlags |= PFLAG_DRAWN | PFLAG_DRAWING_CACHE_VALID;
13979                     mPrivateFlags &= ~PFLAG_DIRTY_MASK;
13980
13981                     // Fast path for layouts with no backgrounds
13982                     if ((mPrivateFlags & PFLAG_SKIP_DRAW) == PFLAG_SKIP_DRAW) {
13983                         dispatchDraw(canvas);
13984                         if (mOverlay != null && !mOverlay.isEmpty()) {
13985                             mOverlay.getOverlayView().draw(canvas);
13986                         }
13987                     } else {
13988                         draw(canvas);
13989                     }
13990                     drawAccessibilityFocus(canvas);
13991                 }
13992             } finally {
13993                 renderNode.end(canvas);
13994                 setDisplayListProperties(renderNode);
13995             }
13996         } else {
13997             mPrivateFlags |= PFLAG_DRAWN | PFLAG_DRAWING_CACHE_VALID;
13998             mPrivateFlags &= ~PFLAG_DIRTY_MASK;
13999         }
14000     }
14001
14002     /**
14003      * Returns a RenderNode with View draw content recorded, which can be
14004      * used to draw this view again without executing its draw method.
14005      *
14006      * @return A RenderNode ready to replay, or null if caching is not enabled.
14007      *
14008      * @hide
14009      */
14010     public RenderNode getDisplayList() {
14011         updateDisplayListIfDirty();
14012         return mRenderNode;
14013     }
14014
14015     private void resetDisplayList() {
14016         if (mRenderNode.isValid()) {
14017             mRenderNode.destroyDisplayListData();
14018         }
14019
14020         if (mBackgroundRenderNode != null && mBackgroundRenderNode.isValid()) {
14021             mBackgroundRenderNode.destroyDisplayListData();
14022         }
14023     }
14024
14025     /**
14026      * <p>Calling this method is equivalent to calling <code>getDrawingCache(false)</code>.</p>
14027      *
14028      * @return A non-scaled bitmap representing this view or null if cache is disabled.
14029      *
14030      * @see #getDrawingCache(boolean)
14031      */
14032     public Bitmap getDrawingCache() {
14033         return getDrawingCache(false);
14034     }
14035
14036     /**
14037      * <p>Returns the bitmap in which this view drawing is cached. The returned bitmap
14038      * is null when caching is disabled. If caching is enabled and the cache is not ready,
14039      * this method will create it. Calling {@link #draw(android.graphics.Canvas)} will not
14040      * draw from the cache when the cache is enabled. To benefit from the cache, you must
14041      * request the drawing cache by calling this method and draw it on screen if the
14042      * returned bitmap is not null.</p>
14043      *
14044      * <p>Note about auto scaling in compatibility mode: When auto scaling is not enabled,
14045      * this method will create a bitmap of the same size as this view. Because this bitmap
14046      * will be drawn scaled by the parent ViewGroup, the result on screen might show
14047      * scaling artifacts. To avoid such artifacts, you should call this method by setting
14048      * the auto scaling to true. Doing so, however, will generate a bitmap of a different
14049      * size than the view. This implies that your application must be able to handle this
14050      * size.</p>
14051      *
14052      * @param autoScale Indicates whether the generated bitmap should be scaled based on
14053      *        the current density of the screen when the application is in compatibility
14054      *        mode.
14055      *
14056      * @return A bitmap representing this view or null if cache is disabled.
14057      *
14058      * @see #setDrawingCacheEnabled(boolean)
14059      * @see #isDrawingCacheEnabled()
14060      * @see #buildDrawingCache(boolean)
14061      * @see #destroyDrawingCache()
14062      */
14063     public Bitmap getDrawingCache(boolean autoScale) {
14064         if ((mViewFlags & WILL_NOT_CACHE_DRAWING) == WILL_NOT_CACHE_DRAWING) {
14065             return null;
14066         }
14067         if ((mViewFlags & DRAWING_CACHE_ENABLED) == DRAWING_CACHE_ENABLED) {
14068             buildDrawingCache(autoScale);
14069         }
14070         return autoScale ? mDrawingCache : mUnscaledDrawingCache;
14071     }
14072
14073     /**
14074      * <p>Frees the resources used by the drawing cache. If you call
14075      * {@link #buildDrawingCache()} manually without calling
14076      * {@link #setDrawingCacheEnabled(boolean) setDrawingCacheEnabled(true)}, you
14077      * should cleanup the cache with this method afterwards.</p>
14078      *
14079      * @see #setDrawingCacheEnabled(boolean)
14080      * @see #buildDrawingCache()
14081      * @see #getDrawingCache()
14082      */
14083     public void destroyDrawingCache() {
14084         if (mDrawingCache != null) {
14085             mDrawingCache.recycle();
14086             mDrawingCache = null;
14087         }
14088         if (mUnscaledDrawingCache != null) {
14089             mUnscaledDrawingCache.recycle();
14090             mUnscaledDrawingCache = null;
14091         }
14092     }
14093
14094     /**
14095      * Setting a solid background color for the drawing cache's bitmaps will improve
14096      * performance and memory usage. Note, though that this should only be used if this
14097      * view will always be drawn on top of a solid color.
14098      *
14099      * @param color The background color to use for the drawing cache's bitmap
14100      *
14101      * @see #setDrawingCacheEnabled(boolean)
14102      * @see #buildDrawingCache()
14103      * @see #getDrawingCache()
14104      */
14105     public void setDrawingCacheBackgroundColor(int color) {
14106         if (color != mDrawingCacheBackgroundColor) {
14107             mDrawingCacheBackgroundColor = color;
14108             mPrivateFlags &= ~PFLAG_DRAWING_CACHE_VALID;
14109         }
14110     }
14111
14112     /**
14113      * @see #setDrawingCacheBackgroundColor(int)
14114      *
14115      * @return The background color to used for the drawing cache's bitmap
14116      */
14117     public int getDrawingCacheBackgroundColor() {
14118         return mDrawingCacheBackgroundColor;
14119     }
14120
14121     /**
14122      * <p>Calling this method is equivalent to calling <code>buildDrawingCache(false)</code>.</p>
14123      *
14124      * @see #buildDrawingCache(boolean)
14125      */
14126     public void buildDrawingCache() {
14127         buildDrawingCache(false);
14128     }
14129
14130     /**
14131      * <p>Forces the drawing cache to be built if the drawing cache is invalid.</p>
14132      *
14133      * <p>If you call {@link #buildDrawingCache()} manually without calling
14134      * {@link #setDrawingCacheEnabled(boolean) setDrawingCacheEnabled(true)}, you
14135      * should cleanup the cache by calling {@link #destroyDrawingCache()} afterwards.</p>
14136      *
14137      * <p>Note about auto scaling in compatibility mode: When auto scaling is not enabled,
14138      * this method will create a bitmap of the same size as this view. Because this bitmap
14139      * will be drawn scaled by the parent ViewGroup, the result on screen might show
14140      * scaling artifacts. To avoid such artifacts, you should call this method by setting
14141      * the auto scaling to true. Doing so, however, will generate a bitmap of a different
14142      * size than the view. This implies that your application must be able to handle this
14143      * size.</p>
14144      *
14145      * <p>You should avoid calling this method when hardware acceleration is enabled. If
14146      * you do not need the drawing cache bitmap, calling this method will increase memory
14147      * usage and cause the view to be rendered in software once, thus negatively impacting
14148      * performance.</p>
14149      *
14150      * @see #getDrawingCache()
14151      * @see #destroyDrawingCache()
14152      */
14153     public void buildDrawingCache(boolean autoScale) {
14154         if ((mPrivateFlags & PFLAG_DRAWING_CACHE_VALID) == 0 || (autoScale ?
14155                 mDrawingCache == null : mUnscaledDrawingCache == null)) {
14156             mCachingFailed = false;
14157
14158             int width = mRight - mLeft;
14159             int height = mBottom - mTop;
14160
14161             final AttachInfo attachInfo = mAttachInfo;
14162             final boolean scalingRequired = attachInfo != null && attachInfo.mScalingRequired;
14163
14164             if (autoScale && scalingRequired) {
14165                 width = (int) ((width * attachInfo.mApplicationScale) + 0.5f);
14166                 height = (int) ((height * attachInfo.mApplicationScale) + 0.5f);
14167             }
14168
14169             final int drawingCacheBackgroundColor = mDrawingCacheBackgroundColor;
14170             final boolean opaque = drawingCacheBackgroundColor != 0 || isOpaque();
14171             final boolean use32BitCache = attachInfo != null && attachInfo.mUse32BitDrawingCache;
14172
14173             final long projectedBitmapSize = width * height * (opaque && !use32BitCache ? 2 : 4);
14174             final long drawingCacheSize =
14175                     ViewConfiguration.get(mContext).getScaledMaximumDrawingCacheSize();
14176             if (width <= 0 || height <= 0 || projectedBitmapSize > drawingCacheSize) {
14177                 if (width > 0 && height > 0) {
14178                     Log.w(VIEW_LOG_TAG, "View too large to fit into drawing cache, needs "
14179                             + projectedBitmapSize + " bytes, only "
14180                             + drawingCacheSize + " available");
14181                 }
14182                 destroyDrawingCache();
14183                 mCachingFailed = true;
14184                 return;
14185             }
14186
14187             boolean clear = true;
14188             Bitmap bitmap = autoScale ? mDrawingCache : mUnscaledDrawingCache;
14189
14190             if (bitmap == null || bitmap.getWidth() != width || bitmap.getHeight() != height) {
14191                 Bitmap.Config quality;
14192                 if (!opaque) {
14193                     // Never pick ARGB_4444 because it looks awful
14194                     // Keep the DRAWING_CACHE_QUALITY_LOW flag just in case
14195                     switch (mViewFlags & DRAWING_CACHE_QUALITY_MASK) {
14196                         case DRAWING_CACHE_QUALITY_AUTO:
14197                         case DRAWING_CACHE_QUALITY_LOW:
14198                         case DRAWING_CACHE_QUALITY_HIGH:
14199                         default:
14200                             quality = Bitmap.Config.ARGB_8888;
14201                             break;
14202                     }
14203                 } else {
14204                     // Optimization for translucent windows
14205                     // If the window is translucent, use a 32 bits bitmap to benefit from memcpy()
14206                     quality = use32BitCache ? Bitmap.Config.ARGB_8888 : Bitmap.Config.RGB_565;
14207                 }
14208
14209                 // Try to cleanup memory
14210                 if (bitmap != null) bitmap.recycle();
14211
14212                 try {
14213                     bitmap = Bitmap.createBitmap(mResources.getDisplayMetrics(),
14214                             width, height, quality);
14215                     bitmap.setDensity(getResources().getDisplayMetrics().densityDpi);
14216                     if (autoScale) {
14217                         mDrawingCache = bitmap;
14218                     } else {
14219                         mUnscaledDrawingCache = bitmap;
14220                     }
14221                     if (opaque && use32BitCache) bitmap.setHasAlpha(false);
14222                 } catch (OutOfMemoryError e) {
14223                     // If there is not enough memory to create the bitmap cache, just
14224                     // ignore the issue as bitmap caches are not required to draw the
14225                     // view hierarchy
14226                     if (autoScale) {
14227                         mDrawingCache = null;
14228                     } else {
14229                         mUnscaledDrawingCache = null;
14230                     }
14231                     mCachingFailed = true;
14232                     return;
14233                 }
14234
14235                 clear = drawingCacheBackgroundColor != 0;
14236             }
14237
14238             Canvas canvas;
14239             if (attachInfo != null) {
14240                 canvas = attachInfo.mCanvas;
14241                 if (canvas == null) {
14242                     canvas = new Canvas();
14243                 }
14244                 canvas.setBitmap(bitmap);
14245                 // Temporarily clobber the cached Canvas in case one of our children
14246                 // is also using a drawing cache. Without this, the children would
14247                 // steal the canvas by attaching their own bitmap to it and bad, bad
14248                 // thing would happen (invisible views, corrupted drawings, etc.)
14249                 attachInfo.mCanvas = null;
14250             } else {
14251                 // This case should hopefully never or seldom happen
14252                 canvas = new Canvas(bitmap);
14253             }
14254
14255             if (clear) {
14256                 bitmap.eraseColor(drawingCacheBackgroundColor);
14257             }
14258
14259             computeScroll();
14260             final int restoreCount = canvas.save();
14261
14262             if (autoScale && scalingRequired) {
14263                 final float scale = attachInfo.mApplicationScale;
14264                 canvas.scale(scale, scale);
14265             }
14266
14267             canvas.translate(-mScrollX, -mScrollY);
14268
14269             mPrivateFlags |= PFLAG_DRAWN;
14270             if (mAttachInfo == null || !mAttachInfo.mHardwareAccelerated ||
14271                     mLayerType != LAYER_TYPE_NONE) {
14272                 mPrivateFlags |= PFLAG_DRAWING_CACHE_VALID;
14273             }
14274
14275             // Fast path for layouts with no backgrounds
14276             if ((mPrivateFlags & PFLAG_SKIP_DRAW) == PFLAG_SKIP_DRAW) {
14277                 mPrivateFlags &= ~PFLAG_DIRTY_MASK;
14278                 dispatchDraw(canvas);
14279                 if (mOverlay != null && !mOverlay.isEmpty()) {
14280                     mOverlay.getOverlayView().draw(canvas);
14281                 }
14282             } else {
14283                 draw(canvas);
14284             }
14285             drawAccessibilityFocus(canvas);
14286
14287             canvas.restoreToCount(restoreCount);
14288             canvas.setBitmap(null);
14289
14290             if (attachInfo != null) {
14291                 // Restore the cached Canvas for our siblings
14292                 attachInfo.mCanvas = canvas;
14293             }
14294         }
14295     }
14296
14297     /**
14298      * Create a snapshot of the view into a bitmap.  We should probably make
14299      * some form of this public, but should think about the API.
14300      */
14301     Bitmap createSnapshot(Bitmap.Config quality, int backgroundColor, boolean skipChildren) {
14302         int width = mRight - mLeft;
14303         int height = mBottom - mTop;
14304
14305         final AttachInfo attachInfo = mAttachInfo;
14306         final float scale = attachInfo != null ? attachInfo.mApplicationScale : 1.0f;
14307         width = (int) ((width * scale) + 0.5f);
14308         height = (int) ((height * scale) + 0.5f);
14309
14310         Bitmap bitmap = Bitmap.createBitmap(mResources.getDisplayMetrics(),
14311                 width > 0 ? width : 1, height > 0 ? height : 1, quality);
14312         if (bitmap == null) {
14313             throw new OutOfMemoryError();
14314         }
14315
14316         Resources resources = getResources();
14317         if (resources != null) {
14318             bitmap.setDensity(resources.getDisplayMetrics().densityDpi);
14319         }
14320
14321         Canvas canvas;
14322         if (attachInfo != null) {
14323             canvas = attachInfo.mCanvas;
14324             if (canvas == null) {
14325                 canvas = new Canvas();
14326             }
14327             canvas.setBitmap(bitmap);
14328             // Temporarily clobber the cached Canvas in case one of our children
14329             // is also using a drawing cache. Without this, the children would
14330             // steal the canvas by attaching their own bitmap to it and bad, bad
14331             // things would happen (invisible views, corrupted drawings, etc.)
14332             attachInfo.mCanvas = null;
14333         } else {
14334             // This case should hopefully never or seldom happen
14335             canvas = new Canvas(bitmap);
14336         }
14337
14338         if ((backgroundColor & 0xff000000) != 0) {
14339             bitmap.eraseColor(backgroundColor);
14340         }
14341
14342         computeScroll();
14343         final int restoreCount = canvas.save();
14344         canvas.scale(scale, scale);
14345         canvas.translate(-mScrollX, -mScrollY);
14346
14347         // Temporarily remove the dirty mask
14348         int flags = mPrivateFlags;
14349         mPrivateFlags &= ~PFLAG_DIRTY_MASK;
14350
14351         // Fast path for layouts with no backgrounds
14352         if ((mPrivateFlags & PFLAG_SKIP_DRAW) == PFLAG_SKIP_DRAW) {
14353             dispatchDraw(canvas);
14354             if (mOverlay != null && !mOverlay.isEmpty()) {
14355                 mOverlay.getOverlayView().draw(canvas);
14356             }
14357         } else {
14358             draw(canvas);
14359         }
14360         drawAccessibilityFocus(canvas);
14361
14362         mPrivateFlags = flags;
14363
14364         canvas.restoreToCount(restoreCount);
14365         canvas.setBitmap(null);
14366
14367         if (attachInfo != null) {
14368             // Restore the cached Canvas for our siblings
14369             attachInfo.mCanvas = canvas;
14370         }
14371
14372         return bitmap;
14373     }
14374
14375     /**
14376      * Indicates whether this View is currently in edit mode. A View is usually
14377      * in edit mode when displayed within a developer tool. For instance, if
14378      * this View is being drawn by a visual user interface builder, this method
14379      * should return true.
14380      *
14381      * Subclasses should check the return value of this method to provide
14382      * different behaviors if their normal behavior might interfere with the
14383      * host environment. For instance: the class spawns a thread in its
14384      * constructor, the drawing code relies on device-specific features, etc.
14385      *
14386      * This method is usually checked in the drawing code of custom widgets.
14387      *
14388      * @return True if this View is in edit mode, false otherwise.
14389      */
14390     public boolean isInEditMode() {
14391         return false;
14392     }
14393
14394     /**
14395      * If the View draws content inside its padding and enables fading edges,
14396      * it needs to support padding offsets. Padding offsets are added to the
14397      * fading edges to extend the length of the fade so that it covers pixels
14398      * drawn inside the padding.
14399      *
14400      * Subclasses of this class should override this method if they need
14401      * to draw content inside the padding.
14402      *
14403      * @return True if padding offset must be applied, false otherwise.
14404      *
14405      * @see #getLeftPaddingOffset()
14406      * @see #getRightPaddingOffset()
14407      * @see #getTopPaddingOffset()
14408      * @see #getBottomPaddingOffset()
14409      *
14410      * @since CURRENT
14411      */
14412     protected boolean isPaddingOffsetRequired() {
14413         return false;
14414     }
14415
14416     /**
14417      * Amount by which to extend the left fading region. Called only when
14418      * {@link #isPaddingOffsetRequired()} returns true.
14419      *
14420      * @return The left padding offset in pixels.
14421      *
14422      * @see #isPaddingOffsetRequired()
14423      *
14424      * @since CURRENT
14425      */
14426     protected int getLeftPaddingOffset() {
14427         return 0;
14428     }
14429
14430     /**
14431      * Amount by which to extend the right fading region. Called only when
14432      * {@link #isPaddingOffsetRequired()} returns true.
14433      *
14434      * @return The right padding offset in pixels.
14435      *
14436      * @see #isPaddingOffsetRequired()
14437      *
14438      * @since CURRENT
14439      */
14440     protected int getRightPaddingOffset() {
14441         return 0;
14442     }
14443
14444     /**
14445      * Amount by which to extend the top fading region. Called only when
14446      * {@link #isPaddingOffsetRequired()} returns true.
14447      *
14448      * @return The top padding offset in pixels.
14449      *
14450      * @see #isPaddingOffsetRequired()
14451      *
14452      * @since CURRENT
14453      */
14454     protected int getTopPaddingOffset() {
14455         return 0;
14456     }
14457
14458     /**
14459      * Amount by which to extend the bottom fading region. Called only when
14460      * {@link #isPaddingOffsetRequired()} returns true.
14461      *
14462      * @return The bottom padding offset in pixels.
14463      *
14464      * @see #isPaddingOffsetRequired()
14465      *
14466      * @since CURRENT
14467      */
14468     protected int getBottomPaddingOffset() {
14469         return 0;
14470     }
14471
14472     /**
14473      * @hide
14474      * @param offsetRequired
14475      */
14476     protected int getFadeTop(boolean offsetRequired) {
14477         int top = mPaddingTop;
14478         if (offsetRequired) top += getTopPaddingOffset();
14479         return top;
14480     }
14481
14482     /**
14483      * @hide
14484      * @param offsetRequired
14485      */
14486     protected int getFadeHeight(boolean offsetRequired) {
14487         int padding = mPaddingTop;
14488         if (offsetRequired) padding += getTopPaddingOffset();
14489         return mBottom - mTop - mPaddingBottom - padding;
14490     }
14491
14492     /**
14493      * <p>Indicates whether this view is attached to a hardware accelerated
14494      * window or not.</p>
14495      *
14496      * <p>Even if this method returns true, it does not mean that every call
14497      * to {@link #draw(android.graphics.Canvas)} will be made with an hardware
14498      * accelerated {@link android.graphics.Canvas}. For instance, if this view
14499      * is drawn onto an offscreen {@link android.graphics.Bitmap} and its
14500      * window is hardware accelerated,
14501      * {@link android.graphics.Canvas#isHardwareAccelerated()} will likely
14502      * return false, and this method will return true.</p>
14503      *
14504      * @return True if the view is attached to a window and the window is
14505      *         hardware accelerated; false in any other case.
14506      */
14507     @ViewDebug.ExportedProperty(category = "drawing")
14508     public boolean isHardwareAccelerated() {
14509         return mAttachInfo != null && mAttachInfo.mHardwareAccelerated;
14510     }
14511
14512     /**
14513      * Sets a rectangular area on this view to which the view will be clipped
14514      * when it is drawn. Setting the value to null will remove the clip bounds
14515      * and the view will draw normally, using its full bounds.
14516      *
14517      * @param clipBounds The rectangular area, in the local coordinates of
14518      * this view, to which future drawing operations will be clipped.
14519      */
14520     public void setClipBounds(Rect clipBounds) {
14521         if (clipBounds != null) {
14522             if (clipBounds.equals(mClipBounds)) {
14523                 return;
14524             }
14525             if (mClipBounds == null) {
14526                 invalidate();
14527                 mClipBounds = new Rect(clipBounds);
14528             } else {
14529                 invalidate(Math.min(mClipBounds.left, clipBounds.left),
14530                         Math.min(mClipBounds.top, clipBounds.top),
14531                         Math.max(mClipBounds.right, clipBounds.right),
14532                         Math.max(mClipBounds.bottom, clipBounds.bottom));
14533                 mClipBounds.set(clipBounds);
14534             }
14535         } else {
14536             if (mClipBounds != null) {
14537                 invalidate();
14538                 mClipBounds = null;
14539             }
14540         }
14541         mRenderNode.setClipBounds(mClipBounds);
14542     }
14543
14544     /**
14545      * Returns a copy of the current {@link #setClipBounds(Rect) clipBounds}.
14546      *
14547      * @return A copy of the current clip bounds if clip bounds are set,
14548      * otherwise null.
14549      */
14550     public Rect getClipBounds() {
14551         return (mClipBounds != null) ? new Rect(mClipBounds) : null;
14552     }
14553
14554     /**
14555      * Utility function, called by draw(canvas, parent, drawingTime) to handle the less common
14556      * case of an active Animation being run on the view.
14557      */
14558     private boolean drawAnimation(ViewGroup parent, long drawingTime,
14559             Animation a, boolean scalingRequired) {
14560         Transformation invalidationTransform;
14561         final int flags = parent.mGroupFlags;
14562         final boolean initialized = a.isInitialized();
14563         if (!initialized) {
14564             a.initialize(mRight - mLeft, mBottom - mTop, parent.getWidth(), parent.getHeight());
14565             a.initializeInvalidateRegion(0, 0, mRight - mLeft, mBottom - mTop);
14566             if (mAttachInfo != null) a.setListenerHandler(mAttachInfo.mHandler);
14567             onAnimationStart();
14568         }
14569
14570         final Transformation t = parent.getChildTransformation();
14571         boolean more = a.getTransformation(drawingTime, t, 1f);
14572         if (scalingRequired && mAttachInfo.mApplicationScale != 1f) {
14573             if (parent.mInvalidationTransformation == null) {
14574                 parent.mInvalidationTransformation = new Transformation();
14575             }
14576             invalidationTransform = parent.mInvalidationTransformation;
14577             a.getTransformation(drawingTime, invalidationTransform, 1f);
14578         } else {
14579             invalidationTransform = t;
14580         }
14581
14582         if (more) {
14583             if (!a.willChangeBounds()) {
14584                 if ((flags & (ViewGroup.FLAG_OPTIMIZE_INVALIDATE | ViewGroup.FLAG_ANIMATION_DONE)) ==
14585                         ViewGroup.FLAG_OPTIMIZE_INVALIDATE) {
14586                     parent.mGroupFlags |= ViewGroup.FLAG_INVALIDATE_REQUIRED;
14587                 } else if ((flags & ViewGroup.FLAG_INVALIDATE_REQUIRED) == 0) {
14588                     // The child need to draw an animation, potentially offscreen, so
14589                     // make sure we do not cancel invalidate requests
14590                     parent.mPrivateFlags |= PFLAG_DRAW_ANIMATION;
14591                     parent.invalidate(mLeft, mTop, mRight, mBottom);
14592                 }
14593             } else {
14594                 if (parent.mInvalidateRegion == null) {
14595                     parent.mInvalidateRegion = new RectF();
14596                 }
14597                 final RectF region = parent.mInvalidateRegion;
14598                 a.getInvalidateRegion(0, 0, mRight - mLeft, mBottom - mTop, region,
14599                         invalidationTransform);
14600
14601                 // The child need to draw an animation, potentially offscreen, so
14602                 // make sure we do not cancel invalidate requests
14603                 parent.mPrivateFlags |= PFLAG_DRAW_ANIMATION;
14604
14605                 final int left = mLeft + (int) region.left;
14606                 final int top = mTop + (int) region.top;
14607                 parent.invalidate(left, top, left + (int) (region.width() + .5f),
14608                         top + (int) (region.height() + .5f));
14609             }
14610         }
14611         return more;
14612     }
14613
14614     /**
14615      * This method is called by getDisplayList() when a display list is recorded for a View.
14616      * It pushes any properties to the RenderNode that aren't managed by the RenderNode.
14617      */
14618     void setDisplayListProperties(RenderNode renderNode) {
14619         if (renderNode != null) {
14620             renderNode.setHasOverlappingRendering(hasOverlappingRendering());
14621             if (mParent instanceof ViewGroup) {
14622                 renderNode.setClipToBounds(
14623                         (((ViewGroup) mParent).mGroupFlags & ViewGroup.FLAG_CLIP_CHILDREN) != 0);
14624             }
14625             float alpha = 1;
14626             if (mParent instanceof ViewGroup && (((ViewGroup) mParent).mGroupFlags &
14627                     ViewGroup.FLAG_SUPPORT_STATIC_TRANSFORMATIONS) != 0) {
14628                 ViewGroup parentVG = (ViewGroup) mParent;
14629                 final Transformation t = parentVG.getChildTransformation();
14630                 if (parentVG.getChildStaticTransformation(this, t)) {
14631                     final int transformType = t.getTransformationType();
14632                     if (transformType != Transformation.TYPE_IDENTITY) {
14633                         if ((transformType & Transformation.TYPE_ALPHA) != 0) {
14634                             alpha = t.getAlpha();
14635                         }
14636                         if ((transformType & Transformation.TYPE_MATRIX) != 0) {
14637                             renderNode.setStaticMatrix(t.getMatrix());
14638                         }
14639                     }
14640                 }
14641             }
14642             if (mTransformationInfo != null) {
14643                 alpha *= getFinalAlpha();
14644                 if (alpha < 1) {
14645                     final int multipliedAlpha = (int) (255 * alpha);
14646                     if (onSetAlpha(multipliedAlpha)) {
14647                         alpha = 1;
14648                     }
14649                 }
14650                 renderNode.setAlpha(alpha);
14651             } else if (alpha < 1) {
14652                 renderNode.setAlpha(alpha);
14653             }
14654         }
14655     }
14656
14657     /**
14658      * This method is called by ViewGroup.drawChild() to have each child view draw itself.
14659      * This draw() method is an implementation detail and is not intended to be overridden or
14660      * to be called from anywhere else other than ViewGroup.drawChild().
14661      */
14662     boolean draw(Canvas canvas, ViewGroup parent, long drawingTime) {
14663         boolean usingRenderNodeProperties = mAttachInfo != null && mAttachInfo.mHardwareAccelerated;
14664         boolean more = false;
14665         final boolean childHasIdentityMatrix = hasIdentityMatrix();
14666         final int flags = parent.mGroupFlags;
14667
14668         if ((flags & ViewGroup.FLAG_CLEAR_TRANSFORMATION) == ViewGroup.FLAG_CLEAR_TRANSFORMATION) {
14669             parent.getChildTransformation().clear();
14670             parent.mGroupFlags &= ~ViewGroup.FLAG_CLEAR_TRANSFORMATION;
14671         }
14672
14673         Transformation transformToApply = null;
14674         boolean concatMatrix = false;
14675
14676         boolean scalingRequired = false;
14677         boolean caching;
14678         int layerType = getLayerType();
14679
14680         final boolean hardwareAccelerated = canvas.isHardwareAccelerated();
14681         if ((flags & ViewGroup.FLAG_CHILDREN_DRAWN_WITH_CACHE) != 0 ||
14682                 (flags & ViewGroup.FLAG_ALWAYS_DRAWN_WITH_CACHE) != 0) {
14683             caching = true;
14684             // Auto-scaled apps are not hw-accelerated, no need to set scaling flag on DisplayList
14685             if (mAttachInfo != null) scalingRequired = mAttachInfo.mScalingRequired;
14686         } else {
14687             caching = (layerType != LAYER_TYPE_NONE) || hardwareAccelerated;
14688         }
14689
14690         final Animation a = getAnimation();
14691         if (a != null) {
14692             more = drawAnimation(parent, drawingTime, a, scalingRequired);
14693             concatMatrix = a.willChangeTransformationMatrix();
14694             if (concatMatrix) {
14695                 mPrivateFlags3 |= PFLAG3_VIEW_IS_ANIMATING_TRANSFORM;
14696             }
14697             transformToApply = parent.getChildTransformation();
14698         } else {
14699             if ((mPrivateFlags3 & PFLAG3_VIEW_IS_ANIMATING_TRANSFORM) != 0) {
14700                 // No longer animating: clear out old animation matrix
14701                 mRenderNode.setAnimationMatrix(null);
14702                 mPrivateFlags3 &= ~PFLAG3_VIEW_IS_ANIMATING_TRANSFORM;
14703             }
14704             if (!usingRenderNodeProperties &&
14705                     (flags & ViewGroup.FLAG_SUPPORT_STATIC_TRANSFORMATIONS) != 0) {
14706                 final Transformation t = parent.getChildTransformation();
14707                 final boolean hasTransform = parent.getChildStaticTransformation(this, t);
14708                 if (hasTransform) {
14709                     final int transformType = t.getTransformationType();
14710                     transformToApply = transformType != Transformation.TYPE_IDENTITY ? t : null;
14711                     concatMatrix = (transformType & Transformation.TYPE_MATRIX) != 0;
14712                 }
14713             }
14714         }
14715
14716         concatMatrix |= !childHasIdentityMatrix;
14717
14718         // Sets the flag as early as possible to allow draw() implementations
14719         // to call invalidate() successfully when doing animations
14720         mPrivateFlags |= PFLAG_DRAWN;
14721
14722         if (!concatMatrix &&
14723                 (flags & (ViewGroup.FLAG_SUPPORT_STATIC_TRANSFORMATIONS |
14724                         ViewGroup.FLAG_CLIP_CHILDREN)) == ViewGroup.FLAG_CLIP_CHILDREN &&
14725                 canvas.quickReject(mLeft, mTop, mRight, mBottom, Canvas.EdgeType.BW) &&
14726                 (mPrivateFlags & PFLAG_DRAW_ANIMATION) == 0) {
14727             mPrivateFlags2 |= PFLAG2_VIEW_QUICK_REJECTED;
14728             return more;
14729         }
14730         mPrivateFlags2 &= ~PFLAG2_VIEW_QUICK_REJECTED;
14731
14732         if (hardwareAccelerated) {
14733             // Clear INVALIDATED flag to allow invalidation to occur during rendering, but
14734             // retain the flag's value temporarily in the mRecreateDisplayList flag
14735             mRecreateDisplayList = (mPrivateFlags & PFLAG_INVALIDATED) == PFLAG_INVALIDATED;
14736             mPrivateFlags &= ~PFLAG_INVALIDATED;
14737         }
14738
14739         RenderNode renderNode = null;
14740         Bitmap cache = null;
14741         boolean hasDisplayList = false;
14742         if (caching) {
14743             if (!hardwareAccelerated) {
14744                 if (layerType != LAYER_TYPE_NONE) {
14745                     layerType = LAYER_TYPE_SOFTWARE;
14746                     buildDrawingCache(true);
14747                 }
14748                 cache = getDrawingCache(true);
14749             } else {
14750                 switch (layerType) {
14751                     case LAYER_TYPE_SOFTWARE:
14752                         if (usingRenderNodeProperties) {
14753                             hasDisplayList = canHaveDisplayList();
14754                         } else {
14755                             buildDrawingCache(true);
14756                             cache = getDrawingCache(true);
14757                         }
14758                         break;
14759                     case LAYER_TYPE_HARDWARE:
14760                         if (usingRenderNodeProperties) {
14761                             hasDisplayList = canHaveDisplayList();
14762                         }
14763                         break;
14764                     case LAYER_TYPE_NONE:
14765                         // Delay getting the display list until animation-driven alpha values are
14766                         // set up and possibly passed on to the view
14767                         hasDisplayList = canHaveDisplayList();
14768                         break;
14769                 }
14770             }
14771         }
14772         usingRenderNodeProperties &= hasDisplayList;
14773         if (usingRenderNodeProperties) {
14774             renderNode = getDisplayList();
14775             if (!renderNode.isValid()) {
14776                 // Uncommon, but possible. If a view is removed from the hierarchy during the call
14777                 // to getDisplayList(), the display list will be marked invalid and we should not
14778                 // try to use it again.
14779                 renderNode = null;
14780                 hasDisplayList = false;
14781                 usingRenderNodeProperties = false;
14782             }
14783         }
14784
14785         int sx = 0;
14786         int sy = 0;
14787         if (!hasDisplayList) {
14788             computeScroll();
14789             sx = mScrollX;
14790             sy = mScrollY;
14791         }
14792
14793         final boolean hasNoCache = cache == null || hasDisplayList;
14794         final boolean offsetForScroll = cache == null && !hasDisplayList &&
14795                 layerType != LAYER_TYPE_HARDWARE;
14796
14797         int restoreTo = -1;
14798         if (!usingRenderNodeProperties || transformToApply != null) {
14799             restoreTo = canvas.save();
14800         }
14801         if (offsetForScroll) {
14802             canvas.translate(mLeft - sx, mTop - sy);
14803         } else {
14804             if (!usingRenderNodeProperties) {
14805                 canvas.translate(mLeft, mTop);
14806             }
14807             if (scalingRequired) {
14808                 if (usingRenderNodeProperties) {
14809                     // TODO: Might not need this if we put everything inside the DL
14810                     restoreTo = canvas.save();
14811                 }
14812                 // mAttachInfo cannot be null, otherwise scalingRequired == false
14813                 final float scale = 1.0f / mAttachInfo.mApplicationScale;
14814                 canvas.scale(scale, scale);
14815             }
14816         }
14817
14818         float alpha = usingRenderNodeProperties ? 1 : (getAlpha() * getTransitionAlpha());
14819         if (transformToApply != null || alpha < 1 ||  !hasIdentityMatrix() ||
14820                 (mPrivateFlags3 & PFLAG3_VIEW_IS_ANIMATING_ALPHA) == PFLAG3_VIEW_IS_ANIMATING_ALPHA) {
14821             if (transformToApply != null || !childHasIdentityMatrix) {
14822                 int transX = 0;
14823                 int transY = 0;
14824
14825                 if (offsetForScroll) {
14826                     transX = -sx;
14827                     transY = -sy;
14828                 }
14829
14830                 if (transformToApply != null) {
14831                     if (concatMatrix) {
14832                         if (usingRenderNodeProperties) {
14833                             renderNode.setAnimationMatrix(transformToApply.getMatrix());
14834                         } else {
14835                             // Undo the scroll translation, apply the transformation matrix,
14836                             // then redo the scroll translate to get the correct result.
14837                             canvas.translate(-transX, -transY);
14838                             canvas.concat(transformToApply.getMatrix());
14839                             canvas.translate(transX, transY);
14840                         }
14841                         parent.mGroupFlags |= ViewGroup.FLAG_CLEAR_TRANSFORMATION;
14842                     }
14843
14844                     float transformAlpha = transformToApply.getAlpha();
14845                     if (transformAlpha < 1) {
14846                         alpha *= transformAlpha;
14847                         parent.mGroupFlags |= ViewGroup.FLAG_CLEAR_TRANSFORMATION;
14848                     }
14849                 }
14850
14851                 if (!childHasIdentityMatrix && !usingRenderNodeProperties) {
14852                     canvas.translate(-transX, -transY);
14853                     canvas.concat(getMatrix());
14854                     canvas.translate(transX, transY);
14855                 }
14856             }
14857
14858             // Deal with alpha if it is or used to be <1
14859             if (alpha < 1 ||
14860                     (mPrivateFlags3 & PFLAG3_VIEW_IS_ANIMATING_ALPHA) == PFLAG3_VIEW_IS_ANIMATING_ALPHA) {
14861                 if (alpha < 1) {
14862                     mPrivateFlags3 |= PFLAG3_VIEW_IS_ANIMATING_ALPHA;
14863                 } else {
14864                     mPrivateFlags3 &= ~PFLAG3_VIEW_IS_ANIMATING_ALPHA;
14865                 }
14866                 parent.mGroupFlags |= ViewGroup.FLAG_CLEAR_TRANSFORMATION;
14867                 if (hasNoCache) {
14868                     final int multipliedAlpha = (int) (255 * alpha);
14869                     if (!onSetAlpha(multipliedAlpha)) {
14870                         int layerFlags = Canvas.HAS_ALPHA_LAYER_SAVE_FLAG;
14871                         if ((flags & ViewGroup.FLAG_CLIP_CHILDREN) != 0 ||
14872                                 layerType != LAYER_TYPE_NONE) {
14873                             layerFlags |= Canvas.CLIP_TO_LAYER_SAVE_FLAG;
14874                         }
14875                         if (usingRenderNodeProperties) {
14876                             renderNode.setAlpha(alpha * getAlpha() * getTransitionAlpha());
14877                         } else  if (layerType == LAYER_TYPE_NONE) {
14878                             final int scrollX = hasDisplayList ? 0 : sx;
14879                             final int scrollY = hasDisplayList ? 0 : sy;
14880                             canvas.saveLayerAlpha(scrollX, scrollY,
14881                                     scrollX + (mRight - mLeft), scrollY + (mBottom - mTop),
14882                                     multipliedAlpha, layerFlags);
14883                         }
14884                     } else {
14885                         // Alpha is handled by the child directly, clobber the layer's alpha
14886                         mPrivateFlags |= PFLAG_ALPHA_SET;
14887                     }
14888                 }
14889             }
14890         } else if ((mPrivateFlags & PFLAG_ALPHA_SET) == PFLAG_ALPHA_SET) {
14891             onSetAlpha(255);
14892             mPrivateFlags &= ~PFLAG_ALPHA_SET;
14893         }
14894
14895         if (!usingRenderNodeProperties) {
14896             // apply clips directly, since RenderNode won't do it for this draw
14897             if ((flags & ViewGroup.FLAG_CLIP_CHILDREN) == ViewGroup.FLAG_CLIP_CHILDREN
14898                     && cache == null) {
14899                 if (offsetForScroll) {
14900                     canvas.clipRect(sx, sy, sx + (mRight - mLeft), sy + (mBottom - mTop));
14901                 } else {
14902                     if (!scalingRequired || cache == null) {
14903                         canvas.clipRect(0, 0, mRight - mLeft, mBottom - mTop);
14904                     } else {
14905                         canvas.clipRect(0, 0, cache.getWidth(), cache.getHeight());
14906                     }
14907                 }
14908             }
14909
14910             if (mClipBounds != null) {
14911                 // clip bounds ignore scroll
14912                 canvas.clipRect(mClipBounds);
14913             }
14914         }
14915
14916
14917
14918         if (!usingRenderNodeProperties && hasDisplayList) {
14919             renderNode = getDisplayList();
14920             if (!renderNode.isValid()) {
14921                 // Uncommon, but possible. If a view is removed from the hierarchy during the call
14922                 // to getDisplayList(), the display list will be marked invalid and we should not
14923                 // try to use it again.
14924                 renderNode = null;
14925                 hasDisplayList = false;
14926             }
14927         }
14928
14929         if (hasNoCache) {
14930             boolean layerRendered = false;
14931             if (layerType == LAYER_TYPE_HARDWARE && !usingRenderNodeProperties) {
14932                 final HardwareLayer layer = getHardwareLayer();
14933                 if (layer != null && layer.isValid()) {
14934                     int restoreAlpha = mLayerPaint.getAlpha();
14935                     mLayerPaint.setAlpha((int) (alpha * 255));
14936                     ((HardwareCanvas) canvas).drawHardwareLayer(layer, 0, 0, mLayerPaint);
14937                     mLayerPaint.setAlpha(restoreAlpha);
14938                     layerRendered = true;
14939                 } else {
14940                     final int scrollX = hasDisplayList ? 0 : sx;
14941                     final int scrollY = hasDisplayList ? 0 : sy;
14942                     canvas.saveLayer(scrollX, scrollY,
14943                             scrollX + mRight - mLeft, scrollY + mBottom - mTop, mLayerPaint,
14944                             Canvas.HAS_ALPHA_LAYER_SAVE_FLAG | Canvas.CLIP_TO_LAYER_SAVE_FLAG);
14945                 }
14946             }
14947
14948             if (!layerRendered) {
14949                 if (!hasDisplayList) {
14950                     // Fast path for layouts with no backgrounds
14951                     if ((mPrivateFlags & PFLAG_SKIP_DRAW) == PFLAG_SKIP_DRAW) {
14952                         mPrivateFlags &= ~PFLAG_DIRTY_MASK;
14953                         dispatchDraw(canvas);
14954                         if (mOverlay != null && !mOverlay.isEmpty()) {
14955                             mOverlay.getOverlayView().draw(canvas);
14956                         }
14957                     } else {
14958                         draw(canvas);
14959                     }
14960                     drawAccessibilityFocus(canvas);
14961                 } else {
14962                     mPrivateFlags &= ~PFLAG_DIRTY_MASK;
14963                     ((HardwareCanvas) canvas).drawRenderNode(renderNode, null, flags);
14964                 }
14965             }
14966         } else if (cache != null) {
14967             mPrivateFlags &= ~PFLAG_DIRTY_MASK;
14968             Paint cachePaint;
14969             int restoreAlpha = 0;
14970
14971             if (layerType == LAYER_TYPE_NONE) {
14972                 cachePaint = parent.mCachePaint;
14973                 if (cachePaint == null) {
14974                     cachePaint = new Paint();
14975                     cachePaint.setDither(false);
14976                     parent.mCachePaint = cachePaint;
14977                 }
14978             } else {
14979                 cachePaint = mLayerPaint;
14980                 restoreAlpha = mLayerPaint.getAlpha();
14981             }
14982             cachePaint.setAlpha((int) (alpha * 255));
14983             canvas.drawBitmap(cache, 0.0f, 0.0f, cachePaint);
14984             cachePaint.setAlpha(restoreAlpha);
14985         }
14986
14987         if (restoreTo >= 0) {
14988             canvas.restoreToCount(restoreTo);
14989         }
14990
14991         if (a != null && !more) {
14992             if (!hardwareAccelerated && !a.getFillAfter()) {
14993                 onSetAlpha(255);
14994             }
14995             parent.finishAnimatingView(this, a);
14996         }
14997
14998         if (more && hardwareAccelerated) {
14999             if (a.hasAlpha() && (mPrivateFlags & PFLAG_ALPHA_SET) == PFLAG_ALPHA_SET) {
15000                 // alpha animations should cause the child to recreate its display list
15001                 invalidate(true);
15002             }
15003         }
15004
15005         mRecreateDisplayList = false;
15006
15007         return more;
15008     }
15009
15010     /**
15011      * Manually render this view (and all of its children) to the given Canvas.
15012      * The view must have already done a full layout before this function is
15013      * called.  When implementing a view, implement
15014      * {@link #onDraw(android.graphics.Canvas)} instead of overriding this method.
15015      * If you do need to override this method, call the superclass version.
15016      *
15017      * @param canvas The Canvas to which the View is rendered.
15018      */
15019     public void draw(Canvas canvas) {
15020         final int privateFlags = mPrivateFlags;
15021         final boolean dirtyOpaque = (privateFlags & PFLAG_DIRTY_MASK) == PFLAG_DIRTY_OPAQUE &&
15022                 (mAttachInfo == null || !mAttachInfo.mIgnoreDirtyState);
15023         mPrivateFlags = (privateFlags & ~PFLAG_DIRTY_MASK) | PFLAG_DRAWN;
15024
15025         /*
15026          * Draw traversal performs several drawing steps which must be executed
15027          * in the appropriate order:
15028          *
15029          *      1. Draw the background
15030          *      2. If necessary, save the canvas' layers to prepare for fading
15031          *      3. Draw view's content
15032          *      4. Draw children
15033          *      5. If necessary, draw the fading edges and restore layers
15034          *      6. Draw decorations (scrollbars for instance)
15035          */
15036
15037         // Step 1, draw the background, if needed
15038         int saveCount;
15039
15040         if (!dirtyOpaque) {
15041             drawBackground(canvas);
15042         }
15043
15044         // skip step 2 & 5 if possible (common case)
15045         final int viewFlags = mViewFlags;
15046         boolean horizontalEdges = (viewFlags & FADING_EDGE_HORIZONTAL) != 0;
15047         boolean verticalEdges = (viewFlags & FADING_EDGE_VERTICAL) != 0;
15048         if (!verticalEdges && !horizontalEdges) {
15049             // Step 3, draw the content
15050             if (!dirtyOpaque) onDraw(canvas);
15051
15052             // Step 4, draw the children
15053             dispatchDraw(canvas);
15054
15055             // Step 6, draw decorations (scrollbars)
15056             onDrawScrollBars(canvas);
15057
15058             if (mOverlay != null && !mOverlay.isEmpty()) {
15059                 mOverlay.getOverlayView().dispatchDraw(canvas);
15060             }
15061
15062             // we're done...
15063             return;
15064         }
15065
15066         /*
15067          * Here we do the full fledged routine...
15068          * (this is an uncommon case where speed matters less,
15069          * this is why we repeat some of the tests that have been
15070          * done above)
15071          */
15072
15073         boolean drawTop = false;
15074         boolean drawBottom = false;
15075         boolean drawLeft = false;
15076         boolean drawRight = false;
15077
15078         float topFadeStrength = 0.0f;
15079         float bottomFadeStrength = 0.0f;
15080         float leftFadeStrength = 0.0f;
15081         float rightFadeStrength = 0.0f;
15082
15083         // Step 2, save the canvas' layers
15084         int paddingLeft = mPaddingLeft;
15085
15086         final boolean offsetRequired = isPaddingOffsetRequired();
15087         if (offsetRequired) {
15088             paddingLeft += getLeftPaddingOffset();
15089         }
15090
15091         int left = mScrollX + paddingLeft;
15092         int right = left + mRight - mLeft - mPaddingRight - paddingLeft;
15093         int top = mScrollY + getFadeTop(offsetRequired);
15094         int bottom = top + getFadeHeight(offsetRequired);
15095
15096         if (offsetRequired) {
15097             right += getRightPaddingOffset();
15098             bottom += getBottomPaddingOffset();
15099         }
15100
15101         final ScrollabilityCache scrollabilityCache = mScrollCache;
15102         final float fadeHeight = scrollabilityCache.fadingEdgeLength;
15103         int length = (int) fadeHeight;
15104
15105         // clip the fade length if top and bottom fades overlap
15106         // overlapping fades produce odd-looking artifacts
15107         if (verticalEdges && (top + length > bottom - length)) {
15108             length = (bottom - top) / 2;
15109         }
15110
15111         // also clip horizontal fades if necessary
15112         if (horizontalEdges && (left + length > right - length)) {
15113             length = (right - left) / 2;
15114         }
15115
15116         if (verticalEdges) {
15117             topFadeStrength = Math.max(0.0f, Math.min(1.0f, getTopFadingEdgeStrength()));
15118             drawTop = topFadeStrength * fadeHeight > 1.0f;
15119             bottomFadeStrength = Math.max(0.0f, Math.min(1.0f, getBottomFadingEdgeStrength()));
15120             drawBottom = bottomFadeStrength * fadeHeight > 1.0f;
15121         }
15122
15123         if (horizontalEdges) {
15124             leftFadeStrength = Math.max(0.0f, Math.min(1.0f, getLeftFadingEdgeStrength()));
15125             drawLeft = leftFadeStrength * fadeHeight > 1.0f;
15126             rightFadeStrength = Math.max(0.0f, Math.min(1.0f, getRightFadingEdgeStrength()));
15127             drawRight = rightFadeStrength * fadeHeight > 1.0f;
15128         }
15129
15130         saveCount = canvas.getSaveCount();
15131
15132         int solidColor = getSolidColor();
15133         if (solidColor == 0) {
15134             final int flags = Canvas.HAS_ALPHA_LAYER_SAVE_FLAG;
15135
15136             if (drawTop) {
15137                 canvas.saveLayer(left, top, right, top + length, null, flags);
15138             }
15139
15140             if (drawBottom) {
15141                 canvas.saveLayer(left, bottom - length, right, bottom, null, flags);
15142             }
15143
15144             if (drawLeft) {
15145                 canvas.saveLayer(left, top, left + length, bottom, null, flags);
15146             }
15147
15148             if (drawRight) {
15149                 canvas.saveLayer(right - length, top, right, bottom, null, flags);
15150             }
15151         } else {
15152             scrollabilityCache.setFadeColor(solidColor);
15153         }
15154
15155         // Step 3, draw the content
15156         if (!dirtyOpaque) onDraw(canvas);
15157
15158         // Step 4, draw the children
15159         dispatchDraw(canvas);
15160
15161         // Step 5, draw the fade effect and restore layers
15162         final Paint p = scrollabilityCache.paint;
15163         final Matrix matrix = scrollabilityCache.matrix;
15164         final Shader fade = scrollabilityCache.shader;
15165
15166         if (drawTop) {
15167             matrix.setScale(1, fadeHeight * topFadeStrength);
15168             matrix.postTranslate(left, top);
15169             fade.setLocalMatrix(matrix);
15170             p.setShader(fade);
15171             canvas.drawRect(left, top, right, top + length, p);
15172         }
15173
15174         if (drawBottom) {
15175             matrix.setScale(1, fadeHeight * bottomFadeStrength);
15176             matrix.postRotate(180);
15177             matrix.postTranslate(left, bottom);
15178             fade.setLocalMatrix(matrix);
15179             p.setShader(fade);
15180             canvas.drawRect(left, bottom - length, right, bottom, p);
15181         }
15182
15183         if (drawLeft) {
15184             matrix.setScale(1, fadeHeight * leftFadeStrength);
15185             matrix.postRotate(-90);
15186             matrix.postTranslate(left, top);
15187             fade.setLocalMatrix(matrix);
15188             p.setShader(fade);
15189             canvas.drawRect(left, top, left + length, bottom, p);
15190         }
15191
15192         if (drawRight) {
15193             matrix.setScale(1, fadeHeight * rightFadeStrength);
15194             matrix.postRotate(90);
15195             matrix.postTranslate(right, top);
15196             fade.setLocalMatrix(matrix);
15197             p.setShader(fade);
15198             canvas.drawRect(right - length, top, right, bottom, p);
15199         }
15200
15201         canvas.restoreToCount(saveCount);
15202
15203         // Step 6, draw decorations (scrollbars)
15204         onDrawScrollBars(canvas);
15205
15206         if (mOverlay != null && !mOverlay.isEmpty()) {
15207             mOverlay.getOverlayView().dispatchDraw(canvas);
15208         }
15209     }
15210
15211     /**
15212      * Draws the accessibility focus rect onto the specified canvas.
15213      *
15214      * @param canvas Canvas on which to draw the focus rect
15215      */
15216     private void drawAccessibilityFocus(Canvas canvas) {
15217         if (mAttachInfo == null) {
15218             return;
15219         }
15220
15221         final Rect bounds = mAttachInfo.mTmpInvalRect;
15222         final ViewRootImpl viewRoot = getViewRootImpl();
15223         if (viewRoot == null || viewRoot.getAccessibilityFocusedHost() != this) {
15224             return;
15225         }
15226
15227         final AccessibilityManager manager = AccessibilityManager.getInstance(mContext);
15228         if (!manager.isEnabled() || !manager.isTouchExplorationEnabled()) {
15229             return;
15230         }
15231
15232         final Drawable drawable = viewRoot.getAccessibilityFocusedDrawable();
15233         if (drawable == null) {
15234             return;
15235         }
15236
15237         final AccessibilityNodeInfo virtualView = viewRoot.getAccessibilityFocusedVirtualView();
15238         if (virtualView != null) {
15239             virtualView.getBoundsInScreen(bounds);
15240             final int[] offset = mAttachInfo.mTmpLocation;
15241             getLocationOnScreen(offset);
15242             bounds.offset(-offset[0], -offset[1]);
15243         } else {
15244             bounds.set(0, 0, mRight - mLeft, mBottom - mTop);
15245         }
15246
15247         canvas.save();
15248         canvas.translate(mScrollX, mScrollY);
15249         canvas.clipRect(bounds, Region.Op.REPLACE);
15250         drawable.setBounds(bounds);
15251         drawable.draw(canvas);
15252         canvas.restore();
15253     }
15254
15255     /**
15256      * Draws the background onto the specified canvas.
15257      *
15258      * @param canvas Canvas on which to draw the background
15259      */
15260     private void drawBackground(Canvas canvas) {
15261         final Drawable background = mBackground;
15262         if (background == null) {
15263             return;
15264         }
15265
15266         if (mBackgroundSizeChanged) {
15267             background.setBounds(0, 0,  mRight - mLeft, mBottom - mTop);
15268             mBackgroundSizeChanged = false;
15269             invalidateOutline();
15270         }
15271
15272         // Attempt to use a display list if requested.
15273         if (canvas.isHardwareAccelerated() && mAttachInfo != null
15274                 && mAttachInfo.mHardwareRenderer != null) {
15275             mBackgroundRenderNode = getDrawableRenderNode(background, mBackgroundRenderNode);
15276
15277             final RenderNode displayList = mBackgroundRenderNode;
15278             if (displayList != null && displayList.isValid()) {
15279                 setBackgroundDisplayListProperties(displayList);
15280                 ((HardwareCanvas) canvas).drawRenderNode(displayList);
15281                 return;
15282             }
15283         }
15284
15285         final int scrollX = mScrollX;
15286         final int scrollY = mScrollY;
15287         if ((scrollX | scrollY) == 0) {
15288             background.draw(canvas);
15289         } else {
15290             canvas.translate(scrollX, scrollY);
15291             background.draw(canvas);
15292             canvas.translate(-scrollX, -scrollY);
15293         }
15294     }
15295
15296     /**
15297      * Set up background drawable display list properties.
15298      *
15299      * @param displayList Valid display list for the background drawable
15300      */
15301     private void setBackgroundDisplayListProperties(RenderNode displayList) {
15302         displayList.setTranslationX(mScrollX);
15303         displayList.setTranslationY(mScrollY);
15304     }
15305
15306     /**
15307      * Creates a new display list or updates the existing display list for the
15308      * specified Drawable.
15309      *
15310      * @param drawable Drawable for which to create a display list
15311      * @param renderNode Existing RenderNode, or {@code null}
15312      * @return A valid display list for the specified drawable
15313      */
15314     private RenderNode getDrawableRenderNode(Drawable drawable, RenderNode renderNode) {
15315         if (renderNode == null) {
15316             renderNode = RenderNode.create(drawable.getClass().getName(), this);
15317         }
15318
15319         final Rect bounds = drawable.getBounds();
15320         final int width = bounds.width();
15321         final int height = bounds.height();
15322         final HardwareCanvas canvas = renderNode.start(width, height);
15323         try {
15324             drawable.draw(canvas);
15325         } finally {
15326             renderNode.end(canvas);
15327         }
15328
15329         // Set up drawable properties that are view-independent.
15330         renderNode.setLeftTopRightBottom(bounds.left, bounds.top, bounds.right, bounds.bottom);
15331         renderNode.setProjectBackwards(drawable.isProjected());
15332         renderNode.setProjectionReceiver(true);
15333         renderNode.setClipToBounds(false);
15334         return renderNode;
15335     }
15336
15337     /**
15338      * Returns the overlay for this view, creating it if it does not yet exist.
15339      * Adding drawables to the overlay will cause them to be displayed whenever
15340      * the view itself is redrawn. Objects in the overlay should be actively
15341      * managed: remove them when they should not be displayed anymore. The
15342      * overlay will always have the same size as its host view.
15343      *
15344      * <p>Note: Overlays do not currently work correctly with {@link
15345      * SurfaceView} or {@link TextureView}; contents in overlays for these
15346      * types of views may not display correctly.</p>
15347      *
15348      * @return The ViewOverlay object for this view.
15349      * @see ViewOverlay
15350      */
15351     public ViewOverlay getOverlay() {
15352         if (mOverlay == null) {
15353             mOverlay = new ViewOverlay(mContext, this);
15354         }
15355         return mOverlay;
15356     }
15357
15358     /**
15359      * Override this if your view is known to always be drawn on top of a solid color background,
15360      * and needs to draw fading edges. Returning a non-zero color enables the view system to
15361      * optimize the drawing of the fading edges. If you do return a non-zero color, the alpha
15362      * should be set to 0xFF.
15363      *
15364      * @see #setVerticalFadingEdgeEnabled(boolean)
15365      * @see #setHorizontalFadingEdgeEnabled(boolean)
15366      *
15367      * @return The known solid color background for this view, or 0 if the color may vary
15368      */
15369     @ViewDebug.ExportedProperty(category = "drawing")
15370     public int getSolidColor() {
15371         return 0;
15372     }
15373
15374     /**
15375      * Build a human readable string representation of the specified view flags.
15376      *
15377      * @param flags the view flags to convert to a string
15378      * @return a String representing the supplied flags
15379      */
15380     private static String printFlags(int flags) {
15381         String output = "";
15382         int numFlags = 0;
15383         if ((flags & FOCUSABLE_MASK) == FOCUSABLE) {
15384             output += "TAKES_FOCUS";
15385             numFlags++;
15386         }
15387
15388         switch (flags & VISIBILITY_MASK) {
15389         case INVISIBLE:
15390             if (numFlags > 0) {
15391                 output += " ";
15392             }
15393             output += "INVISIBLE";
15394             // USELESS HERE numFlags++;
15395             break;
15396         case GONE:
15397             if (numFlags > 0) {
15398                 output += " ";
15399             }
15400             output += "GONE";
15401             // USELESS HERE numFlags++;
15402             break;
15403         default:
15404             break;
15405         }
15406         return output;
15407     }
15408
15409     /**
15410      * Build a human readable string representation of the specified private
15411      * view flags.
15412      *
15413      * @param privateFlags the private view flags to convert to a string
15414      * @return a String representing the supplied flags
15415      */
15416     private static String printPrivateFlags(int privateFlags) {
15417         String output = "";
15418         int numFlags = 0;
15419
15420         if ((privateFlags & PFLAG_WANTS_FOCUS) == PFLAG_WANTS_FOCUS) {
15421             output += "WANTS_FOCUS";
15422             numFlags++;
15423         }
15424
15425         if ((privateFlags & PFLAG_FOCUSED) == PFLAG_FOCUSED) {
15426             if (numFlags > 0) {
15427                 output += " ";
15428             }
15429             output += "FOCUSED";
15430             numFlags++;
15431         }
15432
15433         if ((privateFlags & PFLAG_SELECTED) == PFLAG_SELECTED) {
15434             if (numFlags > 0) {
15435                 output += " ";
15436             }
15437             output += "SELECTED";
15438             numFlags++;
15439         }
15440
15441         if ((privateFlags & PFLAG_IS_ROOT_NAMESPACE) == PFLAG_IS_ROOT_NAMESPACE) {
15442             if (numFlags > 0) {
15443                 output += " ";
15444             }
15445             output += "IS_ROOT_NAMESPACE";
15446             numFlags++;
15447         }
15448
15449         if ((privateFlags & PFLAG_HAS_BOUNDS) == PFLAG_HAS_BOUNDS) {
15450             if (numFlags > 0) {
15451                 output += " ";
15452             }
15453             output += "HAS_BOUNDS";
15454             numFlags++;
15455         }
15456
15457         if ((privateFlags & PFLAG_DRAWN) == PFLAG_DRAWN) {
15458             if (numFlags > 0) {
15459                 output += " ";
15460             }
15461             output += "DRAWN";
15462             // USELESS HERE numFlags++;
15463         }
15464         return output;
15465     }
15466
15467     /**
15468      * <p>Indicates whether or not this view's layout will be requested during
15469      * the next hierarchy layout pass.</p>
15470      *
15471      * @return true if the layout will be forced during next layout pass
15472      */
15473     public boolean isLayoutRequested() {
15474         return (mPrivateFlags & PFLAG_FORCE_LAYOUT) == PFLAG_FORCE_LAYOUT;
15475     }
15476
15477     /**
15478      * Return true if o is a ViewGroup that is laying out using optical bounds.
15479      * @hide
15480      */
15481     public static boolean isLayoutModeOptical(Object o) {
15482         return o instanceof ViewGroup && ((ViewGroup) o).isLayoutModeOptical();
15483     }
15484
15485     private boolean setOpticalFrame(int left, int top, int right, int bottom) {
15486         Insets parentInsets = mParent instanceof View ?
15487                 ((View) mParent).getOpticalInsets() : Insets.NONE;
15488         Insets childInsets = getOpticalInsets();
15489         return setFrame(
15490                 left   + parentInsets.left - childInsets.left,
15491                 top    + parentInsets.top  - childInsets.top,
15492                 right  + parentInsets.left + childInsets.right,
15493                 bottom + parentInsets.top  + childInsets.bottom);
15494     }
15495
15496     /**
15497      * Assign a size and position to a view and all of its
15498      * descendants
15499      *
15500      * <p>This is the second phase of the layout mechanism.
15501      * (The first is measuring). In this phase, each parent calls
15502      * layout on all of its children to position them.
15503      * This is typically done using the child measurements
15504      * that were stored in the measure pass().</p>
15505      *
15506      * <p>Derived classes should not override this method.
15507      * Derived classes with children should override
15508      * onLayout. In that method, they should
15509      * call layout on each of their children.</p>
15510      *
15511      * @param l Left position, relative to parent
15512      * @param t Top position, relative to parent
15513      * @param r Right position, relative to parent
15514      * @param b Bottom position, relative to parent
15515      */
15516     @SuppressWarnings({"unchecked"})
15517     public void layout(int l, int t, int r, int b) {
15518         if ((mPrivateFlags3 & PFLAG3_MEASURE_NEEDED_BEFORE_LAYOUT) != 0) {
15519             onMeasure(mOldWidthMeasureSpec, mOldHeightMeasureSpec);
15520             mPrivateFlags3 &= ~PFLAG3_MEASURE_NEEDED_BEFORE_LAYOUT;
15521         }
15522
15523         int oldL = mLeft;
15524         int oldT = mTop;
15525         int oldB = mBottom;
15526         int oldR = mRight;
15527
15528         boolean changed = isLayoutModeOptical(mParent) ?
15529                 setOpticalFrame(l, t, r, b) : setFrame(l, t, r, b);
15530
15531         if (changed || (mPrivateFlags & PFLAG_LAYOUT_REQUIRED) == PFLAG_LAYOUT_REQUIRED) {
15532             onLayout(changed, l, t, r, b);
15533             mPrivateFlags &= ~PFLAG_LAYOUT_REQUIRED;
15534
15535             ListenerInfo li = mListenerInfo;
15536             if (li != null && li.mOnLayoutChangeListeners != null) {
15537                 ArrayList<OnLayoutChangeListener> listenersCopy =
15538                         (ArrayList<OnLayoutChangeListener>)li.mOnLayoutChangeListeners.clone();
15539                 int numListeners = listenersCopy.size();
15540                 for (int i = 0; i < numListeners; ++i) {
15541                     listenersCopy.get(i).onLayoutChange(this, l, t, r, b, oldL, oldT, oldR, oldB);
15542                 }
15543             }
15544         }
15545
15546         mPrivateFlags &= ~PFLAG_FORCE_LAYOUT;
15547         mPrivateFlags3 |= PFLAG3_IS_LAID_OUT;
15548     }
15549
15550     /**
15551      * Called from layout when this view should
15552      * assign a size and position to each of its children.
15553      *
15554      * Derived classes with children should override
15555      * this method and call layout on each of
15556      * their children.
15557      * @param changed This is a new size or position for this view
15558      * @param left Left position, relative to parent
15559      * @param top Top position, relative to parent
15560      * @param right Right position, relative to parent
15561      * @param bottom Bottom position, relative to parent
15562      */
15563     protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
15564     }
15565
15566     /**
15567      * Assign a size and position to this view.
15568      *
15569      * This is called from layout.
15570      *
15571      * @param left Left position, relative to parent
15572      * @param top Top position, relative to parent
15573      * @param right Right position, relative to parent
15574      * @param bottom Bottom position, relative to parent
15575      * @return true if the new size and position are different than the
15576      *         previous ones
15577      * {@hide}
15578      */
15579     protected boolean setFrame(int left, int top, int right, int bottom) {
15580         boolean changed = false;
15581
15582         if (DBG) {
15583             Log.d("View", this + " View.setFrame(" + left + "," + top + ","
15584                     + right + "," + bottom + ")");
15585         }
15586
15587         if (mLeft != left || mRight != right || mTop != top || mBottom != bottom) {
15588             changed = true;
15589
15590             // Remember our drawn bit
15591             int drawn = mPrivateFlags & PFLAG_DRAWN;
15592
15593             int oldWidth = mRight - mLeft;
15594             int oldHeight = mBottom - mTop;
15595             int newWidth = right - left;
15596             int newHeight = bottom - top;
15597             boolean sizeChanged = (newWidth != oldWidth) || (newHeight != oldHeight);
15598
15599             // Invalidate our old position
15600             invalidate(sizeChanged);
15601
15602             mLeft = left;
15603             mTop = top;
15604             mRight = right;
15605             mBottom = bottom;
15606             mRenderNode.setLeftTopRightBottom(mLeft, mTop, mRight, mBottom);
15607
15608             mPrivateFlags |= PFLAG_HAS_BOUNDS;
15609
15610
15611             if (sizeChanged) {
15612                 sizeChange(newWidth, newHeight, oldWidth, oldHeight);
15613             }
15614
15615             if ((mViewFlags & VISIBILITY_MASK) == VISIBLE) {
15616                 // If we are visible, force the DRAWN bit to on so that
15617                 // this invalidate will go through (at least to our parent).
15618                 // This is because someone may have invalidated this view
15619                 // before this call to setFrame came in, thereby clearing
15620                 // the DRAWN bit.
15621                 mPrivateFlags |= PFLAG_DRAWN;
15622                 invalidate(sizeChanged);
15623                 // parent display list may need to be recreated based on a change in the bounds
15624                 // of any child
15625                 invalidateParentCaches();
15626             }
15627
15628             // Reset drawn bit to original value (invalidate turns it off)
15629             mPrivateFlags |= drawn;
15630
15631             mBackgroundSizeChanged = true;
15632
15633             notifySubtreeAccessibilityStateChangedIfNeeded();
15634         }
15635         return changed;
15636     }
15637
15638     private void sizeChange(int newWidth, int newHeight, int oldWidth, int oldHeight) {
15639         onSizeChanged(newWidth, newHeight, oldWidth, oldHeight);
15640         if (mOverlay != null) {
15641             mOverlay.getOverlayView().setRight(newWidth);
15642             mOverlay.getOverlayView().setBottom(newHeight);
15643         }
15644         invalidateOutline();
15645     }
15646
15647     /**
15648      * Finalize inflating a view from XML.  This is called as the last phase
15649      * of inflation, after all child views have been added.
15650      *
15651      * <p>Even if the subclass overrides onFinishInflate, they should always be
15652      * sure to call the super method, so that we get called.
15653      */
15654     protected void onFinishInflate() {
15655     }
15656
15657     /**
15658      * Returns the resources associated with this view.
15659      *
15660      * @return Resources object.
15661      */
15662     public Resources getResources() {
15663         return mResources;
15664     }
15665
15666     /**
15667      * Invalidates the specified Drawable.
15668      *
15669      * @param drawable the drawable to invalidate
15670      */
15671     @Override
15672     public void invalidateDrawable(@NonNull Drawable drawable) {
15673         if (verifyDrawable(drawable)) {
15674             final Rect dirty = drawable.getDirtyBounds();
15675             final int scrollX = mScrollX;
15676             final int scrollY = mScrollY;
15677
15678             invalidate(dirty.left + scrollX, dirty.top + scrollY,
15679                     dirty.right + scrollX, dirty.bottom + scrollY);
15680
15681             invalidateOutline();
15682         }
15683     }
15684
15685     /**
15686      * Schedules an action on a drawable to occur at a specified time.
15687      *
15688      * @param who the recipient of the action
15689      * @param what the action to run on the drawable
15690      * @param when the time at which the action must occur. Uses the
15691      *        {@link SystemClock#uptimeMillis} timebase.
15692      */
15693     @Override
15694     public void scheduleDrawable(Drawable who, Runnable what, long when) {
15695         if (verifyDrawable(who) && what != null) {
15696             final long delay = when - SystemClock.uptimeMillis();
15697             if (mAttachInfo != null) {
15698                 mAttachInfo.mViewRootImpl.mChoreographer.postCallbackDelayed(
15699                         Choreographer.CALLBACK_ANIMATION, what, who,
15700                         Choreographer.subtractFrameDelay(delay));
15701             } else {
15702                 ViewRootImpl.getRunQueue().postDelayed(what, delay);
15703             }
15704         }
15705     }
15706
15707     /**
15708      * Cancels a scheduled action on a drawable.
15709      *
15710      * @param who the recipient of the action
15711      * @param what the action to cancel
15712      */
15713     @Override
15714     public void unscheduleDrawable(Drawable who, Runnable what) {
15715         if (verifyDrawable(who) && what != null) {
15716             if (mAttachInfo != null) {
15717                 mAttachInfo.mViewRootImpl.mChoreographer.removeCallbacks(
15718                         Choreographer.CALLBACK_ANIMATION, what, who);
15719             }
15720             ViewRootImpl.getRunQueue().removeCallbacks(what);
15721         }
15722     }
15723
15724     /**
15725      * Unschedule any events associated with the given Drawable.  This can be
15726      * used when selecting a new Drawable into a view, so that the previous
15727      * one is completely unscheduled.
15728      *
15729      * @param who The Drawable to unschedule.
15730      *
15731      * @see #drawableStateChanged
15732      */
15733     public void unscheduleDrawable(Drawable who) {
15734         if (mAttachInfo != null && who != null) {
15735             mAttachInfo.mViewRootImpl.mChoreographer.removeCallbacks(
15736                     Choreographer.CALLBACK_ANIMATION, null, who);
15737         }
15738     }
15739
15740     /**
15741      * Resolve the Drawables depending on the layout direction. This is implicitly supposing
15742      * that the View directionality can and will be resolved before its Drawables.
15743      *
15744      * Will call {@link View#onResolveDrawables} when resolution is done.
15745      *
15746      * @hide
15747      */
15748     protected void resolveDrawables() {
15749         // Drawables resolution may need to happen before resolving the layout direction (which is
15750         // done only during the measure() call).
15751         // If the layout direction is not resolved yet, we cannot resolve the Drawables except in
15752         // one case: when the raw layout direction has not been defined as LAYOUT_DIRECTION_INHERIT.
15753         // So, if the raw layout direction is LAYOUT_DIRECTION_LTR or LAYOUT_DIRECTION_RTL or
15754         // LAYOUT_DIRECTION_LOCALE, we can "cheat" and we don't need to wait for the layout
15755         // direction to be resolved as its resolved value will be the same as its raw value.
15756         if (!isLayoutDirectionResolved() &&
15757                 getRawLayoutDirection() == View.LAYOUT_DIRECTION_INHERIT) {
15758             return;
15759         }
15760
15761         final int layoutDirection = isLayoutDirectionResolved() ?
15762                 getLayoutDirection() : getRawLayoutDirection();
15763
15764         if (mBackground != null) {
15765             mBackground.setLayoutDirection(layoutDirection);
15766         }
15767         mPrivateFlags2 |= PFLAG2_DRAWABLE_RESOLVED;
15768         onResolveDrawables(layoutDirection);
15769     }
15770
15771     /**
15772      * Called when layout direction has been resolved.
15773      *
15774      * The default implementation does nothing.
15775      *
15776      * @param layoutDirection The resolved layout direction.
15777      *
15778      * @see #LAYOUT_DIRECTION_LTR
15779      * @see #LAYOUT_DIRECTION_RTL
15780      *
15781      * @hide
15782      */
15783     public void onResolveDrawables(@ResolvedLayoutDir int layoutDirection) {
15784     }
15785
15786     /**
15787      * @hide
15788      */
15789     protected void resetResolvedDrawables() {
15790         mPrivateFlags2 &= ~PFLAG2_DRAWABLE_RESOLVED;
15791     }
15792
15793     private boolean isDrawablesResolved() {
15794         return (mPrivateFlags2 & PFLAG2_DRAWABLE_RESOLVED) == PFLAG2_DRAWABLE_RESOLVED;
15795     }
15796
15797     /**
15798      * If your view subclass is displaying its own Drawable objects, it should
15799      * override this function and return true for any Drawable it is
15800      * displaying.  This allows animations for those drawables to be
15801      * scheduled.
15802      *
15803      * <p>Be sure to call through to the super class when overriding this
15804      * function.
15805      *
15806      * @param who The Drawable to verify.  Return true if it is one you are
15807      *            displaying, else return the result of calling through to the
15808      *            super class.
15809      *
15810      * @return boolean If true than the Drawable is being displayed in the
15811      *         view; else false and it is not allowed to animate.
15812      *
15813      * @see #unscheduleDrawable(android.graphics.drawable.Drawable)
15814      * @see #drawableStateChanged()
15815      */
15816     protected boolean verifyDrawable(Drawable who) {
15817         return who == mBackground;
15818     }
15819
15820     /**
15821      * This function is called whenever the state of the view changes in such
15822      * a way that it impacts the state of drawables being shown.
15823      * <p>
15824      * If the View has a StateListAnimator, it will also be called to run necessary state
15825      * change animations.
15826      * <p>
15827      * Be sure to call through to the superclass when overriding this function.
15828      *
15829      * @see Drawable#setState(int[])
15830      */
15831     protected void drawableStateChanged() {
15832         final Drawable d = mBackground;
15833         if (d != null && d.isStateful()) {
15834             d.setState(getDrawableState());
15835         }
15836
15837         if (mStateListAnimator != null) {
15838             mStateListAnimator.setState(getDrawableState());
15839         }
15840     }
15841
15842     /**
15843      * This function is called whenever the view hotspot changes and needs to
15844      * be propagated to drawables managed by the view.
15845      * <p>
15846      * Be sure to call through to the superclass when overriding this function.
15847      *
15848      * @param x hotspot x coordinate
15849      * @param y hotspot y coordinate
15850      */
15851     public void drawableHotspotChanged(float x, float y) {
15852         if (mBackground != null) {
15853             mBackground.setHotspot(x, y);
15854         }
15855     }
15856
15857     /**
15858      * Call this to force a view to update its drawable state. This will cause
15859      * drawableStateChanged to be called on this view. Views that are interested
15860      * in the new state should call getDrawableState.
15861      *
15862      * @see #drawableStateChanged
15863      * @see #getDrawableState
15864      */
15865     public void refreshDrawableState() {
15866         mPrivateFlags |= PFLAG_DRAWABLE_STATE_DIRTY;
15867         drawableStateChanged();
15868
15869         ViewParent parent = mParent;
15870         if (parent != null) {
15871             parent.childDrawableStateChanged(this);
15872         }
15873     }
15874
15875     /**
15876      * Return an array of resource IDs of the drawable states representing the
15877      * current state of the view.
15878      *
15879      * @return The current drawable state
15880      *
15881      * @see Drawable#setState(int[])
15882      * @see #drawableStateChanged()
15883      * @see #onCreateDrawableState(int)
15884      */
15885     public final int[] getDrawableState() {
15886         if ((mDrawableState != null) && ((mPrivateFlags & PFLAG_DRAWABLE_STATE_DIRTY) == 0)) {
15887             return mDrawableState;
15888         } else {
15889             mDrawableState = onCreateDrawableState(0);
15890             mPrivateFlags &= ~PFLAG_DRAWABLE_STATE_DIRTY;
15891             return mDrawableState;
15892         }
15893     }
15894
15895     /**
15896      * Generate the new {@link android.graphics.drawable.Drawable} state for
15897      * this view. This is called by the view
15898      * system when the cached Drawable state is determined to be invalid.  To
15899      * retrieve the current state, you should use {@link #getDrawableState}.
15900      *
15901      * @param extraSpace if non-zero, this is the number of extra entries you
15902      * would like in the returned array in which you can place your own
15903      * states.
15904      *
15905      * @return Returns an array holding the current {@link Drawable} state of
15906      * the view.
15907      *
15908      * @see #mergeDrawableStates(int[], int[])
15909      */
15910     protected int[] onCreateDrawableState(int extraSpace) {
15911         if ((mViewFlags & DUPLICATE_PARENT_STATE) == DUPLICATE_PARENT_STATE &&
15912                 mParent instanceof View) {
15913             return ((View) mParent).onCreateDrawableState(extraSpace);
15914         }
15915
15916         int[] drawableState;
15917
15918         int privateFlags = mPrivateFlags;
15919
15920         int viewStateIndex = 0;
15921         if ((privateFlags & PFLAG_PRESSED) != 0) viewStateIndex |= VIEW_STATE_PRESSED;
15922         if ((mViewFlags & ENABLED_MASK) == ENABLED) viewStateIndex |= VIEW_STATE_ENABLED;
15923         if (isFocused()) viewStateIndex |= VIEW_STATE_FOCUSED;
15924         if ((privateFlags & PFLAG_SELECTED) != 0) viewStateIndex |= VIEW_STATE_SELECTED;
15925         if (hasWindowFocus()) viewStateIndex |= VIEW_STATE_WINDOW_FOCUSED;
15926         if ((privateFlags & PFLAG_ACTIVATED) != 0) viewStateIndex |= VIEW_STATE_ACTIVATED;
15927         if (mAttachInfo != null && mAttachInfo.mHardwareAccelerationRequested &&
15928                 HardwareRenderer.isAvailable()) {
15929             // This is set if HW acceleration is requested, even if the current
15930             // process doesn't allow it.  This is just to allow app preview
15931             // windows to better match their app.
15932             viewStateIndex |= VIEW_STATE_ACCELERATED;
15933         }
15934         if ((privateFlags & PFLAG_HOVERED) != 0) viewStateIndex |= VIEW_STATE_HOVERED;
15935
15936         final int privateFlags2 = mPrivateFlags2;
15937         if ((privateFlags2 & PFLAG2_DRAG_CAN_ACCEPT) != 0) viewStateIndex |= VIEW_STATE_DRAG_CAN_ACCEPT;
15938         if ((privateFlags2 & PFLAG2_DRAG_HOVERED) != 0) viewStateIndex |= VIEW_STATE_DRAG_HOVERED;
15939
15940         drawableState = VIEW_STATE_SETS[viewStateIndex];
15941
15942         //noinspection ConstantIfStatement
15943         if (false) {
15944             Log.i("View", "drawableStateIndex=" + viewStateIndex);
15945             Log.i("View", toString()
15946                     + " pressed=" + ((privateFlags & PFLAG_PRESSED) != 0)
15947                     + " en=" + ((mViewFlags & ENABLED_MASK) == ENABLED)
15948                     + " fo=" + hasFocus()
15949                     + " sl=" + ((privateFlags & PFLAG_SELECTED) != 0)
15950                     + " wf=" + hasWindowFocus()
15951                     + ": " + Arrays.toString(drawableState));
15952         }
15953
15954         if (extraSpace == 0) {
15955             return drawableState;
15956         }
15957
15958         final int[] fullState;
15959         if (drawableState != null) {
15960             fullState = new int[drawableState.length + extraSpace];
15961             System.arraycopy(drawableState, 0, fullState, 0, drawableState.length);
15962         } else {
15963             fullState = new int[extraSpace];
15964         }
15965
15966         return fullState;
15967     }
15968
15969     /**
15970      * Merge your own state values in <var>additionalState</var> into the base
15971      * state values <var>baseState</var> that were returned by
15972      * {@link #onCreateDrawableState(int)}.
15973      *
15974      * @param baseState The base state values returned by
15975      * {@link #onCreateDrawableState(int)}, which will be modified to also hold your
15976      * own additional state values.
15977      *
15978      * @param additionalState The additional state values you would like
15979      * added to <var>baseState</var>; this array is not modified.
15980      *
15981      * @return As a convenience, the <var>baseState</var> array you originally
15982      * passed into the function is returned.
15983      *
15984      * @see #onCreateDrawableState(int)
15985      */
15986     protected static int[] mergeDrawableStates(int[] baseState, int[] additionalState) {
15987         final int N = baseState.length;
15988         int i = N - 1;
15989         while (i >= 0 && baseState[i] == 0) {
15990             i--;
15991         }
15992         System.arraycopy(additionalState, 0, baseState, i + 1, additionalState.length);
15993         return baseState;
15994     }
15995
15996     /**
15997      * Call {@link Drawable#jumpToCurrentState() Drawable.jumpToCurrentState()}
15998      * on all Drawable objects associated with this view.
15999      * <p>
16000      * Also calls {@link StateListAnimator#jumpToCurrentState()} if there is a StateListAnimator
16001      * attached to this view.
16002      */
16003     public void jumpDrawablesToCurrentState() {
16004         if (mBackground != null) {
16005             mBackground.jumpToCurrentState();
16006         }
16007         if (mStateListAnimator != null) {
16008             mStateListAnimator.jumpToCurrentState();
16009         }
16010     }
16011
16012     /**
16013      * Sets the background color for this view.
16014      * @param color the color of the background
16015      */
16016     @RemotableViewMethod
16017     public void setBackgroundColor(int color) {
16018         if (mBackground instanceof ColorDrawable) {
16019             ((ColorDrawable) mBackground.mutate()).setColor(color);
16020             computeOpaqueFlags();
16021             mBackgroundResource = 0;
16022         } else {
16023             setBackground(new ColorDrawable(color));
16024         }
16025     }
16026
16027     /**
16028      * Set the background to a given resource. The resource should refer to
16029      * a Drawable object or 0 to remove the background.
16030      * @param resid The identifier of the resource.
16031      *
16032      * @attr ref android.R.styleable#View_background
16033      */
16034     @RemotableViewMethod
16035     public void setBackgroundResource(int resid) {
16036         if (resid != 0 && resid == mBackgroundResource) {
16037             return;
16038         }
16039
16040         Drawable d = null;
16041         if (resid != 0) {
16042             d = mContext.getDrawable(resid);
16043         }
16044         setBackground(d);
16045
16046         mBackgroundResource = resid;
16047     }
16048
16049     /**
16050      * Set the background to a given Drawable, or remove the background. If the
16051      * background has padding, this View's padding is set to the background's
16052      * padding. However, when a background is removed, this View's padding isn't
16053      * touched. If setting the padding is desired, please use
16054      * {@link #setPadding(int, int, int, int)}.
16055      *
16056      * @param background The Drawable to use as the background, or null to remove the
16057      *        background
16058      */
16059     public void setBackground(Drawable background) {
16060         //noinspection deprecation
16061         setBackgroundDrawable(background);
16062     }
16063
16064     /**
16065      * @deprecated use {@link #setBackground(Drawable)} instead
16066      */
16067     @Deprecated
16068     public void setBackgroundDrawable(Drawable background) {
16069         computeOpaqueFlags();
16070
16071         if (background == mBackground) {
16072             return;
16073         }
16074
16075         boolean requestLayout = false;
16076
16077         mBackgroundResource = 0;
16078
16079         /*
16080          * Regardless of whether we're setting a new background or not, we want
16081          * to clear the previous drawable.
16082          */
16083         if (mBackground != null) {
16084             mBackground.setCallback(null);
16085             unscheduleDrawable(mBackground);
16086         }
16087
16088         if (background != null) {
16089             Rect padding = sThreadLocal.get();
16090             if (padding == null) {
16091                 padding = new Rect();
16092                 sThreadLocal.set(padding);
16093             }
16094             resetResolvedDrawables();
16095             background.setLayoutDirection(getLayoutDirection());
16096             if (background.getPadding(padding)) {
16097                 resetResolvedPadding();
16098                 switch (background.getLayoutDirection()) {
16099                     case LAYOUT_DIRECTION_RTL:
16100                         mUserPaddingLeftInitial = padding.right;
16101                         mUserPaddingRightInitial = padding.left;
16102                         internalSetPadding(padding.right, padding.top, padding.left, padding.bottom);
16103                         break;
16104                     case LAYOUT_DIRECTION_LTR:
16105                     default:
16106                         mUserPaddingLeftInitial = padding.left;
16107                         mUserPaddingRightInitial = padding.right;
16108                         internalSetPadding(padding.left, padding.top, padding.right, padding.bottom);
16109                 }
16110                 mLeftPaddingDefined = false;
16111                 mRightPaddingDefined = false;
16112             }
16113
16114             // Compare the minimum sizes of the old Drawable and the new.  If there isn't an old or
16115             // if it has a different minimum size, we should layout again
16116             if (mBackground == null
16117                     || mBackground.getMinimumHeight() != background.getMinimumHeight()
16118                     || mBackground.getMinimumWidth() != background.getMinimumWidth()) {
16119                 requestLayout = true;
16120             }
16121
16122             background.setCallback(this);
16123             if (background.isStateful()) {
16124                 background.setState(getDrawableState());
16125             }
16126             background.setVisible(getVisibility() == VISIBLE, false);
16127             mBackground = background;
16128
16129             applyBackgroundTint();
16130
16131             if ((mPrivateFlags & PFLAG_SKIP_DRAW) != 0) {
16132                 mPrivateFlags &= ~PFLAG_SKIP_DRAW;
16133                 mPrivateFlags |= PFLAG_ONLY_DRAWS_BACKGROUND;
16134                 requestLayout = true;
16135             }
16136         } else {
16137             /* Remove the background */
16138             mBackground = null;
16139
16140             if ((mPrivateFlags & PFLAG_ONLY_DRAWS_BACKGROUND) != 0) {
16141                 /*
16142                  * This view ONLY drew the background before and we're removing
16143                  * the background, so now it won't draw anything
16144                  * (hence we SKIP_DRAW)
16145                  */
16146                 mPrivateFlags &= ~PFLAG_ONLY_DRAWS_BACKGROUND;
16147                 mPrivateFlags |= PFLAG_SKIP_DRAW;
16148             }
16149
16150             /*
16151              * When the background is set, we try to apply its padding to this
16152              * View. When the background is removed, we don't touch this View's
16153              * padding. This is noted in the Javadocs. Hence, we don't need to
16154              * requestLayout(), the invalidate() below is sufficient.
16155              */
16156
16157             // The old background's minimum size could have affected this
16158             // View's layout, so let's requestLayout
16159             requestLayout = true;
16160         }
16161
16162         computeOpaqueFlags();
16163
16164         if (requestLayout) {
16165             requestLayout();
16166         }
16167
16168         mBackgroundSizeChanged = true;
16169         invalidate(true);
16170     }
16171
16172     /**
16173      * Gets the background drawable
16174      *
16175      * @return The drawable used as the background for this view, if any.
16176      *
16177      * @see #setBackground(Drawable)
16178      *
16179      * @attr ref android.R.styleable#View_background
16180      */
16181     public Drawable getBackground() {
16182         return mBackground;
16183     }
16184
16185     /**
16186      * Applies a tint to the background drawable. Does not modify the current tint
16187      * mode, which is {@link PorterDuff.Mode#SRC_ATOP} by default.
16188      * <p>
16189      * Subsequent calls to {@link #setBackground(Drawable)} will automatically
16190      * mutate the drawable and apply the specified tint and tint mode using
16191      * {@link Drawable#setTintList(ColorStateList)}.
16192      *
16193      * @param tint the tint to apply, may be {@code null} to clear tint
16194      *
16195      * @attr ref android.R.styleable#View_backgroundTint
16196      * @see #getBackgroundTintList()
16197      * @see Drawable#setTintList(ColorStateList)
16198      */
16199     public void setBackgroundTintList(@Nullable ColorStateList tint) {
16200         mBackgroundTintList = tint;
16201         mHasBackgroundTint = true;
16202
16203         applyBackgroundTint();
16204     }
16205
16206     /**
16207      * @return the tint applied to the background drawable
16208      * @attr ref android.R.styleable#View_backgroundTint
16209      * @see #setBackgroundTintList(ColorStateList)
16210      */
16211     @Nullable
16212     public ColorStateList getBackgroundTintList() {
16213         return mBackgroundTintList;
16214     }
16215
16216     /**
16217      * Specifies the blending mode used to apply the tint specified by
16218      * {@link #setBackgroundTintList(ColorStateList)}} to the background drawable.
16219      * The default mode is {@link PorterDuff.Mode#SRC_ATOP}.
16220      *
16221      * @param tintMode the blending mode used to apply the tint, may be
16222      *                 {@code null} to clear tint
16223      * @attr ref android.R.styleable#View_backgroundTintMode
16224      * @see #getBackgroundTintMode()
16225      * @see Drawable#setTintMode(PorterDuff.Mode)
16226      */
16227     public void setBackgroundTintMode(@Nullable PorterDuff.Mode tintMode) {
16228         mBackgroundTintMode = tintMode;
16229
16230         applyBackgroundTint();
16231     }
16232
16233     /**
16234      * @return the blending mode used to apply the tint to the background drawable
16235      * @attr ref android.R.styleable#View_backgroundTintMode
16236      * @see #setBackgroundTintMode(PorterDuff.Mode)
16237      */
16238     @Nullable
16239     public PorterDuff.Mode getBackgroundTintMode() {
16240         return mBackgroundTintMode;
16241     }
16242
16243     private void applyBackgroundTint() {
16244         if (mBackground != null && mHasBackgroundTint) {
16245             mBackground = mBackground.mutate();
16246             mBackground.setTintList(mBackgroundTintList);
16247             mBackground.setTintMode(mBackgroundTintMode);
16248         }
16249     }
16250
16251     /**
16252      * Sets the padding. The view may add on the space required to display
16253      * the scrollbars, depending on the style and visibility of the scrollbars.
16254      * So the values returned from {@link #getPaddingLeft}, {@link #getPaddingTop},
16255      * {@link #getPaddingRight} and {@link #getPaddingBottom} may be different
16256      * from the values set in this call.
16257      *
16258      * @attr ref android.R.styleable#View_padding
16259      * @attr ref android.R.styleable#View_paddingBottom
16260      * @attr ref android.R.styleable#View_paddingLeft
16261      * @attr ref android.R.styleable#View_paddingRight
16262      * @attr ref android.R.styleable#View_paddingTop
16263      * @param left the left padding in pixels
16264      * @param top the top padding in pixels
16265      * @param right the right padding in pixels
16266      * @param bottom the bottom padding in pixels
16267      */
16268     public void setPadding(int left, int top, int right, int bottom) {
16269         resetResolvedPadding();
16270
16271         mUserPaddingStart = UNDEFINED_PADDING;
16272         mUserPaddingEnd = UNDEFINED_PADDING;
16273
16274         mUserPaddingLeftInitial = left;
16275         mUserPaddingRightInitial = right;
16276
16277         mLeftPaddingDefined = true;
16278         mRightPaddingDefined = true;
16279
16280         internalSetPadding(left, top, right, bottom);
16281     }
16282
16283     /**
16284      * @hide
16285      */
16286     protected void internalSetPadding(int left, int top, int right, int bottom) {
16287         mUserPaddingLeft = left;
16288         mUserPaddingRight = right;
16289         mUserPaddingBottom = bottom;
16290
16291         final int viewFlags = mViewFlags;
16292         boolean changed = false;
16293
16294         // Common case is there are no scroll bars.
16295         if ((viewFlags & (SCROLLBARS_VERTICAL|SCROLLBARS_HORIZONTAL)) != 0) {
16296             if ((viewFlags & SCROLLBARS_VERTICAL) != 0) {
16297                 final int offset = (viewFlags & SCROLLBARS_INSET_MASK) == 0
16298                         ? 0 : getVerticalScrollbarWidth();
16299                 switch (mVerticalScrollbarPosition) {
16300                     case SCROLLBAR_POSITION_DEFAULT:
16301                         if (isLayoutRtl()) {
16302                             left += offset;
16303                         } else {
16304                             right += offset;
16305                         }
16306                         break;
16307                     case SCROLLBAR_POSITION_RIGHT:
16308                         right += offset;
16309                         break;
16310                     case SCROLLBAR_POSITION_LEFT:
16311                         left += offset;
16312                         break;
16313                 }
16314             }
16315             if ((viewFlags & SCROLLBARS_HORIZONTAL) != 0) {
16316                 bottom += (viewFlags & SCROLLBARS_INSET_MASK) == 0
16317                         ? 0 : getHorizontalScrollbarHeight();
16318             }
16319         }
16320
16321         if (mPaddingLeft != left) {
16322             changed = true;
16323             mPaddingLeft = left;
16324         }
16325         if (mPaddingTop != top) {
16326             changed = true;
16327             mPaddingTop = top;
16328         }
16329         if (mPaddingRight != right) {
16330             changed = true;
16331             mPaddingRight = right;
16332         }
16333         if (mPaddingBottom != bottom) {
16334             changed = true;
16335             mPaddingBottom = bottom;
16336         }
16337
16338         if (changed) {
16339             requestLayout();
16340         }
16341     }
16342
16343     /**
16344      * Sets the relative padding. The view may add on the space required to display
16345      * the scrollbars, depending on the style and visibility of the scrollbars.
16346      * So the values returned from {@link #getPaddingStart}, {@link #getPaddingTop},
16347      * {@link #getPaddingEnd} and {@link #getPaddingBottom} may be different
16348      * from the values set in this call.
16349      *
16350      * @attr ref android.R.styleable#View_padding
16351      * @attr ref android.R.styleable#View_paddingBottom
16352      * @attr ref android.R.styleable#View_paddingStart
16353      * @attr ref android.R.styleable#View_paddingEnd
16354      * @attr ref android.R.styleable#View_paddingTop
16355      * @param start the start padding in pixels
16356      * @param top the top padding in pixels
16357      * @param end the end padding in pixels
16358      * @param bottom the bottom padding in pixels
16359      */
16360     public void setPaddingRelative(int start, int top, int end, int bottom) {
16361         resetResolvedPadding();
16362
16363         mUserPaddingStart = start;
16364         mUserPaddingEnd = end;
16365         mLeftPaddingDefined = true;
16366         mRightPaddingDefined = true;
16367
16368         switch(getLayoutDirection()) {
16369             case LAYOUT_DIRECTION_RTL:
16370                 mUserPaddingLeftInitial = end;
16371                 mUserPaddingRightInitial = start;
16372                 internalSetPadding(end, top, start, bottom);
16373                 break;
16374             case LAYOUT_DIRECTION_LTR:
16375             default:
16376                 mUserPaddingLeftInitial = start;
16377                 mUserPaddingRightInitial = end;
16378                 internalSetPadding(start, top, end, bottom);
16379         }
16380     }
16381
16382     /**
16383      * Returns the top padding of this view.
16384      *
16385      * @return the top padding in pixels
16386      */
16387     public int getPaddingTop() {
16388         return mPaddingTop;
16389     }
16390
16391     /**
16392      * Returns the bottom padding of this view. If there are inset and enabled
16393      * scrollbars, this value may include the space required to display the
16394      * scrollbars as well.
16395      *
16396      * @return the bottom padding in pixels
16397      */
16398     public int getPaddingBottom() {
16399         return mPaddingBottom;
16400     }
16401
16402     /**
16403      * Returns the left padding of this view. If there are inset and enabled
16404      * scrollbars, this value may include the space required to display the
16405      * scrollbars as well.
16406      *
16407      * @return the left padding in pixels
16408      */
16409     public int getPaddingLeft() {
16410         if (!isPaddingResolved()) {
16411             resolvePadding();
16412         }
16413         return mPaddingLeft;
16414     }
16415
16416     /**
16417      * Returns the start padding of this view depending on its resolved layout direction.
16418      * If there are inset and enabled scrollbars, this value may include the space
16419      * required to display the scrollbars as well.
16420      *
16421      * @return the start padding in pixels
16422      */
16423     public int getPaddingStart() {
16424         if (!isPaddingResolved()) {
16425             resolvePadding();
16426         }
16427         return (getLayoutDirection() == LAYOUT_DIRECTION_RTL) ?
16428                 mPaddingRight : mPaddingLeft;
16429     }
16430
16431     /**
16432      * Returns the right padding of this view. If there are inset and enabled
16433      * scrollbars, this value may include the space required to display the
16434      * scrollbars as well.
16435      *
16436      * @return the right padding in pixels
16437      */
16438     public int getPaddingRight() {
16439         if (!isPaddingResolved()) {
16440             resolvePadding();
16441         }
16442         return mPaddingRight;
16443     }
16444
16445     /**
16446      * Returns the end padding of this view depending on its resolved layout direction.
16447      * If there are inset and enabled scrollbars, this value may include the space
16448      * required to display the scrollbars as well.
16449      *
16450      * @return the end padding in pixels
16451      */
16452     public int getPaddingEnd() {
16453         if (!isPaddingResolved()) {
16454             resolvePadding();
16455         }
16456         return (getLayoutDirection() == LAYOUT_DIRECTION_RTL) ?
16457                 mPaddingLeft : mPaddingRight;
16458     }
16459
16460     /**
16461      * Return if the padding as been set thru relative values
16462      * {@link #setPaddingRelative(int, int, int, int)} or thru
16463      * @attr ref android.R.styleable#View_paddingStart or
16464      * @attr ref android.R.styleable#View_paddingEnd
16465      *
16466      * @return true if the padding is relative or false if it is not.
16467      */
16468     public boolean isPaddingRelative() {
16469         return (mUserPaddingStart != UNDEFINED_PADDING || mUserPaddingEnd != UNDEFINED_PADDING);
16470     }
16471
16472     Insets computeOpticalInsets() {
16473         return (mBackground == null) ? Insets.NONE : mBackground.getOpticalInsets();
16474     }
16475
16476     /**
16477      * @hide
16478      */
16479     public void resetPaddingToInitialValues() {
16480         if (isRtlCompatibilityMode()) {
16481             mPaddingLeft = mUserPaddingLeftInitial;
16482             mPaddingRight = mUserPaddingRightInitial;
16483             return;
16484         }
16485         if (isLayoutRtl()) {
16486             mPaddingLeft = (mUserPaddingEnd >= 0) ? mUserPaddingEnd : mUserPaddingLeftInitial;
16487             mPaddingRight = (mUserPaddingStart >= 0) ? mUserPaddingStart : mUserPaddingRightInitial;
16488         } else {
16489             mPaddingLeft = (mUserPaddingStart >= 0) ? mUserPaddingStart : mUserPaddingLeftInitial;
16490             mPaddingRight = (mUserPaddingEnd >= 0) ? mUserPaddingEnd : mUserPaddingRightInitial;
16491         }
16492     }
16493
16494     /**
16495      * @hide
16496      */
16497     public Insets getOpticalInsets() {
16498         if (mLayoutInsets == null) {
16499             mLayoutInsets = computeOpticalInsets();
16500         }
16501         return mLayoutInsets;
16502     }
16503
16504     /**
16505      * Set this view's optical insets.
16506      *
16507      * <p>This method should be treated similarly to setMeasuredDimension and not as a general
16508      * property. Views that compute their own optical insets should call it as part of measurement.
16509      * This method does not request layout. If you are setting optical insets outside of
16510      * measure/layout itself you will want to call requestLayout() yourself.
16511      * </p>
16512      * @hide
16513      */
16514     public void setOpticalInsets(Insets insets) {
16515         mLayoutInsets = insets;
16516     }
16517
16518     /**
16519      * Changes the selection state of this view. A view can be selected or not.
16520      * Note that selection is not the same as focus. Views are typically
16521      * selected in the context of an AdapterView like ListView or GridView;
16522      * the selected view is the view that is highlighted.
16523      *
16524      * @param selected true if the view must be selected, false otherwise
16525      */
16526     public void setSelected(boolean selected) {
16527         //noinspection DoubleNegation
16528         if (((mPrivateFlags & PFLAG_SELECTED) != 0) != selected) {
16529             mPrivateFlags = (mPrivateFlags & ~PFLAG_SELECTED) | (selected ? PFLAG_SELECTED : 0);
16530             if (!selected) resetPressedState();
16531             invalidate(true);
16532             refreshDrawableState();
16533             dispatchSetSelected(selected);
16534             notifyViewAccessibilityStateChangedIfNeeded(
16535                     AccessibilityEvent.CONTENT_CHANGE_TYPE_UNDEFINED);
16536         }
16537     }
16538
16539     /**
16540      * Dispatch setSelected to all of this View's children.
16541      *
16542      * @see #setSelected(boolean)
16543      *
16544      * @param selected The new selected state
16545      */
16546     protected void dispatchSetSelected(boolean selected) {
16547     }
16548
16549     /**
16550      * Indicates the selection state of this view.
16551      *
16552      * @return true if the view is selected, false otherwise
16553      */
16554     @ViewDebug.ExportedProperty
16555     public boolean isSelected() {
16556         return (mPrivateFlags & PFLAG_SELECTED) != 0;
16557     }
16558
16559     /**
16560      * Changes the activated state of this view. A view can be activated or not.
16561      * Note that activation is not the same as selection.  Selection is
16562      * a transient property, representing the view (hierarchy) the user is
16563      * currently interacting with.  Activation is a longer-term state that the
16564      * user can move views in and out of.  For example, in a list view with
16565      * single or multiple selection enabled, the views in the current selection
16566      * set are activated.  (Um, yeah, we are deeply sorry about the terminology
16567      * here.)  The activated state is propagated down to children of the view it
16568      * is set on.
16569      *
16570      * @param activated true if the view must be activated, false otherwise
16571      */
16572     public void setActivated(boolean activated) {
16573         //noinspection DoubleNegation
16574         if (((mPrivateFlags & PFLAG_ACTIVATED) != 0) != activated) {
16575             mPrivateFlags = (mPrivateFlags & ~PFLAG_ACTIVATED) | (activated ? PFLAG_ACTIVATED : 0);
16576             invalidate(true);
16577             refreshDrawableState();
16578             dispatchSetActivated(activated);
16579         }
16580     }
16581
16582     /**
16583      * Dispatch setActivated to all of this View's children.
16584      *
16585      * @see #setActivated(boolean)
16586      *
16587      * @param activated The new activated state
16588      */
16589     protected void dispatchSetActivated(boolean activated) {
16590     }
16591
16592     /**
16593      * Indicates the activation state of this view.
16594      *
16595      * @return true if the view is activated, false otherwise
16596      */
16597     @ViewDebug.ExportedProperty
16598     public boolean isActivated() {
16599         return (mPrivateFlags & PFLAG_ACTIVATED) != 0;
16600     }
16601
16602     /**
16603      * Returns the ViewTreeObserver for this view's hierarchy. The view tree
16604      * observer can be used to get notifications when global events, like
16605      * layout, happen.
16606      *
16607      * The returned ViewTreeObserver observer is not guaranteed to remain
16608      * valid for the lifetime of this View. If the caller of this method keeps
16609      * a long-lived reference to ViewTreeObserver, it should always check for
16610      * the return value of {@link ViewTreeObserver#isAlive()}.
16611      *
16612      * @return The ViewTreeObserver for this view's hierarchy.
16613      */
16614     public ViewTreeObserver getViewTreeObserver() {
16615         if (mAttachInfo != null) {
16616             return mAttachInfo.mTreeObserver;
16617         }
16618         if (mFloatingTreeObserver == null) {
16619             mFloatingTreeObserver = new ViewTreeObserver();
16620         }
16621         return mFloatingTreeObserver;
16622     }
16623
16624     /**
16625      * <p>Finds the topmost view in the current view hierarchy.</p>
16626      *
16627      * @return the topmost view containing this view
16628      */
16629     public View getRootView() {
16630         if (mAttachInfo != null) {
16631             final View v = mAttachInfo.mRootView;
16632             if (v != null) {
16633                 return v;
16634             }
16635         }
16636
16637         View parent = this;
16638
16639         while (parent.mParent != null && parent.mParent instanceof View) {
16640             parent = (View) parent.mParent;
16641         }
16642
16643         return parent;
16644     }
16645
16646     /**
16647      * Transforms a motion event from view-local coordinates to on-screen
16648      * coordinates.
16649      *
16650      * @param ev the view-local motion event
16651      * @return false if the transformation could not be applied
16652      * @hide
16653      */
16654     public boolean toGlobalMotionEvent(MotionEvent ev) {
16655         final AttachInfo info = mAttachInfo;
16656         if (info == null) {
16657             return false;
16658         }
16659
16660         final Matrix m = info.mTmpMatrix;
16661         m.set(Matrix.IDENTITY_MATRIX);
16662         transformMatrixToGlobal(m);
16663         ev.transform(m);
16664         return true;
16665     }
16666
16667     /**
16668      * Transforms a motion event from on-screen coordinates to view-local
16669      * coordinates.
16670      *
16671      * @param ev the on-screen motion event
16672      * @return false if the transformation could not be applied
16673      * @hide
16674      */
16675     public boolean toLocalMotionEvent(MotionEvent ev) {
16676         final AttachInfo info = mAttachInfo;
16677         if (info == null) {
16678             return false;
16679         }
16680
16681         final Matrix m = info.mTmpMatrix;
16682         m.set(Matrix.IDENTITY_MATRIX);
16683         transformMatrixToLocal(m);
16684         ev.transform(m);
16685         return true;
16686     }
16687
16688     /**
16689      * Modifies the input matrix such that it maps view-local coordinates to
16690      * on-screen coordinates.
16691      *
16692      * @param m input matrix to modify
16693      * @hide
16694      */
16695     public void transformMatrixToGlobal(Matrix m) {
16696         final ViewParent parent = mParent;
16697         if (parent instanceof View) {
16698             final View vp = (View) parent;
16699             vp.transformMatrixToGlobal(m);
16700             m.preTranslate(-vp.mScrollX, -vp.mScrollY);
16701         } else if (parent instanceof ViewRootImpl) {
16702             final ViewRootImpl vr = (ViewRootImpl) parent;
16703             vr.transformMatrixToGlobal(m);
16704             m.preTranslate(0, -vr.mCurScrollY);
16705         }
16706
16707         m.preTranslate(mLeft, mTop);
16708
16709         if (!hasIdentityMatrix()) {
16710             m.preConcat(getMatrix());
16711         }
16712     }
16713
16714     /**
16715      * Modifies the input matrix such that it maps on-screen coordinates to
16716      * view-local coordinates.
16717      *
16718      * @param m input matrix to modify
16719      * @hide
16720      */
16721     public void transformMatrixToLocal(Matrix m) {
16722         final ViewParent parent = mParent;
16723         if (parent instanceof View) {
16724             final View vp = (View) parent;
16725             vp.transformMatrixToLocal(m);
16726             m.postTranslate(vp.mScrollX, vp.mScrollY);
16727         } else if (parent instanceof ViewRootImpl) {
16728             final ViewRootImpl vr = (ViewRootImpl) parent;
16729             vr.transformMatrixToLocal(m);
16730             m.postTranslate(0, vr.mCurScrollY);
16731         }
16732
16733         m.postTranslate(-mLeft, -mTop);
16734
16735         if (!hasIdentityMatrix()) {
16736             m.postConcat(getInverseMatrix());
16737         }
16738     }
16739
16740     /**
16741      * @hide
16742      */
16743     @ViewDebug.ExportedProperty(category = "layout", indexMapping = {
16744             @ViewDebug.IntToString(from = 0, to = "x"),
16745             @ViewDebug.IntToString(from = 1, to = "y")
16746     })
16747     public int[] getLocationOnScreen() {
16748         int[] location = new int[2];
16749         getLocationOnScreen(location);
16750         return location;
16751     }
16752
16753     /**
16754      * <p>Computes the coordinates of this view on the screen. The argument
16755      * must be an array of two integers. After the method returns, the array
16756      * contains the x and y location in that order.</p>
16757      *
16758      * @param location an array of two integers in which to hold the coordinates
16759      */
16760     public void getLocationOnScreen(int[] location) {
16761         getLocationInWindow(location);
16762
16763         final AttachInfo info = mAttachInfo;
16764         if (info != null) {
16765             location[0] += info.mWindowLeft;
16766             location[1] += info.mWindowTop;
16767         }
16768     }
16769
16770     /**
16771      * <p>Computes the coordinates of this view in its window. The argument
16772      * must be an array of two integers. After the method returns, the array
16773      * contains the x and y location in that order.</p>
16774      *
16775      * @param location an array of two integers in which to hold the coordinates
16776      */
16777     public void getLocationInWindow(int[] location) {
16778         if (location == null || location.length < 2) {
16779             throw new IllegalArgumentException("location must be an array of two integers");
16780         }
16781
16782         if (mAttachInfo == null) {
16783             // When the view is not attached to a window, this method does not make sense
16784             location[0] = location[1] = 0;
16785             return;
16786         }
16787
16788         float[] position = mAttachInfo.mTmpTransformLocation;
16789         position[0] = position[1] = 0.0f;
16790
16791         if (!hasIdentityMatrix()) {
16792             getMatrix().mapPoints(position);
16793         }
16794
16795         position[0] += mLeft;
16796         position[1] += mTop;
16797
16798         ViewParent viewParent = mParent;
16799         while (viewParent instanceof View) {
16800             final View view = (View) viewParent;
16801
16802             position[0] -= view.mScrollX;
16803             position[1] -= view.mScrollY;
16804
16805             if (!view.hasIdentityMatrix()) {
16806                 view.getMatrix().mapPoints(position);
16807             }
16808
16809             position[0] += view.mLeft;
16810             position[1] += view.mTop;
16811
16812             viewParent = view.mParent;
16813          }
16814
16815         if (viewParent instanceof ViewRootImpl) {
16816             // *cough*
16817             final ViewRootImpl vr = (ViewRootImpl) viewParent;
16818             position[1] -= vr.mCurScrollY;
16819         }
16820
16821         location[0] = (int) (position[0] + 0.5f);
16822         location[1] = (int) (position[1] + 0.5f);
16823     }
16824
16825     /**
16826      * {@hide}
16827      * @param id the id of the view to be found
16828      * @return the view of the specified id, null if cannot be found
16829      */
16830     protected View findViewTraversal(int id) {
16831         if (id == mID) {
16832             return this;
16833         }
16834         return null;
16835     }
16836
16837     /**
16838      * {@hide}
16839      * @param tag the tag of the view to be found
16840      * @return the view of specified tag, null if cannot be found
16841      */
16842     protected View findViewWithTagTraversal(Object tag) {
16843         if (tag != null && tag.equals(mTag)) {
16844             return this;
16845         }
16846         return null;
16847     }
16848
16849     /**
16850      * {@hide}
16851      * @param predicate The predicate to evaluate.
16852      * @param childToSkip If not null, ignores this child during the recursive traversal.
16853      * @return The first view that matches the predicate or null.
16854      */
16855     protected View findViewByPredicateTraversal(Predicate<View> predicate, View childToSkip) {
16856         if (predicate.apply(this)) {
16857             return this;
16858         }
16859         return null;
16860     }
16861
16862     /**
16863      * Look for a child view with the given id.  If this view has the given
16864      * id, return this view.
16865      *
16866      * @param id The id to search for.
16867      * @return The view that has the given id in the hierarchy or null
16868      */
16869     public final View findViewById(int id) {
16870         if (id < 0) {
16871             return null;
16872         }
16873         return findViewTraversal(id);
16874     }
16875
16876     /**
16877      * Finds a view by its unuque and stable accessibility id.
16878      *
16879      * @param accessibilityId The searched accessibility id.
16880      * @return The found view.
16881      */
16882     final View findViewByAccessibilityId(int accessibilityId) {
16883         if (accessibilityId < 0) {
16884             return null;
16885         }
16886         return findViewByAccessibilityIdTraversal(accessibilityId);
16887     }
16888
16889     /**
16890      * Performs the traversal to find a view by its unuque and stable accessibility id.
16891      *
16892      * <strong>Note:</strong>This method does not stop at the root namespace
16893      * boundary since the user can touch the screen at an arbitrary location
16894      * potentially crossing the root namespace bounday which will send an
16895      * accessibility event to accessibility services and they should be able
16896      * to obtain the event source. Also accessibility ids are guaranteed to be
16897      * unique in the window.
16898      *
16899      * @param accessibilityId The accessibility id.
16900      * @return The found view.
16901      *
16902      * @hide
16903      */
16904     public View findViewByAccessibilityIdTraversal(int accessibilityId) {
16905         if (getAccessibilityViewId() == accessibilityId) {
16906             return this;
16907         }
16908         return null;
16909     }
16910
16911     /**
16912      * Look for a child view with the given tag.  If this view has the given
16913      * tag, return this view.
16914      *
16915      * @param tag The tag to search for, using "tag.equals(getTag())".
16916      * @return The View that has the given tag in the hierarchy or null
16917      */
16918     public final View findViewWithTag(Object tag) {
16919         if (tag == null) {
16920             return null;
16921         }
16922         return findViewWithTagTraversal(tag);
16923     }
16924
16925     /**
16926      * {@hide}
16927      * Look for a child view that matches the specified predicate.
16928      * If this view matches the predicate, return this view.
16929      *
16930      * @param predicate The predicate to evaluate.
16931      * @return The first view that matches the predicate or null.
16932      */
16933     public final View findViewByPredicate(Predicate<View> predicate) {
16934         return findViewByPredicateTraversal(predicate, null);
16935     }
16936
16937     /**
16938      * {@hide}
16939      * Look for a child view that matches the specified predicate,
16940      * starting with the specified view and its descendents and then
16941      * recusively searching the ancestors and siblings of that view
16942      * until this view is reached.
16943      *
16944      * This method is useful in cases where the predicate does not match
16945      * a single unique view (perhaps multiple views use the same id)
16946      * and we are trying to find the view that is "closest" in scope to the
16947      * starting view.
16948      *
16949      * @param start The view to start from.
16950      * @param predicate The predicate to evaluate.
16951      * @return The first view that matches the predicate or null.
16952      */
16953     public final View findViewByPredicateInsideOut(View start, Predicate<View> predicate) {
16954         View childToSkip = null;
16955         for (;;) {
16956             View view = start.findViewByPredicateTraversal(predicate, childToSkip);
16957             if (view != null || start == this) {
16958                 return view;
16959             }
16960
16961             ViewParent parent = start.getParent();
16962             if (parent == null || !(parent instanceof View)) {
16963                 return null;
16964             }
16965
16966             childToSkip = start;
16967             start = (View) parent;
16968         }
16969     }
16970
16971     /**
16972      * Sets the identifier for this view. The identifier does not have to be
16973      * unique in this view's hierarchy. The identifier should be a positive
16974      * number.
16975      *
16976      * @see #NO_ID
16977      * @see #getId()
16978      * @see #findViewById(int)
16979      *
16980      * @param id a number used to identify the view
16981      *
16982      * @attr ref android.R.styleable#View_id
16983      */
16984     public void setId(int id) {
16985         mID = id;
16986         if (mID == View.NO_ID && mLabelForId != View.NO_ID) {
16987             mID = generateViewId();
16988         }
16989     }
16990
16991     /**
16992      * {@hide}
16993      *
16994      * @param isRoot true if the view belongs to the root namespace, false
16995      *        otherwise
16996      */
16997     public void setIsRootNamespace(boolean isRoot) {
16998         if (isRoot) {
16999             mPrivateFlags |= PFLAG_IS_ROOT_NAMESPACE;
17000         } else {
17001             mPrivateFlags &= ~PFLAG_IS_ROOT_NAMESPACE;
17002         }
17003     }
17004
17005     /**
17006      * {@hide}
17007      *
17008      * @return true if the view belongs to the root namespace, false otherwise
17009      */
17010     public boolean isRootNamespace() {
17011         return (mPrivateFlags&PFLAG_IS_ROOT_NAMESPACE) != 0;
17012     }
17013
17014     /**
17015      * Returns this view's identifier.
17016      *
17017      * @return a positive integer used to identify the view or {@link #NO_ID}
17018      *         if the view has no ID
17019      *
17020      * @see #setId(int)
17021      * @see #findViewById(int)
17022      * @attr ref android.R.styleable#View_id
17023      */
17024     @ViewDebug.CapturedViewProperty
17025     public int getId() {
17026         return mID;
17027     }
17028
17029     /**
17030      * Returns this view's tag.
17031      *
17032      * @return the Object stored in this view as a tag, or {@code null} if not
17033      *         set
17034      *
17035      * @see #setTag(Object)
17036      * @see #getTag(int)
17037      */
17038     @ViewDebug.ExportedProperty
17039     public Object getTag() {
17040         return mTag;
17041     }
17042
17043     /**
17044      * Sets the tag associated with this view. A tag can be used to mark
17045      * a view in its hierarchy and does not have to be unique within the
17046      * hierarchy. Tags can also be used to store data within a view without
17047      * resorting to another data structure.
17048      *
17049      * @param tag an Object to tag the view with
17050      *
17051      * @see #getTag()
17052      * @see #setTag(int, Object)
17053      */
17054     public void setTag(final Object tag) {
17055         mTag = tag;
17056     }
17057
17058     /**
17059      * Returns the tag associated with this view and the specified key.
17060      *
17061      * @param key The key identifying the tag
17062      *
17063      * @return the Object stored in this view as a tag, or {@code null} if not
17064      *         set
17065      *
17066      * @see #setTag(int, Object)
17067      * @see #getTag()
17068      */
17069     public Object getTag(int key) {
17070         if (mKeyedTags != null) return mKeyedTags.get(key);
17071         return null;
17072     }
17073
17074     /**
17075      * Sets a tag associated with this view and a key. A tag can be used
17076      * to mark a view in its hierarchy and does not have to be unique within
17077      * the hierarchy. Tags can also be used to store data within a view
17078      * without resorting to another data structure.
17079      *
17080      * The specified key should be an id declared in the resources of the
17081      * application to ensure it is unique (see the <a
17082      * href={@docRoot}guide/topics/resources/more-resources.html#Id">ID resource type</a>).
17083      * Keys identified as belonging to
17084      * the Android framework or not associated with any package will cause
17085      * an {@link IllegalArgumentException} to be thrown.
17086      *
17087      * @param key The key identifying the tag
17088      * @param tag An Object to tag the view with
17089      *
17090      * @throws IllegalArgumentException If they specified key is not valid
17091      *
17092      * @see #setTag(Object)
17093      * @see #getTag(int)
17094      */
17095     public void setTag(int key, final Object tag) {
17096         // If the package id is 0x00 or 0x01, it's either an undefined package
17097         // or a framework id
17098         if ((key >>> 24) < 2) {
17099             throw new IllegalArgumentException("The key must be an application-specific "
17100                     + "resource id.");
17101         }
17102
17103         setKeyedTag(key, tag);
17104     }
17105
17106     /**
17107      * Variation of {@link #setTag(int, Object)} that enforces the key to be a
17108      * framework id.
17109      *
17110      * @hide
17111      */
17112     public void setTagInternal(int key, Object tag) {
17113         if ((key >>> 24) != 0x1) {
17114             throw new IllegalArgumentException("The key must be a framework-specific "
17115                     + "resource id.");
17116         }
17117
17118         setKeyedTag(key, tag);
17119     }
17120
17121     private void setKeyedTag(int key, Object tag) {
17122         if (mKeyedTags == null) {
17123             mKeyedTags = new SparseArray<Object>(2);
17124         }
17125
17126         mKeyedTags.put(key, tag);
17127     }
17128
17129     /**
17130      * Prints information about this view in the log output, with the tag
17131      * {@link #VIEW_LOG_TAG}.
17132      *
17133      * @hide
17134      */
17135     public void debug() {
17136         debug(0);
17137     }
17138
17139     /**
17140      * Prints information about this view in the log output, with the tag
17141      * {@link #VIEW_LOG_TAG}. Each line in the output is preceded with an
17142      * indentation defined by the <code>depth</code>.
17143      *
17144      * @param depth the indentation level
17145      *
17146      * @hide
17147      */
17148     protected void debug(int depth) {
17149         String output = debugIndent(depth - 1);
17150
17151         output += "+ " + this;
17152         int id = getId();
17153         if (id != -1) {
17154             output += " (id=" + id + ")";
17155         }
17156         Object tag = getTag();
17157         if (tag != null) {
17158             output += " (tag=" + tag + ")";
17159         }
17160         Log.d(VIEW_LOG_TAG, output);
17161
17162         if ((mPrivateFlags & PFLAG_FOCUSED) != 0) {
17163             output = debugIndent(depth) + " FOCUSED";
17164             Log.d(VIEW_LOG_TAG, output);
17165         }
17166
17167         output = debugIndent(depth);
17168         output += "frame={" + mLeft + ", " + mTop + ", " + mRight
17169                 + ", " + mBottom + "} scroll={" + mScrollX + ", " + mScrollY
17170                 + "} ";
17171         Log.d(VIEW_LOG_TAG, output);
17172
17173         if (mPaddingLeft != 0 || mPaddingTop != 0 || mPaddingRight != 0
17174                 || mPaddingBottom != 0) {
17175             output = debugIndent(depth);
17176             output += "padding={" + mPaddingLeft + ", " + mPaddingTop
17177                     + ", " + mPaddingRight + ", " + mPaddingBottom + "}";
17178             Log.d(VIEW_LOG_TAG, output);
17179         }
17180
17181         output = debugIndent(depth);
17182         output += "mMeasureWidth=" + mMeasuredWidth +
17183                 " mMeasureHeight=" + mMeasuredHeight;
17184         Log.d(VIEW_LOG_TAG, output);
17185
17186         output = debugIndent(depth);
17187         if (mLayoutParams == null) {
17188             output += "BAD! no layout params";
17189         } else {
17190             output = mLayoutParams.debug(output);
17191         }
17192         Log.d(VIEW_LOG_TAG, output);
17193
17194         output = debugIndent(depth);
17195         output += "flags={";
17196         output += View.printFlags(mViewFlags);
17197         output += "}";
17198         Log.d(VIEW_LOG_TAG, output);
17199
17200         output = debugIndent(depth);
17201         output += "privateFlags={";
17202         output += View.printPrivateFlags(mPrivateFlags);
17203         output += "}";
17204         Log.d(VIEW_LOG_TAG, output);
17205     }
17206
17207     /**
17208      * Creates a string of whitespaces used for indentation.
17209      *
17210      * @param depth the indentation level
17211      * @return a String containing (depth * 2 + 3) * 2 white spaces
17212      *
17213      * @hide
17214      */
17215     protected static String debugIndent(int depth) {
17216         StringBuilder spaces = new StringBuilder((depth * 2 + 3) * 2);
17217         for (int i = 0; i < (depth * 2) + 3; i++) {
17218             spaces.append(' ').append(' ');
17219         }
17220         return spaces.toString();
17221     }
17222
17223     /**
17224      * <p>Return the offset of the widget's text baseline from the widget's top
17225      * boundary. If this widget does not support baseline alignment, this
17226      * method returns -1. </p>
17227      *
17228      * @return the offset of the baseline within the widget's bounds or -1
17229      *         if baseline alignment is not supported
17230      */
17231     @ViewDebug.ExportedProperty(category = "layout")
17232     public int getBaseline() {
17233         return -1;
17234     }
17235
17236     /**
17237      * Returns whether the view hierarchy is currently undergoing a layout pass. This
17238      * information is useful to avoid situations such as calling {@link #requestLayout()} during
17239      * a layout pass.
17240      *
17241      * @return whether the view hierarchy is currently undergoing a layout pass
17242      */
17243     public boolean isInLayout() {
17244         ViewRootImpl viewRoot = getViewRootImpl();
17245         return (viewRoot != null && viewRoot.isInLayout());
17246     }
17247
17248     /**
17249      * Call this when something has changed which has invalidated the
17250      * layout of this view. This will schedule a layout pass of the view
17251      * tree. This should not be called while the view hierarchy is currently in a layout
17252      * pass ({@link #isInLayout()}. If layout is happening, the request may be honored at the
17253      * end of the current layout pass (and then layout will run again) or after the current
17254      * frame is drawn and the next layout occurs.
17255      *
17256      * <p>Subclasses which override this method should call the superclass method to
17257      * handle possible request-during-layout errors correctly.</p>
17258      */
17259     public void requestLayout() {
17260         if (mMeasureCache != null) mMeasureCache.clear();
17261
17262         if (mAttachInfo != null && mAttachInfo.mViewRequestingLayout == null) {
17263             // Only trigger request-during-layout logic if this is the view requesting it,
17264             // not the views in its parent hierarchy
17265             ViewRootImpl viewRoot = getViewRootImpl();
17266             if (viewRoot != null && viewRoot.isInLayout()) {
17267                 if (!viewRoot.requestLayoutDuringLayout(this)) {
17268                     return;
17269                 }
17270             }
17271             mAttachInfo.mViewRequestingLayout = this;
17272         }
17273
17274         mPrivateFlags |= PFLAG_FORCE_LAYOUT;
17275         mPrivateFlags |= PFLAG_INVALIDATED;
17276
17277         if (mParent != null && !mParent.isLayoutRequested()) {
17278             mParent.requestLayout();
17279         }
17280         if (mAttachInfo != null && mAttachInfo.mViewRequestingLayout == this) {
17281             mAttachInfo.mViewRequestingLayout = null;
17282         }
17283     }
17284
17285     /**
17286      * Forces this view to be laid out during the next layout pass.
17287      * This method does not call requestLayout() or forceLayout()
17288      * on the parent.
17289      */
17290     public void forceLayout() {
17291         if (mMeasureCache != null) mMeasureCache.clear();
17292
17293         mPrivateFlags |= PFLAG_FORCE_LAYOUT;
17294         mPrivateFlags |= PFLAG_INVALIDATED;
17295     }
17296
17297     /**
17298      * <p>
17299      * This is called to find out how big a view should be. The parent
17300      * supplies constraint information in the width and height parameters.
17301      * </p>
17302      *
17303      * <p>
17304      * The actual measurement work of a view is performed in
17305      * {@link #onMeasure(int, int)}, called by this method. Therefore, only
17306      * {@link #onMeasure(int, int)} can and must be overridden by subclasses.
17307      * </p>
17308      *
17309      *
17310      * @param widthMeasureSpec Horizontal space requirements as imposed by the
17311      *        parent
17312      * @param heightMeasureSpec Vertical space requirements as imposed by the
17313      *        parent
17314      *
17315      * @see #onMeasure(int, int)
17316      */
17317     public final void measure(int widthMeasureSpec, int heightMeasureSpec) {
17318         boolean optical = isLayoutModeOptical(this);
17319         if (optical != isLayoutModeOptical(mParent)) {
17320             Insets insets = getOpticalInsets();
17321             int oWidth  = insets.left + insets.right;
17322             int oHeight = insets.top  + insets.bottom;
17323             widthMeasureSpec  = MeasureSpec.adjust(widthMeasureSpec,  optical ? -oWidth  : oWidth);
17324             heightMeasureSpec = MeasureSpec.adjust(heightMeasureSpec, optical ? -oHeight : oHeight);
17325         }
17326
17327         // Suppress sign extension for the low bytes
17328         long key = (long) widthMeasureSpec << 32 | (long) heightMeasureSpec & 0xffffffffL;
17329         if (mMeasureCache == null) mMeasureCache = new LongSparseLongArray(2);
17330
17331         if ((mPrivateFlags & PFLAG_FORCE_LAYOUT) == PFLAG_FORCE_LAYOUT ||
17332                 widthMeasureSpec != mOldWidthMeasureSpec ||
17333                 heightMeasureSpec != mOldHeightMeasureSpec) {
17334
17335             // first clears the measured dimension flag
17336             mPrivateFlags &= ~PFLAG_MEASURED_DIMENSION_SET;
17337
17338             resolveRtlPropertiesIfNeeded();
17339
17340             int cacheIndex = (mPrivateFlags & PFLAG_FORCE_LAYOUT) == PFLAG_FORCE_LAYOUT ? -1 :
17341                     mMeasureCache.indexOfKey(key);
17342             if (cacheIndex < 0 || sIgnoreMeasureCache) {
17343                 // measure ourselves, this should set the measured dimension flag back
17344                 onMeasure(widthMeasureSpec, heightMeasureSpec);
17345                 mPrivateFlags3 &= ~PFLAG3_MEASURE_NEEDED_BEFORE_LAYOUT;
17346             } else {
17347                 long value = mMeasureCache.valueAt(cacheIndex);
17348                 // Casting a long to int drops the high 32 bits, no mask needed
17349                 setMeasuredDimensionRaw((int) (value >> 32), (int) value);
17350                 mPrivateFlags3 |= PFLAG3_MEASURE_NEEDED_BEFORE_LAYOUT;
17351             }
17352
17353             // flag not set, setMeasuredDimension() was not invoked, we raise
17354             // an exception to warn the developer
17355             if ((mPrivateFlags & PFLAG_MEASURED_DIMENSION_SET) != PFLAG_MEASURED_DIMENSION_SET) {
17356                 throw new IllegalStateException("onMeasure() did not set the"
17357                         + " measured dimension by calling"
17358                         + " setMeasuredDimension()");
17359             }
17360
17361             mPrivateFlags |= PFLAG_LAYOUT_REQUIRED;
17362         }
17363
17364         mOldWidthMeasureSpec = widthMeasureSpec;
17365         mOldHeightMeasureSpec = heightMeasureSpec;
17366
17367         mMeasureCache.put(key, ((long) mMeasuredWidth) << 32 |
17368                 (long) mMeasuredHeight & 0xffffffffL); // suppress sign extension
17369     }
17370
17371     /**
17372      * <p>
17373      * Measure the view and its content to determine the measured width and the
17374      * measured height. This method is invoked by {@link #measure(int, int)} and
17375      * should be overriden by subclasses to provide accurate and efficient
17376      * measurement of their contents.
17377      * </p>
17378      *
17379      * <p>
17380      * <strong>CONTRACT:</strong> When overriding this method, you
17381      * <em>must</em> call {@link #setMeasuredDimension(int, int)} to store the
17382      * measured width and height of this view. Failure to do so will trigger an
17383      * <code>IllegalStateException</code>, thrown by
17384      * {@link #measure(int, int)}. Calling the superclass'
17385      * {@link #onMeasure(int, int)} is a valid use.
17386      * </p>
17387      *
17388      * <p>
17389      * The base class implementation of measure defaults to the background size,
17390      * unless a larger size is allowed by the MeasureSpec. Subclasses should
17391      * override {@link #onMeasure(int, int)} to provide better measurements of
17392      * their content.
17393      * </p>
17394      *
17395      * <p>
17396      * If this method is overridden, it is the subclass's responsibility to make
17397      * sure the measured height and width are at least the view's minimum height
17398      * and width ({@link #getSuggestedMinimumHeight()} and
17399      * {@link #getSuggestedMinimumWidth()}).
17400      * </p>
17401      *
17402      * @param widthMeasureSpec horizontal space requirements as imposed by the parent.
17403      *                         The requirements are encoded with
17404      *                         {@link android.view.View.MeasureSpec}.
17405      * @param heightMeasureSpec vertical space requirements as imposed by the parent.
17406      *                         The requirements are encoded with
17407      *                         {@link android.view.View.MeasureSpec}.
17408      *
17409      * @see #getMeasuredWidth()
17410      * @see #getMeasuredHeight()
17411      * @see #setMeasuredDimension(int, int)
17412      * @see #getSuggestedMinimumHeight()
17413      * @see #getSuggestedMinimumWidth()
17414      * @see android.view.View.MeasureSpec#getMode(int)
17415      * @see android.view.View.MeasureSpec#getSize(int)
17416      */
17417     protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
17418         setMeasuredDimension(getDefaultSize(getSuggestedMinimumWidth(), widthMeasureSpec),
17419                 getDefaultSize(getSuggestedMinimumHeight(), heightMeasureSpec));
17420     }
17421
17422     /**
17423      * <p>This method must be called by {@link #onMeasure(int, int)} to store the
17424      * measured width and measured height. Failing to do so will trigger an
17425      * exception at measurement time.</p>
17426      *
17427      * @param measuredWidth The measured width of this view.  May be a complex
17428      * bit mask as defined by {@link #MEASURED_SIZE_MASK} and
17429      * {@link #MEASURED_STATE_TOO_SMALL}.
17430      * @param measuredHeight The measured height of this view.  May be a complex
17431      * bit mask as defined by {@link #MEASURED_SIZE_MASK} and
17432      * {@link #MEASURED_STATE_TOO_SMALL}.
17433      */
17434     protected final void setMeasuredDimension(int measuredWidth, int measuredHeight) {
17435         boolean optical = isLayoutModeOptical(this);
17436         if (optical != isLayoutModeOptical(mParent)) {
17437             Insets insets = getOpticalInsets();
17438             int opticalWidth  = insets.left + insets.right;
17439             int opticalHeight = insets.top  + insets.bottom;
17440
17441             measuredWidth  += optical ? opticalWidth  : -opticalWidth;
17442             measuredHeight += optical ? opticalHeight : -opticalHeight;
17443         }
17444         setMeasuredDimensionRaw(measuredWidth, measuredHeight);
17445     }
17446
17447     /**
17448      * Sets the measured dimension without extra processing for things like optical bounds.
17449      * Useful for reapplying consistent values that have already been cooked with adjustments
17450      * for optical bounds, etc. such as those from the measurement cache.
17451      *
17452      * @param measuredWidth The measured width of this view.  May be a complex
17453      * bit mask as defined by {@link #MEASURED_SIZE_MASK} and
17454      * {@link #MEASURED_STATE_TOO_SMALL}.
17455      * @param measuredHeight The measured height of this view.  May be a complex
17456      * bit mask as defined by {@link #MEASURED_SIZE_MASK} and
17457      * {@link #MEASURED_STATE_TOO_SMALL}.
17458      */
17459     private void setMeasuredDimensionRaw(int measuredWidth, int measuredHeight) {
17460         mMeasuredWidth = measuredWidth;
17461         mMeasuredHeight = measuredHeight;
17462
17463         mPrivateFlags |= PFLAG_MEASURED_DIMENSION_SET;
17464     }
17465
17466     /**
17467      * Merge two states as returned by {@link #getMeasuredState()}.
17468      * @param curState The current state as returned from a view or the result
17469      * of combining multiple views.
17470      * @param newState The new view state to combine.
17471      * @return Returns a new integer reflecting the combination of the two
17472      * states.
17473      */
17474     public static int combineMeasuredStates(int curState, int newState) {
17475         return curState | newState;
17476     }
17477
17478     /**
17479      * Version of {@link #resolveSizeAndState(int, int, int)}
17480      * returning only the {@link #MEASURED_SIZE_MASK} bits of the result.
17481      */
17482     public static int resolveSize(int size, int measureSpec) {
17483         return resolveSizeAndState(size, measureSpec, 0) & MEASURED_SIZE_MASK;
17484     }
17485
17486     /**
17487      * Utility to reconcile a desired size and state, with constraints imposed
17488      * by a MeasureSpec.  Will take the desired size, unless a different size
17489      * is imposed by the constraints.  The returned value is a compound integer,
17490      * with the resolved size in the {@link #MEASURED_SIZE_MASK} bits and
17491      * optionally the bit {@link #MEASURED_STATE_TOO_SMALL} set if the resulting
17492      * size is smaller than the size the view wants to be.
17493      *
17494      * @param size How big the view wants to be
17495      * @param measureSpec Constraints imposed by the parent
17496      * @return Size information bit mask as defined by
17497      * {@link #MEASURED_SIZE_MASK} and {@link #MEASURED_STATE_TOO_SMALL}.
17498      */
17499     public static int resolveSizeAndState(int size, int measureSpec, int childMeasuredState) {
17500         int result = size;
17501         int specMode = MeasureSpec.getMode(measureSpec);
17502         int specSize =  MeasureSpec.getSize(measureSpec);
17503         switch (specMode) {
17504         case MeasureSpec.UNSPECIFIED:
17505             result = size;
17506             break;
17507         case MeasureSpec.AT_MOST:
17508             if (specSize < size) {
17509                 result = specSize | MEASURED_STATE_TOO_SMALL;
17510             } else {
17511                 result = size;
17512             }
17513             break;
17514         case MeasureSpec.EXACTLY:
17515             result = specSize;
17516             break;
17517         }
17518         return result | (childMeasuredState&MEASURED_STATE_MASK);
17519     }
17520
17521     /**
17522      * Utility to return a default size. Uses the supplied size if the
17523      * MeasureSpec imposed no constraints. Will get larger if allowed
17524      * by the MeasureSpec.
17525      *
17526      * @param size Default size for this view
17527      * @param measureSpec Constraints imposed by the parent
17528      * @return The size this view should be.
17529      */
17530     public static int getDefaultSize(int size, int measureSpec) {
17531         int result = size;
17532         int specMode = MeasureSpec.getMode(measureSpec);
17533         int specSize = MeasureSpec.getSize(measureSpec);
17534
17535         switch (specMode) {
17536         case MeasureSpec.UNSPECIFIED:
17537             result = size;
17538             break;
17539         case MeasureSpec.AT_MOST:
17540         case MeasureSpec.EXACTLY:
17541             result = specSize;
17542             break;
17543         }
17544         return result;
17545     }
17546
17547     /**
17548      * Returns the suggested minimum height that the view should use. This
17549      * returns the maximum of the view's minimum height
17550      * and the background's minimum height
17551      * ({@link android.graphics.drawable.Drawable#getMinimumHeight()}).
17552      * <p>
17553      * When being used in {@link #onMeasure(int, int)}, the caller should still
17554      * ensure the returned height is within the requirements of the parent.
17555      *
17556      * @return The suggested minimum height of the view.
17557      */
17558     protected int getSuggestedMinimumHeight() {
17559         return (mBackground == null) ? mMinHeight : max(mMinHeight, mBackground.getMinimumHeight());
17560
17561     }
17562
17563     /**
17564      * Returns the suggested minimum width that the view should use. This
17565      * returns the maximum of the view's minimum width)
17566      * and the background's minimum width
17567      *  ({@link android.graphics.drawable.Drawable#getMinimumWidth()}).
17568      * <p>
17569      * When being used in {@link #onMeasure(int, int)}, the caller should still
17570      * ensure the returned width is within the requirements of the parent.
17571      *
17572      * @return The suggested minimum width of the view.
17573      */
17574     protected int getSuggestedMinimumWidth() {
17575         return (mBackground == null) ? mMinWidth : max(mMinWidth, mBackground.getMinimumWidth());
17576     }
17577
17578     /**
17579      * Returns the minimum height of the view.
17580      *
17581      * @return the minimum height the view will try to be.
17582      *
17583      * @see #setMinimumHeight(int)
17584      *
17585      * @attr ref android.R.styleable#View_minHeight
17586      */
17587     public int getMinimumHeight() {
17588         return mMinHeight;
17589     }
17590
17591     /**
17592      * Sets the minimum height of the view. It is not guaranteed the view will
17593      * be able to achieve this minimum height (for example, if its parent layout
17594      * constrains it with less available height).
17595      *
17596      * @param minHeight The minimum height the view will try to be.
17597      *
17598      * @see #getMinimumHeight()
17599      *
17600      * @attr ref android.R.styleable#View_minHeight
17601      */
17602     public void setMinimumHeight(int minHeight) {
17603         mMinHeight = minHeight;
17604         requestLayout();
17605     }
17606
17607     /**
17608      * Returns the minimum width of the view.
17609      *
17610      * @return the minimum width the view will try to be.
17611      *
17612      * @see #setMinimumWidth(int)
17613      *
17614      * @attr ref android.R.styleable#View_minWidth
17615      */
17616     public int getMinimumWidth() {
17617         return mMinWidth;
17618     }
17619
17620     /**
17621      * Sets the minimum width of the view. It is not guaranteed the view will
17622      * be able to achieve this minimum width (for example, if its parent layout
17623      * constrains it with less available width).
17624      *
17625      * @param minWidth The minimum width the view will try to be.
17626      *
17627      * @see #getMinimumWidth()
17628      *
17629      * @attr ref android.R.styleable#View_minWidth
17630      */
17631     public void setMinimumWidth(int minWidth) {
17632         mMinWidth = minWidth;
17633         requestLayout();
17634
17635     }
17636
17637     /**
17638      * Get the animation currently associated with this view.
17639      *
17640      * @return The animation that is currently playing or
17641      *         scheduled to play for this view.
17642      */
17643     public Animation getAnimation() {
17644         return mCurrentAnimation;
17645     }
17646
17647     /**
17648      * Start the specified animation now.
17649      *
17650      * @param animation the animation to start now
17651      */
17652     public void startAnimation(Animation animation) {
17653         animation.setStartTime(Animation.START_ON_FIRST_FRAME);
17654         setAnimation(animation);
17655         invalidateParentCaches();
17656         invalidate(true);
17657     }
17658
17659     /**
17660      * Cancels any animations for this view.
17661      */
17662     public void clearAnimation() {
17663         if (mCurrentAnimation != null) {
17664             mCurrentAnimation.detach();
17665         }
17666         mCurrentAnimation = null;
17667         invalidateParentIfNeeded();
17668     }
17669
17670     /**
17671      * Sets the next animation to play for this view.
17672      * If you want the animation to play immediately, use
17673      * {@link #startAnimation(android.view.animation.Animation)} instead.
17674      * This method provides allows fine-grained
17675      * control over the start time and invalidation, but you
17676      * must make sure that 1) the animation has a start time set, and
17677      * 2) the view's parent (which controls animations on its children)
17678      * will be invalidated when the animation is supposed to
17679      * start.
17680      *
17681      * @param animation The next animation, or null.
17682      */
17683     public void setAnimation(Animation animation) {
17684         mCurrentAnimation = animation;
17685
17686         if (animation != null) {
17687             // If the screen is off assume the animation start time is now instead of
17688             // the next frame we draw. Keeping the START_ON_FIRST_FRAME start time
17689             // would cause the animation to start when the screen turns back on
17690             if (mAttachInfo != null && mAttachInfo.mDisplayState == Display.STATE_OFF
17691                     && animation.getStartTime() == Animation.START_ON_FIRST_FRAME) {
17692                 animation.setStartTime(AnimationUtils.currentAnimationTimeMillis());
17693             }
17694             animation.reset();
17695         }
17696     }
17697
17698     /**
17699      * Invoked by a parent ViewGroup to notify the start of the animation
17700      * currently associated with this view. If you override this method,
17701      * always call super.onAnimationStart();
17702      *
17703      * @see #setAnimation(android.view.animation.Animation)
17704      * @see #getAnimation()
17705      */
17706     protected void onAnimationStart() {
17707         mPrivateFlags |= PFLAG_ANIMATION_STARTED;
17708     }
17709
17710     /**
17711      * Invoked by a parent ViewGroup to notify the end of the animation
17712      * currently associated with this view. If you override this method,
17713      * always call super.onAnimationEnd();
17714      *
17715      * @see #setAnimation(android.view.animation.Animation)
17716      * @see #getAnimation()
17717      */
17718     protected void onAnimationEnd() {
17719         mPrivateFlags &= ~PFLAG_ANIMATION_STARTED;
17720     }
17721
17722     /**
17723      * Invoked if there is a Transform that involves alpha. Subclass that can
17724      * draw themselves with the specified alpha should return true, and then
17725      * respect that alpha when their onDraw() is called. If this returns false
17726      * then the view may be redirected to draw into an offscreen buffer to
17727      * fulfill the request, which will look fine, but may be slower than if the
17728      * subclass handles it internally. The default implementation returns false.
17729      *
17730      * @param alpha The alpha (0..255) to apply to the view's drawing
17731      * @return true if the view can draw with the specified alpha.
17732      */
17733     protected boolean onSetAlpha(int alpha) {
17734         return false;
17735     }
17736
17737     /**
17738      * This is used by the RootView to perform an optimization when
17739      * the view hierarchy contains one or several SurfaceView.
17740      * SurfaceView is always considered transparent, but its children are not,
17741      * therefore all View objects remove themselves from the global transparent
17742      * region (passed as a parameter to this function).
17743      *
17744      * @param region The transparent region for this ViewAncestor (window).
17745      *
17746      * @return Returns true if the effective visibility of the view at this
17747      * point is opaque, regardless of the transparent region; returns false
17748      * if it is possible for underlying windows to be seen behind the view.
17749      *
17750      * {@hide}
17751      */
17752     public boolean gatherTransparentRegion(Region region) {
17753         final AttachInfo attachInfo = mAttachInfo;
17754         if (region != null && attachInfo != null) {
17755             final int pflags = mPrivateFlags;
17756             if ((pflags & PFLAG_SKIP_DRAW) == 0) {
17757                 // The SKIP_DRAW flag IS NOT set, so this view draws. We need to
17758                 // remove it from the transparent region.
17759                 final int[] location = attachInfo.mTransparentLocation;
17760                 getLocationInWindow(location);
17761                 region.op(location[0], location[1], location[0] + mRight - mLeft,
17762                         location[1] + mBottom - mTop, Region.Op.DIFFERENCE);
17763             } else if ((pflags & PFLAG_ONLY_DRAWS_BACKGROUND) != 0 && mBackground != null &&
17764                     mBackground.getOpacity() != PixelFormat.TRANSPARENT) {
17765                 // The ONLY_DRAWS_BACKGROUND flag IS set and the background drawable
17766                 // exists, so we remove the background drawable's non-transparent
17767                 // parts from this transparent region.
17768                 applyDrawableToTransparentRegion(mBackground, region);
17769             }
17770         }
17771         return true;
17772     }
17773
17774     /**
17775      * Play a sound effect for this view.
17776      *
17777      * <p>The framework will play sound effects for some built in actions, such as
17778      * clicking, but you may wish to play these effects in your widget,
17779      * for instance, for internal navigation.
17780      *
17781      * <p>The sound effect will only be played if sound effects are enabled by the user, and
17782      * {@link #isSoundEffectsEnabled()} is true.
17783      *
17784      * @param soundConstant One of the constants defined in {@link SoundEffectConstants}
17785      */
17786     public void playSoundEffect(int soundConstant) {
17787         if (mAttachInfo == null || mAttachInfo.mRootCallbacks == null || !isSoundEffectsEnabled()) {
17788             return;
17789         }
17790         mAttachInfo.mRootCallbacks.playSoundEffect(soundConstant);
17791     }
17792
17793     /**
17794      * BZZZTT!!1!
17795      *
17796      * <p>Provide haptic feedback to the user for this view.
17797      *
17798      * <p>The framework will provide haptic feedback for some built in actions,
17799      * such as long presses, but you may wish to provide feedback for your
17800      * own widget.
17801      *
17802      * <p>The feedback will only be performed if
17803      * {@link #isHapticFeedbackEnabled()} is true.
17804      *
17805      * @param feedbackConstant One of the constants defined in
17806      * {@link HapticFeedbackConstants}
17807      */
17808     public boolean performHapticFeedback(int feedbackConstant) {
17809         return performHapticFeedback(feedbackConstant, 0);
17810     }
17811
17812     /**
17813      * BZZZTT!!1!
17814      *
17815      * <p>Like {@link #performHapticFeedback(int)}, with additional options.
17816      *
17817      * @param feedbackConstant One of the constants defined in
17818      * {@link HapticFeedbackConstants}
17819      * @param flags Additional flags as per {@link HapticFeedbackConstants}.
17820      */
17821     public boolean performHapticFeedback(int feedbackConstant, int flags) {
17822         if (mAttachInfo == null) {
17823             return false;
17824         }
17825         //noinspection SimplifiableIfStatement
17826         if ((flags & HapticFeedbackConstants.FLAG_IGNORE_VIEW_SETTING) == 0
17827                 && !isHapticFeedbackEnabled()) {
17828             return false;
17829         }
17830         return mAttachInfo.mRootCallbacks.performHapticFeedback(feedbackConstant,
17831                 (flags & HapticFeedbackConstants.FLAG_IGNORE_GLOBAL_SETTING) != 0);
17832     }
17833
17834     /**
17835      * Request that the visibility of the status bar or other screen/window
17836      * decorations be changed.
17837      *
17838      * <p>This method is used to put the over device UI into temporary modes
17839      * where the user's attention is focused more on the application content,
17840      * by dimming or hiding surrounding system affordances.  This is typically
17841      * used in conjunction with {@link Window#FEATURE_ACTION_BAR_OVERLAY
17842      * Window.FEATURE_ACTION_BAR_OVERLAY}, allowing the applications content
17843      * to be placed behind the action bar (and with these flags other system
17844      * affordances) so that smooth transitions between hiding and showing them
17845      * can be done.
17846      *
17847      * <p>Two representative examples of the use of system UI visibility is
17848      * implementing a content browsing application (like a magazine reader)
17849      * and a video playing application.
17850      *
17851      * <p>The first code shows a typical implementation of a View in a content
17852      * browsing application.  In this implementation, the application goes
17853      * into a content-oriented mode by hiding the status bar and action bar,
17854      * and putting the navigation elements into lights out mode.  The user can
17855      * then interact with content while in this mode.  Such an application should
17856      * provide an easy way for the user to toggle out of the mode (such as to
17857      * check information in the status bar or access notifications).  In the
17858      * implementation here, this is done simply by tapping on the content.
17859      *
17860      * {@sample development/samples/ApiDemos/src/com/example/android/apis/view/ContentBrowserActivity.java
17861      *      content}
17862      *
17863      * <p>This second code sample shows a typical implementation of a View
17864      * in a video playing application.  In this situation, while the video is
17865      * playing the application would like to go into a complete full-screen mode,
17866      * to use as much of the display as possible for the video.  When in this state
17867      * the user can not interact with the application; the system intercepts
17868      * touching on the screen to pop the UI out of full screen mode.  See
17869      * {@link #fitSystemWindows(Rect)} for a sample layout that goes with this code.
17870      *
17871      * {@sample development/samples/ApiDemos/src/com/example/android/apis/view/VideoPlayerActivity.java
17872      *      content}
17873      *
17874      * @param visibility  Bitwise-or of flags {@link #SYSTEM_UI_FLAG_LOW_PROFILE},
17875      * {@link #SYSTEM_UI_FLAG_HIDE_NAVIGATION}, {@link #SYSTEM_UI_FLAG_FULLSCREEN},
17876      * {@link #SYSTEM_UI_FLAG_LAYOUT_STABLE}, {@link #SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION},
17877      * {@link #SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN}, {@link #SYSTEM_UI_FLAG_IMMERSIVE},
17878      * and {@link #SYSTEM_UI_FLAG_IMMERSIVE_STICKY}.
17879      */
17880     public void setSystemUiVisibility(int visibility) {
17881         if (visibility != mSystemUiVisibility) {
17882             mSystemUiVisibility = visibility;
17883             if (mParent != null && mAttachInfo != null && !mAttachInfo.mRecomputeGlobalAttributes) {
17884                 mParent.recomputeViewAttributes(this);
17885             }
17886         }
17887     }
17888
17889     /**
17890      * Returns the last {@link #setSystemUiVisibility(int)} that this view has requested.
17891      * @return  Bitwise-or of flags {@link #SYSTEM_UI_FLAG_LOW_PROFILE},
17892      * {@link #SYSTEM_UI_FLAG_HIDE_NAVIGATION}, {@link #SYSTEM_UI_FLAG_FULLSCREEN},
17893      * {@link #SYSTEM_UI_FLAG_LAYOUT_STABLE}, {@link #SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION},
17894      * {@link #SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN}, {@link #SYSTEM_UI_FLAG_IMMERSIVE},
17895      * and {@link #SYSTEM_UI_FLAG_IMMERSIVE_STICKY}.
17896      */
17897     public int getSystemUiVisibility() {
17898         return mSystemUiVisibility;
17899     }
17900
17901     /**
17902      * Returns the current system UI visibility that is currently set for
17903      * the entire window.  This is the combination of the
17904      * {@link #setSystemUiVisibility(int)} values supplied by all of the
17905      * views in the window.
17906      */
17907     public int getWindowSystemUiVisibility() {
17908         return mAttachInfo != null ? mAttachInfo.mSystemUiVisibility : 0;
17909     }
17910
17911     /**
17912      * Override to find out when the window's requested system UI visibility
17913      * has changed, that is the value returned by {@link #getWindowSystemUiVisibility()}.
17914      * This is different from the callbacks received through
17915      * {@link #setOnSystemUiVisibilityChangeListener(OnSystemUiVisibilityChangeListener)}
17916      * in that this is only telling you about the local request of the window,
17917      * not the actual values applied by the system.
17918      */
17919     public void onWindowSystemUiVisibilityChanged(int visible) {
17920     }
17921
17922     /**
17923      * Dispatch callbacks to {@link #onWindowSystemUiVisibilityChanged(int)} down
17924      * the view hierarchy.
17925      */
17926     public void dispatchWindowSystemUiVisiblityChanged(int visible) {
17927         onWindowSystemUiVisibilityChanged(visible);
17928     }
17929
17930     /**
17931      * Set a listener to receive callbacks when the visibility of the system bar changes.
17932      * @param l  The {@link OnSystemUiVisibilityChangeListener} to receive callbacks.
17933      */
17934     public void setOnSystemUiVisibilityChangeListener(OnSystemUiVisibilityChangeListener l) {
17935         getListenerInfo().mOnSystemUiVisibilityChangeListener = l;
17936         if (mParent != null && mAttachInfo != null && !mAttachInfo.mRecomputeGlobalAttributes) {
17937             mParent.recomputeViewAttributes(this);
17938         }
17939     }
17940
17941     /**
17942      * Dispatch callbacks to {@link #setOnSystemUiVisibilityChangeListener} down
17943      * the view hierarchy.
17944      */
17945     public void dispatchSystemUiVisibilityChanged(int visibility) {
17946         ListenerInfo li = mListenerInfo;
17947         if (li != null && li.mOnSystemUiVisibilityChangeListener != null) {
17948             li.mOnSystemUiVisibilityChangeListener.onSystemUiVisibilityChange(
17949                     visibility & PUBLIC_STATUS_BAR_VISIBILITY_MASK);
17950         }
17951     }
17952
17953     boolean updateLocalSystemUiVisibility(int localValue, int localChanges) {
17954         int val = (mSystemUiVisibility&~localChanges) | (localValue&localChanges);
17955         if (val != mSystemUiVisibility) {
17956             setSystemUiVisibility(val);
17957             return true;
17958         }
17959         return false;
17960     }
17961
17962     /** @hide */
17963     public void setDisabledSystemUiVisibility(int flags) {
17964         if (mAttachInfo != null) {
17965             if (mAttachInfo.mDisabledSystemUiVisibility != flags) {
17966                 mAttachInfo.mDisabledSystemUiVisibility = flags;
17967                 if (mParent != null) {
17968                     mParent.recomputeViewAttributes(this);
17969                 }
17970             }
17971         }
17972     }
17973
17974     /**
17975      * Creates an image that the system displays during the drag and drop
17976      * operation. This is called a &quot;drag shadow&quot;. The default implementation
17977      * for a DragShadowBuilder based on a View returns an image that has exactly the same
17978      * appearance as the given View. The default also positions the center of the drag shadow
17979      * directly under the touch point. If no View is provided (the constructor with no parameters
17980      * is used), and {@link #onProvideShadowMetrics(Point,Point) onProvideShadowMetrics()} and
17981      * {@link #onDrawShadow(Canvas) onDrawShadow()} are not overriden, then the
17982      * default is an invisible drag shadow.
17983      * <p>
17984      * You are not required to use the View you provide to the constructor as the basis of the
17985      * drag shadow. The {@link #onDrawShadow(Canvas) onDrawShadow()} method allows you to draw
17986      * anything you want as the drag shadow.
17987      * </p>
17988      * <p>
17989      *  You pass a DragShadowBuilder object to the system when you start the drag. The system
17990      *  calls {@link #onProvideShadowMetrics(Point,Point) onProvideShadowMetrics()} to get the
17991      *  size and position of the drag shadow. It uses this data to construct a
17992      *  {@link android.graphics.Canvas} object, then it calls {@link #onDrawShadow(Canvas) onDrawShadow()}
17993      *  so that your application can draw the shadow image in the Canvas.
17994      * </p>
17995      *
17996      * <div class="special reference">
17997      * <h3>Developer Guides</h3>
17998      * <p>For a guide to implementing drag and drop features, read the
17999      * <a href="{@docRoot}guide/topics/ui/drag-drop.html">Drag and Drop</a> developer guide.</p>
18000      * </div>
18001      */
18002     public static class DragShadowBuilder {
18003         private final WeakReference<View> mView;
18004
18005         /**
18006          * Constructs a shadow image builder based on a View. By default, the resulting drag
18007          * shadow will have the same appearance and dimensions as the View, with the touch point
18008          * over the center of the View.
18009          * @param view A View. Any View in scope can be used.
18010          */
18011         public DragShadowBuilder(View view) {
18012             mView = new WeakReference<View>(view);
18013         }
18014
18015         /**
18016          * Construct a shadow builder object with no associated View.  This
18017          * constructor variant is only useful when the {@link #onProvideShadowMetrics(Point, Point)}
18018          * and {@link #onDrawShadow(Canvas)} methods are also overridden in order
18019          * to supply the drag shadow's dimensions and appearance without
18020          * reference to any View object. If they are not overridden, then the result is an
18021          * invisible drag shadow.
18022          */
18023         public DragShadowBuilder() {
18024             mView = new WeakReference<View>(null);
18025         }
18026
18027         /**
18028          * Returns the View object that had been passed to the
18029          * {@link #View.DragShadowBuilder(View)}
18030          * constructor.  If that View parameter was {@code null} or if the
18031          * {@link #View.DragShadowBuilder()}
18032          * constructor was used to instantiate the builder object, this method will return
18033          * null.
18034          *
18035          * @return The View object associate with this builder object.
18036          */
18037         @SuppressWarnings({"JavadocReference"})
18038         final public View getView() {
18039             return mView.get();
18040         }
18041
18042         /**
18043          * Provides the metrics for the shadow image. These include the dimensions of
18044          * the shadow image, and the point within that shadow that should
18045          * be centered under the touch location while dragging.
18046          * <p>
18047          * The default implementation sets the dimensions of the shadow to be the
18048          * same as the dimensions of the View itself and centers the shadow under
18049          * the touch point.
18050          * </p>
18051          *
18052          * @param shadowSize A {@link android.graphics.Point} containing the width and height
18053          * of the shadow image. Your application must set {@link android.graphics.Point#x} to the
18054          * desired width and must set {@link android.graphics.Point#y} to the desired height of the
18055          * image.
18056          *
18057          * @param shadowTouchPoint A {@link android.graphics.Point} for the position within the
18058          * shadow image that should be underneath the touch point during the drag and drop
18059          * operation. Your application must set {@link android.graphics.Point#x} to the
18060          * X coordinate and {@link android.graphics.Point#y} to the Y coordinate of this position.
18061          */
18062         public void onProvideShadowMetrics(Point shadowSize, Point shadowTouchPoint) {
18063             final View view = mView.get();
18064             if (view != null) {
18065                 shadowSize.set(view.getWidth(), view.getHeight());
18066                 shadowTouchPoint.set(shadowSize.x / 2, shadowSize.y / 2);
18067             } else {
18068                 Log.e(View.VIEW_LOG_TAG, "Asked for drag thumb metrics but no view");
18069             }
18070         }
18071
18072         /**
18073          * Draws the shadow image. The system creates the {@link android.graphics.Canvas} object
18074          * based on the dimensions it received from the
18075          * {@link #onProvideShadowMetrics(Point, Point)} callback.
18076          *
18077          * @param canvas A {@link android.graphics.Canvas} object in which to draw the shadow image.
18078          */
18079         public void onDrawShadow(Canvas canvas) {
18080             final View view = mView.get();
18081             if (view != null) {
18082                 view.draw(canvas);
18083             } else {
18084                 Log.e(View.VIEW_LOG_TAG, "Asked to draw drag shadow but no view");
18085             }
18086         }
18087     }
18088
18089     /**
18090      * Starts a drag and drop operation. When your application calls this method, it passes a
18091      * {@link android.view.View.DragShadowBuilder} object to the system. The
18092      * system calls this object's {@link DragShadowBuilder#onProvideShadowMetrics(Point, Point)}
18093      * to get metrics for the drag shadow, and then calls the object's
18094      * {@link DragShadowBuilder#onDrawShadow(Canvas)} to draw the drag shadow itself.
18095      * <p>
18096      *  Once the system has the drag shadow, it begins the drag and drop operation by sending
18097      *  drag events to all the View objects in your application that are currently visible. It does
18098      *  this either by calling the View object's drag listener (an implementation of
18099      *  {@link android.view.View.OnDragListener#onDrag(View,DragEvent) onDrag()} or by calling the
18100      *  View object's {@link android.view.View#onDragEvent(DragEvent) onDragEvent()} method.
18101      *  Both are passed a {@link android.view.DragEvent} object that has a
18102      *  {@link android.view.DragEvent#getAction()} value of
18103      *  {@link android.view.DragEvent#ACTION_DRAG_STARTED}.
18104      * </p>
18105      * <p>
18106      * Your application can invoke startDrag() on any attached View object. The View object does not
18107      * need to be the one used in {@link android.view.View.DragShadowBuilder}, nor does it need to
18108      * be related to the View the user selected for dragging.
18109      * </p>
18110      * @param data A {@link android.content.ClipData} object pointing to the data to be
18111      * transferred by the drag and drop operation.
18112      * @param shadowBuilder A {@link android.view.View.DragShadowBuilder} object for building the
18113      * drag shadow.
18114      * @param myLocalState An {@link java.lang.Object} containing local data about the drag and
18115      * drop operation. This Object is put into every DragEvent object sent by the system during the
18116      * current drag.
18117      * <p>
18118      * myLocalState is a lightweight mechanism for the sending information from the dragged View
18119      * to the target Views. For example, it can contain flags that differentiate between a
18120      * a copy operation and a move operation.
18121      * </p>
18122      * @param flags Flags that control the drag and drop operation. No flags are currently defined,
18123      * so the parameter should be set to 0.
18124      * @return {@code true} if the method completes successfully, or
18125      * {@code false} if it fails anywhere. Returning {@code false} means the system was unable to
18126      * do a drag, and so no drag operation is in progress.
18127      */
18128     public final boolean startDrag(ClipData data, DragShadowBuilder shadowBuilder,
18129             Object myLocalState, int flags) {
18130         if (ViewDebug.DEBUG_DRAG) {
18131             Log.d(VIEW_LOG_TAG, "startDrag: data=" + data + " flags=" + flags);
18132         }
18133         boolean okay = false;
18134
18135         Point shadowSize = new Point();
18136         Point shadowTouchPoint = new Point();
18137         shadowBuilder.onProvideShadowMetrics(shadowSize, shadowTouchPoint);
18138
18139         if ((shadowSize.x < 0) || (shadowSize.y < 0) ||
18140                 (shadowTouchPoint.x < 0) || (shadowTouchPoint.y < 0)) {
18141             throw new IllegalStateException("Drag shadow dimensions must not be negative");
18142         }
18143
18144         if (ViewDebug.DEBUG_DRAG) {
18145             Log.d(VIEW_LOG_TAG, "drag shadow: width=" + shadowSize.x + " height=" + shadowSize.y
18146                     + " shadowX=" + shadowTouchPoint.x + " shadowY=" + shadowTouchPoint.y);
18147         }
18148         Surface surface = new Surface();
18149         try {
18150             IBinder token = mAttachInfo.mSession.prepareDrag(mAttachInfo.mWindow,
18151                     flags, shadowSize.x, shadowSize.y, surface);
18152             if (ViewDebug.DEBUG_DRAG) Log.d(VIEW_LOG_TAG, "prepareDrag returned token=" + token
18153                     + " surface=" + surface);
18154             if (token != null) {
18155                 Canvas canvas = surface.lockCanvas(null);
18156                 try {
18157                     canvas.drawColor(0, PorterDuff.Mode.CLEAR);
18158                     shadowBuilder.onDrawShadow(canvas);
18159                 } finally {
18160                     surface.unlockCanvasAndPost(canvas);
18161                 }
18162
18163                 final ViewRootImpl root = getViewRootImpl();
18164
18165                 // Cache the local state object for delivery with DragEvents
18166                 root.setLocalDragState(myLocalState);
18167
18168                 // repurpose 'shadowSize' for the last touch point
18169                 root.getLastTouchPoint(shadowSize);
18170
18171                 okay = mAttachInfo.mSession.performDrag(mAttachInfo.mWindow, token,
18172                         shadowSize.x, shadowSize.y,
18173                         shadowTouchPoint.x, shadowTouchPoint.y, data);
18174                 if (ViewDebug.DEBUG_DRAG) Log.d(VIEW_LOG_TAG, "performDrag returned " + okay);
18175
18176                 // Off and running!  Release our local surface instance; the drag
18177                 // shadow surface is now managed by the system process.
18178                 surface.release();
18179             }
18180         } catch (Exception e) {
18181             Log.e(VIEW_LOG_TAG, "Unable to initiate drag", e);
18182             surface.destroy();
18183         }
18184
18185         return okay;
18186     }
18187
18188     /**
18189      * Handles drag events sent by the system following a call to
18190      * {@link android.view.View#startDrag(ClipData,DragShadowBuilder,Object,int) startDrag()}.
18191      *<p>
18192      * When the system calls this method, it passes a
18193      * {@link android.view.DragEvent} object. A call to
18194      * {@link android.view.DragEvent#getAction()} returns one of the action type constants defined
18195      * in DragEvent. The method uses these to determine what is happening in the drag and drop
18196      * operation.
18197      * @param event The {@link android.view.DragEvent} sent by the system.
18198      * The {@link android.view.DragEvent#getAction()} method returns an action type constant defined
18199      * in DragEvent, indicating the type of drag event represented by this object.
18200      * @return {@code true} if the method was successful, otherwise {@code false}.
18201      * <p>
18202      *  The method should return {@code true} in response to an action type of
18203      *  {@link android.view.DragEvent#ACTION_DRAG_STARTED} to receive drag events for the current
18204      *  operation.
18205      * </p>
18206      * <p>
18207      *  The method should also return {@code true} in response to an action type of
18208      *  {@link android.view.DragEvent#ACTION_DROP} if it consumed the drop, or
18209      *  {@code false} if it didn't.
18210      * </p>
18211      */
18212     public boolean onDragEvent(DragEvent event) {
18213         return false;
18214     }
18215
18216     /**
18217      * Detects if this View is enabled and has a drag event listener.
18218      * If both are true, then it calls the drag event listener with the
18219      * {@link android.view.DragEvent} it received. If the drag event listener returns
18220      * {@code true}, then dispatchDragEvent() returns {@code true}.
18221      * <p>
18222      * For all other cases, the method calls the
18223      * {@link android.view.View#onDragEvent(DragEvent) onDragEvent()} drag event handler
18224      * method and returns its result.
18225      * </p>
18226      * <p>
18227      * This ensures that a drag event is always consumed, even if the View does not have a drag
18228      * event listener. However, if the View has a listener and the listener returns true, then
18229      * onDragEvent() is not called.
18230      * </p>
18231      */
18232     public boolean dispatchDragEvent(DragEvent event) {
18233         ListenerInfo li = mListenerInfo;
18234         //noinspection SimplifiableIfStatement
18235         if (li != null && li.mOnDragListener != null && (mViewFlags & ENABLED_MASK) == ENABLED
18236                 && li.mOnDragListener.onDrag(this, event)) {
18237             return true;
18238         }
18239         return onDragEvent(event);
18240     }
18241
18242     boolean canAcceptDrag() {
18243         return (mPrivateFlags2 & PFLAG2_DRAG_CAN_ACCEPT) != 0;
18244     }
18245
18246     /**
18247      * This needs to be a better API (NOT ON VIEW) before it is exposed.  If
18248      * it is ever exposed at all.
18249      * @hide
18250      */
18251     public void onCloseSystemDialogs(String reason) {
18252     }
18253
18254     /**
18255      * Given a Drawable whose bounds have been set to draw into this view,
18256      * update a Region being computed for
18257      * {@link #gatherTransparentRegion(android.graphics.Region)} so
18258      * that any non-transparent parts of the Drawable are removed from the
18259      * given transparent region.
18260      *
18261      * @param dr The Drawable whose transparency is to be applied to the region.
18262      * @param region A Region holding the current transparency information,
18263      * where any parts of the region that are set are considered to be
18264      * transparent.  On return, this region will be modified to have the
18265      * transparency information reduced by the corresponding parts of the
18266      * Drawable that are not transparent.
18267      * {@hide}
18268      */
18269     public void applyDrawableToTransparentRegion(Drawable dr, Region region) {
18270         if (DBG) {
18271             Log.i("View", "Getting transparent region for: " + this);
18272         }
18273         final Region r = dr.getTransparentRegion();
18274         final Rect db = dr.getBounds();
18275         final AttachInfo attachInfo = mAttachInfo;
18276         if (r != null && attachInfo != null) {
18277             final int w = getRight()-getLeft();
18278             final int h = getBottom()-getTop();
18279             if (db.left > 0) {
18280                 //Log.i("VIEW", "Drawable left " + db.left + " > view 0");
18281                 r.op(0, 0, db.left, h, Region.Op.UNION);
18282             }
18283             if (db.right < w) {
18284                 //Log.i("VIEW", "Drawable right " + db.right + " < view " + w);
18285                 r.op(db.right, 0, w, h, Region.Op.UNION);
18286             }
18287             if (db.top > 0) {
18288                 //Log.i("VIEW", "Drawable top " + db.top + " > view 0");
18289                 r.op(0, 0, w, db.top, Region.Op.UNION);
18290             }
18291             if (db.bottom < h) {
18292                 //Log.i("VIEW", "Drawable bottom " + db.bottom + " < view " + h);
18293                 r.op(0, db.bottom, w, h, Region.Op.UNION);
18294             }
18295             final int[] location = attachInfo.mTransparentLocation;
18296             getLocationInWindow(location);
18297             r.translate(location[0], location[1]);
18298             region.op(r, Region.Op.INTERSECT);
18299         } else {
18300             region.op(db, Region.Op.DIFFERENCE);
18301         }
18302     }
18303
18304     private void checkForLongClick(int delayOffset) {
18305         if ((mViewFlags & LONG_CLICKABLE) == LONG_CLICKABLE) {
18306             mHasPerformedLongPress = false;
18307
18308             if (mPendingCheckForLongPress == null) {
18309                 mPendingCheckForLongPress = new CheckForLongPress();
18310             }
18311             mPendingCheckForLongPress.rememberWindowAttachCount();
18312             postDelayed(mPendingCheckForLongPress,
18313                     ViewConfiguration.getLongPressTimeout() - delayOffset);
18314         }
18315     }
18316
18317     /**
18318      * Inflate a view from an XML resource.  This convenience method wraps the {@link
18319      * LayoutInflater} class, which provides a full range of options for view inflation.
18320      *
18321      * @param context The Context object for your activity or application.
18322      * @param resource The resource ID to inflate
18323      * @param root A view group that will be the parent.  Used to properly inflate the
18324      * layout_* parameters.
18325      * @see LayoutInflater
18326      */
18327     public static View inflate(Context context, int resource, ViewGroup root) {
18328         LayoutInflater factory = LayoutInflater.from(context);
18329         return factory.inflate(resource, root);
18330     }
18331
18332     /**
18333      * Scroll the view with standard behavior for scrolling beyond the normal
18334      * content boundaries. Views that call this method should override
18335      * {@link #onOverScrolled(int, int, boolean, boolean)} to respond to the
18336      * results of an over-scroll operation.
18337      *
18338      * Views can use this method to handle any touch or fling-based scrolling.
18339      *
18340      * @param deltaX Change in X in pixels
18341      * @param deltaY Change in Y in pixels
18342      * @param scrollX Current X scroll value in pixels before applying deltaX
18343      * @param scrollY Current Y scroll value in pixels before applying deltaY
18344      * @param scrollRangeX Maximum content scroll range along the X axis
18345      * @param scrollRangeY Maximum content scroll range along the Y axis
18346      * @param maxOverScrollX Number of pixels to overscroll by in either direction
18347      *          along the X axis.
18348      * @param maxOverScrollY Number of pixels to overscroll by in either direction
18349      *          along the Y axis.
18350      * @param isTouchEvent true if this scroll operation is the result of a touch event.
18351      * @return true if scrolling was clamped to an over-scroll boundary along either
18352      *          axis, false otherwise.
18353      */
18354     @SuppressWarnings({"UnusedParameters"})
18355     protected boolean overScrollBy(int deltaX, int deltaY,
18356             int scrollX, int scrollY,
18357             int scrollRangeX, int scrollRangeY,
18358             int maxOverScrollX, int maxOverScrollY,
18359             boolean isTouchEvent) {
18360         final int overScrollMode = mOverScrollMode;
18361         final boolean canScrollHorizontal =
18362                 computeHorizontalScrollRange() > computeHorizontalScrollExtent();
18363         final boolean canScrollVertical =
18364                 computeVerticalScrollRange() > computeVerticalScrollExtent();
18365         final boolean overScrollHorizontal = overScrollMode == OVER_SCROLL_ALWAYS ||
18366                 (overScrollMode == OVER_SCROLL_IF_CONTENT_SCROLLS && canScrollHorizontal);
18367         final boolean overScrollVertical = overScrollMode == OVER_SCROLL_ALWAYS ||
18368                 (overScrollMode == OVER_SCROLL_IF_CONTENT_SCROLLS && canScrollVertical);
18369
18370         int newScrollX = scrollX + deltaX;
18371         if (!overScrollHorizontal) {
18372             maxOverScrollX = 0;
18373         }
18374
18375         int newScrollY = scrollY + deltaY;
18376         if (!overScrollVertical) {
18377             maxOverScrollY = 0;
18378         }
18379
18380         // Clamp values if at the limits and record
18381         final int left = -maxOverScrollX;
18382         final int right = maxOverScrollX + scrollRangeX;
18383         final int top = -maxOverScrollY;
18384         final int bottom = maxOverScrollY + scrollRangeY;
18385
18386         boolean clampedX = false;
18387         if (newScrollX > right) {
18388             newScrollX = right;
18389             clampedX = true;
18390         } else if (newScrollX < left) {
18391             newScrollX = left;
18392             clampedX = true;
18393         }
18394
18395         boolean clampedY = false;
18396         if (newScrollY > bottom) {
18397             newScrollY = bottom;
18398             clampedY = true;
18399         } else if (newScrollY < top) {
18400             newScrollY = top;
18401             clampedY = true;
18402         }
18403
18404         onOverScrolled(newScrollX, newScrollY, clampedX, clampedY);
18405
18406         return clampedX || clampedY;
18407     }
18408
18409     /**
18410      * Called by {@link #overScrollBy(int, int, int, int, int, int, int, int, boolean)} to
18411      * respond to the results of an over-scroll operation.
18412      *
18413      * @param scrollX New X scroll value in pixels
18414      * @param scrollY New Y scroll value in pixels
18415      * @param clampedX True if scrollX was clamped to an over-scroll boundary
18416      * @param clampedY True if scrollY was clamped to an over-scroll boundary
18417      */
18418     protected void onOverScrolled(int scrollX, int scrollY,
18419             boolean clampedX, boolean clampedY) {
18420         // Intentionally empty.
18421     }
18422
18423     /**
18424      * Returns the over-scroll mode for this view. The result will be
18425      * one of {@link #OVER_SCROLL_ALWAYS} (default), {@link #OVER_SCROLL_IF_CONTENT_SCROLLS}
18426      * (allow over-scrolling only if the view content is larger than the container),
18427      * or {@link #OVER_SCROLL_NEVER}.
18428      *
18429      * @return This view's over-scroll mode.
18430      */
18431     public int getOverScrollMode() {
18432         return mOverScrollMode;
18433     }
18434
18435     /**
18436      * Set the over-scroll mode for this view. Valid over-scroll modes are
18437      * {@link #OVER_SCROLL_ALWAYS} (default), {@link #OVER_SCROLL_IF_CONTENT_SCROLLS}
18438      * (allow over-scrolling only if the view content is larger than the container),
18439      * or {@link #OVER_SCROLL_NEVER}.
18440      *
18441      * Setting the over-scroll mode of a view will have an effect only if the
18442      * view is capable of scrolling.
18443      *
18444      * @param overScrollMode The new over-scroll mode for this view.
18445      */
18446     public void setOverScrollMode(int overScrollMode) {
18447         if (overScrollMode != OVER_SCROLL_ALWAYS &&
18448                 overScrollMode != OVER_SCROLL_IF_CONTENT_SCROLLS &&
18449                 overScrollMode != OVER_SCROLL_NEVER) {
18450             throw new IllegalArgumentException("Invalid overscroll mode " + overScrollMode);
18451         }
18452         mOverScrollMode = overScrollMode;
18453     }
18454
18455     /**
18456      * Enable or disable nested scrolling for this view.
18457      *
18458      * <p>If this property is set to true the view will be permitted to initiate nested
18459      * scrolling operations with a compatible parent view in the current hierarchy. If this
18460      * view does not implement nested scrolling this will have no effect. Disabling nested scrolling
18461      * while a nested scroll is in progress has the effect of {@link #stopNestedScroll() stopping}
18462      * the nested scroll.</p>
18463      *
18464      * @param enabled true to enable nested scrolling, false to disable
18465      *
18466      * @see #isNestedScrollingEnabled()
18467      */
18468     public void setNestedScrollingEnabled(boolean enabled) {
18469         if (enabled) {
18470             mPrivateFlags3 |= PFLAG3_NESTED_SCROLLING_ENABLED;
18471         } else {
18472             stopNestedScroll();
18473             mPrivateFlags3 &= ~PFLAG3_NESTED_SCROLLING_ENABLED;
18474         }
18475     }
18476
18477     /**
18478      * Returns true if nested scrolling is enabled for this view.
18479      *
18480      * <p>If nested scrolling is enabled and this View class implementation supports it,
18481      * this view will act as a nested scrolling child view when applicable, forwarding data
18482      * about the scroll operation in progress to a compatible and cooperating nested scrolling
18483      * parent.</p>
18484      *
18485      * @return true if nested scrolling is enabled
18486      *
18487      * @see #setNestedScrollingEnabled(boolean)
18488      */
18489     public boolean isNestedScrollingEnabled() {
18490         return (mPrivateFlags3 & PFLAG3_NESTED_SCROLLING_ENABLED) ==
18491                 PFLAG3_NESTED_SCROLLING_ENABLED;
18492     }
18493
18494     /**
18495      * Begin a nestable scroll operation along the given axes.
18496      *
18497      * <p>A view starting a nested scroll promises to abide by the following contract:</p>
18498      *
18499      * <p>The view will call startNestedScroll upon initiating a scroll operation. In the case
18500      * of a touch scroll this corresponds to the initial {@link MotionEvent#ACTION_DOWN}.
18501      * In the case of touch scrolling the nested scroll will be terminated automatically in
18502      * the same manner as {@link ViewParent#requestDisallowInterceptTouchEvent(boolean)}.
18503      * In the event of programmatic scrolling the caller must explicitly call
18504      * {@link #stopNestedScroll()} to indicate the end of the nested scroll.</p>
18505      *
18506      * <p>If <code>startNestedScroll</code> returns true, a cooperative parent was found.
18507      * If it returns false the caller may ignore the rest of this contract until the next scroll.
18508      * Calling startNestedScroll while a nested scroll is already in progress will return true.</p>
18509      *
18510      * <p>At each incremental step of the scroll the caller should invoke
18511      * {@link #dispatchNestedPreScroll(int, int, int[], int[]) dispatchNestedPreScroll}
18512      * once it has calculated the requested scrolling delta. If it returns true the nested scrolling
18513      * parent at least partially consumed the scroll and the caller should adjust the amount it
18514      * scrolls by.</p>
18515      *
18516      * <p>After applying the remainder of the scroll delta the caller should invoke
18517      * {@link #dispatchNestedScroll(int, int, int, int, int[]) dispatchNestedScroll}, passing
18518      * both the delta consumed and the delta unconsumed. A nested scrolling parent may treat
18519      * these values differently. See {@link ViewParent#onNestedScroll(View, int, int, int, int)}.
18520      * </p>
18521      *
18522      * @param axes Flags consisting of a combination of {@link #SCROLL_AXIS_HORIZONTAL} and/or
18523      *             {@link #SCROLL_AXIS_VERTICAL}.
18524      * @return true if a cooperative parent was found and nested scrolling has been enabled for
18525      *         the current gesture.
18526      *
18527      * @see #stopNestedScroll()
18528      * @see #dispatchNestedPreScroll(int, int, int[], int[])
18529      * @see #dispatchNestedScroll(int, int, int, int, int[])
18530      */
18531     public boolean startNestedScroll(int axes) {
18532         if (hasNestedScrollingParent()) {
18533             // Already in progress
18534             return true;
18535         }
18536         if (isNestedScrollingEnabled()) {
18537             ViewParent p = getParent();
18538             View child = this;
18539             while (p != null) {
18540                 try {
18541                     if (p.onStartNestedScroll(child, this, axes)) {
18542                         mNestedScrollingParent = p;
18543                         p.onNestedScrollAccepted(child, this, axes);
18544                         return true;
18545                     }
18546                 } catch (AbstractMethodError e) {
18547                     Log.e(VIEW_LOG_TAG, "ViewParent " + p + " does not implement interface " +
18548                             "method onStartNestedScroll", e);
18549                     // Allow the search upward to continue
18550                 }
18551                 if (p instanceof View) {
18552                     child = (View) p;
18553                 }
18554                 p = p.getParent();
18555             }
18556         }
18557         return false;
18558     }
18559
18560     /**
18561      * Stop a nested scroll in progress.
18562      *
18563      * <p>Calling this method when a nested scroll is not currently in progress is harmless.</p>
18564      *
18565      * @see #startNestedScroll(int)
18566      */
18567     public void stopNestedScroll() {
18568         if (mNestedScrollingParent != null) {
18569             mNestedScrollingParent.onStopNestedScroll(this);
18570             mNestedScrollingParent = null;
18571         }
18572     }
18573
18574     /**
18575      * Returns true if this view has a nested scrolling parent.
18576      *
18577      * <p>The presence of a nested scrolling parent indicates that this view has initiated
18578      * a nested scroll and it was accepted by an ancestor view further up the view hierarchy.</p>
18579      *
18580      * @return whether this view has a nested scrolling parent
18581      */
18582     public boolean hasNestedScrollingParent() {
18583         return mNestedScrollingParent != null;
18584     }
18585
18586     /**
18587      * Dispatch one step of a nested scroll in progress.
18588      *
18589      * <p>Implementations of views that support nested scrolling should call this to report
18590      * info about a scroll in progress to the current nested scrolling parent. If a nested scroll
18591      * is not currently in progress or nested scrolling is not
18592      * {@link #isNestedScrollingEnabled() enabled} for this view this method does nothing.</p>
18593      *
18594      * <p>Compatible View implementations should also call
18595      * {@link #dispatchNestedPreScroll(int, int, int[], int[]) dispatchNestedPreScroll} before
18596      * consuming a component of the scroll event themselves.</p>
18597      *
18598      * @param dxConsumed Horizontal distance in pixels consumed by this view during this scroll step
18599      * @param dyConsumed Vertical distance in pixels consumed by this view during this scroll step
18600      * @param dxUnconsumed Horizontal scroll distance in pixels not consumed by this view
18601      * @param dyUnconsumed Horizontal scroll distance in pixels not consumed by this view
18602      * @param offsetInWindow Optional. If not null, on return this will contain the offset
18603      *                       in local view coordinates of this view from before this operation
18604      *                       to after it completes. View implementations may use this to adjust
18605      *                       expected input coordinate tracking.
18606      * @return true if the event was dispatched, false if it could not be dispatched.
18607      * @see #dispatchNestedPreScroll(int, int, int[], int[])
18608      */
18609     public boolean dispatchNestedScroll(int dxConsumed, int dyConsumed,
18610             int dxUnconsumed, int dyUnconsumed, int[] offsetInWindow) {
18611         if (isNestedScrollingEnabled() && mNestedScrollingParent != null) {
18612             if (dxConsumed != 0 || dyConsumed != 0 || dxUnconsumed != 0 || dyUnconsumed != 0) {
18613                 int startX = 0;
18614                 int startY = 0;
18615                 if (offsetInWindow != null) {
18616                     getLocationInWindow(offsetInWindow);
18617                     startX = offsetInWindow[0];
18618                     startY = offsetInWindow[1];
18619                 }
18620
18621                 mNestedScrollingParent.onNestedScroll(this, dxConsumed, dyConsumed,
18622                         dxUnconsumed, dyUnconsumed);
18623
18624                 if (offsetInWindow != null) {
18625                     getLocationInWindow(offsetInWindow);
18626                     offsetInWindow[0] -= startX;
18627                     offsetInWindow[1] -= startY;
18628                 }
18629                 return true;
18630             } else if (offsetInWindow != null) {
18631                 // No motion, no dispatch. Keep offsetInWindow up to date.
18632                 offsetInWindow[0] = 0;
18633                 offsetInWindow[1] = 0;
18634             }
18635         }
18636         return false;
18637     }
18638
18639     /**
18640      * Dispatch one step of a nested scroll in progress before this view consumes any portion of it.
18641      *
18642      * <p>Nested pre-scroll events are to nested scroll events what touch intercept is to touch.
18643      * <code>dispatchNestedPreScroll</code> offers an opportunity for the parent view in a nested
18644      * scrolling operation to consume some or all of the scroll operation before the child view
18645      * consumes it.</p>
18646      *
18647      * @param dx Horizontal scroll distance in pixels
18648      * @param dy Vertical scroll distance in pixels
18649      * @param consumed Output. If not null, consumed[0] will contain the consumed component of dx
18650      *                 and consumed[1] the consumed dy.
18651      * @param offsetInWindow Optional. If not null, on return this will contain the offset
18652      *                       in local view coordinates of this view from before this operation
18653      *                       to after it completes. View implementations may use this to adjust
18654      *                       expected input coordinate tracking.
18655      * @return true if the parent consumed some or all of the scroll delta
18656      * @see #dispatchNestedScroll(int, int, int, int, int[])
18657      */
18658     public boolean dispatchNestedPreScroll(int dx, int dy, int[] consumed, int[] offsetInWindow) {
18659         if (isNestedScrollingEnabled() && mNestedScrollingParent != null) {
18660             if (dx != 0 || dy != 0) {
18661                 int startX = 0;
18662                 int startY = 0;
18663                 if (offsetInWindow != null) {
18664                     getLocationInWindow(offsetInWindow);
18665                     startX = offsetInWindow[0];
18666                     startY = offsetInWindow[1];
18667                 }
18668
18669                 if (consumed == null) {
18670                     if (mTempNestedScrollConsumed == null) {
18671                         mTempNestedScrollConsumed = new int[2];
18672                     }
18673                     consumed = mTempNestedScrollConsumed;
18674                 }
18675                 consumed[0] = 0;
18676                 consumed[1] = 0;
18677                 mNestedScrollingParent.onNestedPreScroll(this, dx, dy, consumed);
18678
18679                 if (offsetInWindow != null) {
18680                     getLocationInWindow(offsetInWindow);
18681                     offsetInWindow[0] -= startX;
18682                     offsetInWindow[1] -= startY;
18683                 }
18684                 return consumed[0] != 0 || consumed[1] != 0;
18685             } else if (offsetInWindow != null) {
18686                 offsetInWindow[0] = 0;
18687                 offsetInWindow[1] = 0;
18688             }
18689         }
18690         return false;
18691     }
18692
18693     /**
18694      * Dispatch a fling to a nested scrolling parent.
18695      *
18696      * <p>This method should be used to indicate that a nested scrolling child has detected
18697      * suitable conditions for a fling. Generally this means that a touch scroll has ended with a
18698      * {@link VelocityTracker velocity} in the direction of scrolling that meets or exceeds
18699      * the {@link ViewConfiguration#getScaledMinimumFlingVelocity() minimum fling velocity}
18700      * along a scrollable axis.</p>
18701      *
18702      * <p>If a nested scrolling child view would normally fling but it is at the edge of
18703      * its own content, it can use this method to delegate the fling to its nested scrolling
18704      * parent instead. The parent may optionally consume the fling or observe a child fling.</p>
18705      *
18706      * @param velocityX Horizontal fling velocity in pixels per second
18707      * @param velocityY Vertical fling velocity in pixels per second
18708      * @param consumed true if the child consumed the fling, false otherwise
18709      * @return true if the nested scrolling parent consumed or otherwise reacted to the fling
18710      */
18711     public boolean dispatchNestedFling(float velocityX, float velocityY, boolean consumed) {
18712         if (isNestedScrollingEnabled() && mNestedScrollingParent != null) {
18713             return mNestedScrollingParent.onNestedFling(this, velocityX, velocityY, consumed);
18714         }
18715         return false;
18716     }
18717
18718     /**
18719      * Dispatch a fling to a nested scrolling parent before it is processed by this view.
18720      *
18721      * <p>Nested pre-fling events are to nested fling events what touch intercept is to touch
18722      * and what nested pre-scroll is to nested scroll. <code>dispatchNestedPreFling</code>
18723      * offsets an opportunity for the parent view in a nested fling to fully consume the fling
18724      * before the child view consumes it. If this method returns <code>true</code>, a nested
18725      * parent view consumed the fling and this view should not scroll as a result.</p>
18726      *
18727      * <p>For a better user experience, only one view in a nested scrolling chain should consume
18728      * the fling at a time. If a parent view consumed the fling this method will return false.
18729      * Custom view implementations should account for this in two ways:</p>
18730      *
18731      * <ul>
18732      *     <li>If a custom view is paged and needs to settle to a fixed page-point, do not
18733      *     call <code>dispatchNestedPreFling</code>; consume the fling and settle to a valid
18734      *     position regardless.</li>
18735      *     <li>If a nested parent does consume the fling, this view should not scroll at all,
18736      *     even to settle back to a valid idle position.</li>
18737      * </ul>
18738      *
18739      * <p>Views should also not offer fling velocities to nested parent views along an axis
18740      * where scrolling is not currently supported; a {@link android.widget.ScrollView ScrollView}
18741      * should not offer a horizontal fling velocity to its parents since scrolling along that
18742      * axis is not permitted and carrying velocity along that motion does not make sense.</p>
18743      *
18744      * @param velocityX Horizontal fling velocity in pixels per second
18745      * @param velocityY Vertical fling velocity in pixels per second
18746      * @return true if a nested scrolling parent consumed the fling
18747      */
18748     public boolean dispatchNestedPreFling(float velocityX, float velocityY) {
18749         if (isNestedScrollingEnabled() && mNestedScrollingParent != null) {
18750             return mNestedScrollingParent.onNestedPreFling(this, velocityX, velocityY);
18751         }
18752         return false;
18753     }
18754
18755     /**
18756      * Gets a scale factor that determines the distance the view should scroll
18757      * vertically in response to {@link MotionEvent#ACTION_SCROLL}.
18758      * @return The vertical scroll scale factor.
18759      * @hide
18760      */
18761     protected float getVerticalScrollFactor() {
18762         if (mVerticalScrollFactor == 0) {
18763             TypedValue outValue = new TypedValue();
18764             if (!mContext.getTheme().resolveAttribute(
18765                     com.android.internal.R.attr.listPreferredItemHeight, outValue, true)) {
18766                 throw new IllegalStateException(
18767                         "Expected theme to define listPreferredItemHeight.");
18768             }
18769             mVerticalScrollFactor = outValue.getDimension(
18770                     mContext.getResources().getDisplayMetrics());
18771         }
18772         return mVerticalScrollFactor;
18773     }
18774
18775     /**
18776      * Gets a scale factor that determines the distance the view should scroll
18777      * horizontally in response to {@link MotionEvent#ACTION_SCROLL}.
18778      * @return The horizontal scroll scale factor.
18779      * @hide
18780      */
18781     protected float getHorizontalScrollFactor() {
18782         // TODO: Should use something else.
18783         return getVerticalScrollFactor();
18784     }
18785
18786     /**
18787      * Return the value specifying the text direction or policy that was set with
18788      * {@link #setTextDirection(int)}.
18789      *
18790      * @return the defined text direction. It can be one of:
18791      *
18792      * {@link #TEXT_DIRECTION_INHERIT},
18793      * {@link #TEXT_DIRECTION_FIRST_STRONG}
18794      * {@link #TEXT_DIRECTION_ANY_RTL},
18795      * {@link #TEXT_DIRECTION_LTR},
18796      * {@link #TEXT_DIRECTION_RTL},
18797      * {@link #TEXT_DIRECTION_LOCALE}
18798      *
18799      * @attr ref android.R.styleable#View_textDirection
18800      *
18801      * @hide
18802      */
18803     @ViewDebug.ExportedProperty(category = "text", mapping = {
18804             @ViewDebug.IntToString(from = TEXT_DIRECTION_INHERIT, to = "INHERIT"),
18805             @ViewDebug.IntToString(from = TEXT_DIRECTION_FIRST_STRONG, to = "FIRST_STRONG"),
18806             @ViewDebug.IntToString(from = TEXT_DIRECTION_ANY_RTL, to = "ANY_RTL"),
18807             @ViewDebug.IntToString(from = TEXT_DIRECTION_LTR, to = "LTR"),
18808             @ViewDebug.IntToString(from = TEXT_DIRECTION_RTL, to = "RTL"),
18809             @ViewDebug.IntToString(from = TEXT_DIRECTION_LOCALE, to = "LOCALE")
18810     })
18811     public int getRawTextDirection() {
18812         return (mPrivateFlags2 & PFLAG2_TEXT_DIRECTION_MASK) >> PFLAG2_TEXT_DIRECTION_MASK_SHIFT;
18813     }
18814
18815     /**
18816      * Set the text direction.
18817      *
18818      * @param textDirection the direction to set. Should be one of:
18819      *
18820      * {@link #TEXT_DIRECTION_INHERIT},
18821      * {@link #TEXT_DIRECTION_FIRST_STRONG}
18822      * {@link #TEXT_DIRECTION_ANY_RTL},
18823      * {@link #TEXT_DIRECTION_LTR},
18824      * {@link #TEXT_DIRECTION_RTL},
18825      * {@link #TEXT_DIRECTION_LOCALE}
18826      *
18827      * Resolution will be done if the value is set to TEXT_DIRECTION_INHERIT. The resolution
18828      * proceeds up the parent chain of the view to get the value. If there is no parent, then it will
18829      * return the default {@link #TEXT_DIRECTION_FIRST_STRONG}.
18830      *
18831      * @attr ref android.R.styleable#View_textDirection
18832      */
18833     public void setTextDirection(int textDirection) {
18834         if (getRawTextDirection() != textDirection) {
18835             // Reset the current text direction and the resolved one
18836             mPrivateFlags2 &= ~PFLAG2_TEXT_DIRECTION_MASK;
18837             resetResolvedTextDirection();
18838             // Set the new text direction
18839             mPrivateFlags2 |= ((textDirection << PFLAG2_TEXT_DIRECTION_MASK_SHIFT) & PFLAG2_TEXT_DIRECTION_MASK);
18840             // Do resolution
18841             resolveTextDirection();
18842             // Notify change
18843             onRtlPropertiesChanged(getLayoutDirection());
18844             // Refresh
18845             requestLayout();
18846             invalidate(true);
18847         }
18848     }
18849
18850     /**
18851      * Return the resolved text direction.
18852      *
18853      * @return the resolved text direction. Returns one of:
18854      *
18855      * {@link #TEXT_DIRECTION_FIRST_STRONG}
18856      * {@link #TEXT_DIRECTION_ANY_RTL},
18857      * {@link #TEXT_DIRECTION_LTR},
18858      * {@link #TEXT_DIRECTION_RTL},
18859      * {@link #TEXT_DIRECTION_LOCALE}
18860      *
18861      * @attr ref android.R.styleable#View_textDirection
18862      */
18863     @ViewDebug.ExportedProperty(category = "text", mapping = {
18864             @ViewDebug.IntToString(from = TEXT_DIRECTION_INHERIT, to = "INHERIT"),
18865             @ViewDebug.IntToString(from = TEXT_DIRECTION_FIRST_STRONG, to = "FIRST_STRONG"),
18866             @ViewDebug.IntToString(from = TEXT_DIRECTION_ANY_RTL, to = "ANY_RTL"),
18867             @ViewDebug.IntToString(from = TEXT_DIRECTION_LTR, to = "LTR"),
18868             @ViewDebug.IntToString(from = TEXT_DIRECTION_RTL, to = "RTL"),
18869             @ViewDebug.IntToString(from = TEXT_DIRECTION_LOCALE, to = "LOCALE")
18870     })
18871     public int getTextDirection() {
18872         return (mPrivateFlags2 & PFLAG2_TEXT_DIRECTION_RESOLVED_MASK) >> PFLAG2_TEXT_DIRECTION_RESOLVED_MASK_SHIFT;
18873     }
18874
18875     /**
18876      * Resolve the text direction.
18877      *
18878      * @return true if resolution has been done, false otherwise.
18879      *
18880      * @hide
18881      */
18882     public boolean resolveTextDirection() {
18883         // Reset any previous text direction resolution
18884         mPrivateFlags2 &= ~(PFLAG2_TEXT_DIRECTION_RESOLVED | PFLAG2_TEXT_DIRECTION_RESOLVED_MASK);
18885
18886         if (hasRtlSupport()) {
18887             // Set resolved text direction flag depending on text direction flag
18888             final int textDirection = getRawTextDirection();
18889             switch(textDirection) {
18890                 case TEXT_DIRECTION_INHERIT:
18891                     if (!canResolveTextDirection()) {
18892                         // We cannot do the resolution if there is no parent, so use the default one
18893                         mPrivateFlags2 |= PFLAG2_TEXT_DIRECTION_RESOLVED_DEFAULT;
18894                         // Resolution will need to happen again later
18895                         return false;
18896                     }
18897
18898                     // Parent has not yet resolved, so we still return the default
18899                     try {
18900                         if (!mParent.isTextDirectionResolved()) {
18901                             mPrivateFlags2 |= PFLAG2_TEXT_DIRECTION_RESOLVED_DEFAULT;
18902                             // Resolution will need to happen again later
18903                             return false;
18904                         }
18905                     } catch (AbstractMethodError e) {
18906                         Log.e(VIEW_LOG_TAG, mParent.getClass().getSimpleName() +
18907                                 " does not fully implement ViewParent", e);
18908                         mPrivateFlags2 |= PFLAG2_TEXT_DIRECTION_RESOLVED |
18909                                 PFLAG2_TEXT_DIRECTION_RESOLVED_DEFAULT;
18910                         return true;
18911                     }
18912
18913                     // Set current resolved direction to the same value as the parent's one
18914                     int parentResolvedDirection;
18915                     try {
18916                         parentResolvedDirection = mParent.getTextDirection();
18917                     } catch (AbstractMethodError e) {
18918                         Log.e(VIEW_LOG_TAG, mParent.getClass().getSimpleName() +
18919                                 " does not fully implement ViewParent", e);
18920                         parentResolvedDirection = TEXT_DIRECTION_LTR;
18921                     }
18922                     switch (parentResolvedDirection) {
18923                         case TEXT_DIRECTION_FIRST_STRONG:
18924                         case TEXT_DIRECTION_ANY_RTL:
18925                         case TEXT_DIRECTION_LTR:
18926                         case TEXT_DIRECTION_RTL:
18927                         case TEXT_DIRECTION_LOCALE:
18928                             mPrivateFlags2 |=
18929                                     (parentResolvedDirection << PFLAG2_TEXT_DIRECTION_RESOLVED_MASK_SHIFT);
18930                             break;
18931                         default:
18932                             // Default resolved direction is "first strong" heuristic
18933                             mPrivateFlags2 |= PFLAG2_TEXT_DIRECTION_RESOLVED_DEFAULT;
18934                     }
18935                     break;
18936                 case TEXT_DIRECTION_FIRST_STRONG:
18937                 case TEXT_DIRECTION_ANY_RTL:
18938                 case TEXT_DIRECTION_LTR:
18939                 case TEXT_DIRECTION_RTL:
18940                 case TEXT_DIRECTION_LOCALE:
18941                     // Resolved direction is the same as text direction
18942                     mPrivateFlags2 |= (textDirection << PFLAG2_TEXT_DIRECTION_RESOLVED_MASK_SHIFT);
18943                     break;
18944                 default:
18945                     // Default resolved direction is "first strong" heuristic
18946                     mPrivateFlags2 |= PFLAG2_TEXT_DIRECTION_RESOLVED_DEFAULT;
18947             }
18948         } else {
18949             // Default resolved direction is "first strong" heuristic
18950             mPrivateFlags2 |= PFLAG2_TEXT_DIRECTION_RESOLVED_DEFAULT;
18951         }
18952
18953         // Set to resolved
18954         mPrivateFlags2 |= PFLAG2_TEXT_DIRECTION_RESOLVED;
18955         return true;
18956     }
18957
18958     /**
18959      * Check if text direction resolution can be done.
18960      *
18961      * @return true if text direction resolution can be done otherwise return false.
18962      */
18963     public boolean canResolveTextDirection() {
18964         switch (getRawTextDirection()) {
18965             case TEXT_DIRECTION_INHERIT:
18966                 if (mParent != null) {
18967                     try {
18968                         return mParent.canResolveTextDirection();
18969                     } catch (AbstractMethodError e) {
18970                         Log.e(VIEW_LOG_TAG, mParent.getClass().getSimpleName() +
18971                                 " does not fully implement ViewParent", e);
18972                     }
18973                 }
18974                 return false;
18975
18976             default:
18977                 return true;
18978         }
18979     }
18980
18981     /**
18982      * Reset resolved text direction. Text direction will be resolved during a call to
18983      * {@link #onMeasure(int, int)}.
18984      *
18985      * @hide
18986      */
18987     public void resetResolvedTextDirection() {
18988         // Reset any previous text direction resolution
18989         mPrivateFlags2 &= ~(PFLAG2_TEXT_DIRECTION_RESOLVED | PFLAG2_TEXT_DIRECTION_RESOLVED_MASK);
18990         // Set to default value
18991         mPrivateFlags2 |= PFLAG2_TEXT_DIRECTION_RESOLVED_DEFAULT;
18992     }
18993
18994     /**
18995      * @return true if text direction is inherited.
18996      *
18997      * @hide
18998      */
18999     public boolean isTextDirectionInherited() {
19000         return (getRawTextDirection() == TEXT_DIRECTION_INHERIT);
19001     }
19002
19003     /**
19004      * @return true if text direction is resolved.
19005      */
19006     public boolean isTextDirectionResolved() {
19007         return (mPrivateFlags2 & PFLAG2_TEXT_DIRECTION_RESOLVED) == PFLAG2_TEXT_DIRECTION_RESOLVED;
19008     }
19009
19010     /**
19011      * Return the value specifying the text alignment or policy that was set with
19012      * {@link #setTextAlignment(int)}.
19013      *
19014      * @return the defined text alignment. It can be one of:
19015      *
19016      * {@link #TEXT_ALIGNMENT_INHERIT},
19017      * {@link #TEXT_ALIGNMENT_GRAVITY},
19018      * {@link #TEXT_ALIGNMENT_CENTER},
19019      * {@link #TEXT_ALIGNMENT_TEXT_START},
19020      * {@link #TEXT_ALIGNMENT_TEXT_END},
19021      * {@link #TEXT_ALIGNMENT_VIEW_START},
19022      * {@link #TEXT_ALIGNMENT_VIEW_END}
19023      *
19024      * @attr ref android.R.styleable#View_textAlignment
19025      *
19026      * @hide
19027      */
19028     @ViewDebug.ExportedProperty(category = "text", mapping = {
19029             @ViewDebug.IntToString(from = TEXT_ALIGNMENT_INHERIT, to = "INHERIT"),
19030             @ViewDebug.IntToString(from = TEXT_ALIGNMENT_GRAVITY, to = "GRAVITY"),
19031             @ViewDebug.IntToString(from = TEXT_ALIGNMENT_TEXT_START, to = "TEXT_START"),
19032             @ViewDebug.IntToString(from = TEXT_ALIGNMENT_TEXT_END, to = "TEXT_END"),
19033             @ViewDebug.IntToString(from = TEXT_ALIGNMENT_CENTER, to = "CENTER"),
19034             @ViewDebug.IntToString(from = TEXT_ALIGNMENT_VIEW_START, to = "VIEW_START"),
19035             @ViewDebug.IntToString(from = TEXT_ALIGNMENT_VIEW_END, to = "VIEW_END")
19036     })
19037     @TextAlignment
19038     public int getRawTextAlignment() {
19039         return (mPrivateFlags2 & PFLAG2_TEXT_ALIGNMENT_MASK) >> PFLAG2_TEXT_ALIGNMENT_MASK_SHIFT;
19040     }
19041
19042     /**
19043      * Set the text alignment.
19044      *
19045      * @param textAlignment The text alignment to set. Should be one of
19046      *
19047      * {@link #TEXT_ALIGNMENT_INHERIT},
19048      * {@link #TEXT_ALIGNMENT_GRAVITY},
19049      * {@link #TEXT_ALIGNMENT_CENTER},
19050      * {@link #TEXT_ALIGNMENT_TEXT_START},
19051      * {@link #TEXT_ALIGNMENT_TEXT_END},
19052      * {@link #TEXT_ALIGNMENT_VIEW_START},
19053      * {@link #TEXT_ALIGNMENT_VIEW_END}
19054      *
19055      * Resolution will be done if the value is set to TEXT_ALIGNMENT_INHERIT. The resolution
19056      * proceeds up the parent chain of the view to get the value. If there is no parent, then it
19057      * will return the default {@link #TEXT_ALIGNMENT_GRAVITY}.
19058      *
19059      * @attr ref android.R.styleable#View_textAlignment
19060      */
19061     public void setTextAlignment(@TextAlignment int textAlignment) {
19062         if (textAlignment != getRawTextAlignment()) {
19063             // Reset the current and resolved text alignment
19064             mPrivateFlags2 &= ~PFLAG2_TEXT_ALIGNMENT_MASK;
19065             resetResolvedTextAlignment();
19066             // Set the new text alignment
19067             mPrivateFlags2 |=
19068                     ((textAlignment << PFLAG2_TEXT_ALIGNMENT_MASK_SHIFT) & PFLAG2_TEXT_ALIGNMENT_MASK);
19069             // Do resolution
19070             resolveTextAlignment();
19071             // Notify change
19072             onRtlPropertiesChanged(getLayoutDirection());
19073             // Refresh
19074             requestLayout();
19075             invalidate(true);
19076         }
19077     }
19078
19079     /**
19080      * Return the resolved text alignment.
19081      *
19082      * @return the resolved text alignment. Returns one of:
19083      *
19084      * {@link #TEXT_ALIGNMENT_GRAVITY},
19085      * {@link #TEXT_ALIGNMENT_CENTER},
19086      * {@link #TEXT_ALIGNMENT_TEXT_START},
19087      * {@link #TEXT_ALIGNMENT_TEXT_END},
19088      * {@link #TEXT_ALIGNMENT_VIEW_START},
19089      * {@link #TEXT_ALIGNMENT_VIEW_END}
19090      *
19091      * @attr ref android.R.styleable#View_textAlignment
19092      */
19093     @ViewDebug.ExportedProperty(category = "text", mapping = {
19094             @ViewDebug.IntToString(from = TEXT_ALIGNMENT_INHERIT, to = "INHERIT"),
19095             @ViewDebug.IntToString(from = TEXT_ALIGNMENT_GRAVITY, to = "GRAVITY"),
19096             @ViewDebug.IntToString(from = TEXT_ALIGNMENT_TEXT_START, to = "TEXT_START"),
19097             @ViewDebug.IntToString(from = TEXT_ALIGNMENT_TEXT_END, to = "TEXT_END"),
19098             @ViewDebug.IntToString(from = TEXT_ALIGNMENT_CENTER, to = "CENTER"),
19099             @ViewDebug.IntToString(from = TEXT_ALIGNMENT_VIEW_START, to = "VIEW_START"),
19100             @ViewDebug.IntToString(from = TEXT_ALIGNMENT_VIEW_END, to = "VIEW_END")
19101     })
19102     @TextAlignment
19103     public int getTextAlignment() {
19104         return (mPrivateFlags2 & PFLAG2_TEXT_ALIGNMENT_RESOLVED_MASK) >>
19105                 PFLAG2_TEXT_ALIGNMENT_RESOLVED_MASK_SHIFT;
19106     }
19107
19108     /**
19109      * Resolve the text alignment.
19110      *
19111      * @return true if resolution has been done, false otherwise.
19112      *
19113      * @hide
19114      */
19115     public boolean resolveTextAlignment() {
19116         // Reset any previous text alignment resolution
19117         mPrivateFlags2 &= ~(PFLAG2_TEXT_ALIGNMENT_RESOLVED | PFLAG2_TEXT_ALIGNMENT_RESOLVED_MASK);
19118
19119         if (hasRtlSupport()) {
19120             // Set resolved text alignment flag depending on text alignment flag
19121             final int textAlignment = getRawTextAlignment();
19122             switch (textAlignment) {
19123                 case TEXT_ALIGNMENT_INHERIT:
19124                     // Check if we can resolve the text alignment
19125                     if (!canResolveTextAlignment()) {
19126                         // We cannot do the resolution if there is no parent so use the default
19127                         mPrivateFlags2 |= PFLAG2_TEXT_ALIGNMENT_RESOLVED_DEFAULT;
19128                         // Resolution will need to happen again later
19129                         return false;
19130                     }
19131
19132                     // Parent has not yet resolved, so we still return the default
19133                     try {
19134                         if (!mParent.isTextAlignmentResolved()) {
19135                             mPrivateFlags2 |= PFLAG2_TEXT_ALIGNMENT_RESOLVED_DEFAULT;
19136                             // Resolution will need to happen again later
19137                             return false;
19138                         }
19139                     } catch (AbstractMethodError e) {
19140                         Log.e(VIEW_LOG_TAG, mParent.getClass().getSimpleName() +
19141                                 " does not fully implement ViewParent", e);
19142                         mPrivateFlags2 |= PFLAG2_TEXT_ALIGNMENT_RESOLVED |
19143                                 PFLAG2_TEXT_ALIGNMENT_RESOLVED_DEFAULT;
19144                         return true;
19145                     }
19146
19147                     int parentResolvedTextAlignment;
19148                     try {
19149                         parentResolvedTextAlignment = mParent.getTextAlignment();
19150                     } catch (AbstractMethodError e) {
19151                         Log.e(VIEW_LOG_TAG, mParent.getClass().getSimpleName() +
19152                                 " does not fully implement ViewParent", e);
19153                         parentResolvedTextAlignment = TEXT_ALIGNMENT_GRAVITY;
19154                     }
19155                     switch (parentResolvedTextAlignment) {
19156                         case TEXT_ALIGNMENT_GRAVITY:
19157                         case TEXT_ALIGNMENT_TEXT_START:
19158                         case TEXT_ALIGNMENT_TEXT_END:
19159                         case TEXT_ALIGNMENT_CENTER:
19160                         case TEXT_ALIGNMENT_VIEW_START:
19161                         case TEXT_ALIGNMENT_VIEW_END:
19162                             // Resolved text alignment is the same as the parent resolved
19163                             // text alignment
19164                             mPrivateFlags2 |=
19165                                     (parentResolvedTextAlignment << PFLAG2_TEXT_ALIGNMENT_RESOLVED_MASK_SHIFT);
19166                             break;
19167                         default:
19168                             // Use default resolved text alignment
19169                             mPrivateFlags2 |= PFLAG2_TEXT_ALIGNMENT_RESOLVED_DEFAULT;
19170                     }
19171                     break;
19172                 case TEXT_ALIGNMENT_GRAVITY:
19173                 case TEXT_ALIGNMENT_TEXT_START:
19174                 case TEXT_ALIGNMENT_TEXT_END:
19175                 case TEXT_ALIGNMENT_CENTER:
19176                 case TEXT_ALIGNMENT_VIEW_START:
19177                 case TEXT_ALIGNMENT_VIEW_END:
19178                     // Resolved text alignment is the same as text alignment
19179                     mPrivateFlags2 |= (textAlignment << PFLAG2_TEXT_ALIGNMENT_RESOLVED_MASK_SHIFT);
19180                     break;
19181                 default:
19182                     // Use default resolved text alignment
19183                     mPrivateFlags2 |= PFLAG2_TEXT_ALIGNMENT_RESOLVED_DEFAULT;
19184             }
19185         } else {
19186             // Use default resolved text alignment
19187             mPrivateFlags2 |= PFLAG2_TEXT_ALIGNMENT_RESOLVED_DEFAULT;
19188         }
19189
19190         // Set the resolved
19191         mPrivateFlags2 |= PFLAG2_TEXT_ALIGNMENT_RESOLVED;
19192         return true;
19193     }
19194
19195     /**
19196      * Check if text alignment resolution can be done.
19197      *
19198      * @return true if text alignment resolution can be done otherwise return false.
19199      */
19200     public boolean canResolveTextAlignment() {
19201         switch (getRawTextAlignment()) {
19202             case TEXT_DIRECTION_INHERIT:
19203                 if (mParent != null) {
19204                     try {
19205                         return mParent.canResolveTextAlignment();
19206                     } catch (AbstractMethodError e) {
19207                         Log.e(VIEW_LOG_TAG, mParent.getClass().getSimpleName() +
19208                                 " does not fully implement ViewParent", e);
19209                     }
19210                 }
19211                 return false;
19212
19213             default:
19214                 return true;
19215         }
19216     }
19217
19218     /**
19219      * Reset resolved text alignment. Text alignment will be resolved during a call to
19220      * {@link #onMeasure(int, int)}.
19221      *
19222      * @hide
19223      */
19224     public void resetResolvedTextAlignment() {
19225         // Reset any previous text alignment resolution
19226         mPrivateFlags2 &= ~(PFLAG2_TEXT_ALIGNMENT_RESOLVED | PFLAG2_TEXT_ALIGNMENT_RESOLVED_MASK);
19227         // Set to default
19228         mPrivateFlags2 |= PFLAG2_TEXT_ALIGNMENT_RESOLVED_DEFAULT;
19229     }
19230
19231     /**
19232      * @return true if text alignment is inherited.
19233      *
19234      * @hide
19235      */
19236     public boolean isTextAlignmentInherited() {
19237         return (getRawTextAlignment() == TEXT_ALIGNMENT_INHERIT);
19238     }
19239
19240     /**
19241      * @return true if text alignment is resolved.
19242      */
19243     public boolean isTextAlignmentResolved() {
19244         return (mPrivateFlags2 & PFLAG2_TEXT_ALIGNMENT_RESOLVED) == PFLAG2_TEXT_ALIGNMENT_RESOLVED;
19245     }
19246
19247     /**
19248      * Generate a value suitable for use in {@link #setId(int)}.
19249      * This value will not collide with ID values generated at build time by aapt for R.id.
19250      *
19251      * @return a generated ID value
19252      */
19253     public static int generateViewId() {
19254         for (;;) {
19255             final int result = sNextGeneratedId.get();
19256             // aapt-generated IDs have the high byte nonzero; clamp to the range under that.
19257             int newValue = result + 1;
19258             if (newValue > 0x00FFFFFF) newValue = 1; // Roll over to 1, not 0.
19259             if (sNextGeneratedId.compareAndSet(result, newValue)) {
19260                 return result;
19261             }
19262         }
19263     }
19264
19265     /**
19266      * Gets the Views in the hierarchy affected by entering and exiting Activity Scene transitions.
19267      * @param transitioningViews This View will be added to transitioningViews if it is VISIBLE and
19268      *                           a normal View or a ViewGroup with
19269      *                           {@link android.view.ViewGroup#isTransitionGroup()} true.
19270      * @hide
19271      */
19272     public void captureTransitioningViews(List<View> transitioningViews) {
19273         if (getVisibility() == View.VISIBLE) {
19274             transitioningViews.add(this);
19275         }
19276     }
19277
19278     /**
19279      * Adds all Views that have {@link #getTransitionName()} non-null to namedElements.
19280      * @param namedElements Will contain all Views in the hierarchy having a transitionName.
19281      * @hide
19282      */
19283     public void findNamedViews(Map<String, View> namedElements) {
19284         if (getVisibility() == VISIBLE || mGhostView != null) {
19285             String transitionName = getTransitionName();
19286             if (transitionName != null) {
19287                 namedElements.put(transitionName, this);
19288             }
19289         }
19290     }
19291
19292     //
19293     // Properties
19294     //
19295     /**
19296      * A Property wrapper around the <code>alpha</code> functionality handled by the
19297      * {@link View#setAlpha(float)} and {@link View#getAlpha()} methods.
19298      */
19299     public static final Property<View, Float> ALPHA = new FloatProperty<View>("alpha") {
19300         @Override
19301         public void setValue(View object, float value) {
19302             object.setAlpha(value);
19303         }
19304
19305         @Override
19306         public Float get(View object) {
19307             return object.getAlpha();
19308         }
19309     };
19310
19311     /**
19312      * A Property wrapper around the <code>translationX</code> functionality handled by the
19313      * {@link View#setTranslationX(float)} and {@link View#getTranslationX()} methods.
19314      */
19315     public static final Property<View, Float> TRANSLATION_X = new FloatProperty<View>("translationX") {
19316         @Override
19317         public void setValue(View object, float value) {
19318             object.setTranslationX(value);
19319         }
19320
19321                 @Override
19322         public Float get(View object) {
19323             return object.getTranslationX();
19324         }
19325     };
19326
19327     /**
19328      * A Property wrapper around the <code>translationY</code> functionality handled by the
19329      * {@link View#setTranslationY(float)} and {@link View#getTranslationY()} methods.
19330      */
19331     public static final Property<View, Float> TRANSLATION_Y = new FloatProperty<View>("translationY") {
19332         @Override
19333         public void setValue(View object, float value) {
19334             object.setTranslationY(value);
19335         }
19336
19337         @Override
19338         public Float get(View object) {
19339             return object.getTranslationY();
19340         }
19341     };
19342
19343     /**
19344      * A Property wrapper around the <code>translationZ</code> functionality handled by the
19345      * {@link View#setTranslationZ(float)} and {@link View#getTranslationZ()} methods.
19346      */
19347     public static final Property<View, Float> TRANSLATION_Z = new FloatProperty<View>("translationZ") {
19348         @Override
19349         public void setValue(View object, float value) {
19350             object.setTranslationZ(value);
19351         }
19352
19353         @Override
19354         public Float get(View object) {
19355             return object.getTranslationZ();
19356         }
19357     };
19358
19359     /**
19360      * A Property wrapper around the <code>x</code> functionality handled by the
19361      * {@link View#setX(float)} and {@link View#getX()} methods.
19362      */
19363     public static final Property<View, Float> X = new FloatProperty<View>("x") {
19364         @Override
19365         public void setValue(View object, float value) {
19366             object.setX(value);
19367         }
19368
19369         @Override
19370         public Float get(View object) {
19371             return object.getX();
19372         }
19373     };
19374
19375     /**
19376      * A Property wrapper around the <code>y</code> functionality handled by the
19377      * {@link View#setY(float)} and {@link View#getY()} methods.
19378      */
19379     public static final Property<View, Float> Y = new FloatProperty<View>("y") {
19380         @Override
19381         public void setValue(View object, float value) {
19382             object.setY(value);
19383         }
19384
19385         @Override
19386         public Float get(View object) {
19387             return object.getY();
19388         }
19389     };
19390
19391     /**
19392      * A Property wrapper around the <code>z</code> functionality handled by the
19393      * {@link View#setZ(float)} and {@link View#getZ()} methods.
19394      */
19395     public static final Property<View, Float> Z = new FloatProperty<View>("z") {
19396         @Override
19397         public void setValue(View object, float value) {
19398             object.setZ(value);
19399         }
19400
19401         @Override
19402         public Float get(View object) {
19403             return object.getZ();
19404         }
19405     };
19406
19407     /**
19408      * A Property wrapper around the <code>rotation</code> functionality handled by the
19409      * {@link View#setRotation(float)} and {@link View#getRotation()} methods.
19410      */
19411     public static final Property<View, Float> ROTATION = new FloatProperty<View>("rotation") {
19412         @Override
19413         public void setValue(View object, float value) {
19414             object.setRotation(value);
19415         }
19416
19417         @Override
19418         public Float get(View object) {
19419             return object.getRotation();
19420         }
19421     };
19422
19423     /**
19424      * A Property wrapper around the <code>rotationX</code> functionality handled by the
19425      * {@link View#setRotationX(float)} and {@link View#getRotationX()} methods.
19426      */
19427     public static final Property<View, Float> ROTATION_X = new FloatProperty<View>("rotationX") {
19428         @Override
19429         public void setValue(View object, float value) {
19430             object.setRotationX(value);
19431         }
19432
19433         @Override
19434         public Float get(View object) {
19435             return object.getRotationX();
19436         }
19437     };
19438
19439     /**
19440      * A Property wrapper around the <code>rotationY</code> functionality handled by the
19441      * {@link View#setRotationY(float)} and {@link View#getRotationY()} methods.
19442      */
19443     public static final Property<View, Float> ROTATION_Y = new FloatProperty<View>("rotationY") {
19444         @Override
19445         public void setValue(View object, float value) {
19446             object.setRotationY(value);
19447         }
19448
19449         @Override
19450         public Float get(View object) {
19451             return object.getRotationY();
19452         }
19453     };
19454
19455     /**
19456      * A Property wrapper around the <code>scaleX</code> functionality handled by the
19457      * {@link View#setScaleX(float)} and {@link View#getScaleX()} methods.
19458      */
19459     public static final Property<View, Float> SCALE_X = new FloatProperty<View>("scaleX") {
19460         @Override
19461         public void setValue(View object, float value) {
19462             object.setScaleX(value);
19463         }
19464
19465         @Override
19466         public Float get(View object) {
19467             return object.getScaleX();
19468         }
19469     };
19470
19471     /**
19472      * A Property wrapper around the <code>scaleY</code> functionality handled by the
19473      * {@link View#setScaleY(float)} and {@link View#getScaleY()} methods.
19474      */
19475     public static final Property<View, Float> SCALE_Y = new FloatProperty<View>("scaleY") {
19476         @Override
19477         public void setValue(View object, float value) {
19478             object.setScaleY(value);
19479         }
19480
19481         @Override
19482         public Float get(View object) {
19483             return object.getScaleY();
19484         }
19485     };
19486
19487     /**
19488      * A MeasureSpec encapsulates the layout requirements passed from parent to child.
19489      * Each MeasureSpec represents a requirement for either the width or the height.
19490      * A MeasureSpec is comprised of a size and a mode. There are three possible
19491      * modes:
19492      * <dl>
19493      * <dt>UNSPECIFIED</dt>
19494      * <dd>
19495      * The parent has not imposed any constraint on the child. It can be whatever size
19496      * it wants.
19497      * </dd>
19498      *
19499      * <dt>EXACTLY</dt>
19500      * <dd>
19501      * The parent has determined an exact size for the child. The child is going to be
19502      * given those bounds regardless of how big it wants to be.
19503      * </dd>
19504      *
19505      * <dt>AT_MOST</dt>
19506      * <dd>
19507      * The child can be as large as it wants up to the specified size.
19508      * </dd>
19509      * </dl>
19510      *
19511      * MeasureSpecs are implemented as ints to reduce object allocation. This class
19512      * is provided to pack and unpack the &lt;size, mode&gt; tuple into the int.
19513      */
19514     public static class MeasureSpec {
19515         private static final int MODE_SHIFT = 30;
19516         private static final int MODE_MASK  = 0x3 << MODE_SHIFT;
19517
19518         /**
19519          * Measure specification mode: The parent has not imposed any constraint
19520          * on the child. It can be whatever size it wants.
19521          */
19522         public static final int UNSPECIFIED = 0 << MODE_SHIFT;
19523
19524         /**
19525          * Measure specification mode: The parent has determined an exact size
19526          * for the child. The child is going to be given those bounds regardless
19527          * of how big it wants to be.
19528          */
19529         public static final int EXACTLY     = 1 << MODE_SHIFT;
19530
19531         /**
19532          * Measure specification mode: The child can be as large as it wants up
19533          * to the specified size.
19534          */
19535         public static final int AT_MOST     = 2 << MODE_SHIFT;
19536
19537         /**
19538          * Creates a measure specification based on the supplied size and mode.
19539          *
19540          * The mode must always be one of the following:
19541          * <ul>
19542          *  <li>{@link android.view.View.MeasureSpec#UNSPECIFIED}</li>
19543          *  <li>{@link android.view.View.MeasureSpec#EXACTLY}</li>
19544          *  <li>{@link android.view.View.MeasureSpec#AT_MOST}</li>
19545          * </ul>
19546          *
19547          * <p><strong>Note:</strong> On API level 17 and lower, makeMeasureSpec's
19548          * implementation was such that the order of arguments did not matter
19549          * and overflow in either value could impact the resulting MeasureSpec.
19550          * {@link android.widget.RelativeLayout} was affected by this bug.
19551          * Apps targeting API levels greater than 17 will get the fixed, more strict
19552          * behavior.</p>
19553          *
19554          * @param size the size of the measure specification
19555          * @param mode the mode of the measure specification
19556          * @return the measure specification based on size and mode
19557          */
19558         public static int makeMeasureSpec(int size, int mode) {
19559             if (sUseBrokenMakeMeasureSpec) {
19560                 return size + mode;
19561             } else {
19562                 return (size & ~MODE_MASK) | (mode & MODE_MASK);
19563             }
19564         }
19565
19566         /**
19567          * Extracts the mode from the supplied measure specification.
19568          *
19569          * @param measureSpec the measure specification to extract the mode from
19570          * @return {@link android.view.View.MeasureSpec#UNSPECIFIED},
19571          *         {@link android.view.View.MeasureSpec#AT_MOST} or
19572          *         {@link android.view.View.MeasureSpec#EXACTLY}
19573          */
19574         public static int getMode(int measureSpec) {
19575             return (measureSpec & MODE_MASK);
19576         }
19577
19578         /**
19579          * Extracts the size from the supplied measure specification.
19580          *
19581          * @param measureSpec the measure specification to extract the size from
19582          * @return the size in pixels defined in the supplied measure specification
19583          */
19584         public static int getSize(int measureSpec) {
19585             return (measureSpec & ~MODE_MASK);
19586         }
19587
19588         static int adjust(int measureSpec, int delta) {
19589             final int mode = getMode(measureSpec);
19590             if (mode == UNSPECIFIED) {
19591                 // No need to adjust size for UNSPECIFIED mode.
19592                 return makeMeasureSpec(0, UNSPECIFIED);
19593             }
19594             int size = getSize(measureSpec) + delta;
19595             if (size < 0) {
19596                 Log.e(VIEW_LOG_TAG, "MeasureSpec.adjust: new size would be negative! (" + size +
19597                         ") spec: " + toString(measureSpec) + " delta: " + delta);
19598                 size = 0;
19599             }
19600             return makeMeasureSpec(size, mode);
19601         }
19602
19603         /**
19604          * Returns a String representation of the specified measure
19605          * specification.
19606          *
19607          * @param measureSpec the measure specification to convert to a String
19608          * @return a String with the following format: "MeasureSpec: MODE SIZE"
19609          */
19610         public static String toString(int measureSpec) {
19611             int mode = getMode(measureSpec);
19612             int size = getSize(measureSpec);
19613
19614             StringBuilder sb = new StringBuilder("MeasureSpec: ");
19615
19616             if (mode == UNSPECIFIED)
19617                 sb.append("UNSPECIFIED ");
19618             else if (mode == EXACTLY)
19619                 sb.append("EXACTLY ");
19620             else if (mode == AT_MOST)
19621                 sb.append("AT_MOST ");
19622             else
19623                 sb.append(mode).append(" ");
19624
19625             sb.append(size);
19626             return sb.toString();
19627         }
19628     }
19629
19630     private final class CheckForLongPress implements Runnable {
19631         private int mOriginalWindowAttachCount;
19632
19633         @Override
19634         public void run() {
19635             if (isPressed() && (mParent != null)
19636                     && mOriginalWindowAttachCount == mWindowAttachCount) {
19637                 if (performLongClick()) {
19638                     mHasPerformedLongPress = true;
19639                 }
19640             }
19641         }
19642
19643         public void rememberWindowAttachCount() {
19644             mOriginalWindowAttachCount = mWindowAttachCount;
19645         }
19646     }
19647
19648     private final class CheckForTap implements Runnable {
19649         public float x;
19650         public float y;
19651
19652         @Override
19653         public void run() {
19654             mPrivateFlags &= ~PFLAG_PREPRESSED;
19655             setPressed(true, x, y);
19656             checkForLongClick(ViewConfiguration.getTapTimeout());
19657         }
19658     }
19659
19660     private final class PerformClick implements Runnable {
19661         @Override
19662         public void run() {
19663             performClick();
19664         }
19665     }
19666
19667     /** @hide */
19668     public void hackTurnOffWindowResizeAnim(boolean off) {
19669         mAttachInfo.mTurnOffWindowResizeAnim = off;
19670     }
19671
19672     /**
19673      * This method returns a ViewPropertyAnimator object, which can be used to animate
19674      * specific properties on this View.
19675      *
19676      * @return ViewPropertyAnimator The ViewPropertyAnimator associated with this View.
19677      */
19678     public ViewPropertyAnimator animate() {
19679         if (mAnimator == null) {
19680             mAnimator = new ViewPropertyAnimator(this);
19681         }
19682         return mAnimator;
19683     }
19684
19685     /**
19686      * Sets the name of the View to be used to identify Views in Transitions.
19687      * Names should be unique in the View hierarchy.
19688      *
19689      * @param transitionName The name of the View to uniquely identify it for Transitions.
19690      */
19691     public final void setTransitionName(String transitionName) {
19692         mTransitionName = transitionName;
19693     }
19694
19695     /**
19696      * Returns the name of the View to be used to identify Views in Transitions.
19697      * Names should be unique in the View hierarchy.
19698      *
19699      * <p>This returns null if the View has not been given a name.</p>
19700      *
19701      * @return The name used of the View to be used to identify Views in Transitions or null
19702      * if no name has been given.
19703      */
19704     @ViewDebug.ExportedProperty
19705     public String getTransitionName() {
19706         return mTransitionName;
19707     }
19708
19709     /**
19710      * Interface definition for a callback to be invoked when a hardware key event is
19711      * dispatched to this view. The callback will be invoked before the key event is
19712      * given to the view. This is only useful for hardware keyboards; a software input
19713      * method has no obligation to trigger this listener.
19714      */
19715     public interface OnKeyListener {
19716         /**
19717          * Called when a hardware key is dispatched to a view. This allows listeners to
19718          * get a chance to respond before the target view.
19719          * <p>Key presses in software keyboards will generally NOT trigger this method,
19720          * although some may elect to do so in some situations. Do not assume a
19721          * software input method has to be key-based; even if it is, it may use key presses
19722          * in a different way than you expect, so there is no way to reliably catch soft
19723          * input key presses.
19724          *
19725          * @param v The view the key has been dispatched to.
19726          * @param keyCode The code for the physical key that was pressed
19727          * @param event The KeyEvent object containing full information about
19728          *        the event.
19729          * @return True if the listener has consumed the event, false otherwise.
19730          */
19731         boolean onKey(View v, int keyCode, KeyEvent event);
19732     }
19733
19734     /**
19735      * Interface definition for a callback to be invoked when a touch event is
19736      * dispatched to this view. The callback will be invoked before the touch
19737      * event is given to the view.
19738      */
19739     public interface OnTouchListener {
19740         /**
19741          * Called when a touch event is dispatched to a view. This allows listeners to
19742          * get a chance to respond before the target view.
19743          *
19744          * @param v The view the touch event has been dispatched to.
19745          * @param event The MotionEvent object containing full information about
19746          *        the event.
19747          * @return True if the listener has consumed the event, false otherwise.
19748          */
19749         boolean onTouch(View v, MotionEvent event);
19750     }
19751
19752     /**
19753      * Interface definition for a callback to be invoked when a hover event is
19754      * dispatched to this view. The callback will be invoked before the hover
19755      * event is given to the view.
19756      */
19757     public interface OnHoverListener {
19758         /**
19759          * Called when a hover event is dispatched to a view. This allows listeners to
19760          * get a chance to respond before the target view.
19761          *
19762          * @param v The view the hover event has been dispatched to.
19763          * @param event The MotionEvent object containing full information about
19764          *        the event.
19765          * @return True if the listener has consumed the event, false otherwise.
19766          */
19767         boolean onHover(View v, MotionEvent event);
19768     }
19769
19770     /**
19771      * Interface definition for a callback to be invoked when a generic motion event is
19772      * dispatched to this view. The callback will be invoked before the generic motion
19773      * event is given to the view.
19774      */
19775     public interface OnGenericMotionListener {
19776         /**
19777          * Called when a generic motion event is dispatched to a view. This allows listeners to
19778          * get a chance to respond before the target view.
19779          *
19780          * @param v The view the generic motion event has been dispatched to.
19781          * @param event The MotionEvent object containing full information about
19782          *        the event.
19783          * @return True if the listener has consumed the event, false otherwise.
19784          */
19785         boolean onGenericMotion(View v, MotionEvent event);
19786     }
19787
19788     /**
19789      * Interface definition for a callback to be invoked when a view has been clicked and held.
19790      */
19791     public interface OnLongClickListener {
19792         /**
19793          * Called when a view has been clicked and held.
19794          *
19795          * @param v The view that was clicked and held.
19796          *
19797          * @return true if the callback consumed the long click, false otherwise.
19798          */
19799         boolean onLongClick(View v);
19800     }
19801
19802     /**
19803      * Interface definition for a callback to be invoked when a drag is being dispatched
19804      * to this view.  The callback will be invoked before the hosting view's own
19805      * onDrag(event) method.  If the listener wants to fall back to the hosting view's
19806      * onDrag(event) behavior, it should return 'false' from this callback.
19807      *
19808      * <div class="special reference">
19809      * <h3>Developer Guides</h3>
19810      * <p>For a guide to implementing drag and drop features, read the
19811      * <a href="{@docRoot}guide/topics/ui/drag-drop.html">Drag and Drop</a> developer guide.</p>
19812      * </div>
19813      */
19814     public interface OnDragListener {
19815         /**
19816          * Called when a drag event is dispatched to a view. This allows listeners
19817          * to get a chance to override base View behavior.
19818          *
19819          * @param v The View that received the drag event.
19820          * @param event The {@link android.view.DragEvent} object for the drag event.
19821          * @return {@code true} if the drag event was handled successfully, or {@code false}
19822          * if the drag event was not handled. Note that {@code false} will trigger the View
19823          * to call its {@link #onDragEvent(DragEvent) onDragEvent()} handler.
19824          */
19825         boolean onDrag(View v, DragEvent event);
19826     }
19827
19828     /**
19829      * Interface definition for a callback to be invoked when the focus state of
19830      * a view changed.
19831      */
19832     public interface OnFocusChangeListener {
19833         /**
19834          * Called when the focus state of a view has changed.
19835          *
19836          * @param v The view whose state has changed.
19837          * @param hasFocus The new focus state of v.
19838          */
19839         void onFocusChange(View v, boolean hasFocus);
19840     }
19841
19842     /**
19843      * Interface definition for a callback to be invoked when a view is clicked.
19844      */
19845     public interface OnClickListener {
19846         /**
19847          * Called when a view has been clicked.
19848          *
19849          * @param v The view that was clicked.
19850          */
19851         void onClick(View v);
19852     }
19853
19854     /**
19855      * Interface definition for a callback to be invoked when the context menu
19856      * for this view is being built.
19857      */
19858     public interface OnCreateContextMenuListener {
19859         /**
19860          * Called when the context menu for this view is being built. It is not
19861          * safe to hold onto the menu after this method returns.
19862          *
19863          * @param menu The context menu that is being built
19864          * @param v The view for which the context menu is being built
19865          * @param menuInfo Extra information about the item for which the
19866          *            context menu should be shown. This information will vary
19867          *            depending on the class of v.
19868          */
19869         void onCreateContextMenu(ContextMenu menu, View v, ContextMenuInfo menuInfo);
19870     }
19871
19872     /**
19873      * Interface definition for a callback to be invoked when the status bar changes
19874      * visibility.  This reports <strong>global</strong> changes to the system UI
19875      * state, not what the application is requesting.
19876      *
19877      * @see View#setOnSystemUiVisibilityChangeListener(android.view.View.OnSystemUiVisibilityChangeListener)
19878      */
19879     public interface OnSystemUiVisibilityChangeListener {
19880         /**
19881          * Called when the status bar changes visibility because of a call to
19882          * {@link View#setSystemUiVisibility(int)}.
19883          *
19884          * @param visibility  Bitwise-or of flags {@link #SYSTEM_UI_FLAG_LOW_PROFILE},
19885          * {@link #SYSTEM_UI_FLAG_HIDE_NAVIGATION}, and {@link #SYSTEM_UI_FLAG_FULLSCREEN}.
19886          * This tells you the <strong>global</strong> state of these UI visibility
19887          * flags, not what your app is currently applying.
19888          */
19889         public void onSystemUiVisibilityChange(int visibility);
19890     }
19891
19892     /**
19893      * Interface definition for a callback to be invoked when this view is attached
19894      * or detached from its window.
19895      */
19896     public interface OnAttachStateChangeListener {
19897         /**
19898          * Called when the view is attached to a window.
19899          * @param v The view that was attached
19900          */
19901         public void onViewAttachedToWindow(View v);
19902         /**
19903          * Called when the view is detached from a window.
19904          * @param v The view that was detached
19905          */
19906         public void onViewDetachedFromWindow(View v);
19907     }
19908
19909     /**
19910      * Listener for applying window insets on a view in a custom way.
19911      *
19912      * <p>Apps may choose to implement this interface if they want to apply custom policy
19913      * to the way that window insets are treated for a view. If an OnApplyWindowInsetsListener
19914      * is set, its
19915      * {@link OnApplyWindowInsetsListener#onApplyWindowInsets(View, WindowInsets) onApplyWindowInsets}
19916      * method will be called instead of the View's own
19917      * {@link #onApplyWindowInsets(WindowInsets) onApplyWindowInsets} method. The listener
19918      * may optionally call the parameter View's <code>onApplyWindowInsets</code> method to apply
19919      * the View's normal behavior as part of its own.</p>
19920      */
19921     public interface OnApplyWindowInsetsListener {
19922         /**
19923          * When {@link View#setOnApplyWindowInsetsListener(View.OnApplyWindowInsetsListener) set}
19924          * on a View, this listener method will be called instead of the view's own
19925          * {@link View#onApplyWindowInsets(WindowInsets) onApplyWindowInsets} method.
19926          *
19927          * @param v The view applying window insets
19928          * @param insets The insets to apply
19929          * @return The insets supplied, minus any insets that were consumed
19930          */
19931         public WindowInsets onApplyWindowInsets(View v, WindowInsets insets);
19932     }
19933
19934     private final class UnsetPressedState implements Runnable {
19935         @Override
19936         public void run() {
19937             setPressed(false);
19938         }
19939     }
19940
19941     /**
19942      * Base class for derived classes that want to save and restore their own
19943      * state in {@link android.view.View#onSaveInstanceState()}.
19944      */
19945     public static class BaseSavedState extends AbsSavedState {
19946         /**
19947          * Constructor used when reading from a parcel. Reads the state of the superclass.
19948          *
19949          * @param source
19950          */
19951         public BaseSavedState(Parcel source) {
19952             super(source);
19953         }
19954
19955         /**
19956          * Constructor called by derived classes when creating their SavedState objects
19957          *
19958          * @param superState The state of the superclass of this view
19959          */
19960         public BaseSavedState(Parcelable superState) {
19961             super(superState);
19962         }
19963
19964         public static final Parcelable.Creator<BaseSavedState> CREATOR =
19965                 new Parcelable.Creator<BaseSavedState>() {
19966             public BaseSavedState createFromParcel(Parcel in) {
19967                 return new BaseSavedState(in);
19968             }
19969
19970             public BaseSavedState[] newArray(int size) {
19971                 return new BaseSavedState[size];
19972             }
19973         };
19974     }
19975
19976     /**
19977      * A set of information given to a view when it is attached to its parent
19978      * window.
19979      */
19980     final static class AttachInfo {
19981         interface Callbacks {
19982             void playSoundEffect(int effectId);
19983             boolean performHapticFeedback(int effectId, boolean always);
19984         }
19985
19986         /**
19987          * InvalidateInfo is used to post invalidate(int, int, int, int) messages
19988          * to a Handler. This class contains the target (View) to invalidate and
19989          * the coordinates of the dirty rectangle.
19990          *
19991          * For performance purposes, this class also implements a pool of up to
19992          * POOL_LIMIT objects that get reused. This reduces memory allocations
19993          * whenever possible.
19994          */
19995         static class InvalidateInfo {
19996             private static final int POOL_LIMIT = 10;
19997
19998             private static final SynchronizedPool<InvalidateInfo> sPool =
19999                     new SynchronizedPool<InvalidateInfo>(POOL_LIMIT);
20000
20001             View target;
20002
20003             int left;
20004             int top;
20005             int right;
20006             int bottom;
20007
20008             public static InvalidateInfo obtain() {
20009                 InvalidateInfo instance = sPool.acquire();
20010                 return (instance != null) ? instance : new InvalidateInfo();
20011             }
20012
20013             public void recycle() {
20014                 target = null;
20015                 sPool.release(this);
20016             }
20017         }
20018
20019         final IWindowSession mSession;
20020
20021         final IWindow mWindow;
20022
20023         final IBinder mWindowToken;
20024
20025         final Display mDisplay;
20026
20027         final Callbacks mRootCallbacks;
20028
20029         IWindowId mIWindowId;
20030         WindowId mWindowId;
20031
20032         /**
20033          * The top view of the hierarchy.
20034          */
20035         View mRootView;
20036
20037         IBinder mPanelParentWindowToken;
20038
20039         boolean mHardwareAccelerated;
20040         boolean mHardwareAccelerationRequested;
20041         HardwareRenderer mHardwareRenderer;
20042         List<RenderNode> mPendingAnimatingRenderNodes;
20043
20044         /**
20045          * The state of the display to which the window is attached, as reported
20046          * by {@link Display#getState()}.  Note that the display state constants
20047          * declared by {@link Display} do not exactly line up with the screen state
20048          * constants declared by {@link View} (there are more display states than
20049          * screen states).
20050          */
20051         int mDisplayState = Display.STATE_UNKNOWN;
20052
20053         /**
20054          * Scale factor used by the compatibility mode
20055          */
20056         float mApplicationScale;
20057
20058         /**
20059          * Indicates whether the application is in compatibility mode
20060          */
20061         boolean mScalingRequired;
20062
20063         /**
20064          * If set, ViewRootImpl doesn't use its lame animation for when the window resizes.
20065          */
20066         boolean mTurnOffWindowResizeAnim;
20067
20068         /**
20069          * Left position of this view's window
20070          */
20071         int mWindowLeft;
20072
20073         /**
20074          * Top position of this view's window
20075          */
20076         int mWindowTop;
20077
20078         /**
20079          * Indicates whether views need to use 32-bit drawing caches
20080          */
20081         boolean mUse32BitDrawingCache;
20082
20083         /**
20084          * For windows that are full-screen but using insets to layout inside
20085          * of the screen areas, these are the current insets to appear inside
20086          * the overscan area of the display.
20087          */
20088         final Rect mOverscanInsets = new Rect();
20089
20090         /**
20091          * For windows that are full-screen but using insets to layout inside
20092          * of the screen decorations, these are the current insets for the
20093          * content of the window.
20094          */
20095         final Rect mContentInsets = new Rect();
20096
20097         /**
20098          * For windows that are full-screen but using insets to layout inside
20099          * of the screen decorations, these are the current insets for the
20100          * actual visible parts of the window.
20101          */
20102         final Rect mVisibleInsets = new Rect();
20103
20104         /**
20105          * For windows that are full-screen but using insets to layout inside
20106          * of the screen decorations, these are the current insets for the
20107          * stable system windows.
20108          */
20109         final Rect mStableInsets = new Rect();
20110
20111         /**
20112          * The internal insets given by this window.  This value is
20113          * supplied by the client (through
20114          * {@link ViewTreeObserver.OnComputeInternalInsetsListener}) and will
20115          * be given to the window manager when changed to be used in laying
20116          * out windows behind it.
20117          */
20118         final ViewTreeObserver.InternalInsetsInfo mGivenInternalInsets
20119                 = new ViewTreeObserver.InternalInsetsInfo();
20120
20121         /**
20122          * Set to true when mGivenInternalInsets is non-empty.
20123          */
20124         boolean mHasNonEmptyGivenInternalInsets;
20125
20126         /**
20127          * All views in the window's hierarchy that serve as scroll containers,
20128          * used to determine if the window can be resized or must be panned
20129          * to adjust for a soft input area.
20130          */
20131         final ArrayList<View> mScrollContainers = new ArrayList<View>();
20132
20133         final KeyEvent.DispatcherState mKeyDispatchState
20134                 = new KeyEvent.DispatcherState();
20135
20136         /**
20137          * Indicates whether the view's window currently has the focus.
20138          */
20139         boolean mHasWindowFocus;
20140
20141         /**
20142          * The current visibility of the window.
20143          */
20144         int mWindowVisibility;
20145
20146         /**
20147          * Indicates the time at which drawing started to occur.
20148          */
20149         long mDrawingTime;
20150
20151         /**
20152          * Indicates whether or not ignoring the DIRTY_MASK flags.
20153          */
20154         boolean mIgnoreDirtyState;
20155
20156         /**
20157          * This flag tracks when the mIgnoreDirtyState flag is set during draw(),
20158          * to avoid clearing that flag prematurely.
20159          */
20160         boolean mSetIgnoreDirtyState = false;
20161
20162         /**
20163          * Indicates whether the view's window is currently in touch mode.
20164          */
20165         boolean mInTouchMode;
20166
20167         /**
20168          * Indicates whether the view has requested unbuffered input dispatching for the current
20169          * event stream.
20170          */
20171         boolean mUnbufferedDispatchRequested;
20172
20173         /**
20174          * Indicates that ViewAncestor should trigger a global layout change
20175          * the next time it performs a traversal
20176          */
20177         boolean mRecomputeGlobalAttributes;
20178
20179         /**
20180          * Always report new attributes at next traversal.
20181          */
20182         boolean mForceReportNewAttributes;
20183
20184         /**
20185          * Set during a traveral if any views want to keep the screen on.
20186          */
20187         boolean mKeepScreenOn;
20188
20189         /**
20190          * Bitwise-or of all of the values that views have passed to setSystemUiVisibility().
20191          */
20192         int mSystemUiVisibility;
20193
20194         /**
20195          * Hack to force certain system UI visibility flags to be cleared.
20196          */
20197         int mDisabledSystemUiVisibility;
20198
20199         /**
20200          * Last global system UI visibility reported by the window manager.
20201          */
20202         int mGlobalSystemUiVisibility;
20203
20204         /**
20205          * True if a view in this hierarchy has an OnSystemUiVisibilityChangeListener
20206          * attached.
20207          */
20208         boolean mHasSystemUiListeners;
20209
20210         /**
20211          * Set if the window has requested to extend into the overscan region
20212          * via WindowManager.LayoutParams.FLAG_LAYOUT_IN_OVERSCAN.
20213          */
20214         boolean mOverscanRequested;
20215
20216         /**
20217          * Set if the visibility of any views has changed.
20218          */
20219         boolean mViewVisibilityChanged;
20220
20221         /**
20222          * Set to true if a view has been scrolled.
20223          */
20224         boolean mViewScrollChanged;
20225
20226         /**
20227          * Set to true if high contrast mode enabled
20228          */
20229         boolean mHighContrastText;
20230
20231         /**
20232          * Global to the view hierarchy used as a temporary for dealing with
20233          * x/y points in the transparent region computations.
20234          */
20235         final int[] mTransparentLocation = new int[2];
20236
20237         /**
20238          * Global to the view hierarchy used as a temporary for dealing with
20239          * x/y points in the ViewGroup.invalidateChild implementation.
20240          */
20241         final int[] mInvalidateChildLocation = new int[2];
20242
20243         /**
20244          * Global to the view hierarchy used as a temporary for dealng with
20245          * computing absolute on-screen location.
20246          */
20247         final int[] mTmpLocation = new int[2];
20248
20249         /**
20250          * Global to the view hierarchy used as a temporary for dealing with
20251          * x/y location when view is transformed.
20252          */
20253         final float[] mTmpTransformLocation = new float[2];
20254
20255         /**
20256          * The view tree observer used to dispatch global events like
20257          * layout, pre-draw, touch mode change, etc.
20258          */
20259         final ViewTreeObserver mTreeObserver = new ViewTreeObserver();
20260
20261         /**
20262          * A Canvas used by the view hierarchy to perform bitmap caching.
20263          */
20264         Canvas mCanvas;
20265
20266         /**
20267          * The view root impl.
20268          */
20269         final ViewRootImpl mViewRootImpl;
20270
20271         /**
20272          * A Handler supplied by a view's {@link android.view.ViewRootImpl}. This
20273          * handler can be used to pump events in the UI events queue.
20274          */
20275         final Handler mHandler;
20276
20277         /**
20278          * Temporary for use in computing invalidate rectangles while
20279          * calling up the hierarchy.
20280          */
20281         final Rect mTmpInvalRect = new Rect();
20282
20283         /**
20284          * Temporary for use in computing hit areas with transformed views
20285          */
20286         final RectF mTmpTransformRect = new RectF();
20287
20288         /**
20289          * Temporary for use in computing hit areas with transformed views
20290          */
20291         final RectF mTmpTransformRect1 = new RectF();
20292
20293         /**
20294          * Temporary list of rectanges.
20295          */
20296         final List<RectF> mTmpRectList = new ArrayList<>();
20297
20298         /**
20299          * Temporary for use in transforming invalidation rect
20300          */
20301         final Matrix mTmpMatrix = new Matrix();
20302
20303         /**
20304          * Temporary for use in transforming invalidation rect
20305          */
20306         final Transformation mTmpTransformation = new Transformation();
20307
20308         /**
20309          * Temporary for use in querying outlines from OutlineProviders
20310          */
20311         final Outline mTmpOutline = new Outline();
20312
20313         /**
20314          * Temporary list for use in collecting focusable descendents of a view.
20315          */
20316         final ArrayList<View> mTempArrayList = new ArrayList<View>(24);
20317
20318         /**
20319          * The id of the window for accessibility purposes.
20320          */
20321         int mAccessibilityWindowId = AccessibilityNodeInfo.UNDEFINED_ITEM_ID;
20322
20323         /**
20324          * Flags related to accessibility processing.
20325          *
20326          * @see AccessibilityNodeInfo#FLAG_INCLUDE_NOT_IMPORTANT_VIEWS
20327          * @see AccessibilityNodeInfo#FLAG_REPORT_VIEW_IDS
20328          */
20329         int mAccessibilityFetchFlags;
20330
20331         /**
20332          * The drawable for highlighting accessibility focus.
20333          */
20334         Drawable mAccessibilityFocusDrawable;
20335
20336         /**
20337          * Show where the margins, bounds and layout bounds are for each view.
20338          */
20339         boolean mDebugLayout = SystemProperties.getBoolean(DEBUG_LAYOUT_PROPERTY, false);
20340
20341         /**
20342          * Point used to compute visible regions.
20343          */
20344         final Point mPoint = new Point();
20345
20346         /**
20347          * Used to track which View originated a requestLayout() call, used when
20348          * requestLayout() is called during layout.
20349          */
20350         View mViewRequestingLayout;
20351
20352         /**
20353          * Creates a new set of attachment information with the specified
20354          * events handler and thread.
20355          *
20356          * @param handler the events handler the view must use
20357          */
20358         AttachInfo(IWindowSession session, IWindow window, Display display,
20359                 ViewRootImpl viewRootImpl, Handler handler, Callbacks effectPlayer) {
20360             mSession = session;
20361             mWindow = window;
20362             mWindowToken = window.asBinder();
20363             mDisplay = display;
20364             mViewRootImpl = viewRootImpl;
20365             mHandler = handler;
20366             mRootCallbacks = effectPlayer;
20367         }
20368     }
20369
20370     /**
20371      * <p>ScrollabilityCache holds various fields used by a View when scrolling
20372      * is supported. This avoids keeping too many unused fields in most
20373      * instances of View.</p>
20374      */
20375     private static class ScrollabilityCache implements Runnable {
20376
20377         /**
20378          * Scrollbars are not visible
20379          */
20380         public static final int OFF = 0;
20381
20382         /**
20383          * Scrollbars are visible
20384          */
20385         public static final int ON = 1;
20386
20387         /**
20388          * Scrollbars are fading away
20389          */
20390         public static final int FADING = 2;
20391
20392         public boolean fadeScrollBars;
20393
20394         public int fadingEdgeLength;
20395         public int scrollBarDefaultDelayBeforeFade;
20396         public int scrollBarFadeDuration;
20397
20398         public int scrollBarSize;
20399         public ScrollBarDrawable scrollBar;
20400         public float[] interpolatorValues;
20401         public View host;
20402
20403         public final Paint paint;
20404         public final Matrix matrix;
20405         public Shader shader;
20406
20407         public final Interpolator scrollBarInterpolator = new Interpolator(1, 2);
20408
20409         private static final float[] OPAQUE = { 255 };
20410         private static final float[] TRANSPARENT = { 0.0f };
20411
20412         /**
20413          * When fading should start. This time moves into the future every time
20414          * a new scroll happens. Measured based on SystemClock.uptimeMillis()
20415          */
20416         public long fadeStartTime;
20417
20418
20419         /**
20420          * The current state of the scrollbars: ON, OFF, or FADING
20421          */
20422         public int state = OFF;
20423
20424         private int mLastColor;
20425
20426         public ScrollabilityCache(ViewConfiguration configuration, View host) {
20427             fadingEdgeLength = configuration.getScaledFadingEdgeLength();
20428             scrollBarSize = configuration.getScaledScrollBarSize();
20429             scrollBarDefaultDelayBeforeFade = ViewConfiguration.getScrollDefaultDelay();
20430             scrollBarFadeDuration = ViewConfiguration.getScrollBarFadeDuration();
20431
20432             paint = new Paint();
20433             matrix = new Matrix();
20434             // use use a height of 1, and then wack the matrix each time we
20435             // actually use it.
20436             shader = new LinearGradient(0, 0, 0, 1, 0xFF000000, 0, Shader.TileMode.CLAMP);
20437             paint.setShader(shader);
20438             paint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.DST_OUT));
20439
20440             this.host = host;
20441         }
20442
20443         public void setFadeColor(int color) {
20444             if (color != mLastColor) {
20445                 mLastColor = color;
20446
20447                 if (color != 0) {
20448                     shader = new LinearGradient(0, 0, 0, 1, color | 0xFF000000,
20449                             color & 0x00FFFFFF, Shader.TileMode.CLAMP);
20450                     paint.setShader(shader);
20451                     // Restore the default transfer mode (src_over)
20452                     paint.setXfermode(null);
20453                 } else {
20454                     shader = new LinearGradient(0, 0, 0, 1, 0xFF000000, 0, Shader.TileMode.CLAMP);
20455                     paint.setShader(shader);
20456                     paint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.DST_OUT));
20457                 }
20458             }
20459         }
20460
20461         public void run() {
20462             long now = AnimationUtils.currentAnimationTimeMillis();
20463             if (now >= fadeStartTime) {
20464
20465                 // the animation fades the scrollbars out by changing
20466                 // the opacity (alpha) from fully opaque to fully
20467                 // transparent
20468                 int nextFrame = (int) now;
20469                 int framesCount = 0;
20470
20471                 Interpolator interpolator = scrollBarInterpolator;
20472
20473                 // Start opaque
20474                 interpolator.setKeyFrame(framesCount++, nextFrame, OPAQUE);
20475
20476                 // End transparent
20477                 nextFrame += scrollBarFadeDuration;
20478                 interpolator.setKeyFrame(framesCount, nextFrame, TRANSPARENT);
20479
20480                 state = FADING;
20481
20482                 // Kick off the fade animation
20483                 host.invalidate(true);
20484             }
20485         }
20486     }
20487
20488     /**
20489      * Resuable callback for sending
20490      * {@link AccessibilityEvent#TYPE_VIEW_SCROLLED} accessibility event.
20491      */
20492     private class SendViewScrolledAccessibilityEvent implements Runnable {
20493         public volatile boolean mIsPending;
20494
20495         public void run() {
20496             sendAccessibilityEvent(AccessibilityEvent.TYPE_VIEW_SCROLLED);
20497             mIsPending = false;
20498         }
20499     }
20500
20501     /**
20502      * <p>
20503      * This class represents a delegate that can be registered in a {@link View}
20504      * to enhance accessibility support via composition rather via inheritance.
20505      * It is specifically targeted to widget developers that extend basic View
20506      * classes i.e. classes in package android.view, that would like their
20507      * applications to be backwards compatible.
20508      * </p>
20509      * <div class="special reference">
20510      * <h3>Developer Guides</h3>
20511      * <p>For more information about making applications accessible, read the
20512      * <a href="{@docRoot}guide/topics/ui/accessibility/index.html">Accessibility</a>
20513      * developer guide.</p>
20514      * </div>
20515      * <p>
20516      * A scenario in which a developer would like to use an accessibility delegate
20517      * is overriding a method introduced in a later API version then the minimal API
20518      * version supported by the application. For example, the method
20519      * {@link View#onInitializeAccessibilityNodeInfo(AccessibilityNodeInfo)} is not available
20520      * in API version 4 when the accessibility APIs were first introduced. If a
20521      * developer would like his application to run on API version 4 devices (assuming
20522      * all other APIs used by the application are version 4 or lower) and take advantage
20523      * of this method, instead of overriding the method which would break the application's
20524      * backwards compatibility, he can override the corresponding method in this
20525      * delegate and register the delegate in the target View if the API version of
20526      * the system is high enough i.e. the API version is same or higher to the API
20527      * version that introduced
20528      * {@link View#onInitializeAccessibilityNodeInfo(AccessibilityNodeInfo)}.
20529      * </p>
20530      * <p>
20531      * Here is an example implementation:
20532      * </p>
20533      * <code><pre><p>
20534      * if (Build.VERSION.SDK_INT >= 14) {
20535      *     // If the API version is equal of higher than the version in
20536      *     // which onInitializeAccessibilityNodeInfo was introduced we
20537      *     // register a delegate with a customized implementation.
20538      *     View view = findViewById(R.id.view_id);
20539      *     view.setAccessibilityDelegate(new AccessibilityDelegate() {
20540      *         public void onInitializeAccessibilityNodeInfo(View host,
20541      *                 AccessibilityNodeInfo info) {
20542      *             // Let the default implementation populate the info.
20543      *             super.onInitializeAccessibilityNodeInfo(host, info);
20544      *             // Set some other information.
20545      *             info.setEnabled(host.isEnabled());
20546      *         }
20547      *     });
20548      * }
20549      * </code></pre></p>
20550      * <p>
20551      * This delegate contains methods that correspond to the accessibility methods
20552      * in View. If a delegate has been specified the implementation in View hands
20553      * off handling to the corresponding method in this delegate. The default
20554      * implementation the delegate methods behaves exactly as the corresponding
20555      * method in View for the case of no accessibility delegate been set. Hence,
20556      * to customize the behavior of a View method, clients can override only the
20557      * corresponding delegate method without altering the behavior of the rest
20558      * accessibility related methods of the host view.
20559      * </p>
20560      */
20561     public static class AccessibilityDelegate {
20562
20563         /**
20564          * Sends an accessibility event of the given type. If accessibility is not
20565          * enabled this method has no effect.
20566          * <p>
20567          * The default implementation behaves as {@link View#sendAccessibilityEvent(int)
20568          *  View#sendAccessibilityEvent(int)} for the case of no accessibility delegate
20569          * been set.
20570          * </p>
20571          *
20572          * @param host The View hosting the delegate.
20573          * @param eventType The type of the event to send.
20574          *
20575          * @see View#sendAccessibilityEvent(int) View#sendAccessibilityEvent(int)
20576          */
20577         public void sendAccessibilityEvent(View host, int eventType) {
20578             host.sendAccessibilityEventInternal(eventType);
20579         }
20580
20581         /**
20582          * Performs the specified accessibility action on the view. For
20583          * possible accessibility actions look at {@link AccessibilityNodeInfo}.
20584          * <p>
20585          * The default implementation behaves as
20586          * {@link View#performAccessibilityAction(int, Bundle)
20587          *  View#performAccessibilityAction(int, Bundle)} for the case of
20588          *  no accessibility delegate been set.
20589          * </p>
20590          *
20591          * @param action The action to perform.
20592          * @return Whether the action was performed.
20593          *
20594          * @see View#performAccessibilityAction(int, Bundle)
20595          *      View#performAccessibilityAction(int, Bundle)
20596          */
20597         public boolean performAccessibilityAction(View host, int action, Bundle args) {
20598             return host.performAccessibilityActionInternal(action, args);
20599         }
20600
20601         /**
20602          * Sends an accessibility event. This method behaves exactly as
20603          * {@link #sendAccessibilityEvent(View, int)} but takes as an argument an
20604          * empty {@link AccessibilityEvent} and does not perform a check whether
20605          * accessibility is enabled.
20606          * <p>
20607          * The default implementation behaves as
20608          * {@link View#sendAccessibilityEventUnchecked(AccessibilityEvent)
20609          *  View#sendAccessibilityEventUnchecked(AccessibilityEvent)} for
20610          * the case of no accessibility delegate been set.
20611          * </p>
20612          *
20613          * @param host The View hosting the delegate.
20614          * @param event The event to send.
20615          *
20616          * @see View#sendAccessibilityEventUnchecked(AccessibilityEvent)
20617          *      View#sendAccessibilityEventUnchecked(AccessibilityEvent)
20618          */
20619         public void sendAccessibilityEventUnchecked(View host, AccessibilityEvent event) {
20620             host.sendAccessibilityEventUncheckedInternal(event);
20621         }
20622
20623         /**
20624          * Dispatches an {@link AccessibilityEvent} to the host {@link View} first and then
20625          * to its children for adding their text content to the event.
20626          * <p>
20627          * The default implementation behaves as
20628          * {@link View#dispatchPopulateAccessibilityEvent(AccessibilityEvent)
20629          *  View#dispatchPopulateAccessibilityEvent(AccessibilityEvent)} for
20630          * the case of no accessibility delegate been set.
20631          * </p>
20632          *
20633          * @param host The View hosting the delegate.
20634          * @param event The event.
20635          * @return True if the event population was completed.
20636          *
20637          * @see View#dispatchPopulateAccessibilityEvent(AccessibilityEvent)
20638          *      View#dispatchPopulateAccessibilityEvent(AccessibilityEvent)
20639          */
20640         public boolean dispatchPopulateAccessibilityEvent(View host, AccessibilityEvent event) {
20641             return host.dispatchPopulateAccessibilityEventInternal(event);
20642         }
20643
20644         /**
20645          * Gives a chance to the host View to populate the accessibility event with its
20646          * text content.
20647          * <p>
20648          * The default implementation behaves as
20649          * {@link View#onPopulateAccessibilityEvent(AccessibilityEvent)
20650          *  View#onPopulateAccessibilityEvent(AccessibilityEvent)} for
20651          * the case of no accessibility delegate been set.
20652          * </p>
20653          *
20654          * @param host The View hosting the delegate.
20655          * @param event The accessibility event which to populate.
20656          *
20657          * @see View#onPopulateAccessibilityEvent(AccessibilityEvent)
20658          *      View#onPopulateAccessibilityEvent(AccessibilityEvent)
20659          */
20660         public void onPopulateAccessibilityEvent(View host, AccessibilityEvent event) {
20661             host.onPopulateAccessibilityEventInternal(event);
20662         }
20663
20664         /**
20665          * Initializes an {@link AccessibilityEvent} with information about the
20666          * the host View which is the event source.
20667          * <p>
20668          * The default implementation behaves as
20669          * {@link View#onInitializeAccessibilityEvent(AccessibilityEvent)
20670          *  View#onInitializeAccessibilityEvent(AccessibilityEvent)} for
20671          * the case of no accessibility delegate been set.
20672          * </p>
20673          *
20674          * @param host The View hosting the delegate.
20675          * @param event The event to initialize.
20676          *
20677          * @see View#onInitializeAccessibilityEvent(AccessibilityEvent)
20678          *      View#onInitializeAccessibilityEvent(AccessibilityEvent)
20679          */
20680         public void onInitializeAccessibilityEvent(View host, AccessibilityEvent event) {
20681             host.onInitializeAccessibilityEventInternal(event);
20682         }
20683
20684         /**
20685          * Initializes an {@link AccessibilityNodeInfo} with information about the host view.
20686          * <p>
20687          * The default implementation behaves as
20688          * {@link View#onInitializeAccessibilityNodeInfo(AccessibilityNodeInfo)
20689          *  View#onInitializeAccessibilityNodeInfo(AccessibilityNodeInfo)} for
20690          * the case of no accessibility delegate been set.
20691          * </p>
20692          *
20693          * @param host The View hosting the delegate.
20694          * @param info The instance to initialize.
20695          *
20696          * @see View#onInitializeAccessibilityNodeInfo(AccessibilityNodeInfo)
20697          *      View#onInitializeAccessibilityNodeInfo(AccessibilityNodeInfo)
20698          */
20699         public void onInitializeAccessibilityNodeInfo(View host, AccessibilityNodeInfo info) {
20700             host.onInitializeAccessibilityNodeInfoInternal(info);
20701         }
20702
20703         /**
20704          * Called when a child of the host View has requested sending an
20705          * {@link AccessibilityEvent} and gives an opportunity to the parent (the host)
20706          * to augment the event.
20707          * <p>
20708          * The default implementation behaves as
20709          * {@link ViewGroup#onRequestSendAccessibilityEvent(View, AccessibilityEvent)
20710          *  ViewGroup#onRequestSendAccessibilityEvent(View, AccessibilityEvent)} for
20711          * the case of no accessibility delegate been set.
20712          * </p>
20713          *
20714          * @param host The View hosting the delegate.
20715          * @param child The child which requests sending the event.
20716          * @param event The event to be sent.
20717          * @return True if the event should be sent
20718          *
20719          * @see ViewGroup#onRequestSendAccessibilityEvent(View, AccessibilityEvent)
20720          *      ViewGroup#onRequestSendAccessibilityEvent(View, AccessibilityEvent)
20721          */
20722         public boolean onRequestSendAccessibilityEvent(ViewGroup host, View child,
20723                 AccessibilityEvent event) {
20724             return host.onRequestSendAccessibilityEventInternal(child, event);
20725         }
20726
20727         /**
20728          * Gets the provider for managing a virtual view hierarchy rooted at this View
20729          * and reported to {@link android.accessibilityservice.AccessibilityService}s
20730          * that explore the window content.
20731          * <p>
20732          * The default implementation behaves as
20733          * {@link View#getAccessibilityNodeProvider() View#getAccessibilityNodeProvider()} for
20734          * the case of no accessibility delegate been set.
20735          * </p>
20736          *
20737          * @return The provider.
20738          *
20739          * @see AccessibilityNodeProvider
20740          */
20741         public AccessibilityNodeProvider getAccessibilityNodeProvider(View host) {
20742             return null;
20743         }
20744
20745         /**
20746          * Returns an {@link AccessibilityNodeInfo} representing the host view from the
20747          * point of view of an {@link android.accessibilityservice.AccessibilityService}.
20748          * This method is responsible for obtaining an accessibility node info from a
20749          * pool of reusable instances and calling
20750          * {@link #onInitializeAccessibilityNodeInfo(AccessibilityNodeInfo)} on the host
20751          * view to initialize the former.
20752          * <p>
20753          * <strong>Note:</strong> The client is responsible for recycling the obtained
20754          * instance by calling {@link AccessibilityNodeInfo#recycle()} to minimize object
20755          * creation.
20756          * </p>
20757          * <p>
20758          * The default implementation behaves as
20759          * {@link View#createAccessibilityNodeInfo() View#createAccessibilityNodeInfo()} for
20760          * the case of no accessibility delegate been set.
20761          * </p>
20762          * @return A populated {@link AccessibilityNodeInfo}.
20763          *
20764          * @see AccessibilityNodeInfo
20765          *
20766          * @hide
20767          */
20768         public AccessibilityNodeInfo createAccessibilityNodeInfo(View host) {
20769             return host.createAccessibilityNodeInfoInternal();
20770         }
20771     }
20772
20773     private class MatchIdPredicate implements Predicate<View> {
20774         public int mId;
20775
20776         @Override
20777         public boolean apply(View view) {
20778             return (view.mID == mId);
20779         }
20780     }
20781
20782     private class MatchLabelForPredicate implements Predicate<View> {
20783         private int mLabeledId;
20784
20785         @Override
20786         public boolean apply(View view) {
20787             return (view.mLabelForId == mLabeledId);
20788         }
20789     }
20790
20791     private class SendViewStateChangedAccessibilityEvent implements Runnable {
20792         private int mChangeTypes = 0;
20793         private boolean mPosted;
20794         private boolean mPostedWithDelay;
20795         private long mLastEventTimeMillis;
20796
20797         @Override
20798         public void run() {
20799             mPosted = false;
20800             mPostedWithDelay = false;
20801             mLastEventTimeMillis = SystemClock.uptimeMillis();
20802             if (AccessibilityManager.getInstance(mContext).isEnabled()) {
20803                 final AccessibilityEvent event = AccessibilityEvent.obtain();
20804                 event.setEventType(AccessibilityEvent.TYPE_WINDOW_CONTENT_CHANGED);
20805                 event.setContentChangeTypes(mChangeTypes);
20806                 sendAccessibilityEventUnchecked(event);
20807             }
20808             mChangeTypes = 0;
20809         }
20810
20811         public void runOrPost(int changeType) {
20812             mChangeTypes |= changeType;
20813
20814             // If this is a live region or the child of a live region, collect
20815             // all events from this frame and send them on the next frame.
20816             if (inLiveRegion()) {
20817                 // If we're already posted with a delay, remove that.
20818                 if (mPostedWithDelay) {
20819                     removeCallbacks(this);
20820                     mPostedWithDelay = false;
20821                 }
20822                 // Only post if we're not already posted.
20823                 if (!mPosted) {
20824                     post(this);
20825                     mPosted = true;
20826                 }
20827                 return;
20828             }
20829
20830             if (mPosted) {
20831                 return;
20832             }
20833
20834             final long timeSinceLastMillis = SystemClock.uptimeMillis() - mLastEventTimeMillis;
20835             final long minEventIntevalMillis =
20836                     ViewConfiguration.getSendRecurringAccessibilityEventsInterval();
20837             if (timeSinceLastMillis >= minEventIntevalMillis) {
20838                 removeCallbacks(this);
20839                 run();
20840             } else {
20841                 postDelayed(this, minEventIntevalMillis - timeSinceLastMillis);
20842                 mPostedWithDelay = true;
20843             }
20844         }
20845     }
20846
20847     private boolean inLiveRegion() {
20848         if (getAccessibilityLiveRegion() != View.ACCESSIBILITY_LIVE_REGION_NONE) {
20849             return true;
20850         }
20851
20852         ViewParent parent = getParent();
20853         while (parent instanceof View) {
20854             if (((View) parent).getAccessibilityLiveRegion()
20855                     != View.ACCESSIBILITY_LIVE_REGION_NONE) {
20856                 return true;
20857             }
20858             parent = parent.getParent();
20859         }
20860
20861         return false;
20862     }
20863
20864     /**
20865      * Dump all private flags in readable format, useful for documentation and
20866      * sanity checking.
20867      */
20868     private static void dumpFlags() {
20869         final HashMap<String, String> found = Maps.newHashMap();
20870         try {
20871             for (Field field : View.class.getDeclaredFields()) {
20872                 final int modifiers = field.getModifiers();
20873                 if (Modifier.isStatic(modifiers) && Modifier.isFinal(modifiers)) {
20874                     if (field.getType().equals(int.class)) {
20875                         final int value = field.getInt(null);
20876                         dumpFlag(found, field.getName(), value);
20877                     } else if (field.getType().equals(int[].class)) {
20878                         final int[] values = (int[]) field.get(null);
20879                         for (int i = 0; i < values.length; i++) {
20880                             dumpFlag(found, field.getName() + "[" + i + "]", values[i]);
20881                         }
20882                     }
20883                 }
20884             }
20885         } catch (IllegalAccessException e) {
20886             throw new RuntimeException(e);
20887         }
20888
20889         final ArrayList<String> keys = Lists.newArrayList();
20890         keys.addAll(found.keySet());
20891         Collections.sort(keys);
20892         for (String key : keys) {
20893             Log.d(VIEW_LOG_TAG, found.get(key));
20894         }
20895     }
20896
20897     private static void dumpFlag(HashMap<String, String> found, String name, int value) {
20898         // Sort flags by prefix, then by bits, always keeping unique keys
20899         final String bits = String.format("%32s", Integer.toBinaryString(value)).replace('0', ' ');
20900         final int prefix = name.indexOf('_');
20901         final String key = (prefix > 0 ? name.substring(0, prefix) : name) + bits + name;
20902         final String output = bits + " " + name;
20903         found.put(key, output);
20904     }
20905 }