OSDN Git Service

am b3c7ad32: am 7c97a3dd: Merge "Permissions control via profile/device owner admin...
[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.CallSuper;
22 import android.annotation.ColorInt;
23 import android.annotation.DrawableRes;
24 import android.annotation.FloatRange;
25 import android.annotation.IdRes;
26 import android.annotation.IntDef;
27 import android.annotation.LayoutRes;
28 import android.annotation.NonNull;
29 import android.annotation.Nullable;
30 import android.annotation.Size;
31 import android.content.ClipData;
32 import android.content.Context;
33 import android.content.ContextWrapper;
34 import android.content.Intent;
35 import android.content.res.ColorStateList;
36 import android.content.res.Configuration;
37 import android.content.res.Resources;
38 import android.content.res.TypedArray;
39 import android.graphics.Bitmap;
40 import android.graphics.Canvas;
41 import android.graphics.Insets;
42 import android.graphics.Interpolator;
43 import android.graphics.LinearGradient;
44 import android.graphics.Matrix;
45 import android.graphics.Outline;
46 import android.graphics.Paint;
47 import android.graphics.PixelFormat;
48 import android.graphics.Point;
49 import android.graphics.PorterDuff;
50 import android.graphics.PorterDuffXfermode;
51 import android.graphics.Rect;
52 import android.graphics.RectF;
53 import android.graphics.Region;
54 import android.graphics.Shader;
55 import android.graphics.drawable.ColorDrawable;
56 import android.graphics.drawable.Drawable;
57 import android.hardware.display.DisplayManagerGlobal;
58 import android.os.Bundle;
59 import android.os.Handler;
60 import android.os.IBinder;
61 import android.os.Parcel;
62 import android.os.Parcelable;
63 import android.os.RemoteException;
64 import android.os.SystemClock;
65 import android.os.SystemProperties;
66 import android.os.Trace;
67 import android.text.TextUtils;
68 import android.util.AttributeSet;
69 import android.util.FloatProperty;
70 import android.util.LayoutDirection;
71 import android.util.Log;
72 import android.util.LongSparseLongArray;
73 import android.util.Pools.SynchronizedPool;
74 import android.util.Property;
75 import android.util.SparseArray;
76 import android.util.StateSet;
77 import android.util.SuperNotCalledException;
78 import android.util.TypedValue;
79 import android.view.ContextMenu.ContextMenuInfo;
80 import android.view.AccessibilityIterators.TextSegmentIterator;
81 import android.view.AccessibilityIterators.CharacterTextSegmentIterator;
82 import android.view.AccessibilityIterators.WordTextSegmentIterator;
83 import android.view.AccessibilityIterators.ParagraphTextSegmentIterator;
84 import android.view.accessibility.AccessibilityEvent;
85 import android.view.accessibility.AccessibilityEventSource;
86 import android.view.accessibility.AccessibilityManager;
87 import android.view.accessibility.AccessibilityNodeInfo;
88 import android.view.accessibility.AccessibilityNodeInfo.AccessibilityAction;
89 import android.view.accessibility.AccessibilityNodeProvider;
90 import android.view.animation.Animation;
91 import android.view.animation.AnimationUtils;
92 import android.view.animation.Transformation;
93 import android.view.inputmethod.EditorInfo;
94 import android.view.inputmethod.InputConnection;
95 import android.view.inputmethod.InputMethodManager;
96 import android.widget.Checkable;
97 import android.widget.ScrollBarDrawable;
98
99 import static android.os.Build.VERSION_CODES.*;
100 import static java.lang.Math.max;
101
102 import com.android.internal.R;
103 import com.android.internal.util.Predicate;
104 import com.android.internal.view.menu.MenuBuilder;
105 import com.google.android.collect.Lists;
106 import com.google.android.collect.Maps;
107
108 import java.lang.annotation.Retention;
109 import java.lang.annotation.RetentionPolicy;
110 import java.lang.ref.WeakReference;
111 import java.lang.reflect.Field;
112 import java.lang.reflect.InvocationTargetException;
113 import java.lang.reflect.Method;
114 import java.lang.reflect.Modifier;
115 import java.util.ArrayList;
116 import java.util.Arrays;
117 import java.util.Collections;
118 import java.util.HashMap;
119 import java.util.List;
120 import java.util.Locale;
121 import java.util.Map;
122 import java.util.concurrent.CopyOnWriteArrayList;
123 import java.util.concurrent.atomic.AtomicInteger;
124
125 /**
126  * <p>
127  * This class represents the basic building block for user interface components. A View
128  * occupies a rectangular area on the screen and is responsible for drawing and
129  * event handling. View is the base class for <em>widgets</em>, which are
130  * used to create interactive UI components (buttons, text fields, etc.). The
131  * {@link android.view.ViewGroup} subclass is the base class for <em>layouts</em>, which
132  * are invisible containers that hold other Views (or other ViewGroups) and define
133  * their layout properties.
134  * </p>
135  *
136  * <div class="special reference">
137  * <h3>Developer Guides</h3>
138  * <p>For information about using this class to develop your application's user interface,
139  * read the <a href="{@docRoot}guide/topics/ui/index.html">User Interface</a> developer guide.
140  * </div>
141  *
142  * <a name="Using"></a>
143  * <h3>Using Views</h3>
144  * <p>
145  * All of the views in a window are arranged in a single tree. You can add views
146  * either from code or by specifying a tree of views in one or more XML layout
147  * files. There are many specialized subclasses of views that act as controls or
148  * are capable of displaying text, images, or other content.
149  * </p>
150  * <p>
151  * Once you have created a tree of views, there are typically a few types of
152  * common operations you may wish to perform:
153  * <ul>
154  * <li><strong>Set properties:</strong> for example setting the text of a
155  * {@link android.widget.TextView}. The available properties and the methods
156  * that set them will vary among the different subclasses of views. Note that
157  * properties that are known at build time can be set in the XML layout
158  * files.</li>
159  * <li><strong>Set focus:</strong> The framework will handled moving focus in
160  * response to user input. To force focus to a specific view, call
161  * {@link #requestFocus}.</li>
162  * <li><strong>Set up listeners:</strong> Views allow clients to set listeners
163  * that will be notified when something interesting happens to the view. For
164  * example, all views will let you set a listener to be notified when the view
165  * gains or loses focus. You can register such a listener using
166  * {@link #setOnFocusChangeListener(android.view.View.OnFocusChangeListener)}.
167  * Other view subclasses offer more specialized listeners. For example, a Button
168  * exposes a listener to notify clients when the button is clicked.</li>
169  * <li><strong>Set visibility:</strong> You can hide or show views using
170  * {@link #setVisibility(int)}.</li>
171  * </ul>
172  * </p>
173  * <p><em>
174  * Note: The Android framework is responsible for measuring, laying out and
175  * drawing views. You should not call methods that perform these actions on
176  * views yourself unless you are actually implementing a
177  * {@link android.view.ViewGroup}.
178  * </em></p>
179  *
180  * <a name="Lifecycle"></a>
181  * <h3>Implementing a Custom View</h3>
182  *
183  * <p>
184  * To implement a custom view, you will usually begin by providing overrides for
185  * some of the standard methods that the framework calls on all views. You do
186  * not need to override all of these methods. In fact, you can start by just
187  * overriding {@link #onDraw(android.graphics.Canvas)}.
188  * <table border="2" width="85%" align="center" cellpadding="5">
189  *     <thead>
190  *         <tr><th>Category</th> <th>Methods</th> <th>Description</th></tr>
191  *     </thead>
192  *
193  *     <tbody>
194  *     <tr>
195  *         <td rowspan="2">Creation</td>
196  *         <td>Constructors</td>
197  *         <td>There is a form of the constructor that are called when the view
198  *         is created from code and a form that is called when the view is
199  *         inflated from a layout file. The second form should parse and apply
200  *         any attributes defined in the layout file.
201  *         </td>
202  *     </tr>
203  *     <tr>
204  *         <td><code>{@link #onFinishInflate()}</code></td>
205  *         <td>Called after a view and all of its children has been inflated
206  *         from XML.</td>
207  *     </tr>
208  *
209  *     <tr>
210  *         <td rowspan="3">Layout</td>
211  *         <td><code>{@link #onMeasure(int, int)}</code></td>
212  *         <td>Called to determine the size requirements for this view and all
213  *         of its children.
214  *         </td>
215  *     </tr>
216  *     <tr>
217  *         <td><code>{@link #onLayout(boolean, int, int, int, int)}</code></td>
218  *         <td>Called when this view should assign a size and position to all
219  *         of its children.
220  *         </td>
221  *     </tr>
222  *     <tr>
223  *         <td><code>{@link #onSizeChanged(int, int, int, int)}</code></td>
224  *         <td>Called when the size of this view has changed.
225  *         </td>
226  *     </tr>
227  *
228  *     <tr>
229  *         <td>Drawing</td>
230  *         <td><code>{@link #onDraw(android.graphics.Canvas)}</code></td>
231  *         <td>Called when the view should render its content.
232  *         </td>
233  *     </tr>
234  *
235  *     <tr>
236  *         <td rowspan="4">Event processing</td>
237  *         <td><code>{@link #onKeyDown(int, KeyEvent)}</code></td>
238  *         <td>Called when a new hardware key event occurs.
239  *         </td>
240  *     </tr>
241  *     <tr>
242  *         <td><code>{@link #onKeyUp(int, KeyEvent)}</code></td>
243  *         <td>Called when a hardware key up event occurs.
244  *         </td>
245  *     </tr>
246  *     <tr>
247  *         <td><code>{@link #onTrackballEvent(MotionEvent)}</code></td>
248  *         <td>Called when a trackball motion event occurs.
249  *         </td>
250  *     </tr>
251  *     <tr>
252  *         <td><code>{@link #onTouchEvent(MotionEvent)}</code></td>
253  *         <td>Called when a touch screen motion event occurs.
254  *         </td>
255  *     </tr>
256  *
257  *     <tr>
258  *         <td rowspan="2">Focus</td>
259  *         <td><code>{@link #onFocusChanged(boolean, int, android.graphics.Rect)}</code></td>
260  *         <td>Called when the view gains or loses focus.
261  *         </td>
262  *     </tr>
263  *
264  *     <tr>
265  *         <td><code>{@link #onWindowFocusChanged(boolean)}</code></td>
266  *         <td>Called when the window containing the view gains or loses focus.
267  *         </td>
268  *     </tr>
269  *
270  *     <tr>
271  *         <td rowspan="3">Attaching</td>
272  *         <td><code>{@link #onAttachedToWindow()}</code></td>
273  *         <td>Called when the view is attached to a window.
274  *         </td>
275  *     </tr>
276  *
277  *     <tr>
278  *         <td><code>{@link #onDetachedFromWindow}</code></td>
279  *         <td>Called when the view is detached from its window.
280  *         </td>
281  *     </tr>
282  *
283  *     <tr>
284  *         <td><code>{@link #onWindowVisibilityChanged(int)}</code></td>
285  *         <td>Called when the visibility of the window containing the view
286  *         has changed.
287  *         </td>
288  *     </tr>
289  *     </tbody>
290  *
291  * </table>
292  * </p>
293  *
294  * <a name="IDs"></a>
295  * <h3>IDs</h3>
296  * Views may have an integer id associated with them. These ids are typically
297  * assigned in the layout XML files, and are used to find specific views within
298  * the view tree. A common pattern is to:
299  * <ul>
300  * <li>Define a Button in the layout file and assign it a unique ID.
301  * <pre>
302  * &lt;Button
303  *     android:id="@+id/my_button"
304  *     android:layout_width="wrap_content"
305  *     android:layout_height="wrap_content"
306  *     android:text="@string/my_button_text"/&gt;
307  * </pre></li>
308  * <li>From the onCreate method of an Activity, find the Button
309  * <pre class="prettyprint">
310  *      Button myButton = (Button) findViewById(R.id.my_button);
311  * </pre></li>
312  * </ul>
313  * <p>
314  * View IDs need not be unique throughout the tree, but it is good practice to
315  * ensure that they are at least unique within the part of the tree you are
316  * searching.
317  * </p>
318  *
319  * <a name="Position"></a>
320  * <h3>Position</h3>
321  * <p>
322  * The geometry of a view is that of a rectangle. A view has a location,
323  * expressed as a pair of <em>left</em> and <em>top</em> coordinates, and
324  * two dimensions, expressed as a width and a height. The unit for location
325  * and dimensions is the pixel.
326  * </p>
327  *
328  * <p>
329  * It is possible to retrieve the location of a view by invoking the methods
330  * {@link #getLeft()} and {@link #getTop()}. The former returns the left, or X,
331  * coordinate of the rectangle representing the view. The latter returns the
332  * top, or Y, coordinate of the rectangle representing the view. These methods
333  * both return the location of the view relative to its parent. For instance,
334  * when getLeft() returns 20, that means the view is located 20 pixels to the
335  * right of the left edge of its direct parent.
336  * </p>
337  *
338  * <p>
339  * In addition, several convenience methods are offered to avoid unnecessary
340  * computations, namely {@link #getRight()} and {@link #getBottom()}.
341  * These methods return the coordinates of the right and bottom edges of the
342  * rectangle representing the view. For instance, calling {@link #getRight()}
343  * is similar to the following computation: <code>getLeft() + getWidth()</code>
344  * (see <a href="#SizePaddingMargins">Size</a> for more information about the width.)
345  * </p>
346  *
347  * <a name="SizePaddingMargins"></a>
348  * <h3>Size, padding and margins</h3>
349  * <p>
350  * The size of a view is expressed with a width and a height. A view actually
351  * possess two pairs of width and height values.
352  * </p>
353  *
354  * <p>
355  * The first pair is known as <em>measured width</em> and
356  * <em>measured height</em>. These dimensions define how big a view wants to be
357  * within its parent (see <a href="#Layout">Layout</a> for more details.) The
358  * measured dimensions can be obtained by calling {@link #getMeasuredWidth()}
359  * and {@link #getMeasuredHeight()}.
360  * </p>
361  *
362  * <p>
363  * The second pair is simply known as <em>width</em> and <em>height</em>, or
364  * sometimes <em>drawing width</em> and <em>drawing height</em>. These
365  * dimensions define the actual size of the view on screen, at drawing time and
366  * after layout. These values may, but do not have to, be different from the
367  * measured width and height. The width and height can be obtained by calling
368  * {@link #getWidth()} and {@link #getHeight()}.
369  * </p>
370  *
371  * <p>
372  * To measure its dimensions, a view takes into account its padding. The padding
373  * is expressed in pixels for the left, top, right and bottom parts of the view.
374  * Padding can be used to offset the content of the view by a specific amount of
375  * pixels. For instance, a left padding of 2 will push the view's content by
376  * 2 pixels to the right of the left edge. Padding can be set using the
377  * {@link #setPadding(int, int, int, int)} or {@link #setPaddingRelative(int, int, int, int)}
378  * method and queried by calling {@link #getPaddingLeft()}, {@link #getPaddingTop()},
379  * {@link #getPaddingRight()}, {@link #getPaddingBottom()}, {@link #getPaddingStart()},
380  * {@link #getPaddingEnd()}.
381  * </p>
382  *
383  * <p>
384  * Even though a view can define a padding, it does not provide any support for
385  * margins. However, view groups provide such a support. Refer to
386  * {@link android.view.ViewGroup} and
387  * {@link android.view.ViewGroup.MarginLayoutParams} for further information.
388  * </p>
389  *
390  * <a name="Layout"></a>
391  * <h3>Layout</h3>
392  * <p>
393  * Layout is a two pass process: a measure pass and a layout pass. The measuring
394  * pass is implemented in {@link #measure(int, int)} and is a top-down traversal
395  * of the view tree. Each view pushes dimension specifications down the tree
396  * during the recursion. At the end of the measure pass, every view has stored
397  * its measurements. The second pass happens in
398  * {@link #layout(int,int,int,int)} and is also top-down. During
399  * this pass each parent is responsible for positioning all of its children
400  * using the sizes computed in the measure pass.
401  * </p>
402  *
403  * <p>
404  * When a view's measure() method returns, its {@link #getMeasuredWidth()} and
405  * {@link #getMeasuredHeight()} values must be set, along with those for all of
406  * that view's descendants. A view's measured width and measured height values
407  * must respect the constraints imposed by the view's parents. This guarantees
408  * that at the end of the measure pass, all parents accept all of their
409  * children's measurements. A parent view may call measure() more than once on
410  * its children. For example, the parent may measure each child once with
411  * unspecified dimensions to find out how big they want to be, then call
412  * measure() on them again with actual numbers if the sum of all the children's
413  * unconstrained sizes is too big or too small.
414  * </p>
415  *
416  * <p>
417  * The measure pass uses two classes to communicate dimensions. The
418  * {@link MeasureSpec} class is used by views to tell their parents how they
419  * want to be measured and positioned. The base LayoutParams class just
420  * describes how big the view wants to be for both width and height. For each
421  * dimension, it can specify one of:
422  * <ul>
423  * <li> an exact number
424  * <li>MATCH_PARENT, which means the view wants to be as big as its parent
425  * (minus padding)
426  * <li> WRAP_CONTENT, which means that the view wants to be just big enough to
427  * enclose its content (plus padding).
428  * </ul>
429  * There are subclasses of LayoutParams for different subclasses of ViewGroup.
430  * For example, AbsoluteLayout has its own subclass of LayoutParams which adds
431  * an X and Y value.
432  * </p>
433  *
434  * <p>
435  * MeasureSpecs are used to push requirements down the tree from parent to
436  * child. A MeasureSpec can be in one of three modes:
437  * <ul>
438  * <li>UNSPECIFIED: This is used by a parent to determine the desired dimension
439  * of a child view. For example, a LinearLayout may call measure() on its child
440  * with the height set to UNSPECIFIED and a width of EXACTLY 240 to find out how
441  * tall the child view wants to be given a width of 240 pixels.
442  * <li>EXACTLY: This is used by the parent to impose an exact size on the
443  * child. The child must use this size, and guarantee that all of its
444  * descendants will fit within this size.
445  * <li>AT_MOST: This is used by the parent to impose a maximum size on the
446  * child. The child must guarantee that it and all of its descendants will fit
447  * within this size.
448  * </ul>
449  * </p>
450  *
451  * <p>
452  * To initiate a layout, call {@link #requestLayout}. This method is typically
453  * called by a view on itself when it believes that is can no longer fit within
454  * its current bounds.
455  * </p>
456  *
457  * <a name="Drawing"></a>
458  * <h3>Drawing</h3>
459  * <p>
460  * Drawing is handled by walking the tree and recording the drawing commands of
461  * any View that needs to update. After this, the drawing commands of the
462  * entire tree are issued to screen, clipped to the newly damaged area.
463  * </p>
464  *
465  * <p>
466  * The tree is largely recorded and drawn in order, with parents drawn before
467  * (i.e., behind) their children, with siblings drawn in the order they appear
468  * in the tree. If you set a background drawable for a View, then the View will
469  * draw it before calling back to its <code>onDraw()</code> method. The child
470  * drawing order can be overridden with
471  * {@link ViewGroup#setChildrenDrawingOrderEnabled(boolean) custom child drawing order}
472  * in a ViewGroup, and with {@link #setZ(float)} custom Z values} set on Views.
473  * </p>
474  *
475  * <p>
476  * To force a view to draw, call {@link #invalidate()}.
477  * </p>
478  *
479  * <a name="EventHandlingThreading"></a>
480  * <h3>Event Handling and Threading</h3>
481  * <p>
482  * The basic cycle of a view is as follows:
483  * <ol>
484  * <li>An event comes in and is dispatched to the appropriate view. The view
485  * handles the event and notifies any listeners.</li>
486  * <li>If in the course of processing the event, the view's bounds may need
487  * to be changed, the view will call {@link #requestLayout()}.</li>
488  * <li>Similarly, if in the course of processing the event the view's appearance
489  * may need to be changed, the view will call {@link #invalidate()}.</li>
490  * <li>If either {@link #requestLayout()} or {@link #invalidate()} were called,
491  * the framework will take care of measuring, laying out, and drawing the tree
492  * as appropriate.</li>
493  * </ol>
494  * </p>
495  *
496  * <p><em>Note: The entire view tree is single threaded. You must always be on
497  * the UI thread when calling any method on any view.</em>
498  * If you are doing work on other threads and want to update the state of a view
499  * from that thread, you should use a {@link Handler}.
500  * </p>
501  *
502  * <a name="FocusHandling"></a>
503  * <h3>Focus Handling</h3>
504  * <p>
505  * The framework will handle routine focus movement in response to user input.
506  * This includes changing the focus as views are removed or hidden, or as new
507  * views become available. Views indicate their willingness to take focus
508  * through the {@link #isFocusable} method. To change whether a view can take
509  * focus, call {@link #setFocusable(boolean)}.  When in touch mode (see notes below)
510  * views indicate whether they still would like focus via {@link #isFocusableInTouchMode}
511  * and can change this via {@link #setFocusableInTouchMode(boolean)}.
512  * </p>
513  * <p>
514  * Focus movement is based on an algorithm which finds the nearest neighbor in a
515  * given direction. In rare cases, the default algorithm may not match the
516  * intended behavior of the developer. In these situations, you can provide
517  * explicit overrides by using these XML attributes in the layout file:
518  * <pre>
519  * nextFocusDown
520  * nextFocusLeft
521  * nextFocusRight
522  * nextFocusUp
523  * </pre>
524  * </p>
525  *
526  *
527  * <p>
528  * To get a particular view to take focus, call {@link #requestFocus()}.
529  * </p>
530  *
531  * <a name="TouchMode"></a>
532  * <h3>Touch Mode</h3>
533  * <p>
534  * When a user is navigating a user interface via directional keys such as a D-pad, it is
535  * necessary to give focus to actionable items such as buttons so the user can see
536  * what will take input.  If the device has touch capabilities, however, and the user
537  * begins interacting with the interface by touching it, it is no longer necessary to
538  * always highlight, or give focus to, a particular view.  This motivates a mode
539  * for interaction named 'touch mode'.
540  * </p>
541  * <p>
542  * For a touch capable device, once the user touches the screen, the device
543  * will enter touch mode.  From this point onward, only views for which
544  * {@link #isFocusableInTouchMode} is true will be focusable, such as text editing widgets.
545  * Other views that are touchable, like buttons, will not take focus when touched; they will
546  * only fire the on click listeners.
547  * </p>
548  * <p>
549  * Any time a user hits a directional key, such as a D-pad direction, the view device will
550  * exit touch mode, and find a view to take focus, so that the user may resume interacting
551  * with the user interface without touching the screen again.
552  * </p>
553  * <p>
554  * The touch mode state is maintained across {@link android.app.Activity}s.  Call
555  * {@link #isInTouchMode} to see whether the device is currently in touch mode.
556  * </p>
557  *
558  * <a name="Scrolling"></a>
559  * <h3>Scrolling</h3>
560  * <p>
561  * The framework provides basic support for views that wish to internally
562  * scroll their content. This includes keeping track of the X and Y scroll
563  * offset as well as mechanisms for drawing scrollbars. See
564  * {@link #scrollBy(int, int)}, {@link #scrollTo(int, int)}, and
565  * {@link #awakenScrollBars()} for more details.
566  * </p>
567  *
568  * <a name="Tags"></a>
569  * <h3>Tags</h3>
570  * <p>
571  * Unlike IDs, tags are not used to identify views. Tags are essentially an
572  * extra piece of information that can be associated with a view. They are most
573  * often used as a convenience to store data related to views in the views
574  * themselves rather than by putting them in a separate structure.
575  * </p>
576  *
577  * <a name="Properties"></a>
578  * <h3>Properties</h3>
579  * <p>
580  * The View class exposes an {@link #ALPHA} property, as well as several transform-related
581  * properties, such as {@link #TRANSLATION_X} and {@link #TRANSLATION_Y}. These properties are
582  * available both in the {@link Property} form as well as in similarly-named setter/getter
583  * methods (such as {@link #setAlpha(float)} for {@link #ALPHA}). These properties can
584  * be used to set persistent state associated with these rendering-related properties on the view.
585  * The properties and methods can also be used in conjunction with
586  * {@link android.animation.Animator Animator}-based animations, described more in the
587  * <a href="#Animation">Animation</a> section.
588  * </p>
589  *
590  * <a name="Animation"></a>
591  * <h3>Animation</h3>
592  * <p>
593  * Starting with Android 3.0, the preferred way of animating views is to use the
594  * {@link android.animation} package APIs. These {@link android.animation.Animator Animator}-based
595  * classes change actual properties of the View object, such as {@link #setAlpha(float) alpha} and
596  * {@link #setTranslationX(float) translationX}. This behavior is contrasted to that of the pre-3.0
597  * {@link android.view.animation.Animation Animation}-based classes, which instead animate only
598  * how the view is drawn on the display. In particular, the {@link ViewPropertyAnimator} class
599  * makes animating these View properties particularly easy and efficient.
600  * </p>
601  * <p>
602  * Alternatively, you can use the pre-3.0 animation classes to animate how Views are rendered.
603  * You can attach an {@link Animation} object to a view using
604  * {@link #setAnimation(Animation)} or
605  * {@link #startAnimation(Animation)}. The animation can alter the scale,
606  * rotation, translation and alpha of a view over time. If the animation is
607  * attached to a view that has children, the animation will affect the entire
608  * subtree rooted by that node. When an animation is started, the framework will
609  * take care of redrawing the appropriate views until the animation completes.
610  * </p>
611  *
612  * <a name="Security"></a>
613  * <h3>Security</h3>
614  * <p>
615  * Sometimes it is essential that an application be able to verify that an action
616  * is being performed with the full knowledge and consent of the user, such as
617  * granting a permission request, making a purchase or clicking on an advertisement.
618  * Unfortunately, a malicious application could try to spoof the user into
619  * performing these actions, unaware, by concealing the intended purpose of the view.
620  * As a remedy, the framework offers a touch filtering mechanism that can be used to
621  * improve the security of views that provide access to sensitive functionality.
622  * </p><p>
623  * To enable touch filtering, call {@link #setFilterTouchesWhenObscured(boolean)} or set the
624  * android:filterTouchesWhenObscured layout attribute to true.  When enabled, the framework
625  * will discard touches that are received whenever the view's window is obscured by
626  * another visible window.  As a result, the view will not receive touches whenever a
627  * toast, dialog or other window appears above the view's window.
628  * </p><p>
629  * For more fine-grained control over security, consider overriding the
630  * {@link #onFilterTouchEventForSecurity(MotionEvent)} method to implement your own
631  * security policy. See also {@link MotionEvent#FLAG_WINDOW_IS_OBSCURED}.
632  * </p>
633  *
634  * @attr ref android.R.styleable#View_alpha
635  * @attr ref android.R.styleable#View_assistBlocked
636  * @attr ref android.R.styleable#View_background
637  * @attr ref android.R.styleable#View_clickable
638  * @attr ref android.R.styleable#View_contentDescription
639  * @attr ref android.R.styleable#View_drawingCacheQuality
640  * @attr ref android.R.styleable#View_duplicateParentState
641  * @attr ref android.R.styleable#View_id
642  * @attr ref android.R.styleable#View_requiresFadingEdge
643  * @attr ref android.R.styleable#View_fadeScrollbars
644  * @attr ref android.R.styleable#View_fadingEdgeLength
645  * @attr ref android.R.styleable#View_filterTouchesWhenObscured
646  * @attr ref android.R.styleable#View_fitsSystemWindows
647  * @attr ref android.R.styleable#View_isScrollContainer
648  * @attr ref android.R.styleable#View_focusable
649  * @attr ref android.R.styleable#View_focusableInTouchMode
650  * @attr ref android.R.styleable#View_hapticFeedbackEnabled
651  * @attr ref android.R.styleable#View_keepScreenOn
652  * @attr ref android.R.styleable#View_layerType
653  * @attr ref android.R.styleable#View_layoutDirection
654  * @attr ref android.R.styleable#View_longClickable
655  * @attr ref android.R.styleable#View_minHeight
656  * @attr ref android.R.styleable#View_minWidth
657  * @attr ref android.R.styleable#View_nextFocusDown
658  * @attr ref android.R.styleable#View_nextFocusLeft
659  * @attr ref android.R.styleable#View_nextFocusRight
660  * @attr ref android.R.styleable#View_nextFocusUp
661  * @attr ref android.R.styleable#View_onClick
662  * @attr ref android.R.styleable#View_padding
663  * @attr ref android.R.styleable#View_paddingBottom
664  * @attr ref android.R.styleable#View_paddingLeft
665  * @attr ref android.R.styleable#View_paddingRight
666  * @attr ref android.R.styleable#View_paddingTop
667  * @attr ref android.R.styleable#View_paddingStart
668  * @attr ref android.R.styleable#View_paddingEnd
669  * @attr ref android.R.styleable#View_saveEnabled
670  * @attr ref android.R.styleable#View_rotation
671  * @attr ref android.R.styleable#View_rotationX
672  * @attr ref android.R.styleable#View_rotationY
673  * @attr ref android.R.styleable#View_scaleX
674  * @attr ref android.R.styleable#View_scaleY
675  * @attr ref android.R.styleable#View_scrollX
676  * @attr ref android.R.styleable#View_scrollY
677  * @attr ref android.R.styleable#View_scrollbarSize
678  * @attr ref android.R.styleable#View_scrollbarStyle
679  * @attr ref android.R.styleable#View_scrollbars
680  * @attr ref android.R.styleable#View_scrollbarDefaultDelayBeforeFade
681  * @attr ref android.R.styleable#View_scrollbarFadeDuration
682  * @attr ref android.R.styleable#View_scrollbarTrackHorizontal
683  * @attr ref android.R.styleable#View_scrollbarThumbHorizontal
684  * @attr ref android.R.styleable#View_scrollbarThumbVertical
685  * @attr ref android.R.styleable#View_scrollbarTrackVertical
686  * @attr ref android.R.styleable#View_scrollbarAlwaysDrawHorizontalTrack
687  * @attr ref android.R.styleable#View_scrollbarAlwaysDrawVerticalTrack
688  * @attr ref android.R.styleable#View_stateListAnimator
689  * @attr ref android.R.styleable#View_transitionName
690  * @attr ref android.R.styleable#View_soundEffectsEnabled
691  * @attr ref android.R.styleable#View_tag
692  * @attr ref android.R.styleable#View_textAlignment
693  * @attr ref android.R.styleable#View_textDirection
694  * @attr ref android.R.styleable#View_transformPivotX
695  * @attr ref android.R.styleable#View_transformPivotY
696  * @attr ref android.R.styleable#View_translationX
697  * @attr ref android.R.styleable#View_translationY
698  * @attr ref android.R.styleable#View_translationZ
699  * @attr ref android.R.styleable#View_visibility
700  *
701  * @see android.view.ViewGroup
702  */
703 public class View implements Drawable.Callback, KeyEvent.Callback,
704         AccessibilityEventSource {
705     private static final boolean DBG = false;
706
707     /**
708      * The logging tag used by this class with android.util.Log.
709      */
710     protected static final String VIEW_LOG_TAG = "View";
711
712     /**
713      * When set to true, apps will draw debugging information about their layouts.
714      *
715      * @hide
716      */
717     public static final String DEBUG_LAYOUT_PROPERTY = "debug.layout";
718
719     /**
720      * When set to true, this view will save its attribute data.
721      *
722      * @hide
723      */
724     public static boolean mDebugViewAttributes = false;
725
726     /**
727      * Used to mark a View that has no ID.
728      */
729     public static final int NO_ID = -1;
730
731     /**
732      * Signals that compatibility booleans have been initialized according to
733      * target SDK versions.
734      */
735     private static boolean sCompatibilityDone = false;
736
737     /**
738      * Use the old (broken) way of building MeasureSpecs.
739      */
740     private static boolean sUseBrokenMakeMeasureSpec = false;
741
742     /**
743      * Ignore any optimizations using the measure cache.
744      */
745     private static boolean sIgnoreMeasureCache = false;
746
747     /**
748      * This view does not want keystrokes. Use with TAKES_FOCUS_MASK when
749      * calling setFlags.
750      */
751     private static final int NOT_FOCUSABLE = 0x00000000;
752
753     /**
754      * This view wants keystrokes. Use with TAKES_FOCUS_MASK when calling
755      * setFlags.
756      */
757     private static final int FOCUSABLE = 0x00000001;
758
759     /**
760      * Mask for use with setFlags indicating bits used for focus.
761      */
762     private static final int FOCUSABLE_MASK = 0x00000001;
763
764     /**
765      * This view will adjust its padding to fit sytem windows (e.g. status bar)
766      */
767     private static final int FITS_SYSTEM_WINDOWS = 0x00000002;
768
769     /** @hide */
770     @IntDef({VISIBLE, INVISIBLE, GONE})
771     @Retention(RetentionPolicy.SOURCE)
772     public @interface Visibility {}
773
774     /**
775      * This view is visible.
776      * Use with {@link #setVisibility} and <a href="#attr_android:visibility">{@code
777      * android:visibility}.
778      */
779     public static final int VISIBLE = 0x00000000;
780
781     /**
782      * This view is invisible, but it still takes up space for layout purposes.
783      * Use with {@link #setVisibility} and <a href="#attr_android:visibility">{@code
784      * android:visibility}.
785      */
786     public static final int INVISIBLE = 0x00000004;
787
788     /**
789      * This view is invisible, and it doesn't take any space for layout
790      * purposes. Use with {@link #setVisibility} and <a href="#attr_android:visibility">{@code
791      * android:visibility}.
792      */
793     public static final int GONE = 0x00000008;
794
795     /**
796      * Mask for use with setFlags indicating bits used for visibility.
797      * {@hide}
798      */
799     static final int VISIBILITY_MASK = 0x0000000C;
800
801     private static final int[] VISIBILITY_FLAGS = {VISIBLE, INVISIBLE, GONE};
802
803     /**
804      * This view is enabled. Interpretation varies by subclass.
805      * Use with ENABLED_MASK when calling setFlags.
806      * {@hide}
807      */
808     static final int ENABLED = 0x00000000;
809
810     /**
811      * This view is disabled. Interpretation varies by subclass.
812      * Use with ENABLED_MASK when calling setFlags.
813      * {@hide}
814      */
815     static final int DISABLED = 0x00000020;
816
817    /**
818     * Mask for use with setFlags indicating bits used for indicating whether
819     * this view is enabled
820     * {@hide}
821     */
822     static final int ENABLED_MASK = 0x00000020;
823
824     /**
825      * This view won't draw. {@link #onDraw(android.graphics.Canvas)} won't be
826      * called and further optimizations will be performed. It is okay to have
827      * this flag set and a background. Use with DRAW_MASK when calling setFlags.
828      * {@hide}
829      */
830     static final int WILL_NOT_DRAW = 0x00000080;
831
832     /**
833      * Mask for use with setFlags indicating bits used for indicating whether
834      * this view is will draw
835      * {@hide}
836      */
837     static final int DRAW_MASK = 0x00000080;
838
839     /**
840      * <p>This view doesn't show scrollbars.</p>
841      * {@hide}
842      */
843     static final int SCROLLBARS_NONE = 0x00000000;
844
845     /**
846      * <p>This view shows horizontal scrollbars.</p>
847      * {@hide}
848      */
849     static final int SCROLLBARS_HORIZONTAL = 0x00000100;
850
851     /**
852      * <p>This view shows vertical scrollbars.</p>
853      * {@hide}
854      */
855     static final int SCROLLBARS_VERTICAL = 0x00000200;
856
857     /**
858      * <p>Mask for use with setFlags indicating bits used for indicating which
859      * scrollbars are enabled.</p>
860      * {@hide}
861      */
862     static final int SCROLLBARS_MASK = 0x00000300;
863
864     /**
865      * Indicates that the view should filter touches when its window is obscured.
866      * Refer to the class comments for more information about this security feature.
867      * {@hide}
868      */
869     static final int FILTER_TOUCHES_WHEN_OBSCURED = 0x00000400;
870
871     /**
872      * Set for framework elements that use FITS_SYSTEM_WINDOWS, to indicate
873      * that they are optional and should be skipped if the window has
874      * requested system UI flags that ignore those insets for layout.
875      */
876     static final int OPTIONAL_FITS_SYSTEM_WINDOWS = 0x00000800;
877
878     /**
879      * <p>This view doesn't show fading edges.</p>
880      * {@hide}
881      */
882     static final int FADING_EDGE_NONE = 0x00000000;
883
884     /**
885      * <p>This view shows horizontal fading edges.</p>
886      * {@hide}
887      */
888     static final int FADING_EDGE_HORIZONTAL = 0x00001000;
889
890     /**
891      * <p>This view shows vertical fading edges.</p>
892      * {@hide}
893      */
894     static final int FADING_EDGE_VERTICAL = 0x00002000;
895
896     /**
897      * <p>Mask for use with setFlags indicating bits used for indicating which
898      * fading edges are enabled.</p>
899      * {@hide}
900      */
901     static final int FADING_EDGE_MASK = 0x00003000;
902
903     /**
904      * <p>Indicates this view can be clicked. When clickable, a View reacts
905      * to clicks by notifying the OnClickListener.<p>
906      * {@hide}
907      */
908     static final int CLICKABLE = 0x00004000;
909
910     /**
911      * <p>Indicates this view is caching its drawing into a bitmap.</p>
912      * {@hide}
913      */
914     static final int DRAWING_CACHE_ENABLED = 0x00008000;
915
916     /**
917      * <p>Indicates that no icicle should be saved for this view.<p>
918      * {@hide}
919      */
920     static final int SAVE_DISABLED = 0x000010000;
921
922     /**
923      * <p>Mask for use with setFlags indicating bits used for the saveEnabled
924      * property.</p>
925      * {@hide}
926      */
927     static final int SAVE_DISABLED_MASK = 0x000010000;
928
929     /**
930      * <p>Indicates that no drawing cache should ever be created for this view.<p>
931      * {@hide}
932      */
933     static final int WILL_NOT_CACHE_DRAWING = 0x000020000;
934
935     /**
936      * <p>Indicates this view can take / keep focus when int touch mode.</p>
937      * {@hide}
938      */
939     static final int FOCUSABLE_IN_TOUCH_MODE = 0x00040000;
940
941     /** @hide */
942     @Retention(RetentionPolicy.SOURCE)
943     @IntDef({DRAWING_CACHE_QUALITY_LOW, DRAWING_CACHE_QUALITY_HIGH, DRAWING_CACHE_QUALITY_AUTO})
944     public @interface DrawingCacheQuality {}
945
946     /**
947      * <p>Enables low quality mode for the drawing cache.</p>
948      */
949     public static final int DRAWING_CACHE_QUALITY_LOW = 0x00080000;
950
951     /**
952      * <p>Enables high quality mode for the drawing cache.</p>
953      */
954     public static final int DRAWING_CACHE_QUALITY_HIGH = 0x00100000;
955
956     /**
957      * <p>Enables automatic quality mode for the drawing cache.</p>
958      */
959     public static final int DRAWING_CACHE_QUALITY_AUTO = 0x00000000;
960
961     private static final int[] DRAWING_CACHE_QUALITY_FLAGS = {
962             DRAWING_CACHE_QUALITY_AUTO, DRAWING_CACHE_QUALITY_LOW, DRAWING_CACHE_QUALITY_HIGH
963     };
964
965     /**
966      * <p>Mask for use with setFlags indicating bits used for the cache
967      * quality property.</p>
968      * {@hide}
969      */
970     static final int DRAWING_CACHE_QUALITY_MASK = 0x00180000;
971
972     /**
973      * <p>
974      * Indicates this view can be long clicked. When long clickable, a View
975      * reacts to long clicks by notifying the OnLongClickListener or showing a
976      * context menu.
977      * </p>
978      * {@hide}
979      */
980     static final int LONG_CLICKABLE = 0x00200000;
981
982     /**
983      * <p>Indicates that this view gets its drawable states from its direct parent
984      * and ignores its original internal states.</p>
985      *
986      * @hide
987      */
988     static final int DUPLICATE_PARENT_STATE = 0x00400000;
989
990     /** @hide */
991     @IntDef({
992         SCROLLBARS_INSIDE_OVERLAY,
993         SCROLLBARS_INSIDE_INSET,
994         SCROLLBARS_OUTSIDE_OVERLAY,
995         SCROLLBARS_OUTSIDE_INSET
996     })
997     @Retention(RetentionPolicy.SOURCE)
998     public @interface ScrollBarStyle {}
999
1000     /**
1001      * The scrollbar style to display the scrollbars inside the content area,
1002      * without increasing the padding. The scrollbars will be overlaid with
1003      * translucency on the view's content.
1004      */
1005     public static final int SCROLLBARS_INSIDE_OVERLAY = 0;
1006
1007     /**
1008      * The scrollbar style to display the scrollbars inside the padded area,
1009      * increasing the padding of the view. The scrollbars will not overlap the
1010      * content area of the view.
1011      */
1012     public static final int SCROLLBARS_INSIDE_INSET = 0x01000000;
1013
1014     /**
1015      * The scrollbar style to display the scrollbars at the edge of the view,
1016      * without increasing the padding. The scrollbars will be overlaid with
1017      * translucency.
1018      */
1019     public static final int SCROLLBARS_OUTSIDE_OVERLAY = 0x02000000;
1020
1021     /**
1022      * The scrollbar style to display the scrollbars at the edge of the view,
1023      * increasing the padding of the view. The scrollbars will only overlap the
1024      * background, if any.
1025      */
1026     public static final int SCROLLBARS_OUTSIDE_INSET = 0x03000000;
1027
1028     /**
1029      * Mask to check if the scrollbar style is overlay or inset.
1030      * {@hide}
1031      */
1032     static final int SCROLLBARS_INSET_MASK = 0x01000000;
1033
1034     /**
1035      * Mask to check if the scrollbar style is inside or outside.
1036      * {@hide}
1037      */
1038     static final int SCROLLBARS_OUTSIDE_MASK = 0x02000000;
1039
1040     /**
1041      * Mask for scrollbar style.
1042      * {@hide}
1043      */
1044     static final int SCROLLBARS_STYLE_MASK = 0x03000000;
1045
1046     /**
1047      * View flag indicating that the screen should remain on while the
1048      * window containing this view is visible to the user.  This effectively
1049      * takes care of automatically setting the WindowManager's
1050      * {@link WindowManager.LayoutParams#FLAG_KEEP_SCREEN_ON}.
1051      */
1052     public static final int KEEP_SCREEN_ON = 0x04000000;
1053
1054     /**
1055      * View flag indicating whether this view should have sound effects enabled
1056      * for events such as clicking and touching.
1057      */
1058     public static final int SOUND_EFFECTS_ENABLED = 0x08000000;
1059
1060     /**
1061      * View flag indicating whether this view should have haptic feedback
1062      * enabled for events such as long presses.
1063      */
1064     public static final int HAPTIC_FEEDBACK_ENABLED = 0x10000000;
1065
1066     /**
1067      * <p>Indicates that the view hierarchy should stop saving state when
1068      * it reaches this view.  If state saving is initiated immediately at
1069      * the view, it will be allowed.
1070      * {@hide}
1071      */
1072     static final int PARENT_SAVE_DISABLED = 0x20000000;
1073
1074     /**
1075      * <p>Mask for use with setFlags indicating bits used for PARENT_SAVE_DISABLED.</p>
1076      * {@hide}
1077      */
1078     static final int PARENT_SAVE_DISABLED_MASK = 0x20000000;
1079
1080     /** @hide */
1081     @IntDef(flag = true,
1082             value = {
1083                 FOCUSABLES_ALL,
1084                 FOCUSABLES_TOUCH_MODE
1085             })
1086     @Retention(RetentionPolicy.SOURCE)
1087     public @interface FocusableMode {}
1088
1089     /**
1090      * View flag indicating whether {@link #addFocusables(ArrayList, int, int)}
1091      * should add all focusable Views regardless if they are focusable in touch mode.
1092      */
1093     public static final int FOCUSABLES_ALL = 0x00000000;
1094
1095     /**
1096      * View flag indicating whether {@link #addFocusables(ArrayList, int, int)}
1097      * should add only Views focusable in touch mode.
1098      */
1099     public static final int FOCUSABLES_TOUCH_MODE = 0x00000001;
1100
1101     /** @hide */
1102     @IntDef({
1103             FOCUS_BACKWARD,
1104             FOCUS_FORWARD,
1105             FOCUS_LEFT,
1106             FOCUS_UP,
1107             FOCUS_RIGHT,
1108             FOCUS_DOWN
1109     })
1110     @Retention(RetentionPolicy.SOURCE)
1111     public @interface FocusDirection {}
1112
1113     /** @hide */
1114     @IntDef({
1115             FOCUS_LEFT,
1116             FOCUS_UP,
1117             FOCUS_RIGHT,
1118             FOCUS_DOWN
1119     })
1120     @Retention(RetentionPolicy.SOURCE)
1121     public @interface FocusRealDirection {} // Like @FocusDirection, but without forward/backward
1122
1123     /**
1124      * Use with {@link #focusSearch(int)}. Move focus to the previous selectable
1125      * item.
1126      */
1127     public static final int FOCUS_BACKWARD = 0x00000001;
1128
1129     /**
1130      * Use with {@link #focusSearch(int)}. Move focus to the next selectable
1131      * item.
1132      */
1133     public static final int FOCUS_FORWARD = 0x00000002;
1134
1135     /**
1136      * Use with {@link #focusSearch(int)}. Move focus to the left.
1137      */
1138     public static final int FOCUS_LEFT = 0x00000011;
1139
1140     /**
1141      * Use with {@link #focusSearch(int)}. Move focus up.
1142      */
1143     public static final int FOCUS_UP = 0x00000021;
1144
1145     /**
1146      * Use with {@link #focusSearch(int)}. Move focus to the right.
1147      */
1148     public static final int FOCUS_RIGHT = 0x00000042;
1149
1150     /**
1151      * Use with {@link #focusSearch(int)}. Move focus down.
1152      */
1153     public static final int FOCUS_DOWN = 0x00000082;
1154
1155     /**
1156      * Bits of {@link #getMeasuredWidthAndState()} and
1157      * {@link #getMeasuredWidthAndState()} that provide the actual measured size.
1158      */
1159     public static final int MEASURED_SIZE_MASK = 0x00ffffff;
1160
1161     /**
1162      * Bits of {@link #getMeasuredWidthAndState()} and
1163      * {@link #getMeasuredWidthAndState()} that provide the additional state bits.
1164      */
1165     public static final int MEASURED_STATE_MASK = 0xff000000;
1166
1167     /**
1168      * Bit shift of {@link #MEASURED_STATE_MASK} to get to the height bits
1169      * for functions that combine both width and height into a single int,
1170      * such as {@link #getMeasuredState()} and the childState argument of
1171      * {@link #resolveSizeAndState(int, int, int)}.
1172      */
1173     public static final int MEASURED_HEIGHT_STATE_SHIFT = 16;
1174
1175     /**
1176      * Bit of {@link #getMeasuredWidthAndState()} and
1177      * {@link #getMeasuredWidthAndState()} that indicates the measured size
1178      * is smaller that the space the view would like to have.
1179      */
1180     public static final int MEASURED_STATE_TOO_SMALL = 0x01000000;
1181
1182     /**
1183      * Base View state sets
1184      */
1185     // Singles
1186     /**
1187      * Indicates the view has no states set. States are used with
1188      * {@link android.graphics.drawable.Drawable} to change the drawing of the
1189      * view depending on its state.
1190      *
1191      * @see android.graphics.drawable.Drawable
1192      * @see #getDrawableState()
1193      */
1194     protected static final int[] EMPTY_STATE_SET;
1195     /**
1196      * Indicates the view is enabled. States are used with
1197      * {@link android.graphics.drawable.Drawable} to change the drawing of the
1198      * view depending on its state.
1199      *
1200      * @see android.graphics.drawable.Drawable
1201      * @see #getDrawableState()
1202      */
1203     protected static final int[] ENABLED_STATE_SET;
1204     /**
1205      * Indicates the view is focused. States are used with
1206      * {@link android.graphics.drawable.Drawable} to change the drawing of the
1207      * view depending on its state.
1208      *
1209      * @see android.graphics.drawable.Drawable
1210      * @see #getDrawableState()
1211      */
1212     protected static final int[] FOCUSED_STATE_SET;
1213     /**
1214      * Indicates the view is selected. States are used with
1215      * {@link android.graphics.drawable.Drawable} to change the drawing of the
1216      * view depending on its state.
1217      *
1218      * @see android.graphics.drawable.Drawable
1219      * @see #getDrawableState()
1220      */
1221     protected static final int[] SELECTED_STATE_SET;
1222     /**
1223      * Indicates the view is pressed. States are used with
1224      * {@link android.graphics.drawable.Drawable} to change the drawing of the
1225      * view depending on its state.
1226      *
1227      * @see android.graphics.drawable.Drawable
1228      * @see #getDrawableState()
1229      */
1230     protected static final int[] PRESSED_STATE_SET;
1231     /**
1232      * Indicates the view's window has focus. States are used with
1233      * {@link android.graphics.drawable.Drawable} to change the drawing of the
1234      * view depending on its state.
1235      *
1236      * @see android.graphics.drawable.Drawable
1237      * @see #getDrawableState()
1238      */
1239     protected static final int[] WINDOW_FOCUSED_STATE_SET;
1240     // Doubles
1241     /**
1242      * Indicates the view is enabled and has the focus.
1243      *
1244      * @see #ENABLED_STATE_SET
1245      * @see #FOCUSED_STATE_SET
1246      */
1247     protected static final int[] ENABLED_FOCUSED_STATE_SET;
1248     /**
1249      * Indicates the view is enabled and selected.
1250      *
1251      * @see #ENABLED_STATE_SET
1252      * @see #SELECTED_STATE_SET
1253      */
1254     protected static final int[] ENABLED_SELECTED_STATE_SET;
1255     /**
1256      * Indicates the view is enabled and that its window has focus.
1257      *
1258      * @see #ENABLED_STATE_SET
1259      * @see #WINDOW_FOCUSED_STATE_SET
1260      */
1261     protected static final int[] ENABLED_WINDOW_FOCUSED_STATE_SET;
1262     /**
1263      * Indicates the view is focused and selected.
1264      *
1265      * @see #FOCUSED_STATE_SET
1266      * @see #SELECTED_STATE_SET
1267      */
1268     protected static final int[] FOCUSED_SELECTED_STATE_SET;
1269     /**
1270      * Indicates the view has the focus and that its window has the focus.
1271      *
1272      * @see #FOCUSED_STATE_SET
1273      * @see #WINDOW_FOCUSED_STATE_SET
1274      */
1275     protected static final int[] FOCUSED_WINDOW_FOCUSED_STATE_SET;
1276     /**
1277      * Indicates the view is selected and that its window has the focus.
1278      *
1279      * @see #SELECTED_STATE_SET
1280      * @see #WINDOW_FOCUSED_STATE_SET
1281      */
1282     protected static final int[] SELECTED_WINDOW_FOCUSED_STATE_SET;
1283     // Triples
1284     /**
1285      * Indicates the view is enabled, focused and selected.
1286      *
1287      * @see #ENABLED_STATE_SET
1288      * @see #FOCUSED_STATE_SET
1289      * @see #SELECTED_STATE_SET
1290      */
1291     protected static final int[] ENABLED_FOCUSED_SELECTED_STATE_SET;
1292     /**
1293      * Indicates the view is enabled, focused and its window has the focus.
1294      *
1295      * @see #ENABLED_STATE_SET
1296      * @see #FOCUSED_STATE_SET
1297      * @see #WINDOW_FOCUSED_STATE_SET
1298      */
1299     protected static final int[] ENABLED_FOCUSED_WINDOW_FOCUSED_STATE_SET;
1300     /**
1301      * Indicates the view is enabled, selected and its window has the focus.
1302      *
1303      * @see #ENABLED_STATE_SET
1304      * @see #SELECTED_STATE_SET
1305      * @see #WINDOW_FOCUSED_STATE_SET
1306      */
1307     protected static final int[] ENABLED_SELECTED_WINDOW_FOCUSED_STATE_SET;
1308     /**
1309      * Indicates the view is focused, selected and its window has the focus.
1310      *
1311      * @see #FOCUSED_STATE_SET
1312      * @see #SELECTED_STATE_SET
1313      * @see #WINDOW_FOCUSED_STATE_SET
1314      */
1315     protected static final int[] FOCUSED_SELECTED_WINDOW_FOCUSED_STATE_SET;
1316     /**
1317      * Indicates the view is enabled, focused, selected and its window
1318      * has the focus.
1319      *
1320      * @see #ENABLED_STATE_SET
1321      * @see #FOCUSED_STATE_SET
1322      * @see #SELECTED_STATE_SET
1323      * @see #WINDOW_FOCUSED_STATE_SET
1324      */
1325     protected static final int[] ENABLED_FOCUSED_SELECTED_WINDOW_FOCUSED_STATE_SET;
1326     /**
1327      * Indicates the view is pressed and its window has the focus.
1328      *
1329      * @see #PRESSED_STATE_SET
1330      * @see #WINDOW_FOCUSED_STATE_SET
1331      */
1332     protected static final int[] PRESSED_WINDOW_FOCUSED_STATE_SET;
1333     /**
1334      * Indicates the view is pressed and selected.
1335      *
1336      * @see #PRESSED_STATE_SET
1337      * @see #SELECTED_STATE_SET
1338      */
1339     protected static final int[] PRESSED_SELECTED_STATE_SET;
1340     /**
1341      * Indicates the view is pressed, selected and its window has the focus.
1342      *
1343      * @see #PRESSED_STATE_SET
1344      * @see #SELECTED_STATE_SET
1345      * @see #WINDOW_FOCUSED_STATE_SET
1346      */
1347     protected static final int[] PRESSED_SELECTED_WINDOW_FOCUSED_STATE_SET;
1348     /**
1349      * Indicates the view is pressed and focused.
1350      *
1351      * @see #PRESSED_STATE_SET
1352      * @see #FOCUSED_STATE_SET
1353      */
1354     protected static final int[] PRESSED_FOCUSED_STATE_SET;
1355     /**
1356      * Indicates the view is pressed, focused and its window has the focus.
1357      *
1358      * @see #PRESSED_STATE_SET
1359      * @see #FOCUSED_STATE_SET
1360      * @see #WINDOW_FOCUSED_STATE_SET
1361      */
1362     protected static final int[] PRESSED_FOCUSED_WINDOW_FOCUSED_STATE_SET;
1363     /**
1364      * Indicates the view is pressed, focused and selected.
1365      *
1366      * @see #PRESSED_STATE_SET
1367      * @see #SELECTED_STATE_SET
1368      * @see #FOCUSED_STATE_SET
1369      */
1370     protected static final int[] PRESSED_FOCUSED_SELECTED_STATE_SET;
1371     /**
1372      * Indicates the view is pressed, focused, selected and its window has the focus.
1373      *
1374      * @see #PRESSED_STATE_SET
1375      * @see #FOCUSED_STATE_SET
1376      * @see #SELECTED_STATE_SET
1377      * @see #WINDOW_FOCUSED_STATE_SET
1378      */
1379     protected static final int[] PRESSED_FOCUSED_SELECTED_WINDOW_FOCUSED_STATE_SET;
1380     /**
1381      * Indicates the view is pressed and enabled.
1382      *
1383      * @see #PRESSED_STATE_SET
1384      * @see #ENABLED_STATE_SET
1385      */
1386     protected static final int[] PRESSED_ENABLED_STATE_SET;
1387     /**
1388      * Indicates the view is pressed, enabled and its window has the focus.
1389      *
1390      * @see #PRESSED_STATE_SET
1391      * @see #ENABLED_STATE_SET
1392      * @see #WINDOW_FOCUSED_STATE_SET
1393      */
1394     protected static final int[] PRESSED_ENABLED_WINDOW_FOCUSED_STATE_SET;
1395     /**
1396      * Indicates the view is pressed, enabled and selected.
1397      *
1398      * @see #PRESSED_STATE_SET
1399      * @see #ENABLED_STATE_SET
1400      * @see #SELECTED_STATE_SET
1401      */
1402     protected static final int[] PRESSED_ENABLED_SELECTED_STATE_SET;
1403     /**
1404      * Indicates the view is pressed, enabled, selected and its window has the
1405      * focus.
1406      *
1407      * @see #PRESSED_STATE_SET
1408      * @see #ENABLED_STATE_SET
1409      * @see #SELECTED_STATE_SET
1410      * @see #WINDOW_FOCUSED_STATE_SET
1411      */
1412     protected static final int[] PRESSED_ENABLED_SELECTED_WINDOW_FOCUSED_STATE_SET;
1413     /**
1414      * Indicates the view is pressed, enabled and focused.
1415      *
1416      * @see #PRESSED_STATE_SET
1417      * @see #ENABLED_STATE_SET
1418      * @see #FOCUSED_STATE_SET
1419      */
1420     protected static final int[] PRESSED_ENABLED_FOCUSED_STATE_SET;
1421     /**
1422      * Indicates the view is pressed, enabled, focused and its window has the
1423      * focus.
1424      *
1425      * @see #PRESSED_STATE_SET
1426      * @see #ENABLED_STATE_SET
1427      * @see #FOCUSED_STATE_SET
1428      * @see #WINDOW_FOCUSED_STATE_SET
1429      */
1430     protected static final int[] PRESSED_ENABLED_FOCUSED_WINDOW_FOCUSED_STATE_SET;
1431     /**
1432      * Indicates the view is pressed, enabled, focused and selected.
1433      *
1434      * @see #PRESSED_STATE_SET
1435      * @see #ENABLED_STATE_SET
1436      * @see #SELECTED_STATE_SET
1437      * @see #FOCUSED_STATE_SET
1438      */
1439     protected static final int[] PRESSED_ENABLED_FOCUSED_SELECTED_STATE_SET;
1440     /**
1441      * Indicates the view is pressed, enabled, focused, selected and its window
1442      * has the focus.
1443      *
1444      * @see #PRESSED_STATE_SET
1445      * @see #ENABLED_STATE_SET
1446      * @see #SELECTED_STATE_SET
1447      * @see #FOCUSED_STATE_SET
1448      * @see #WINDOW_FOCUSED_STATE_SET
1449      */
1450     protected static final int[] PRESSED_ENABLED_FOCUSED_SELECTED_WINDOW_FOCUSED_STATE_SET;
1451
1452     static {
1453         EMPTY_STATE_SET = StateSet.get(0);
1454
1455         WINDOW_FOCUSED_STATE_SET = StateSet.get(StateSet.VIEW_STATE_WINDOW_FOCUSED);
1456
1457         SELECTED_STATE_SET = StateSet.get(StateSet.VIEW_STATE_SELECTED);
1458         SELECTED_WINDOW_FOCUSED_STATE_SET = StateSet.get(
1459                 StateSet.VIEW_STATE_WINDOW_FOCUSED | StateSet.VIEW_STATE_SELECTED);
1460
1461         FOCUSED_STATE_SET = StateSet.get(StateSet.VIEW_STATE_FOCUSED);
1462         FOCUSED_WINDOW_FOCUSED_STATE_SET = StateSet.get(
1463                 StateSet.VIEW_STATE_WINDOW_FOCUSED | StateSet.VIEW_STATE_FOCUSED);
1464         FOCUSED_SELECTED_STATE_SET = StateSet.get(
1465                 StateSet.VIEW_STATE_SELECTED | StateSet.VIEW_STATE_FOCUSED);
1466         FOCUSED_SELECTED_WINDOW_FOCUSED_STATE_SET = StateSet.get(
1467                 StateSet.VIEW_STATE_WINDOW_FOCUSED | StateSet.VIEW_STATE_SELECTED
1468                         | StateSet.VIEW_STATE_FOCUSED);
1469
1470         ENABLED_STATE_SET = StateSet.get(StateSet.VIEW_STATE_ENABLED);
1471         ENABLED_WINDOW_FOCUSED_STATE_SET = StateSet.get(
1472                 StateSet.VIEW_STATE_WINDOW_FOCUSED | StateSet.VIEW_STATE_ENABLED);
1473         ENABLED_SELECTED_STATE_SET = StateSet.get(
1474                 StateSet.VIEW_STATE_SELECTED | StateSet.VIEW_STATE_ENABLED);
1475         ENABLED_SELECTED_WINDOW_FOCUSED_STATE_SET = StateSet.get(
1476                 StateSet.VIEW_STATE_WINDOW_FOCUSED | StateSet.VIEW_STATE_SELECTED
1477                         | StateSet.VIEW_STATE_ENABLED);
1478         ENABLED_FOCUSED_STATE_SET = StateSet.get(
1479                 StateSet.VIEW_STATE_FOCUSED | StateSet.VIEW_STATE_ENABLED);
1480         ENABLED_FOCUSED_WINDOW_FOCUSED_STATE_SET = StateSet.get(
1481                 StateSet.VIEW_STATE_WINDOW_FOCUSED | StateSet.VIEW_STATE_FOCUSED
1482                         | StateSet.VIEW_STATE_ENABLED);
1483         ENABLED_FOCUSED_SELECTED_STATE_SET = StateSet.get(
1484                 StateSet.VIEW_STATE_SELECTED | StateSet.VIEW_STATE_FOCUSED
1485                         | StateSet.VIEW_STATE_ENABLED);
1486         ENABLED_FOCUSED_SELECTED_WINDOW_FOCUSED_STATE_SET = StateSet.get(
1487                 StateSet.VIEW_STATE_WINDOW_FOCUSED | StateSet.VIEW_STATE_SELECTED
1488                         | StateSet.VIEW_STATE_FOCUSED| StateSet.VIEW_STATE_ENABLED);
1489
1490         PRESSED_STATE_SET = StateSet.get(StateSet.VIEW_STATE_PRESSED);
1491         PRESSED_WINDOW_FOCUSED_STATE_SET = StateSet.get(
1492                 StateSet.VIEW_STATE_WINDOW_FOCUSED | StateSet.VIEW_STATE_PRESSED);
1493         PRESSED_SELECTED_STATE_SET = StateSet.get(
1494                 StateSet.VIEW_STATE_SELECTED | StateSet.VIEW_STATE_PRESSED);
1495         PRESSED_SELECTED_WINDOW_FOCUSED_STATE_SET = StateSet.get(
1496                 StateSet.VIEW_STATE_WINDOW_FOCUSED | StateSet.VIEW_STATE_SELECTED
1497                         | StateSet.VIEW_STATE_PRESSED);
1498         PRESSED_FOCUSED_STATE_SET = StateSet.get(
1499                 StateSet.VIEW_STATE_FOCUSED | StateSet.VIEW_STATE_PRESSED);
1500         PRESSED_FOCUSED_WINDOW_FOCUSED_STATE_SET = StateSet.get(
1501                 StateSet.VIEW_STATE_WINDOW_FOCUSED | StateSet.VIEW_STATE_FOCUSED
1502                         | StateSet.VIEW_STATE_PRESSED);
1503         PRESSED_FOCUSED_SELECTED_STATE_SET = StateSet.get(
1504                 StateSet.VIEW_STATE_SELECTED | StateSet.VIEW_STATE_FOCUSED
1505                         | StateSet.VIEW_STATE_PRESSED);
1506         PRESSED_FOCUSED_SELECTED_WINDOW_FOCUSED_STATE_SET = StateSet.get(
1507                 StateSet.VIEW_STATE_WINDOW_FOCUSED | StateSet.VIEW_STATE_SELECTED
1508                         | StateSet.VIEW_STATE_FOCUSED | StateSet.VIEW_STATE_PRESSED);
1509         PRESSED_ENABLED_STATE_SET = StateSet.get(
1510                 StateSet.VIEW_STATE_ENABLED | StateSet.VIEW_STATE_PRESSED);
1511         PRESSED_ENABLED_WINDOW_FOCUSED_STATE_SET = StateSet.get(
1512                 StateSet.VIEW_STATE_WINDOW_FOCUSED | StateSet.VIEW_STATE_ENABLED
1513                         | StateSet.VIEW_STATE_PRESSED);
1514         PRESSED_ENABLED_SELECTED_STATE_SET = StateSet.get(
1515                 StateSet.VIEW_STATE_SELECTED | StateSet.VIEW_STATE_ENABLED
1516                         | StateSet.VIEW_STATE_PRESSED);
1517         PRESSED_ENABLED_SELECTED_WINDOW_FOCUSED_STATE_SET = StateSet.get(
1518                 StateSet.VIEW_STATE_WINDOW_FOCUSED | StateSet.VIEW_STATE_SELECTED
1519                         | StateSet.VIEW_STATE_ENABLED | StateSet.VIEW_STATE_PRESSED);
1520         PRESSED_ENABLED_FOCUSED_STATE_SET = StateSet.get(
1521                 StateSet.VIEW_STATE_FOCUSED | StateSet.VIEW_STATE_ENABLED
1522                         | StateSet.VIEW_STATE_PRESSED);
1523         PRESSED_ENABLED_FOCUSED_WINDOW_FOCUSED_STATE_SET = StateSet.get(
1524                 StateSet.VIEW_STATE_WINDOW_FOCUSED | StateSet.VIEW_STATE_FOCUSED
1525                         | StateSet.VIEW_STATE_ENABLED | StateSet.VIEW_STATE_PRESSED);
1526         PRESSED_ENABLED_FOCUSED_SELECTED_STATE_SET = StateSet.get(
1527                 StateSet.VIEW_STATE_SELECTED | StateSet.VIEW_STATE_FOCUSED
1528                         | StateSet.VIEW_STATE_ENABLED | StateSet.VIEW_STATE_PRESSED);
1529         PRESSED_ENABLED_FOCUSED_SELECTED_WINDOW_FOCUSED_STATE_SET = StateSet.get(
1530                 StateSet.VIEW_STATE_WINDOW_FOCUSED | StateSet.VIEW_STATE_SELECTED
1531                         | StateSet.VIEW_STATE_FOCUSED| StateSet.VIEW_STATE_ENABLED
1532                         | StateSet.VIEW_STATE_PRESSED);
1533     }
1534
1535     /**
1536      * Accessibility event types that are dispatched for text population.
1537      */
1538     private static final int POPULATING_ACCESSIBILITY_EVENT_TYPES =
1539             AccessibilityEvent.TYPE_VIEW_CLICKED
1540             | AccessibilityEvent.TYPE_VIEW_LONG_CLICKED
1541             | AccessibilityEvent.TYPE_VIEW_SELECTED
1542             | AccessibilityEvent.TYPE_VIEW_FOCUSED
1543             | AccessibilityEvent.TYPE_WINDOW_STATE_CHANGED
1544             | AccessibilityEvent.TYPE_VIEW_HOVER_ENTER
1545             | AccessibilityEvent.TYPE_VIEW_HOVER_EXIT
1546             | AccessibilityEvent.TYPE_VIEW_TEXT_CHANGED
1547             | AccessibilityEvent.TYPE_VIEW_TEXT_SELECTION_CHANGED
1548             | AccessibilityEvent.TYPE_VIEW_ACCESSIBILITY_FOCUSED
1549             | AccessibilityEvent.TYPE_VIEW_TEXT_TRAVERSED_AT_MOVEMENT_GRANULARITY;
1550
1551     /**
1552      * Temporary Rect currently for use in setBackground().  This will probably
1553      * be extended in the future to hold our own class with more than just
1554      * a Rect. :)
1555      */
1556     static final ThreadLocal<Rect> sThreadLocal = new ThreadLocal<Rect>();
1557
1558     /**
1559      * Map used to store views' tags.
1560      */
1561     private SparseArray<Object> mKeyedTags;
1562
1563     /**
1564      * The next available accessibility id.
1565      */
1566     private static int sNextAccessibilityViewId;
1567
1568     /**
1569      * The animation currently associated with this view.
1570      * @hide
1571      */
1572     protected Animation mCurrentAnimation = null;
1573
1574     /**
1575      * Width as measured during measure pass.
1576      * {@hide}
1577      */
1578     @ViewDebug.ExportedProperty(category = "measurement")
1579     int mMeasuredWidth;
1580
1581     /**
1582      * Height as measured during measure pass.
1583      * {@hide}
1584      */
1585     @ViewDebug.ExportedProperty(category = "measurement")
1586     int mMeasuredHeight;
1587
1588     /**
1589      * Flag to indicate that this view was marked INVALIDATED, or had its display list
1590      * invalidated, prior to the current drawing iteration. If true, the view must re-draw
1591      * its display list. This flag, used only when hw accelerated, allows us to clear the
1592      * flag while retaining this information until it's needed (at getDisplayList() time and
1593      * in drawChild(), when we decide to draw a view's children's display lists into our own).
1594      *
1595      * {@hide}
1596      */
1597     boolean mRecreateDisplayList = false;
1598
1599     /**
1600      * The view's identifier.
1601      * {@hide}
1602      *
1603      * @see #setId(int)
1604      * @see #getId()
1605      */
1606     @IdRes
1607     @ViewDebug.ExportedProperty(resolveId = true)
1608     int mID = NO_ID;
1609
1610     /**
1611      * The stable ID of this view for accessibility purposes.
1612      */
1613     int mAccessibilityViewId = NO_ID;
1614
1615     private int mAccessibilityCursorPosition = ACCESSIBILITY_CURSOR_POSITION_UNDEFINED;
1616
1617     SendViewStateChangedAccessibilityEvent mSendViewStateChangedAccessibilityEvent;
1618
1619     /**
1620      * The view's tag.
1621      * {@hide}
1622      *
1623      * @see #setTag(Object)
1624      * @see #getTag()
1625      */
1626     protected Object mTag = null;
1627
1628     // for mPrivateFlags:
1629     /** {@hide} */
1630     static final int PFLAG_WANTS_FOCUS                 = 0x00000001;
1631     /** {@hide} */
1632     static final int PFLAG_FOCUSED                     = 0x00000002;
1633     /** {@hide} */
1634     static final int PFLAG_SELECTED                    = 0x00000004;
1635     /** {@hide} */
1636     static final int PFLAG_IS_ROOT_NAMESPACE           = 0x00000008;
1637     /** {@hide} */
1638     static final int PFLAG_HAS_BOUNDS                  = 0x00000010;
1639     /** {@hide} */
1640     static final int PFLAG_DRAWN                       = 0x00000020;
1641     /**
1642      * When this flag is set, this view is running an animation on behalf of its
1643      * children and should therefore not cancel invalidate requests, even if they
1644      * lie outside of this view's bounds.
1645      *
1646      * {@hide}
1647      */
1648     static final int PFLAG_DRAW_ANIMATION              = 0x00000040;
1649     /** {@hide} */
1650     static final int PFLAG_SKIP_DRAW                   = 0x00000080;
1651     /** {@hide} */
1652     static final int PFLAG_ONLY_DRAWS_BACKGROUND       = 0x00000100;
1653     /** {@hide} */
1654     static final int PFLAG_REQUEST_TRANSPARENT_REGIONS = 0x00000200;
1655     /** {@hide} */
1656     static final int PFLAG_DRAWABLE_STATE_DIRTY        = 0x00000400;
1657     /** {@hide} */
1658     static final int PFLAG_MEASURED_DIMENSION_SET      = 0x00000800;
1659     /** {@hide} */
1660     static final int PFLAG_FORCE_LAYOUT                = 0x00001000;
1661     /** {@hide} */
1662     static final int PFLAG_LAYOUT_REQUIRED             = 0x00002000;
1663
1664     private static final int PFLAG_PRESSED             = 0x00004000;
1665
1666     /** {@hide} */
1667     static final int PFLAG_DRAWING_CACHE_VALID         = 0x00008000;
1668     /**
1669      * Flag used to indicate that this view should be drawn once more (and only once
1670      * more) after its animation has completed.
1671      * {@hide}
1672      */
1673     static final int PFLAG_ANIMATION_STARTED           = 0x00010000;
1674
1675     private static final int PFLAG_SAVE_STATE_CALLED   = 0x00020000;
1676
1677     /**
1678      * Indicates that the View returned true when onSetAlpha() was called and that
1679      * the alpha must be restored.
1680      * {@hide}
1681      */
1682     static final int PFLAG_ALPHA_SET                   = 0x00040000;
1683
1684     /**
1685      * Set by {@link #setScrollContainer(boolean)}.
1686      */
1687     static final int PFLAG_SCROLL_CONTAINER            = 0x00080000;
1688
1689     /**
1690      * Set by {@link #setScrollContainer(boolean)}.
1691      */
1692     static final int PFLAG_SCROLL_CONTAINER_ADDED      = 0x00100000;
1693
1694     /**
1695      * View flag indicating whether this view was invalidated (fully or partially.)
1696      *
1697      * @hide
1698      */
1699     static final int PFLAG_DIRTY                       = 0x00200000;
1700
1701     /**
1702      * View flag indicating whether this view was invalidated by an opaque
1703      * invalidate request.
1704      *
1705      * @hide
1706      */
1707     static final int PFLAG_DIRTY_OPAQUE                = 0x00400000;
1708
1709     /**
1710      * Mask for {@link #PFLAG_DIRTY} and {@link #PFLAG_DIRTY_OPAQUE}.
1711      *
1712      * @hide
1713      */
1714     static final int PFLAG_DIRTY_MASK                  = 0x00600000;
1715
1716     /**
1717      * Indicates whether the background is opaque.
1718      *
1719      * @hide
1720      */
1721     static final int PFLAG_OPAQUE_BACKGROUND           = 0x00800000;
1722
1723     /**
1724      * Indicates whether the scrollbars are opaque.
1725      *
1726      * @hide
1727      */
1728     static final int PFLAG_OPAQUE_SCROLLBARS           = 0x01000000;
1729
1730     /**
1731      * Indicates whether the view is opaque.
1732      *
1733      * @hide
1734      */
1735     static final int PFLAG_OPAQUE_MASK                 = 0x01800000;
1736
1737     /**
1738      * Indicates a prepressed state;
1739      * the short time between ACTION_DOWN and recognizing
1740      * a 'real' press. Prepressed is used to recognize quick taps
1741      * even when they are shorter than ViewConfiguration.getTapTimeout().
1742      *
1743      * @hide
1744      */
1745     private static final int PFLAG_PREPRESSED          = 0x02000000;
1746
1747     /**
1748      * Indicates whether the view is temporarily detached.
1749      *
1750      * @hide
1751      */
1752     static final int PFLAG_CANCEL_NEXT_UP_EVENT        = 0x04000000;
1753
1754     /**
1755      * Indicates that we should awaken scroll bars once attached
1756      *
1757      * @hide
1758      */
1759     private static final int PFLAG_AWAKEN_SCROLL_BARS_ON_ATTACH = 0x08000000;
1760
1761     /**
1762      * Indicates that the view has received HOVER_ENTER.  Cleared on HOVER_EXIT.
1763      * @hide
1764      */
1765     private static final int PFLAG_HOVERED             = 0x10000000;
1766
1767     /**
1768      * no longer needed, should be reused
1769      */
1770     private static final int PFLAG_DOES_NOTHING_REUSE_PLEASE = 0x20000000;
1771
1772     /** {@hide} */
1773     static final int PFLAG_ACTIVATED                   = 0x40000000;
1774
1775     /**
1776      * Indicates that this view was specifically invalidated, not just dirtied because some
1777      * child view was invalidated. The flag is used to determine when we need to recreate
1778      * a view's display list (as opposed to just returning a reference to its existing
1779      * display list).
1780      *
1781      * @hide
1782      */
1783     static final int PFLAG_INVALIDATED                 = 0x80000000;
1784
1785     /**
1786      * Masks for mPrivateFlags2, as generated by dumpFlags():
1787      *
1788      * |-------|-------|-------|-------|
1789      *                                 1 PFLAG2_DRAG_CAN_ACCEPT
1790      *                                1  PFLAG2_DRAG_HOVERED
1791      *                              11   PFLAG2_LAYOUT_DIRECTION_MASK
1792      *                             1     PFLAG2_LAYOUT_DIRECTION_RESOLVED_RTL
1793      *                            1      PFLAG2_LAYOUT_DIRECTION_RESOLVED
1794      *                            11     PFLAG2_LAYOUT_DIRECTION_RESOLVED_MASK
1795      *                           1       PFLAG2_TEXT_DIRECTION_FLAGS[1]
1796      *                          1        PFLAG2_TEXT_DIRECTION_FLAGS[2]
1797      *                          11       PFLAG2_TEXT_DIRECTION_FLAGS[3]
1798      *                         1         PFLAG2_TEXT_DIRECTION_FLAGS[4]
1799      *                         1 1       PFLAG2_TEXT_DIRECTION_FLAGS[5]
1800      *                         11        PFLAG2_TEXT_DIRECTION_FLAGS[6]
1801      *                         111       PFLAG2_TEXT_DIRECTION_FLAGS[7]
1802      *                         111       PFLAG2_TEXT_DIRECTION_MASK
1803      *                        1          PFLAG2_TEXT_DIRECTION_RESOLVED
1804      *                       1           PFLAG2_TEXT_DIRECTION_RESOLVED_DEFAULT
1805      *                     111           PFLAG2_TEXT_DIRECTION_RESOLVED_MASK
1806      *                    1              PFLAG2_TEXT_ALIGNMENT_FLAGS[1]
1807      *                   1               PFLAG2_TEXT_ALIGNMENT_FLAGS[2]
1808      *                   11              PFLAG2_TEXT_ALIGNMENT_FLAGS[3]
1809      *                  1                PFLAG2_TEXT_ALIGNMENT_FLAGS[4]
1810      *                  1 1              PFLAG2_TEXT_ALIGNMENT_FLAGS[5]
1811      *                  11               PFLAG2_TEXT_ALIGNMENT_FLAGS[6]
1812      *                  111              PFLAG2_TEXT_ALIGNMENT_MASK
1813      *                 1                 PFLAG2_TEXT_ALIGNMENT_RESOLVED
1814      *                1                  PFLAG2_TEXT_ALIGNMENT_RESOLVED_DEFAULT
1815      *              111                  PFLAG2_TEXT_ALIGNMENT_RESOLVED_MASK
1816      *           111                     PFLAG2_IMPORTANT_FOR_ACCESSIBILITY_MASK
1817      *         11                        PFLAG2_ACCESSIBILITY_LIVE_REGION_MASK
1818      *       1                           PFLAG2_ACCESSIBILITY_FOCUSED
1819      *      1                            PFLAG2_SUBTREE_ACCESSIBILITY_STATE_CHANGED
1820      *     1                             PFLAG2_VIEW_QUICK_REJECTED
1821      *    1                              PFLAG2_PADDING_RESOLVED
1822      *   1                               PFLAG2_DRAWABLE_RESOLVED
1823      *  1                                PFLAG2_HAS_TRANSIENT_STATE
1824      * |-------|-------|-------|-------|
1825      */
1826
1827     /**
1828      * Indicates that this view has reported that it can accept the current drag's content.
1829      * Cleared when the drag operation concludes.
1830      * @hide
1831      */
1832     static final int PFLAG2_DRAG_CAN_ACCEPT            = 0x00000001;
1833
1834     /**
1835      * Indicates that this view is currently directly under the drag location in a
1836      * drag-and-drop operation involving content that it can accept.  Cleared when
1837      * the drag exits the view, or when the drag operation concludes.
1838      * @hide
1839      */
1840     static final int PFLAG2_DRAG_HOVERED               = 0x00000002;
1841
1842     /** @hide */
1843     @IntDef({
1844         LAYOUT_DIRECTION_LTR,
1845         LAYOUT_DIRECTION_RTL,
1846         LAYOUT_DIRECTION_INHERIT,
1847         LAYOUT_DIRECTION_LOCALE
1848     })
1849     @Retention(RetentionPolicy.SOURCE)
1850     // Not called LayoutDirection to avoid conflict with android.util.LayoutDirection
1851     public @interface LayoutDir {}
1852
1853     /** @hide */
1854     @IntDef({
1855         LAYOUT_DIRECTION_LTR,
1856         LAYOUT_DIRECTION_RTL
1857     })
1858     @Retention(RetentionPolicy.SOURCE)
1859     public @interface ResolvedLayoutDir {}
1860
1861     /**
1862      * Horizontal layout direction of this view is from Left to Right.
1863      * Use with {@link #setLayoutDirection}.
1864      */
1865     public static final int LAYOUT_DIRECTION_LTR = LayoutDirection.LTR;
1866
1867     /**
1868      * Horizontal layout direction of this view is from Right to Left.
1869      * Use with {@link #setLayoutDirection}.
1870      */
1871     public static final int LAYOUT_DIRECTION_RTL = LayoutDirection.RTL;
1872
1873     /**
1874      * Horizontal layout direction of this view is inherited from its parent.
1875      * Use with {@link #setLayoutDirection}.
1876      */
1877     public static final int LAYOUT_DIRECTION_INHERIT = LayoutDirection.INHERIT;
1878
1879     /**
1880      * Horizontal layout direction of this view is from deduced from the default language
1881      * script for the locale. Use with {@link #setLayoutDirection}.
1882      */
1883     public static final int LAYOUT_DIRECTION_LOCALE = LayoutDirection.LOCALE;
1884
1885     /**
1886      * Bit shift to get the horizontal layout direction. (bits after DRAG_HOVERED)
1887      * @hide
1888      */
1889     static final int PFLAG2_LAYOUT_DIRECTION_MASK_SHIFT = 2;
1890
1891     /**
1892      * Mask for use with private flags indicating bits used for horizontal layout direction.
1893      * @hide
1894      */
1895     static final int PFLAG2_LAYOUT_DIRECTION_MASK = 0x00000003 << PFLAG2_LAYOUT_DIRECTION_MASK_SHIFT;
1896
1897     /**
1898      * Indicates whether the view horizontal layout direction has been resolved and drawn to the
1899      * right-to-left direction.
1900      * @hide
1901      */
1902     static final int PFLAG2_LAYOUT_DIRECTION_RESOLVED_RTL = 4 << PFLAG2_LAYOUT_DIRECTION_MASK_SHIFT;
1903
1904     /**
1905      * Indicates whether the view horizontal layout direction has been resolved.
1906      * @hide
1907      */
1908     static final int PFLAG2_LAYOUT_DIRECTION_RESOLVED = 8 << PFLAG2_LAYOUT_DIRECTION_MASK_SHIFT;
1909
1910     /**
1911      * Mask for use with private flags indicating bits used for resolved horizontal layout direction.
1912      * @hide
1913      */
1914     static final int PFLAG2_LAYOUT_DIRECTION_RESOLVED_MASK = 0x0000000C
1915             << PFLAG2_LAYOUT_DIRECTION_MASK_SHIFT;
1916
1917     /*
1918      * Array of horizontal layout direction flags for mapping attribute "layoutDirection" to correct
1919      * flag value.
1920      * @hide
1921      */
1922     private static final int[] LAYOUT_DIRECTION_FLAGS = {
1923             LAYOUT_DIRECTION_LTR,
1924             LAYOUT_DIRECTION_RTL,
1925             LAYOUT_DIRECTION_INHERIT,
1926             LAYOUT_DIRECTION_LOCALE
1927     };
1928
1929     /**
1930      * Default horizontal layout direction.
1931      */
1932     private static final int LAYOUT_DIRECTION_DEFAULT = LAYOUT_DIRECTION_INHERIT;
1933
1934     /**
1935      * Default horizontal layout direction.
1936      * @hide
1937      */
1938     static final int LAYOUT_DIRECTION_RESOLVED_DEFAULT = LAYOUT_DIRECTION_LTR;
1939
1940     /**
1941      * Text direction is inherited through {@link ViewGroup}
1942      */
1943     public static final int TEXT_DIRECTION_INHERIT = 0;
1944
1945     /**
1946      * Text direction is using "first strong algorithm". The first strong directional character
1947      * determines the paragraph direction. If there is no strong directional character, the
1948      * paragraph direction is the view's resolved layout direction.
1949      */
1950     public static final int TEXT_DIRECTION_FIRST_STRONG = 1;
1951
1952     /**
1953      * Text direction is using "any-RTL" algorithm. The paragraph direction is RTL if it contains
1954      * any strong RTL character, otherwise it is LTR if it contains any strong LTR characters.
1955      * If there are neither, the paragraph direction is the view's resolved layout direction.
1956      */
1957     public static final int TEXT_DIRECTION_ANY_RTL = 2;
1958
1959     /**
1960      * Text direction is forced to LTR.
1961      */
1962     public static final int TEXT_DIRECTION_LTR = 3;
1963
1964     /**
1965      * Text direction is forced to RTL.
1966      */
1967     public static final int TEXT_DIRECTION_RTL = 4;
1968
1969     /**
1970      * Text direction is coming from the system Locale.
1971      */
1972     public static final int TEXT_DIRECTION_LOCALE = 5;
1973
1974     /**
1975      * Text direction is using "first strong algorithm". The first strong directional character
1976      * determines the paragraph direction. If there is no strong directional character, the
1977      * paragraph direction is LTR.
1978      */
1979     public static final int TEXT_DIRECTION_FIRST_STRONG_LTR = 6;
1980
1981     /**
1982      * Text direction is using "first strong algorithm". The first strong directional character
1983      * determines the paragraph direction. If there is no strong directional character, the
1984      * paragraph direction is RTL.
1985      */
1986     public static final int TEXT_DIRECTION_FIRST_STRONG_RTL = 7;
1987
1988     /**
1989      * Default text direction is inherited
1990      */
1991     private static final int TEXT_DIRECTION_DEFAULT = TEXT_DIRECTION_INHERIT;
1992
1993     /**
1994      * Default resolved text direction
1995      * @hide
1996      */
1997     static final int TEXT_DIRECTION_RESOLVED_DEFAULT = TEXT_DIRECTION_FIRST_STRONG;
1998
1999     /**
2000      * Bit shift to get the horizontal layout direction. (bits after LAYOUT_DIRECTION_RESOLVED)
2001      * @hide
2002      */
2003     static final int PFLAG2_TEXT_DIRECTION_MASK_SHIFT = 6;
2004
2005     /**
2006      * Mask for use with private flags indicating bits used for text direction.
2007      * @hide
2008      */
2009     static final int PFLAG2_TEXT_DIRECTION_MASK = 0x00000007
2010             << PFLAG2_TEXT_DIRECTION_MASK_SHIFT;
2011
2012     /**
2013      * Array of text direction flags for mapping attribute "textDirection" to correct
2014      * flag value.
2015      * @hide
2016      */
2017     private static final int[] PFLAG2_TEXT_DIRECTION_FLAGS = {
2018             TEXT_DIRECTION_INHERIT << PFLAG2_TEXT_DIRECTION_MASK_SHIFT,
2019             TEXT_DIRECTION_FIRST_STRONG << PFLAG2_TEXT_DIRECTION_MASK_SHIFT,
2020             TEXT_DIRECTION_ANY_RTL << PFLAG2_TEXT_DIRECTION_MASK_SHIFT,
2021             TEXT_DIRECTION_LTR << PFLAG2_TEXT_DIRECTION_MASK_SHIFT,
2022             TEXT_DIRECTION_RTL << PFLAG2_TEXT_DIRECTION_MASK_SHIFT,
2023             TEXT_DIRECTION_LOCALE << PFLAG2_TEXT_DIRECTION_MASK_SHIFT,
2024             TEXT_DIRECTION_FIRST_STRONG_LTR << PFLAG2_TEXT_DIRECTION_MASK_SHIFT,
2025             TEXT_DIRECTION_FIRST_STRONG_RTL << PFLAG2_TEXT_DIRECTION_MASK_SHIFT
2026     };
2027
2028     /**
2029      * Indicates whether the view text direction has been resolved.
2030      * @hide
2031      */
2032     static final int PFLAG2_TEXT_DIRECTION_RESOLVED = 0x00000008
2033             << PFLAG2_TEXT_DIRECTION_MASK_SHIFT;
2034
2035     /**
2036      * Bit shift to get the horizontal layout direction. (bits after DRAG_HOVERED)
2037      * @hide
2038      */
2039     static final int PFLAG2_TEXT_DIRECTION_RESOLVED_MASK_SHIFT = 10;
2040
2041     /**
2042      * Mask for use with private flags indicating bits used for resolved text direction.
2043      * @hide
2044      */
2045     static final int PFLAG2_TEXT_DIRECTION_RESOLVED_MASK = 0x00000007
2046             << PFLAG2_TEXT_DIRECTION_RESOLVED_MASK_SHIFT;
2047
2048     /**
2049      * Indicates whether the view text direction has been resolved to the "first strong" heuristic.
2050      * @hide
2051      */
2052     static final int PFLAG2_TEXT_DIRECTION_RESOLVED_DEFAULT =
2053             TEXT_DIRECTION_RESOLVED_DEFAULT << PFLAG2_TEXT_DIRECTION_RESOLVED_MASK_SHIFT;
2054
2055     /** @hide */
2056     @IntDef({
2057         TEXT_ALIGNMENT_INHERIT,
2058         TEXT_ALIGNMENT_GRAVITY,
2059         TEXT_ALIGNMENT_CENTER,
2060         TEXT_ALIGNMENT_TEXT_START,
2061         TEXT_ALIGNMENT_TEXT_END,
2062         TEXT_ALIGNMENT_VIEW_START,
2063         TEXT_ALIGNMENT_VIEW_END
2064     })
2065     @Retention(RetentionPolicy.SOURCE)
2066     public @interface TextAlignment {}
2067
2068     /**
2069      * Default text alignment. The text alignment of this View is inherited from its parent.
2070      * Use with {@link #setTextAlignment(int)}
2071      */
2072     public static final int TEXT_ALIGNMENT_INHERIT = 0;
2073
2074     /**
2075      * Default for the root view. The gravity determines the text alignment, ALIGN_NORMAL,
2076      * ALIGN_CENTER, or ALIGN_OPPOSITE, which are relative to each paragraph’s text direction.
2077      *
2078      * Use with {@link #setTextAlignment(int)}
2079      */
2080     public static final int TEXT_ALIGNMENT_GRAVITY = 1;
2081
2082     /**
2083      * Align to the start of the paragraph, e.g. ALIGN_NORMAL.
2084      *
2085      * Use with {@link #setTextAlignment(int)}
2086      */
2087     public static final int TEXT_ALIGNMENT_TEXT_START = 2;
2088
2089     /**
2090      * Align to the end of the paragraph, e.g. ALIGN_OPPOSITE.
2091      *
2092      * Use with {@link #setTextAlignment(int)}
2093      */
2094     public static final int TEXT_ALIGNMENT_TEXT_END = 3;
2095
2096     /**
2097      * Center the paragraph, e.g. ALIGN_CENTER.
2098      *
2099      * Use with {@link #setTextAlignment(int)}
2100      */
2101     public static final int TEXT_ALIGNMENT_CENTER = 4;
2102
2103     /**
2104      * Align to the start of the view, which is ALIGN_LEFT if the view’s resolved
2105      * layoutDirection is LTR, and ALIGN_RIGHT otherwise.
2106      *
2107      * Use with {@link #setTextAlignment(int)}
2108      */
2109     public static final int TEXT_ALIGNMENT_VIEW_START = 5;
2110
2111     /**
2112      * Align to the end of the view, which is ALIGN_RIGHT if the view’s resolved
2113      * layoutDirection is LTR, and ALIGN_LEFT otherwise.
2114      *
2115      * Use with {@link #setTextAlignment(int)}
2116      */
2117     public static final int TEXT_ALIGNMENT_VIEW_END = 6;
2118
2119     /**
2120      * Default text alignment is inherited
2121      */
2122     private static final int TEXT_ALIGNMENT_DEFAULT = TEXT_ALIGNMENT_GRAVITY;
2123
2124     /**
2125      * Default resolved text alignment
2126      * @hide
2127      */
2128     static final int TEXT_ALIGNMENT_RESOLVED_DEFAULT = TEXT_ALIGNMENT_GRAVITY;
2129
2130     /**
2131       * Bit shift to get the horizontal layout direction. (bits after DRAG_HOVERED)
2132       * @hide
2133       */
2134     static final int PFLAG2_TEXT_ALIGNMENT_MASK_SHIFT = 13;
2135
2136     /**
2137       * Mask for use with private flags indicating bits used for text alignment.
2138       * @hide
2139       */
2140     static final int PFLAG2_TEXT_ALIGNMENT_MASK = 0x00000007 << PFLAG2_TEXT_ALIGNMENT_MASK_SHIFT;
2141
2142     /**
2143      * Array of text direction flags for mapping attribute "textAlignment" to correct
2144      * flag value.
2145      * @hide
2146      */
2147     private static final int[] PFLAG2_TEXT_ALIGNMENT_FLAGS = {
2148             TEXT_ALIGNMENT_INHERIT << PFLAG2_TEXT_ALIGNMENT_MASK_SHIFT,
2149             TEXT_ALIGNMENT_GRAVITY << PFLAG2_TEXT_ALIGNMENT_MASK_SHIFT,
2150             TEXT_ALIGNMENT_TEXT_START << PFLAG2_TEXT_ALIGNMENT_MASK_SHIFT,
2151             TEXT_ALIGNMENT_TEXT_END << PFLAG2_TEXT_ALIGNMENT_MASK_SHIFT,
2152             TEXT_ALIGNMENT_CENTER << PFLAG2_TEXT_ALIGNMENT_MASK_SHIFT,
2153             TEXT_ALIGNMENT_VIEW_START << PFLAG2_TEXT_ALIGNMENT_MASK_SHIFT,
2154             TEXT_ALIGNMENT_VIEW_END << PFLAG2_TEXT_ALIGNMENT_MASK_SHIFT
2155     };
2156
2157     /**
2158      * Indicates whether the view text alignment has been resolved.
2159      * @hide
2160      */
2161     static final int PFLAG2_TEXT_ALIGNMENT_RESOLVED = 0x00000008 << PFLAG2_TEXT_ALIGNMENT_MASK_SHIFT;
2162
2163     /**
2164      * Bit shift to get the resolved text alignment.
2165      * @hide
2166      */
2167     static final int PFLAG2_TEXT_ALIGNMENT_RESOLVED_MASK_SHIFT = 17;
2168
2169     /**
2170      * Mask for use with private flags indicating bits used for text alignment.
2171      * @hide
2172      */
2173     static final int PFLAG2_TEXT_ALIGNMENT_RESOLVED_MASK = 0x00000007
2174             << PFLAG2_TEXT_ALIGNMENT_RESOLVED_MASK_SHIFT;
2175
2176     /**
2177      * Indicates whether if the view text alignment has been resolved to gravity
2178      */
2179     private static final int PFLAG2_TEXT_ALIGNMENT_RESOLVED_DEFAULT =
2180             TEXT_ALIGNMENT_RESOLVED_DEFAULT << PFLAG2_TEXT_ALIGNMENT_RESOLVED_MASK_SHIFT;
2181
2182     // Accessiblity constants for mPrivateFlags2
2183
2184     /**
2185      * Shift for the bits in {@link #mPrivateFlags2} related to the
2186      * "importantForAccessibility" attribute.
2187      */
2188     static final int PFLAG2_IMPORTANT_FOR_ACCESSIBILITY_SHIFT = 20;
2189
2190     /**
2191      * Automatically determine whether a view is important for accessibility.
2192      */
2193     public static final int IMPORTANT_FOR_ACCESSIBILITY_AUTO = 0x00000000;
2194
2195     /**
2196      * The view is important for accessibility.
2197      */
2198     public static final int IMPORTANT_FOR_ACCESSIBILITY_YES = 0x00000001;
2199
2200     /**
2201      * The view is not important for accessibility.
2202      */
2203     public static final int IMPORTANT_FOR_ACCESSIBILITY_NO = 0x00000002;
2204
2205     /**
2206      * The view is not important for accessibility, nor are any of its
2207      * descendant views.
2208      */
2209     public static final int IMPORTANT_FOR_ACCESSIBILITY_NO_HIDE_DESCENDANTS = 0x00000004;
2210
2211     /**
2212      * The default whether the view is important for accessibility.
2213      */
2214     static final int IMPORTANT_FOR_ACCESSIBILITY_DEFAULT = IMPORTANT_FOR_ACCESSIBILITY_AUTO;
2215
2216     /**
2217      * Mask for obtainig the bits which specify how to determine
2218      * whether a view is important for accessibility.
2219      */
2220     static final int PFLAG2_IMPORTANT_FOR_ACCESSIBILITY_MASK = (IMPORTANT_FOR_ACCESSIBILITY_AUTO
2221         | IMPORTANT_FOR_ACCESSIBILITY_YES | IMPORTANT_FOR_ACCESSIBILITY_NO
2222         | IMPORTANT_FOR_ACCESSIBILITY_NO_HIDE_DESCENDANTS)
2223         << PFLAG2_IMPORTANT_FOR_ACCESSIBILITY_SHIFT;
2224
2225     /**
2226      * Shift for the bits in {@link #mPrivateFlags2} related to the
2227      * "accessibilityLiveRegion" attribute.
2228      */
2229     static final int PFLAG2_ACCESSIBILITY_LIVE_REGION_SHIFT = 23;
2230
2231     /**
2232      * Live region mode specifying that accessibility services should not
2233      * automatically announce changes to this view. This is the default live
2234      * region mode for most views.
2235      * <p>
2236      * Use with {@link #setAccessibilityLiveRegion(int)}.
2237      */
2238     public static final int ACCESSIBILITY_LIVE_REGION_NONE = 0x00000000;
2239
2240     /**
2241      * Live region mode specifying that accessibility services should announce
2242      * changes to this view.
2243      * <p>
2244      * Use with {@link #setAccessibilityLiveRegion(int)}.
2245      */
2246     public static final int ACCESSIBILITY_LIVE_REGION_POLITE = 0x00000001;
2247
2248     /**
2249      * Live region mode specifying that accessibility services should interrupt
2250      * ongoing speech to immediately announce changes to this view.
2251      * <p>
2252      * Use with {@link #setAccessibilityLiveRegion(int)}.
2253      */
2254     public static final int ACCESSIBILITY_LIVE_REGION_ASSERTIVE = 0x00000002;
2255
2256     /**
2257      * The default whether the view is important for accessibility.
2258      */
2259     static final int ACCESSIBILITY_LIVE_REGION_DEFAULT = ACCESSIBILITY_LIVE_REGION_NONE;
2260
2261     /**
2262      * Mask for obtaining the bits which specify a view's accessibility live
2263      * region mode.
2264      */
2265     static final int PFLAG2_ACCESSIBILITY_LIVE_REGION_MASK = (ACCESSIBILITY_LIVE_REGION_NONE
2266             | ACCESSIBILITY_LIVE_REGION_POLITE | ACCESSIBILITY_LIVE_REGION_ASSERTIVE)
2267             << PFLAG2_ACCESSIBILITY_LIVE_REGION_SHIFT;
2268
2269     /**
2270      * Flag indicating whether a view has accessibility focus.
2271      */
2272     static final int PFLAG2_ACCESSIBILITY_FOCUSED = 0x04000000;
2273
2274     /**
2275      * Flag whether the accessibility state of the subtree rooted at this view changed.
2276      */
2277     static final int PFLAG2_SUBTREE_ACCESSIBILITY_STATE_CHANGED = 0x08000000;
2278
2279     /**
2280      * Flag indicating whether a view failed the quickReject() check in draw(). This condition
2281      * is used to check whether later changes to the view's transform should invalidate the
2282      * view to force the quickReject test to run again.
2283      */
2284     static final int PFLAG2_VIEW_QUICK_REJECTED = 0x10000000;
2285
2286     /**
2287      * Flag indicating that start/end padding has been resolved into left/right padding
2288      * for use in measurement, layout, drawing, etc. This is set by {@link #resolvePadding()}
2289      * and checked by {@link #measure(int, int)} to determine if padding needs to be resolved
2290      * during measurement. In some special cases this is required such as when an adapter-based
2291      * view measures prospective children without attaching them to a window.
2292      */
2293     static final int PFLAG2_PADDING_RESOLVED = 0x20000000;
2294
2295     /**
2296      * Flag indicating that the start/end drawables has been resolved into left/right ones.
2297      */
2298     static final int PFLAG2_DRAWABLE_RESOLVED = 0x40000000;
2299
2300     /**
2301      * Indicates that the view is tracking some sort of transient state
2302      * that the app should not need to be aware of, but that the framework
2303      * should take special care to preserve.
2304      */
2305     static final int PFLAG2_HAS_TRANSIENT_STATE = 0x80000000;
2306
2307     /**
2308      * Group of bits indicating that RTL properties resolution is done.
2309      */
2310     static final int ALL_RTL_PROPERTIES_RESOLVED = PFLAG2_LAYOUT_DIRECTION_RESOLVED |
2311             PFLAG2_TEXT_DIRECTION_RESOLVED |
2312             PFLAG2_TEXT_ALIGNMENT_RESOLVED |
2313             PFLAG2_PADDING_RESOLVED |
2314             PFLAG2_DRAWABLE_RESOLVED;
2315
2316     // There are a couple of flags left in mPrivateFlags2
2317
2318     /* End of masks for mPrivateFlags2 */
2319
2320     /**
2321      * Masks for mPrivateFlags3, as generated by dumpFlags():
2322      *
2323      * |-------|-------|-------|-------|
2324      *                                 1 PFLAG3_VIEW_IS_ANIMATING_TRANSFORM
2325      *                                1  PFLAG3_VIEW_IS_ANIMATING_ALPHA
2326      *                               1   PFLAG3_IS_LAID_OUT
2327      *                              1    PFLAG3_MEASURE_NEEDED_BEFORE_LAYOUT
2328      *                             1     PFLAG3_CALLED_SUPER
2329      *                            1      PFLAG3_APPLYING_INSETS
2330      *                           1       PFLAG3_FITTING_SYSTEM_WINDOWS
2331      *                          1        PFLAG3_NESTED_SCROLLING_ENABLED
2332      *                         1         PFLAG3_ASSIST_BLOCKED
2333      * |-------|-------|-------|-------|
2334      */
2335
2336     /**
2337      * Flag indicating that view has a transform animation set on it. This is used to track whether
2338      * an animation is cleared between successive frames, in order to tell the associated
2339      * DisplayList to clear its animation matrix.
2340      */
2341     static final int PFLAG3_VIEW_IS_ANIMATING_TRANSFORM = 0x1;
2342
2343     /**
2344      * Flag indicating that view has an alpha animation set on it. This is used to track whether an
2345      * animation is cleared between successive frames, in order to tell the associated
2346      * DisplayList to restore its alpha value.
2347      */
2348     static final int PFLAG3_VIEW_IS_ANIMATING_ALPHA = 0x2;
2349
2350     /**
2351      * Flag indicating that the view has been through at least one layout since it
2352      * was last attached to a window.
2353      */
2354     static final int PFLAG3_IS_LAID_OUT = 0x4;
2355
2356     /**
2357      * Flag indicating that a call to measure() was skipped and should be done
2358      * instead when layout() is invoked.
2359      */
2360     static final int PFLAG3_MEASURE_NEEDED_BEFORE_LAYOUT = 0x8;
2361
2362     /**
2363      * Flag indicating that an overridden method correctly called down to
2364      * the superclass implementation as required by the API spec.
2365      */
2366     static final int PFLAG3_CALLED_SUPER = 0x10;
2367
2368     /**
2369      * Flag indicating that we're in the process of applying window insets.
2370      */
2371     static final int PFLAG3_APPLYING_INSETS = 0x20;
2372
2373     /**
2374      * Flag indicating that we're in the process of fitting system windows using the old method.
2375      */
2376     static final int PFLAG3_FITTING_SYSTEM_WINDOWS = 0x40;
2377
2378     /**
2379      * Flag indicating that nested scrolling is enabled for this view.
2380      * The view will optionally cooperate with views up its parent chain to allow for
2381      * integrated nested scrolling along the same axis.
2382      */
2383     static final int PFLAG3_NESTED_SCROLLING_ENABLED = 0x80;
2384
2385     /* End of masks for mPrivateFlags3 */
2386
2387     static final int DRAG_MASK = PFLAG2_DRAG_CAN_ACCEPT | PFLAG2_DRAG_HOVERED;
2388
2389     /**
2390      * <p>Indicates that we are allowing {@link android.view.ViewAssistStructure} to traverse
2391      * into this view.<p>
2392      */
2393     static final int PFLAG3_ASSIST_BLOCKED = 0x100;
2394
2395     /**
2396      * Always allow a user to over-scroll this view, provided it is a
2397      * view that can scroll.
2398      *
2399      * @see #getOverScrollMode()
2400      * @see #setOverScrollMode(int)
2401      */
2402     public static final int OVER_SCROLL_ALWAYS = 0;
2403
2404     /**
2405      * Allow a user to over-scroll this view only if the content is large
2406      * enough to meaningfully scroll, provided it is a view that can scroll.
2407      *
2408      * @see #getOverScrollMode()
2409      * @see #setOverScrollMode(int)
2410      */
2411     public static final int OVER_SCROLL_IF_CONTENT_SCROLLS = 1;
2412
2413     /**
2414      * Never allow a user to over-scroll this view.
2415      *
2416      * @see #getOverScrollMode()
2417      * @see #setOverScrollMode(int)
2418      */
2419     public static final int OVER_SCROLL_NEVER = 2;
2420
2421     /**
2422      * Special constant for {@link #setSystemUiVisibility(int)}: View has
2423      * requested the system UI (status bar) to be visible (the default).
2424      *
2425      * @see #setSystemUiVisibility(int)
2426      */
2427     public static final int SYSTEM_UI_FLAG_VISIBLE = 0;
2428
2429     /**
2430      * Flag for {@link #setSystemUiVisibility(int)}: View has requested the
2431      * system UI to enter an unobtrusive "low profile" mode.
2432      *
2433      * <p>This is for use in games, book readers, video players, or any other
2434      * "immersive" application where the usual system chrome is deemed too distracting.
2435      *
2436      * <p>In low profile mode, the status bar and/or navigation icons may dim.
2437      *
2438      * @see #setSystemUiVisibility(int)
2439      */
2440     public static final int SYSTEM_UI_FLAG_LOW_PROFILE = 0x00000001;
2441
2442     /**
2443      * Flag for {@link #setSystemUiVisibility(int)}: View has requested that the
2444      * system navigation be temporarily hidden.
2445      *
2446      * <p>This is an even less obtrusive state than that called for by
2447      * {@link #SYSTEM_UI_FLAG_LOW_PROFILE}; on devices that draw essential navigation controls
2448      * (Home, Back, and the like) on screen, <code>SYSTEM_UI_FLAG_HIDE_NAVIGATION</code> will cause
2449      * those to disappear. This is useful (in conjunction with the
2450      * {@link android.view.WindowManager.LayoutParams#FLAG_FULLSCREEN FLAG_FULLSCREEN} and
2451      * {@link android.view.WindowManager.LayoutParams#FLAG_LAYOUT_IN_SCREEN FLAG_LAYOUT_IN_SCREEN}
2452      * window flags) for displaying content using every last pixel on the display.
2453      *
2454      * <p>There is a limitation: because navigation controls are so important, the least user
2455      * interaction will cause them to reappear immediately.  When this happens, both
2456      * this flag and {@link #SYSTEM_UI_FLAG_FULLSCREEN} will be cleared automatically,
2457      * so that both elements reappear at the same time.
2458      *
2459      * @see #setSystemUiVisibility(int)
2460      */
2461     public static final int SYSTEM_UI_FLAG_HIDE_NAVIGATION = 0x00000002;
2462
2463     /**
2464      * Flag for {@link #setSystemUiVisibility(int)}: View has requested to go
2465      * into the normal fullscreen mode so that its content can take over the screen
2466      * while still allowing the user to interact with the application.
2467      *
2468      * <p>This has the same visual effect as
2469      * {@link android.view.WindowManager.LayoutParams#FLAG_FULLSCREEN
2470      * WindowManager.LayoutParams.FLAG_FULLSCREEN},
2471      * meaning that non-critical screen decorations (such as the status bar) will be
2472      * hidden while the user is in the View's window, focusing the experience on
2473      * that content.  Unlike the window flag, if you are using ActionBar in
2474      * overlay mode with {@link Window#FEATURE_ACTION_BAR_OVERLAY
2475      * Window.FEATURE_ACTION_BAR_OVERLAY}, then enabling this flag will also
2476      * hide the action bar.
2477      *
2478      * <p>This approach to going fullscreen is best used over the window flag when
2479      * it is a transient state -- that is, the application does this at certain
2480      * points in its user interaction where it wants to allow the user to focus
2481      * on content, but not as a continuous state.  For situations where the application
2482      * would like to simply stay full screen the entire time (such as a game that
2483      * wants to take over the screen), the
2484      * {@link android.view.WindowManager.LayoutParams#FLAG_FULLSCREEN window flag}
2485      * is usually a better approach.  The state set here will be removed by the system
2486      * in various situations (such as the user moving to another application) like
2487      * the other system UI states.
2488      *
2489      * <p>When using this flag, the application should provide some easy facility
2490      * for the user to go out of it.  A common example would be in an e-book
2491      * reader, where tapping on the screen brings back whatever screen and UI
2492      * decorations that had been hidden while the user was immersed in reading
2493      * the book.
2494      *
2495      * @see #setSystemUiVisibility(int)
2496      */
2497     public static final int SYSTEM_UI_FLAG_FULLSCREEN = 0x00000004;
2498
2499     /**
2500      * Flag for {@link #setSystemUiVisibility(int)}: When using other layout
2501      * flags, we would like a stable view of the content insets given to
2502      * {@link #fitSystemWindows(Rect)}.  This means that the insets seen there
2503      * will always represent the worst case that the application can expect
2504      * as a continuous state.  In the stock Android UI this is the space for
2505      * the system bar, nav bar, and status bar, but not more transient elements
2506      * such as an input method.
2507      *
2508      * The stable layout your UI sees is based on the system UI modes you can
2509      * switch to.  That is, if you specify {@link #SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN}
2510      * then you will get a stable layout for changes of the
2511      * {@link #SYSTEM_UI_FLAG_FULLSCREEN} mode; if you specify
2512      * {@link #SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN} and
2513      * {@link #SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION}, then you can transition
2514      * to {@link #SYSTEM_UI_FLAG_FULLSCREEN} and {@link #SYSTEM_UI_FLAG_HIDE_NAVIGATION}
2515      * with a stable layout.  (Note that you should avoid using
2516      * {@link #SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION} by itself.)
2517      *
2518      * If you have set the window flag {@link WindowManager.LayoutParams#FLAG_FULLSCREEN}
2519      * to hide the status bar (instead of using {@link #SYSTEM_UI_FLAG_FULLSCREEN}),
2520      * then a hidden status bar will be considered a "stable" state for purposes
2521      * here.  This allows your UI to continually hide the status bar, while still
2522      * using the system UI flags to hide the action bar while still retaining
2523      * a stable layout.  Note that changing the window fullscreen flag will never
2524      * provide a stable layout for a clean transition.
2525      *
2526      * <p>If you are using ActionBar in
2527      * overlay mode with {@link Window#FEATURE_ACTION_BAR_OVERLAY
2528      * Window.FEATURE_ACTION_BAR_OVERLAY}, this flag will also impact the
2529      * insets it adds to those given to the application.
2530      */
2531     public static final int SYSTEM_UI_FLAG_LAYOUT_STABLE = 0x00000100;
2532
2533     /**
2534      * Flag for {@link #setSystemUiVisibility(int)}: View would like its window
2535      * to be laid out as if it has requested
2536      * {@link #SYSTEM_UI_FLAG_HIDE_NAVIGATION}, even if it currently hasn't.  This
2537      * allows it to avoid artifacts when switching in and out of that mode, at
2538      * the expense that some of its user interface may be covered by screen
2539      * decorations when they are shown.  You can perform layout of your inner
2540      * UI elements to account for the navigation system UI through the
2541      * {@link #fitSystemWindows(Rect)} method.
2542      */
2543     public static final int SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION = 0x00000200;
2544
2545     /**
2546      * Flag for {@link #setSystemUiVisibility(int)}: View would like its window
2547      * to be laid out as if it has requested
2548      * {@link #SYSTEM_UI_FLAG_FULLSCREEN}, 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 non-fullscreen system UI through the
2553      * {@link #fitSystemWindows(Rect)} method.
2554      */
2555     public static final int SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN = 0x00000400;
2556
2557     /**
2558      * Flag for {@link #setSystemUiVisibility(int)}: View would like to remain interactive when
2559      * hiding the navigation bar with {@link #SYSTEM_UI_FLAG_HIDE_NAVIGATION}.  If this flag is
2560      * not set, {@link #SYSTEM_UI_FLAG_HIDE_NAVIGATION} will be force cleared by the system on any
2561      * user interaction.
2562      * <p>Since this flag is a modifier for {@link #SYSTEM_UI_FLAG_HIDE_NAVIGATION}, it only
2563      * has an effect when used in combination with that flag.</p>
2564      */
2565     public static final int SYSTEM_UI_FLAG_IMMERSIVE = 0x00000800;
2566
2567     /**
2568      * Flag for {@link #setSystemUiVisibility(int)}: View would like to remain interactive when
2569      * hiding the status bar with {@link #SYSTEM_UI_FLAG_FULLSCREEN} and/or hiding the navigation
2570      * bar with {@link #SYSTEM_UI_FLAG_HIDE_NAVIGATION}.  Use this flag to create an immersive
2571      * experience while also hiding the system bars.  If this flag is not set,
2572      * {@link #SYSTEM_UI_FLAG_HIDE_NAVIGATION} will be force cleared by the system on any user
2573      * interaction, and {@link #SYSTEM_UI_FLAG_FULLSCREEN} will be force-cleared by the system
2574      * if the user swipes from the top of the screen.
2575      * <p>When system bars are hidden in immersive mode, they can be revealed temporarily with
2576      * system gestures, such as swiping from the top of the screen.  These transient system bars
2577      * will overlay app’s content, may have some degree of transparency, and will automatically
2578      * hide after a short timeout.
2579      * </p><p>Since this flag is a modifier for {@link #SYSTEM_UI_FLAG_FULLSCREEN} and
2580      * {@link #SYSTEM_UI_FLAG_HIDE_NAVIGATION}, it only has an effect when used in combination
2581      * with one or both of those flags.</p>
2582      */
2583     public static final int SYSTEM_UI_FLAG_IMMERSIVE_STICKY = 0x00001000;
2584
2585     /**
2586      * Flag for {@link #setSystemUiVisibility(int)}: Requests the status bar to draw in a mode that
2587      * is compatible with light status bar backgrounds.
2588      *
2589      * <p>For this to take effect, the window must request
2590      * {@link android.view.WindowManager.LayoutParams#FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS
2591      *         FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS} but not
2592      * {@link android.view.WindowManager.LayoutParams#FLAG_TRANSLUCENT_STATUS
2593      *         FLAG_TRANSLUCENT_STATUS}.
2594      *
2595      * @see android.R.attr#windowLightStatusBar
2596      */
2597     public static final int SYSTEM_UI_FLAG_LIGHT_STATUS_BAR = 0x00002000;
2598
2599     /**
2600      * @deprecated Use {@link #SYSTEM_UI_FLAG_LOW_PROFILE} instead.
2601      */
2602     public static final int STATUS_BAR_HIDDEN = SYSTEM_UI_FLAG_LOW_PROFILE;
2603
2604     /**
2605      * @deprecated Use {@link #SYSTEM_UI_FLAG_VISIBLE} instead.
2606      */
2607     public static final int STATUS_BAR_VISIBLE = SYSTEM_UI_FLAG_VISIBLE;
2608
2609     /**
2610      * @hide
2611      *
2612      * NOTE: This flag may only be used in subtreeSystemUiVisibility. It is masked
2613      * out of the public fields to keep the undefined bits out of the developer's way.
2614      *
2615      * Flag to make the status bar not expandable.  Unless you also
2616      * set {@link #STATUS_BAR_DISABLE_NOTIFICATION_ICONS}, new notifications will continue to show.
2617      */
2618     public static final int STATUS_BAR_DISABLE_EXPAND = 0x00010000;
2619
2620     /**
2621      * @hide
2622      *
2623      * NOTE: This flag may only be used in subtreeSystemUiVisibility. It is masked
2624      * out of the public fields to keep the undefined bits out of the developer's way.
2625      *
2626      * Flag to hide notification icons and scrolling ticker text.
2627      */
2628     public static final int STATUS_BAR_DISABLE_NOTIFICATION_ICONS = 0x00020000;
2629
2630     /**
2631      * @hide
2632      *
2633      * NOTE: This flag may only be used in subtreeSystemUiVisibility. It is masked
2634      * out of the public fields to keep the undefined bits out of the developer's way.
2635      *
2636      * Flag to disable incoming notification alerts.  This will not block
2637      * icons, but it will block sound, vibrating and other visual or aural notifications.
2638      */
2639     public static final int STATUS_BAR_DISABLE_NOTIFICATION_ALERTS = 0x00040000;
2640
2641     /**
2642      * @hide
2643      *
2644      * NOTE: This flag may only be used in subtreeSystemUiVisibility. It is masked
2645      * out of the public fields to keep the undefined bits out of the developer's way.
2646      *
2647      * Flag to hide only the scrolling ticker.  Note that
2648      * {@link #STATUS_BAR_DISABLE_NOTIFICATION_ICONS} implies
2649      * {@link #STATUS_BAR_DISABLE_NOTIFICATION_TICKER}.
2650      */
2651     public static final int STATUS_BAR_DISABLE_NOTIFICATION_TICKER = 0x00080000;
2652
2653     /**
2654      * @hide
2655      *
2656      * NOTE: This flag may only be used in subtreeSystemUiVisibility. It is masked
2657      * out of the public fields to keep the undefined bits out of the developer's way.
2658      *
2659      * Flag to hide the center system info area.
2660      */
2661     public static final int STATUS_BAR_DISABLE_SYSTEM_INFO = 0x00100000;
2662
2663     /**
2664      * @hide
2665      *
2666      * NOTE: This flag may only be used in subtreeSystemUiVisibility. It is masked
2667      * out of the public fields to keep the undefined bits out of the developer's way.
2668      *
2669      * Flag to hide only the home button.  Don't use this
2670      * unless you're a special part of the system UI (i.e., setup wizard, keyguard).
2671      */
2672     public static final int STATUS_BAR_DISABLE_HOME = 0x00200000;
2673
2674     /**
2675      * @hide
2676      *
2677      * NOTE: This flag may only be used in subtreeSystemUiVisibility. It is masked
2678      * out of the public fields to keep the undefined bits out of the developer's way.
2679      *
2680      * Flag to hide only the back button. Don't use this
2681      * unless you're a special part of the system UI (i.e., setup wizard, keyguard).
2682      */
2683     public static final int STATUS_BAR_DISABLE_BACK = 0x00400000;
2684
2685     /**
2686      * @hide
2687      *
2688      * NOTE: This flag may only be used in subtreeSystemUiVisibility. It is masked
2689      * out of the public fields to keep the undefined bits out of the developer's way.
2690      *
2691      * Flag to hide only the clock.  You might use this if your activity has
2692      * its own clock making the status bar's clock redundant.
2693      */
2694     public static final int STATUS_BAR_DISABLE_CLOCK = 0x00800000;
2695
2696     /**
2697      * @hide
2698      *
2699      * NOTE: This flag may only be used in subtreeSystemUiVisibility. It is masked
2700      * out of the public fields to keep the undefined bits out of the developer's way.
2701      *
2702      * Flag to hide only the recent apps button. Don't use this
2703      * unless you're a special part of the system UI (i.e., setup wizard, keyguard).
2704      */
2705     public static final int STATUS_BAR_DISABLE_RECENT = 0x01000000;
2706
2707     /**
2708      * @hide
2709      *
2710      * NOTE: This flag may only be used in subtreeSystemUiVisibility. It is masked
2711      * out of the public fields to keep the undefined bits out of the developer's way.
2712      *
2713      * Flag to disable the global search gesture. Don't use this
2714      * unless you're a special part of the system UI (i.e., setup wizard, keyguard).
2715      */
2716     public static final int STATUS_BAR_DISABLE_SEARCH = 0x02000000;
2717
2718     /**
2719      * @hide
2720      *
2721      * NOTE: This flag may only be used in subtreeSystemUiVisibility. It is masked
2722      * out of the public fields to keep the undefined bits out of the developer's way.
2723      *
2724      * Flag to specify that the status bar is displayed in transient mode.
2725      */
2726     public static final int STATUS_BAR_TRANSIENT = 0x04000000;
2727
2728     /**
2729      * @hide
2730      *
2731      * NOTE: This flag may only be used in subtreeSystemUiVisibility. It is masked
2732      * out of the public fields to keep the undefined bits out of the developer's way.
2733      *
2734      * Flag to specify that the navigation bar is displayed in transient mode.
2735      */
2736     public static final int NAVIGATION_BAR_TRANSIENT = 0x08000000;
2737
2738     /**
2739      * @hide
2740      *
2741      * NOTE: This flag may only be used in subtreeSystemUiVisibility. It is masked
2742      * out of the public fields to keep the undefined bits out of the developer's way.
2743      *
2744      * Flag to specify that the hidden status bar would like to be shown.
2745      */
2746     public static final int STATUS_BAR_UNHIDE = 0x10000000;
2747
2748     /**
2749      * @hide
2750      *
2751      * NOTE: This flag may only be used in subtreeSystemUiVisibility. It is masked
2752      * out of the public fields to keep the undefined bits out of the developer's way.
2753      *
2754      * Flag to specify that the hidden navigation bar would like to be shown.
2755      */
2756     public static final int NAVIGATION_BAR_UNHIDE = 0x20000000;
2757
2758     /**
2759      * @hide
2760      *
2761      * NOTE: This flag may only be used in subtreeSystemUiVisibility. It is masked
2762      * out of the public fields to keep the undefined bits out of the developer's way.
2763      *
2764      * Flag to specify that the status bar is displayed in translucent mode.
2765      */
2766     public static final int STATUS_BAR_TRANSLUCENT = 0x40000000;
2767
2768     /**
2769      * @hide
2770      *
2771      * NOTE: This flag may only be used in subtreeSystemUiVisibility. It is masked
2772      * out of the public fields to keep the undefined bits out of the developer's way.
2773      *
2774      * Flag to specify that the navigation bar is displayed in translucent mode.
2775      */
2776     public static final int NAVIGATION_BAR_TRANSLUCENT = 0x80000000;
2777
2778     /**
2779      * @hide
2780      *
2781      * Whether Recents is visible or not.
2782      */
2783     public static final int RECENT_APPS_VISIBLE = 0x00004000;
2784
2785     /**
2786      * @hide
2787      *
2788      * Makes system ui transparent.
2789      */
2790     public static final int SYSTEM_UI_TRANSPARENT = 0x00008000;
2791
2792     /**
2793      * @hide
2794      */
2795     public static final int PUBLIC_STATUS_BAR_VISIBILITY_MASK = 0x00003FFF;
2796
2797     /**
2798      * These are the system UI flags that can be cleared by events outside
2799      * of an application.  Currently this is just the ability to tap on the
2800      * screen while hiding the navigation bar to have it return.
2801      * @hide
2802      */
2803     public static final int SYSTEM_UI_CLEARABLE_FLAGS =
2804             SYSTEM_UI_FLAG_LOW_PROFILE | SYSTEM_UI_FLAG_HIDE_NAVIGATION
2805             | SYSTEM_UI_FLAG_FULLSCREEN;
2806
2807     /**
2808      * Flags that can impact the layout in relation to system UI.
2809      */
2810     public static final int SYSTEM_UI_LAYOUT_FLAGS =
2811             SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION
2812             | SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN;
2813
2814     /** @hide */
2815     @IntDef(flag = true,
2816             value = { FIND_VIEWS_WITH_TEXT, FIND_VIEWS_WITH_CONTENT_DESCRIPTION })
2817     @Retention(RetentionPolicy.SOURCE)
2818     public @interface FindViewFlags {}
2819
2820     /**
2821      * Find views that render the specified text.
2822      *
2823      * @see #findViewsWithText(ArrayList, CharSequence, int)
2824      */
2825     public static final int FIND_VIEWS_WITH_TEXT = 0x00000001;
2826
2827     /**
2828      * Find find views that contain the specified content description.
2829      *
2830      * @see #findViewsWithText(ArrayList, CharSequence, int)
2831      */
2832     public static final int FIND_VIEWS_WITH_CONTENT_DESCRIPTION = 0x00000002;
2833
2834     /**
2835      * Find views that contain {@link AccessibilityNodeProvider}. Such
2836      * a View is a root of virtual view hierarchy and may contain the searched
2837      * text. If this flag is set Views with providers are automatically
2838      * added and it is a responsibility of the client to call the APIs of
2839      * the provider to determine whether the virtual tree rooted at this View
2840      * contains the text, i.e. getting the list of {@link AccessibilityNodeInfo}s
2841      * representing the virtual views with this text.
2842      *
2843      * @see #findViewsWithText(ArrayList, CharSequence, int)
2844      *
2845      * @hide
2846      */
2847     public static final int FIND_VIEWS_WITH_ACCESSIBILITY_NODE_PROVIDERS = 0x00000004;
2848
2849     /**
2850      * The undefined cursor position.
2851      *
2852      * @hide
2853      */
2854     public static final int ACCESSIBILITY_CURSOR_POSITION_UNDEFINED = -1;
2855
2856     /**
2857      * Indicates that the screen has changed state and is now off.
2858      *
2859      * @see #onScreenStateChanged(int)
2860      */
2861     public static final int SCREEN_STATE_OFF = 0x0;
2862
2863     /**
2864      * Indicates that the screen has changed state and is now on.
2865      *
2866      * @see #onScreenStateChanged(int)
2867      */
2868     public static final int SCREEN_STATE_ON = 0x1;
2869
2870     /**
2871      * Indicates no axis of view scrolling.
2872      */
2873     public static final int SCROLL_AXIS_NONE = 0;
2874
2875     /**
2876      * Indicates scrolling along the horizontal axis.
2877      */
2878     public static final int SCROLL_AXIS_HORIZONTAL = 1 << 0;
2879
2880     /**
2881      * Indicates scrolling along the vertical axis.
2882      */
2883     public static final int SCROLL_AXIS_VERTICAL = 1 << 1;
2884
2885     /**
2886      * Controls the over-scroll mode for this view.
2887      * See {@link #overScrollBy(int, int, int, int, int, int, int, int, boolean)},
2888      * {@link #OVER_SCROLL_ALWAYS}, {@link #OVER_SCROLL_IF_CONTENT_SCROLLS},
2889      * and {@link #OVER_SCROLL_NEVER}.
2890      */
2891     private int mOverScrollMode;
2892
2893     /**
2894      * The parent this view is attached to.
2895      * {@hide}
2896      *
2897      * @see #getParent()
2898      */
2899     protected ViewParent mParent;
2900
2901     /**
2902      * {@hide}
2903      */
2904     AttachInfo mAttachInfo;
2905
2906     /**
2907      * {@hide}
2908      */
2909     @ViewDebug.ExportedProperty(flagMapping = {
2910         @ViewDebug.FlagToString(mask = PFLAG_FORCE_LAYOUT, equals = PFLAG_FORCE_LAYOUT,
2911                 name = "FORCE_LAYOUT"),
2912         @ViewDebug.FlagToString(mask = PFLAG_LAYOUT_REQUIRED, equals = PFLAG_LAYOUT_REQUIRED,
2913                 name = "LAYOUT_REQUIRED"),
2914         @ViewDebug.FlagToString(mask = PFLAG_DRAWING_CACHE_VALID, equals = PFLAG_DRAWING_CACHE_VALID,
2915             name = "DRAWING_CACHE_INVALID", outputIf = false),
2916         @ViewDebug.FlagToString(mask = PFLAG_DRAWN, equals = PFLAG_DRAWN, name = "DRAWN", outputIf = true),
2917         @ViewDebug.FlagToString(mask = PFLAG_DRAWN, equals = PFLAG_DRAWN, name = "NOT_DRAWN", outputIf = false),
2918         @ViewDebug.FlagToString(mask = PFLAG_DIRTY_MASK, equals = PFLAG_DIRTY_OPAQUE, name = "DIRTY_OPAQUE"),
2919         @ViewDebug.FlagToString(mask = PFLAG_DIRTY_MASK, equals = PFLAG_DIRTY, name = "DIRTY")
2920     }, formatToHexString = true)
2921     int mPrivateFlags;
2922     int mPrivateFlags2;
2923     int mPrivateFlags3;
2924
2925     /**
2926      * This view's request for the visibility of the status bar.
2927      * @hide
2928      */
2929     @ViewDebug.ExportedProperty(flagMapping = {
2930         @ViewDebug.FlagToString(mask = SYSTEM_UI_FLAG_LOW_PROFILE,
2931                                 equals = SYSTEM_UI_FLAG_LOW_PROFILE,
2932                                 name = "SYSTEM_UI_FLAG_LOW_PROFILE", outputIf = true),
2933         @ViewDebug.FlagToString(mask = SYSTEM_UI_FLAG_HIDE_NAVIGATION,
2934                                 equals = SYSTEM_UI_FLAG_HIDE_NAVIGATION,
2935                                 name = "SYSTEM_UI_FLAG_HIDE_NAVIGATION", outputIf = true),
2936         @ViewDebug.FlagToString(mask = PUBLIC_STATUS_BAR_VISIBILITY_MASK,
2937                                 equals = SYSTEM_UI_FLAG_VISIBLE,
2938                                 name = "SYSTEM_UI_FLAG_VISIBLE", outputIf = true)
2939     }, formatToHexString = true)
2940     int mSystemUiVisibility;
2941
2942     /**
2943      * Reference count for transient state.
2944      * @see #setHasTransientState(boolean)
2945      */
2946     int mTransientStateCount = 0;
2947
2948     /**
2949      * Count of how many windows this view has been attached to.
2950      */
2951     int mWindowAttachCount;
2952
2953     /**
2954      * The layout parameters associated with this view and used by the parent
2955      * {@link android.view.ViewGroup} to determine how this view should be
2956      * laid out.
2957      * {@hide}
2958      */
2959     protected ViewGroup.LayoutParams mLayoutParams;
2960
2961     /**
2962      * The view flags hold various views states.
2963      * {@hide}
2964      */
2965     @ViewDebug.ExportedProperty(formatToHexString = true)
2966     int mViewFlags;
2967
2968     static class TransformationInfo {
2969         /**
2970          * The transform matrix for the View. This transform is calculated internally
2971          * based on the translation, rotation, and scale properties.
2972          *
2973          * Do *not* use this variable directly; instead call getMatrix(), which will
2974          * load the value from the View's RenderNode.
2975          */
2976         private final Matrix mMatrix = new Matrix();
2977
2978         /**
2979          * The inverse transform matrix for the View. This transform is calculated
2980          * internally based on the translation, rotation, and scale properties.
2981          *
2982          * Do *not* use this variable directly; instead call getInverseMatrix(),
2983          * which will load the value from the View's RenderNode.
2984          */
2985         private Matrix mInverseMatrix;
2986
2987         /**
2988          * The opacity of the View. This is a value from 0 to 1, where 0 means
2989          * completely transparent and 1 means completely opaque.
2990          */
2991         @ViewDebug.ExportedProperty
2992         float mAlpha = 1f;
2993
2994         /**
2995          * The opacity of the view as manipulated by the Fade transition. This is a hidden
2996          * property only used by transitions, which is composited with the other alpha
2997          * values to calculate the final visual alpha value.
2998          */
2999         float mTransitionAlpha = 1f;
3000     }
3001
3002     TransformationInfo mTransformationInfo;
3003
3004     /**
3005      * Current clip bounds. to which all drawing of this view are constrained.
3006      */
3007     Rect mClipBounds = null;
3008
3009     private boolean mLastIsOpaque;
3010
3011     /**
3012      * The distance in pixels from the left edge of this view's parent
3013      * to the left edge of this view.
3014      * {@hide}
3015      */
3016     @ViewDebug.ExportedProperty(category = "layout")
3017     protected int mLeft;
3018     /**
3019      * The distance in pixels from the left edge of this view's parent
3020      * to the right edge of this view.
3021      * {@hide}
3022      */
3023     @ViewDebug.ExportedProperty(category = "layout")
3024     protected int mRight;
3025     /**
3026      * The distance in pixels from the top edge of this view's parent
3027      * to the top edge of this view.
3028      * {@hide}
3029      */
3030     @ViewDebug.ExportedProperty(category = "layout")
3031     protected int mTop;
3032     /**
3033      * The distance in pixels from the top edge of this view's parent
3034      * to the bottom edge of this view.
3035      * {@hide}
3036      */
3037     @ViewDebug.ExportedProperty(category = "layout")
3038     protected int mBottom;
3039
3040     /**
3041      * The offset, in pixels, by which the content of this view is scrolled
3042      * horizontally.
3043      * {@hide}
3044      */
3045     @ViewDebug.ExportedProperty(category = "scrolling")
3046     protected int mScrollX;
3047     /**
3048      * The offset, in pixels, by which the content of this view is scrolled
3049      * vertically.
3050      * {@hide}
3051      */
3052     @ViewDebug.ExportedProperty(category = "scrolling")
3053     protected int mScrollY;
3054
3055     /**
3056      * The left padding in pixels, that is the distance in pixels between the
3057      * left edge of this view and the left edge of its content.
3058      * {@hide}
3059      */
3060     @ViewDebug.ExportedProperty(category = "padding")
3061     protected int mPaddingLeft = 0;
3062     /**
3063      * The right padding in pixels, that is the distance in pixels between the
3064      * right edge of this view and the right edge of its content.
3065      * {@hide}
3066      */
3067     @ViewDebug.ExportedProperty(category = "padding")
3068     protected int mPaddingRight = 0;
3069     /**
3070      * The top padding in pixels, that is the distance in pixels between the
3071      * top edge of this view and the top edge of its content.
3072      * {@hide}
3073      */
3074     @ViewDebug.ExportedProperty(category = "padding")
3075     protected int mPaddingTop;
3076     /**
3077      * The bottom padding in pixels, that is the distance in pixels between the
3078      * bottom edge of this view and the bottom edge of its content.
3079      * {@hide}
3080      */
3081     @ViewDebug.ExportedProperty(category = "padding")
3082     protected int mPaddingBottom;
3083
3084     /**
3085      * The layout insets in pixels, that is the distance in pixels between the
3086      * visible edges of this view its bounds.
3087      */
3088     private Insets mLayoutInsets;
3089
3090     /**
3091      * Briefly describes the view and is primarily used for accessibility support.
3092      */
3093     private CharSequence mContentDescription;
3094
3095     /**
3096      * Specifies the id of a view for which this view serves as a label for
3097      * accessibility purposes.
3098      */
3099     private int mLabelForId = View.NO_ID;
3100
3101     /**
3102      * Predicate for matching labeled view id with its label for
3103      * accessibility purposes.
3104      */
3105     private MatchLabelForPredicate mMatchLabelForPredicate;
3106
3107     /**
3108      * Specifies a view before which this one is visited in accessibility traversal.
3109      */
3110     private int mAccessibilityTraversalBeforeId = NO_ID;
3111
3112     /**
3113      * Specifies a view after which this one is visited in accessibility traversal.
3114      */
3115     private int mAccessibilityTraversalAfterId = NO_ID;
3116
3117     /**
3118      * Predicate for matching a view by its id.
3119      */
3120     private MatchIdPredicate mMatchIdPredicate;
3121
3122     /**
3123      * Cache the paddingRight set by the user to append to the scrollbar's size.
3124      *
3125      * @hide
3126      */
3127     @ViewDebug.ExportedProperty(category = "padding")
3128     protected int mUserPaddingRight;
3129
3130     /**
3131      * Cache the paddingBottom set by the user to append to the scrollbar's size.
3132      *
3133      * @hide
3134      */
3135     @ViewDebug.ExportedProperty(category = "padding")
3136     protected int mUserPaddingBottom;
3137
3138     /**
3139      * Cache the paddingLeft set by the user to append to the scrollbar's size.
3140      *
3141      * @hide
3142      */
3143     @ViewDebug.ExportedProperty(category = "padding")
3144     protected int mUserPaddingLeft;
3145
3146     /**
3147      * Cache the paddingStart set by the user to append to the scrollbar's size.
3148      *
3149      */
3150     @ViewDebug.ExportedProperty(category = "padding")
3151     int mUserPaddingStart;
3152
3153     /**
3154      * Cache the paddingEnd set by the user to append to the scrollbar's size.
3155      *
3156      */
3157     @ViewDebug.ExportedProperty(category = "padding")
3158     int mUserPaddingEnd;
3159
3160     /**
3161      * Cache initial left padding.
3162      *
3163      * @hide
3164      */
3165     int mUserPaddingLeftInitial;
3166
3167     /**
3168      * Cache initial right padding.
3169      *
3170      * @hide
3171      */
3172     int mUserPaddingRightInitial;
3173
3174     /**
3175      * Default undefined padding
3176      */
3177     private static final int UNDEFINED_PADDING = Integer.MIN_VALUE;
3178
3179     /**
3180      * Cache if a left padding has been defined
3181      */
3182     private boolean mLeftPaddingDefined = false;
3183
3184     /**
3185      * Cache if a right padding has been defined
3186      */
3187     private boolean mRightPaddingDefined = false;
3188
3189     /**
3190      * @hide
3191      */
3192     int mOldWidthMeasureSpec = Integer.MIN_VALUE;
3193     /**
3194      * @hide
3195      */
3196     int mOldHeightMeasureSpec = Integer.MIN_VALUE;
3197
3198     private LongSparseLongArray mMeasureCache;
3199
3200     @ViewDebug.ExportedProperty(deepExport = true, prefix = "bg_")
3201     private Drawable mBackground;
3202     private TintInfo mBackgroundTint;
3203
3204     @ViewDebug.ExportedProperty(deepExport = true, prefix = "fg_")
3205     private ForegroundInfo mForegroundInfo;
3206
3207     /**
3208      * RenderNode used for backgrounds.
3209      * <p>
3210      * When non-null and valid, this is expected to contain an up-to-date copy
3211      * of the background drawable. It is cleared on temporary detach, and reset
3212      * on cleanup.
3213      */
3214     private RenderNode mBackgroundRenderNode;
3215
3216     private int mBackgroundResource;
3217     private boolean mBackgroundSizeChanged;
3218
3219     private String mTransitionName;
3220
3221     static class TintInfo {
3222         ColorStateList mTintList;
3223         PorterDuff.Mode mTintMode;
3224         boolean mHasTintMode;
3225         boolean mHasTintList;
3226     }
3227
3228     private static class ForegroundInfo {
3229         private Drawable mDrawable;
3230         private TintInfo mTintInfo;
3231         private int mGravity = Gravity.FILL;
3232         private boolean mInsidePadding = true;
3233         private boolean mBoundsChanged = true;
3234         private final Rect mSelfBounds = new Rect();
3235         private final Rect mOverlayBounds = new Rect();
3236     }
3237
3238     static class ListenerInfo {
3239         /**
3240          * Listener used to dispatch focus change events.
3241          * This field should be made private, so it is hidden from the SDK.
3242          * {@hide}
3243          */
3244         protected OnFocusChangeListener mOnFocusChangeListener;
3245
3246         /**
3247          * Listeners for layout change events.
3248          */
3249         private ArrayList<OnLayoutChangeListener> mOnLayoutChangeListeners;
3250
3251         protected OnScrollChangeListener mOnScrollChangeListener;
3252
3253         /**
3254          * Listeners for attach events.
3255          */
3256         private CopyOnWriteArrayList<OnAttachStateChangeListener> mOnAttachStateChangeListeners;
3257
3258         /**
3259          * Listener used to dispatch click events.
3260          * This field should be made private, so it is hidden from the SDK.
3261          * {@hide}
3262          */
3263         public OnClickListener mOnClickListener;
3264
3265         /**
3266          * Listener used to dispatch long click events.
3267          * This field should be made private, so it is hidden from the SDK.
3268          * {@hide}
3269          */
3270         protected OnLongClickListener mOnLongClickListener;
3271
3272         /**
3273          * Listener used to build the context menu.
3274          * This field should be made private, so it is hidden from the SDK.
3275          * {@hide}
3276          */
3277         protected OnCreateContextMenuListener mOnCreateContextMenuListener;
3278
3279         private OnKeyListener mOnKeyListener;
3280
3281         private OnTouchListener mOnTouchListener;
3282
3283         private OnHoverListener mOnHoverListener;
3284
3285         private OnGenericMotionListener mOnGenericMotionListener;
3286
3287         private OnDragListener mOnDragListener;
3288
3289         private OnSystemUiVisibilityChangeListener mOnSystemUiVisibilityChangeListener;
3290
3291         OnApplyWindowInsetsListener mOnApplyWindowInsetsListener;
3292     }
3293
3294     ListenerInfo mListenerInfo;
3295
3296     /**
3297      * The application environment this view lives in.
3298      * This field should be made private, so it is hidden from the SDK.
3299      * {@hide}
3300      */
3301     @ViewDebug.ExportedProperty(deepExport = true)
3302     protected Context mContext;
3303
3304     private final Resources mResources;
3305
3306     private ScrollabilityCache mScrollCache;
3307
3308     private int[] mDrawableState = null;
3309
3310     ViewOutlineProvider mOutlineProvider = ViewOutlineProvider.BACKGROUND;
3311
3312     /**
3313      * Animator that automatically runs based on state changes.
3314      */
3315     private StateListAnimator mStateListAnimator;
3316
3317     /**
3318      * When this view has focus and the next focus is {@link #FOCUS_LEFT},
3319      * the user may specify which view to go to next.
3320      */
3321     private int mNextFocusLeftId = View.NO_ID;
3322
3323     /**
3324      * When this view has focus and the next focus is {@link #FOCUS_RIGHT},
3325      * the user may specify which view to go to next.
3326      */
3327     private int mNextFocusRightId = View.NO_ID;
3328
3329     /**
3330      * When this view has focus and the next focus is {@link #FOCUS_UP},
3331      * the user may specify which view to go to next.
3332      */
3333     private int mNextFocusUpId = View.NO_ID;
3334
3335     /**
3336      * When this view has focus and the next focus is {@link #FOCUS_DOWN},
3337      * the user may specify which view to go to next.
3338      */
3339     private int mNextFocusDownId = View.NO_ID;
3340
3341     /**
3342      * When this view has focus and the next focus is {@link #FOCUS_FORWARD},
3343      * the user may specify which view to go to next.
3344      */
3345     int mNextFocusForwardId = View.NO_ID;
3346
3347     private CheckForLongPress mPendingCheckForLongPress;
3348     private CheckForTap mPendingCheckForTap = null;
3349     private PerformClick mPerformClick;
3350     private SendViewScrolledAccessibilityEvent mSendViewScrolledAccessibilityEvent;
3351
3352     private UnsetPressedState mUnsetPressedState;
3353
3354     /**
3355      * Whether the long press's action has been invoked.  The tap's action is invoked on the
3356      * up event while a long press is invoked as soon as the long press duration is reached, so
3357      * a long press could be performed before the tap is checked, in which case the tap's action
3358      * should not be invoked.
3359      */
3360     private boolean mHasPerformedLongPress;
3361
3362     /**
3363      * The minimum height of the view. We'll try our best to have the height
3364      * of this view to at least this amount.
3365      */
3366     @ViewDebug.ExportedProperty(category = "measurement")
3367     private int mMinHeight;
3368
3369     /**
3370      * The minimum width of the view. We'll try our best to have the width
3371      * of this view to at least this amount.
3372      */
3373     @ViewDebug.ExportedProperty(category = "measurement")
3374     private int mMinWidth;
3375
3376     /**
3377      * The delegate to handle touch events that are physically in this view
3378      * but should be handled by another view.
3379      */
3380     private TouchDelegate mTouchDelegate = null;
3381
3382     /**
3383      * Solid color to use as a background when creating the drawing cache. Enables
3384      * the cache to use 16 bit bitmaps instead of 32 bit.
3385      */
3386     private int mDrawingCacheBackgroundColor = 0;
3387
3388     /**
3389      * Special tree observer used when mAttachInfo is null.
3390      */
3391     private ViewTreeObserver mFloatingTreeObserver;
3392
3393     /**
3394      * Cache the touch slop from the context that created the view.
3395      */
3396     private int mTouchSlop;
3397
3398     /**
3399      * Object that handles automatic animation of view properties.
3400      */
3401     private ViewPropertyAnimator mAnimator = null;
3402
3403     /**
3404      * Flag indicating that a drag can cross window boundaries.  When
3405      * {@link #startDrag(ClipData, DragShadowBuilder, Object, int)} is called
3406      * with this flag set, all visible applications will be able to participate
3407      * in the drag operation and receive the dragged content.
3408      *
3409      * @hide
3410      */
3411     public static final int DRAG_FLAG_GLOBAL = 1;
3412
3413     /**
3414      * Vertical scroll factor cached by {@link #getVerticalScrollFactor}.
3415      */
3416     private float mVerticalScrollFactor;
3417
3418     /**
3419      * Position of the vertical scroll bar.
3420      */
3421     private int mVerticalScrollbarPosition;
3422
3423     /**
3424      * Position the scroll bar at the default position as determined by the system.
3425      */
3426     public static final int SCROLLBAR_POSITION_DEFAULT = 0;
3427
3428     /**
3429      * Position the scroll bar along the left edge.
3430      */
3431     public static final int SCROLLBAR_POSITION_LEFT = 1;
3432
3433     /**
3434      * Position the scroll bar along the right edge.
3435      */
3436     public static final int SCROLLBAR_POSITION_RIGHT = 2;
3437
3438     /**
3439      * Indicates that the view does not have a layer.
3440      *
3441      * @see #getLayerType()
3442      * @see #setLayerType(int, android.graphics.Paint)
3443      * @see #LAYER_TYPE_SOFTWARE
3444      * @see #LAYER_TYPE_HARDWARE
3445      */
3446     public static final int LAYER_TYPE_NONE = 0;
3447
3448     /**
3449      * <p>Indicates that the view has a software layer. A software layer is backed
3450      * by a bitmap and causes the view to be rendered using Android's software
3451      * rendering pipeline, even if hardware acceleration is enabled.</p>
3452      *
3453      * <p>Software layers have various usages:</p>
3454      * <p>When the application is not using hardware acceleration, a software layer
3455      * is useful to apply a specific color filter and/or blending mode and/or
3456      * translucency to a view and all its children.</p>
3457      * <p>When the application is using hardware acceleration, a software layer
3458      * is useful to render drawing primitives not supported by the hardware
3459      * accelerated pipeline. It can also be used to cache a complex view tree
3460      * into a texture and reduce the complexity of drawing operations. For instance,
3461      * when animating a complex view tree with a translation, a software layer can
3462      * be used to render the view tree only once.</p>
3463      * <p>Software layers should be avoided when the affected view tree updates
3464      * often. Every update will require to re-render the software layer, which can
3465      * potentially be slow (particularly when hardware acceleration is turned on
3466      * since the layer will have to be uploaded into a hardware texture after every
3467      * update.)</p>
3468      *
3469      * @see #getLayerType()
3470      * @see #setLayerType(int, android.graphics.Paint)
3471      * @see #LAYER_TYPE_NONE
3472      * @see #LAYER_TYPE_HARDWARE
3473      */
3474     public static final int LAYER_TYPE_SOFTWARE = 1;
3475
3476     /**
3477      * <p>Indicates that the view has a hardware layer. A hardware layer is backed
3478      * by a hardware specific texture (generally Frame Buffer Objects or FBO on
3479      * OpenGL hardware) and causes the view to be rendered using Android's hardware
3480      * rendering pipeline, but only if hardware acceleration is turned on for the
3481      * view hierarchy. When hardware acceleration is turned off, hardware layers
3482      * behave exactly as {@link #LAYER_TYPE_SOFTWARE software layers}.</p>
3483      *
3484      * <p>A hardware layer is useful to apply a specific color filter and/or
3485      * blending mode and/or translucency to a view and all its children.</p>
3486      * <p>A hardware layer can be used to cache a complex view tree into a
3487      * texture and reduce the complexity of drawing operations. For instance,
3488      * when animating a complex view tree with a translation, a hardware layer can
3489      * be used to render the view tree only once.</p>
3490      * <p>A hardware layer can also be used to increase the rendering quality when
3491      * rotation transformations are applied on a view. It can also be used to
3492      * prevent potential clipping issues when applying 3D transforms on a view.</p>
3493      *
3494      * @see #getLayerType()
3495      * @see #setLayerType(int, android.graphics.Paint)
3496      * @see #LAYER_TYPE_NONE
3497      * @see #LAYER_TYPE_SOFTWARE
3498      */
3499     public static final int LAYER_TYPE_HARDWARE = 2;
3500
3501     @ViewDebug.ExportedProperty(category = "drawing", mapping = {
3502             @ViewDebug.IntToString(from = LAYER_TYPE_NONE, to = "NONE"),
3503             @ViewDebug.IntToString(from = LAYER_TYPE_SOFTWARE, to = "SOFTWARE"),
3504             @ViewDebug.IntToString(from = LAYER_TYPE_HARDWARE, to = "HARDWARE")
3505     })
3506     int mLayerType = LAYER_TYPE_NONE;
3507     Paint mLayerPaint;
3508
3509     /**
3510      * Set to true when drawing cache is enabled and cannot be created.
3511      *
3512      * @hide
3513      */
3514     public boolean mCachingFailed;
3515     private Bitmap mDrawingCache;
3516     private Bitmap mUnscaledDrawingCache;
3517
3518     /**
3519      * RenderNode holding View properties, potentially holding a DisplayList of View content.
3520      * <p>
3521      * When non-null and valid, this is expected to contain an up-to-date copy
3522      * of the View content. Its DisplayList content is cleared on temporary detach and reset on
3523      * cleanup.
3524      */
3525     final RenderNode mRenderNode;
3526
3527     /**
3528      * Set to true when the view is sending hover accessibility events because it
3529      * is the innermost hovered view.
3530      */
3531     private boolean mSendingHoverAccessibilityEvents;
3532
3533     /**
3534      * Delegate for injecting accessibility functionality.
3535      */
3536     AccessibilityDelegate mAccessibilityDelegate;
3537
3538     /**
3539      * The view's overlay layer. Developers get a reference to the overlay via getOverlay()
3540      * and add/remove objects to/from the overlay directly through the Overlay methods.
3541      */
3542     ViewOverlay mOverlay;
3543
3544     /**
3545      * The currently active parent view for receiving delegated nested scrolling events.
3546      * This is set by {@link #startNestedScroll(int)} during a touch interaction and cleared
3547      * by {@link #stopNestedScroll()} at the same point where we clear
3548      * requestDisallowInterceptTouchEvent.
3549      */
3550     private ViewParent mNestedScrollingParent;
3551
3552     /**
3553      * Consistency verifier for debugging purposes.
3554      * @hide
3555      */
3556     protected final InputEventConsistencyVerifier mInputEventConsistencyVerifier =
3557             InputEventConsistencyVerifier.isInstrumentationEnabled() ?
3558                     new InputEventConsistencyVerifier(this, 0) : null;
3559
3560     private static final AtomicInteger sNextGeneratedId = new AtomicInteger(1);
3561
3562     private int[] mTempNestedScrollConsumed;
3563
3564     /**
3565      * An overlay is going to draw this View instead of being drawn as part of this
3566      * View's parent. mGhostView is the View in the Overlay that must be invalidated
3567      * when this view is invalidated.
3568      */
3569     GhostView mGhostView;
3570
3571     /**
3572      * Holds pairs of adjacent attribute data: attribute name followed by its value.
3573      * @hide
3574      */
3575     @ViewDebug.ExportedProperty(category = "attributes", hasAdjacentMapping = true)
3576     public String[] mAttributes;
3577
3578     /**
3579      * Maps a Resource id to its name.
3580      */
3581     private static SparseArray<String> mAttributeMap;
3582
3583     /**
3584      * @hide
3585      */
3586     String mStartActivityRequestWho;
3587
3588     /**
3589      * Simple constructor to use when creating a view from code.
3590      *
3591      * @param context The Context the view is running in, through which it can
3592      *        access the current theme, resources, etc.
3593      */
3594     public View(Context context) {
3595         mContext = context;
3596         mResources = context != null ? context.getResources() : null;
3597         mViewFlags = SOUND_EFFECTS_ENABLED | HAPTIC_FEEDBACK_ENABLED;
3598         // Set some flags defaults
3599         mPrivateFlags2 =
3600                 (LAYOUT_DIRECTION_DEFAULT << PFLAG2_LAYOUT_DIRECTION_MASK_SHIFT) |
3601                 (TEXT_DIRECTION_DEFAULT << PFLAG2_TEXT_DIRECTION_MASK_SHIFT) |
3602                 (PFLAG2_TEXT_DIRECTION_RESOLVED_DEFAULT) |
3603                 (TEXT_ALIGNMENT_DEFAULT << PFLAG2_TEXT_ALIGNMENT_MASK_SHIFT) |
3604                 (PFLAG2_TEXT_ALIGNMENT_RESOLVED_DEFAULT) |
3605                 (IMPORTANT_FOR_ACCESSIBILITY_DEFAULT << PFLAG2_IMPORTANT_FOR_ACCESSIBILITY_SHIFT);
3606         mTouchSlop = ViewConfiguration.get(context).getScaledTouchSlop();
3607         setOverScrollMode(OVER_SCROLL_IF_CONTENT_SCROLLS);
3608         mUserPaddingStart = UNDEFINED_PADDING;
3609         mUserPaddingEnd = UNDEFINED_PADDING;
3610         mRenderNode = RenderNode.create(getClass().getName(), this);
3611
3612         if (!sCompatibilityDone && context != null) {
3613             final int targetSdkVersion = context.getApplicationInfo().targetSdkVersion;
3614
3615             // Older apps may need this compatibility hack for measurement.
3616             sUseBrokenMakeMeasureSpec = targetSdkVersion <= JELLY_BEAN_MR1;
3617
3618             // Older apps expect onMeasure() to always be called on a layout pass, regardless
3619             // of whether a layout was requested on that View.
3620             sIgnoreMeasureCache = targetSdkVersion < KITKAT;
3621
3622             Canvas.sCompatibilityRestore = targetSdkVersion < MNC;
3623
3624             sCompatibilityDone = true;
3625         }
3626     }
3627
3628     /**
3629      * Constructor that is called when inflating a view from XML. This is called
3630      * when a view is being constructed from an XML file, supplying attributes
3631      * that were specified in the XML file. This version uses a default style of
3632      * 0, so the only attribute values applied are those in the Context's Theme
3633      * and the given AttributeSet.
3634      *
3635      * <p>
3636      * The method onFinishInflate() will be called after all children have been
3637      * added.
3638      *
3639      * @param context The Context the view is running in, through which it can
3640      *        access the current theme, resources, etc.
3641      * @param attrs The attributes of the XML tag that is inflating the view.
3642      * @see #View(Context, AttributeSet, int)
3643      */
3644     public View(Context context, @Nullable AttributeSet attrs) {
3645         this(context, attrs, 0);
3646     }
3647
3648     /**
3649      * Perform inflation from XML and apply a class-specific base style from a
3650      * theme attribute. This constructor of View allows subclasses to use their
3651      * own base style when they are inflating. For example, a Button class's
3652      * constructor would call this version of the super class constructor and
3653      * supply <code>R.attr.buttonStyle</code> for <var>defStyleAttr</var>; this
3654      * allows the theme's button style to modify all of the base view attributes
3655      * (in particular its background) as well as the Button class's attributes.
3656      *
3657      * @param context The Context the view is running in, through which it can
3658      *        access the current theme, resources, etc.
3659      * @param attrs The attributes of the XML tag that is inflating the view.
3660      * @param defStyleAttr An attribute in the current theme that contains a
3661      *        reference to a style resource that supplies default values for
3662      *        the view. Can be 0 to not look for defaults.
3663      * @see #View(Context, AttributeSet)
3664      */
3665     public View(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
3666         this(context, attrs, defStyleAttr, 0);
3667     }
3668
3669     /**
3670      * Perform inflation from XML and apply a class-specific base style from a
3671      * theme attribute or style resource. This constructor of View allows
3672      * subclasses to use their own base style when they are inflating.
3673      * <p>
3674      * When determining the final value of a particular attribute, there are
3675      * four inputs that come into play:
3676      * <ol>
3677      * <li>Any attribute values in the given AttributeSet.
3678      * <li>The style resource specified in the AttributeSet (named "style").
3679      * <li>The default style specified by <var>defStyleAttr</var>.
3680      * <li>The default style specified by <var>defStyleRes</var>.
3681      * <li>The base values in this theme.
3682      * </ol>
3683      * <p>
3684      * Each of these inputs is considered in-order, with the first listed taking
3685      * precedence over the following ones. In other words, if in the
3686      * AttributeSet you have supplied <code>&lt;Button * textColor="#ff000000"&gt;</code>
3687      * , then the button's text will <em>always</em> be black, regardless of
3688      * what is specified in any of the styles.
3689      *
3690      * @param context The Context the view is running in, through which it can
3691      *        access the current theme, resources, etc.
3692      * @param attrs The attributes of the XML tag that is inflating the view.
3693      * @param defStyleAttr An attribute in the current theme that contains a
3694      *        reference to a style resource that supplies default values for
3695      *        the view. Can be 0 to not look for defaults.
3696      * @param defStyleRes A resource identifier of a style resource that
3697      *        supplies default values for the view, used only if
3698      *        defStyleAttr is 0 or can not be found in the theme. Can be 0
3699      *        to not look for defaults.
3700      * @see #View(Context, AttributeSet, int)
3701      */
3702     public View(Context context, @Nullable AttributeSet attrs, int defStyleAttr, int defStyleRes) {
3703         this(context);
3704
3705         final TypedArray a = context.obtainStyledAttributes(
3706                 attrs, com.android.internal.R.styleable.View, defStyleAttr, defStyleRes);
3707
3708         if (mDebugViewAttributes) {
3709             saveAttributeData(attrs, a);
3710         }
3711
3712         Drawable background = null;
3713
3714         int leftPadding = -1;
3715         int topPadding = -1;
3716         int rightPadding = -1;
3717         int bottomPadding = -1;
3718         int startPadding = UNDEFINED_PADDING;
3719         int endPadding = UNDEFINED_PADDING;
3720
3721         int padding = -1;
3722
3723         int viewFlagValues = 0;
3724         int viewFlagMasks = 0;
3725
3726         boolean setScrollContainer = false;
3727
3728         int x = 0;
3729         int y = 0;
3730
3731         float tx = 0;
3732         float ty = 0;
3733         float tz = 0;
3734         float elevation = 0;
3735         float rotation = 0;
3736         float rotationX = 0;
3737         float rotationY = 0;
3738         float sx = 1f;
3739         float sy = 1f;
3740         boolean transformSet = false;
3741
3742         int scrollbarStyle = SCROLLBARS_INSIDE_OVERLAY;
3743         int overScrollMode = mOverScrollMode;
3744         boolean initializeScrollbars = false;
3745
3746         boolean startPaddingDefined = false;
3747         boolean endPaddingDefined = false;
3748         boolean leftPaddingDefined = false;
3749         boolean rightPaddingDefined = false;
3750
3751         final int targetSdkVersion = context.getApplicationInfo().targetSdkVersion;
3752
3753         final int N = a.getIndexCount();
3754         for (int i = 0; i < N; i++) {
3755             int attr = a.getIndex(i);
3756             switch (attr) {
3757                 case com.android.internal.R.styleable.View_background:
3758                     background = a.getDrawable(attr);
3759                     break;
3760                 case com.android.internal.R.styleable.View_padding:
3761                     padding = a.getDimensionPixelSize(attr, -1);
3762                     mUserPaddingLeftInitial = padding;
3763                     mUserPaddingRightInitial = padding;
3764                     leftPaddingDefined = true;
3765                     rightPaddingDefined = true;
3766                     break;
3767                  case com.android.internal.R.styleable.View_paddingLeft:
3768                     leftPadding = a.getDimensionPixelSize(attr, -1);
3769                     mUserPaddingLeftInitial = leftPadding;
3770                     leftPaddingDefined = true;
3771                     break;
3772                 case com.android.internal.R.styleable.View_paddingTop:
3773                     topPadding = a.getDimensionPixelSize(attr, -1);
3774                     break;
3775                 case com.android.internal.R.styleable.View_paddingRight:
3776                     rightPadding = a.getDimensionPixelSize(attr, -1);
3777                     mUserPaddingRightInitial = rightPadding;
3778                     rightPaddingDefined = true;
3779                     break;
3780                 case com.android.internal.R.styleable.View_paddingBottom:
3781                     bottomPadding = a.getDimensionPixelSize(attr, -1);
3782                     break;
3783                 case com.android.internal.R.styleable.View_paddingStart:
3784                     startPadding = a.getDimensionPixelSize(attr, UNDEFINED_PADDING);
3785                     startPaddingDefined = (startPadding != UNDEFINED_PADDING);
3786                     break;
3787                 case com.android.internal.R.styleable.View_paddingEnd:
3788                     endPadding = a.getDimensionPixelSize(attr, UNDEFINED_PADDING);
3789                     endPaddingDefined = (endPadding != UNDEFINED_PADDING);
3790                     break;
3791                 case com.android.internal.R.styleable.View_scrollX:
3792                     x = a.getDimensionPixelOffset(attr, 0);
3793                     break;
3794                 case com.android.internal.R.styleable.View_scrollY:
3795                     y = a.getDimensionPixelOffset(attr, 0);
3796                     break;
3797                 case com.android.internal.R.styleable.View_alpha:
3798                     setAlpha(a.getFloat(attr, 1f));
3799                     break;
3800                 case com.android.internal.R.styleable.View_transformPivotX:
3801                     setPivotX(a.getDimensionPixelOffset(attr, 0));
3802                     break;
3803                 case com.android.internal.R.styleable.View_transformPivotY:
3804                     setPivotY(a.getDimensionPixelOffset(attr, 0));
3805                     break;
3806                 case com.android.internal.R.styleable.View_translationX:
3807                     tx = a.getDimensionPixelOffset(attr, 0);
3808                     transformSet = true;
3809                     break;
3810                 case com.android.internal.R.styleable.View_translationY:
3811                     ty = a.getDimensionPixelOffset(attr, 0);
3812                     transformSet = true;
3813                     break;
3814                 case com.android.internal.R.styleable.View_translationZ:
3815                     tz = a.getDimensionPixelOffset(attr, 0);
3816                     transformSet = true;
3817                     break;
3818                 case com.android.internal.R.styleable.View_elevation:
3819                     elevation = a.getDimensionPixelOffset(attr, 0);
3820                     transformSet = true;
3821                     break;
3822                 case com.android.internal.R.styleable.View_rotation:
3823                     rotation = a.getFloat(attr, 0);
3824                     transformSet = true;
3825                     break;
3826                 case com.android.internal.R.styleable.View_rotationX:
3827                     rotationX = a.getFloat(attr, 0);
3828                     transformSet = true;
3829                     break;
3830                 case com.android.internal.R.styleable.View_rotationY:
3831                     rotationY = a.getFloat(attr, 0);
3832                     transformSet = true;
3833                     break;
3834                 case com.android.internal.R.styleable.View_scaleX:
3835                     sx = a.getFloat(attr, 1f);
3836                     transformSet = true;
3837                     break;
3838                 case com.android.internal.R.styleable.View_scaleY:
3839                     sy = a.getFloat(attr, 1f);
3840                     transformSet = true;
3841                     break;
3842                 case com.android.internal.R.styleable.View_id:
3843                     mID = a.getResourceId(attr, NO_ID);
3844                     break;
3845                 case com.android.internal.R.styleable.View_tag:
3846                     mTag = a.getText(attr);
3847                     break;
3848                 case com.android.internal.R.styleable.View_fitsSystemWindows:
3849                     if (a.getBoolean(attr, false)) {
3850                         viewFlagValues |= FITS_SYSTEM_WINDOWS;
3851                         viewFlagMasks |= FITS_SYSTEM_WINDOWS;
3852                     }
3853                     break;
3854                 case com.android.internal.R.styleable.View_focusable:
3855                     if (a.getBoolean(attr, false)) {
3856                         viewFlagValues |= FOCUSABLE;
3857                         viewFlagMasks |= FOCUSABLE_MASK;
3858                     }
3859                     break;
3860                 case com.android.internal.R.styleable.View_focusableInTouchMode:
3861                     if (a.getBoolean(attr, false)) {
3862                         viewFlagValues |= FOCUSABLE_IN_TOUCH_MODE | FOCUSABLE;
3863                         viewFlagMasks |= FOCUSABLE_IN_TOUCH_MODE | FOCUSABLE_MASK;
3864                     }
3865                     break;
3866                 case com.android.internal.R.styleable.View_clickable:
3867                     if (a.getBoolean(attr, false)) {
3868                         viewFlagValues |= CLICKABLE;
3869                         viewFlagMasks |= CLICKABLE;
3870                     }
3871                     break;
3872                 case com.android.internal.R.styleable.View_longClickable:
3873                     if (a.getBoolean(attr, false)) {
3874                         viewFlagValues |= LONG_CLICKABLE;
3875                         viewFlagMasks |= LONG_CLICKABLE;
3876                     }
3877                     break;
3878                 case com.android.internal.R.styleable.View_saveEnabled:
3879                     if (!a.getBoolean(attr, true)) {
3880                         viewFlagValues |= SAVE_DISABLED;
3881                         viewFlagMasks |= SAVE_DISABLED_MASK;
3882                     }
3883                     break;
3884                 case com.android.internal.R.styleable.View_assistBlocked:
3885                     if (a.getBoolean(attr, false)) {
3886                         mPrivateFlags3 |= PFLAG3_ASSIST_BLOCKED;
3887                     }
3888                     break;
3889                 case com.android.internal.R.styleable.View_duplicateParentState:
3890                     if (a.getBoolean(attr, false)) {
3891                         viewFlagValues |= DUPLICATE_PARENT_STATE;
3892                         viewFlagMasks |= DUPLICATE_PARENT_STATE;
3893                     }
3894                     break;
3895                 case com.android.internal.R.styleable.View_visibility:
3896                     final int visibility = a.getInt(attr, 0);
3897                     if (visibility != 0) {
3898                         viewFlagValues |= VISIBILITY_FLAGS[visibility];
3899                         viewFlagMasks |= VISIBILITY_MASK;
3900                     }
3901                     break;
3902                 case com.android.internal.R.styleable.View_layoutDirection:
3903                     // Clear any layout direction flags (included resolved bits) already set
3904                     mPrivateFlags2 &=
3905                             ~(PFLAG2_LAYOUT_DIRECTION_MASK | PFLAG2_LAYOUT_DIRECTION_RESOLVED_MASK);
3906                     // Set the layout direction flags depending on the value of the attribute
3907                     final int layoutDirection = a.getInt(attr, -1);
3908                     final int value = (layoutDirection != -1) ?
3909                             LAYOUT_DIRECTION_FLAGS[layoutDirection] : LAYOUT_DIRECTION_DEFAULT;
3910                     mPrivateFlags2 |= (value << PFLAG2_LAYOUT_DIRECTION_MASK_SHIFT);
3911                     break;
3912                 case com.android.internal.R.styleable.View_drawingCacheQuality:
3913                     final int cacheQuality = a.getInt(attr, 0);
3914                     if (cacheQuality != 0) {
3915                         viewFlagValues |= DRAWING_CACHE_QUALITY_FLAGS[cacheQuality];
3916                         viewFlagMasks |= DRAWING_CACHE_QUALITY_MASK;
3917                     }
3918                     break;
3919                 case com.android.internal.R.styleable.View_contentDescription:
3920                     setContentDescription(a.getString(attr));
3921                     break;
3922                 case com.android.internal.R.styleable.View_accessibilityTraversalBefore:
3923                     setAccessibilityTraversalBefore(a.getResourceId(attr, NO_ID));
3924                     break;
3925                 case com.android.internal.R.styleable.View_accessibilityTraversalAfter:
3926                     setAccessibilityTraversalAfter(a.getResourceId(attr, NO_ID));
3927                     break;
3928                 case com.android.internal.R.styleable.View_labelFor:
3929                     setLabelFor(a.getResourceId(attr, NO_ID));
3930                     break;
3931                 case com.android.internal.R.styleable.View_soundEffectsEnabled:
3932                     if (!a.getBoolean(attr, true)) {
3933                         viewFlagValues &= ~SOUND_EFFECTS_ENABLED;
3934                         viewFlagMasks |= SOUND_EFFECTS_ENABLED;
3935                     }
3936                     break;
3937                 case com.android.internal.R.styleable.View_hapticFeedbackEnabled:
3938                     if (!a.getBoolean(attr, true)) {
3939                         viewFlagValues &= ~HAPTIC_FEEDBACK_ENABLED;
3940                         viewFlagMasks |= HAPTIC_FEEDBACK_ENABLED;
3941                     }
3942                     break;
3943                 case R.styleable.View_scrollbars:
3944                     final int scrollbars = a.getInt(attr, SCROLLBARS_NONE);
3945                     if (scrollbars != SCROLLBARS_NONE) {
3946                         viewFlagValues |= scrollbars;
3947                         viewFlagMasks |= SCROLLBARS_MASK;
3948                         initializeScrollbars = true;
3949                     }
3950                     break;
3951                 //noinspection deprecation
3952                 case R.styleable.View_fadingEdge:
3953                     if (targetSdkVersion >= ICE_CREAM_SANDWICH) {
3954                         // Ignore the attribute starting with ICS
3955                         break;
3956                     }
3957                     // With builds < ICS, fall through and apply fading edges
3958                 case R.styleable.View_requiresFadingEdge:
3959                     final int fadingEdge = a.getInt(attr, FADING_EDGE_NONE);
3960                     if (fadingEdge != FADING_EDGE_NONE) {
3961                         viewFlagValues |= fadingEdge;
3962                         viewFlagMasks |= FADING_EDGE_MASK;
3963                         initializeFadingEdgeInternal(a);
3964                     }
3965                     break;
3966                 case R.styleable.View_scrollbarStyle:
3967                     scrollbarStyle = a.getInt(attr, SCROLLBARS_INSIDE_OVERLAY);
3968                     if (scrollbarStyle != SCROLLBARS_INSIDE_OVERLAY) {
3969                         viewFlagValues |= scrollbarStyle & SCROLLBARS_STYLE_MASK;
3970                         viewFlagMasks |= SCROLLBARS_STYLE_MASK;
3971                     }
3972                     break;
3973                 case R.styleable.View_isScrollContainer:
3974                     setScrollContainer = true;
3975                     if (a.getBoolean(attr, false)) {
3976                         setScrollContainer(true);
3977                     }
3978                     break;
3979                 case com.android.internal.R.styleable.View_keepScreenOn:
3980                     if (a.getBoolean(attr, false)) {
3981                         viewFlagValues |= KEEP_SCREEN_ON;
3982                         viewFlagMasks |= KEEP_SCREEN_ON;
3983                     }
3984                     break;
3985                 case R.styleable.View_filterTouchesWhenObscured:
3986                     if (a.getBoolean(attr, false)) {
3987                         viewFlagValues |= FILTER_TOUCHES_WHEN_OBSCURED;
3988                         viewFlagMasks |= FILTER_TOUCHES_WHEN_OBSCURED;
3989                     }
3990                     break;
3991                 case R.styleable.View_nextFocusLeft:
3992                     mNextFocusLeftId = a.getResourceId(attr, View.NO_ID);
3993                     break;
3994                 case R.styleable.View_nextFocusRight:
3995                     mNextFocusRightId = a.getResourceId(attr, View.NO_ID);
3996                     break;
3997                 case R.styleable.View_nextFocusUp:
3998                     mNextFocusUpId = a.getResourceId(attr, View.NO_ID);
3999                     break;
4000                 case R.styleable.View_nextFocusDown:
4001                     mNextFocusDownId = a.getResourceId(attr, View.NO_ID);
4002                     break;
4003                 case R.styleable.View_nextFocusForward:
4004                     mNextFocusForwardId = a.getResourceId(attr, View.NO_ID);
4005                     break;
4006                 case R.styleable.View_minWidth:
4007                     mMinWidth = a.getDimensionPixelSize(attr, 0);
4008                     break;
4009                 case R.styleable.View_minHeight:
4010                     mMinHeight = a.getDimensionPixelSize(attr, 0);
4011                     break;
4012                 case R.styleable.View_onClick:
4013                     if (context.isRestricted()) {
4014                         throw new IllegalStateException("The android:onClick attribute cannot "
4015                                 + "be used within a restricted context");
4016                     }
4017
4018                     final String handlerName = a.getString(attr);
4019                     if (handlerName != null) {
4020                         setOnClickListener(new DeclaredOnClickListener(this, handlerName));
4021                     }
4022                     break;
4023                 case R.styleable.View_overScrollMode:
4024                     overScrollMode = a.getInt(attr, OVER_SCROLL_IF_CONTENT_SCROLLS);
4025                     break;
4026                 case R.styleable.View_verticalScrollbarPosition:
4027                     mVerticalScrollbarPosition = a.getInt(attr, SCROLLBAR_POSITION_DEFAULT);
4028                     break;
4029                 case R.styleable.View_layerType:
4030                     setLayerType(a.getInt(attr, LAYER_TYPE_NONE), null);
4031                     break;
4032                 case R.styleable.View_textDirection:
4033                     // Clear any text direction flag already set
4034                     mPrivateFlags2 &= ~PFLAG2_TEXT_DIRECTION_MASK;
4035                     // Set the text direction flags depending on the value of the attribute
4036                     final int textDirection = a.getInt(attr, -1);
4037                     if (textDirection != -1) {
4038                         mPrivateFlags2 |= PFLAG2_TEXT_DIRECTION_FLAGS[textDirection];
4039                     }
4040                     break;
4041                 case R.styleable.View_textAlignment:
4042                     // Clear any text alignment flag already set
4043                     mPrivateFlags2 &= ~PFLAG2_TEXT_ALIGNMENT_MASK;
4044                     // Set the text alignment flag depending on the value of the attribute
4045                     final int textAlignment = a.getInt(attr, TEXT_ALIGNMENT_DEFAULT);
4046                     mPrivateFlags2 |= PFLAG2_TEXT_ALIGNMENT_FLAGS[textAlignment];
4047                     break;
4048                 case R.styleable.View_importantForAccessibility:
4049                     setImportantForAccessibility(a.getInt(attr,
4050                             IMPORTANT_FOR_ACCESSIBILITY_DEFAULT));
4051                     break;
4052                 case R.styleable.View_accessibilityLiveRegion:
4053                     setAccessibilityLiveRegion(a.getInt(attr, ACCESSIBILITY_LIVE_REGION_DEFAULT));
4054                     break;
4055                 case R.styleable.View_transitionName:
4056                     setTransitionName(a.getString(attr));
4057                     break;
4058                 case R.styleable.View_nestedScrollingEnabled:
4059                     setNestedScrollingEnabled(a.getBoolean(attr, false));
4060                     break;
4061                 case R.styleable.View_stateListAnimator:
4062                     setStateListAnimator(AnimatorInflater.loadStateListAnimator(context,
4063                             a.getResourceId(attr, 0)));
4064                     break;
4065                 case R.styleable.View_backgroundTint:
4066                     // This will get applied later during setBackground().
4067                     if (mBackgroundTint == null) {
4068                         mBackgroundTint = new TintInfo();
4069                     }
4070                     mBackgroundTint.mTintList = a.getColorStateList(
4071                             R.styleable.View_backgroundTint);
4072                     mBackgroundTint.mHasTintList = true;
4073                     break;
4074                 case R.styleable.View_backgroundTintMode:
4075                     // This will get applied later during setBackground().
4076                     if (mBackgroundTint == null) {
4077                         mBackgroundTint = new TintInfo();
4078                     }
4079                     mBackgroundTint.mTintMode = Drawable.parseTintMode(a.getInt(
4080                             R.styleable.View_backgroundTintMode, -1), null);
4081                     mBackgroundTint.mHasTintMode = true;
4082                     break;
4083                 case R.styleable.View_outlineProvider:
4084                     setOutlineProviderFromAttribute(a.getInt(R.styleable.View_outlineProvider,
4085                             PROVIDER_BACKGROUND));
4086                     break;
4087                 case R.styleable.View_foreground:
4088                     setForeground(a.getDrawable(attr));
4089                     break;
4090                 case R.styleable.View_foregroundGravity:
4091                     setForegroundGravity(a.getInt(attr, Gravity.NO_GRAVITY));
4092                     break;
4093                 case R.styleable.View_foregroundTintMode:
4094                     setForegroundTintMode(Drawable.parseTintMode(a.getInt(attr, -1), null));
4095                     break;
4096                 case R.styleable.View_foregroundTint:
4097                     setForegroundTintList(a.getColorStateList(attr));
4098                     break;
4099                 case R.styleable.View_foregroundInsidePadding:
4100                     if (mForegroundInfo == null) {
4101                         mForegroundInfo = new ForegroundInfo();
4102                     }
4103                     mForegroundInfo.mInsidePadding = a.getBoolean(attr,
4104                             mForegroundInfo.mInsidePadding);
4105                     break;
4106             }
4107         }
4108
4109         setOverScrollMode(overScrollMode);
4110
4111         // Cache start/end user padding as we cannot fully resolve padding here (we dont have yet
4112         // the resolved layout direction). Those cached values will be used later during padding
4113         // resolution.
4114         mUserPaddingStart = startPadding;
4115         mUserPaddingEnd = endPadding;
4116
4117         if (background != null) {
4118             setBackground(background);
4119         }
4120
4121         // setBackground above will record that padding is currently provided by the background.
4122         // If we have padding specified via xml, record that here instead and use it.
4123         mLeftPaddingDefined = leftPaddingDefined;
4124         mRightPaddingDefined = rightPaddingDefined;
4125
4126         if (padding >= 0) {
4127             leftPadding = padding;
4128             topPadding = padding;
4129             rightPadding = padding;
4130             bottomPadding = padding;
4131             mUserPaddingLeftInitial = padding;
4132             mUserPaddingRightInitial = padding;
4133         }
4134
4135         if (isRtlCompatibilityMode()) {
4136             // RTL compatibility mode: pre Jelly Bean MR1 case OR no RTL support case.
4137             // left / right padding are used if defined (meaning here nothing to do). If they are not
4138             // defined and start / end padding are defined (e.g. in Frameworks resources), then we use
4139             // start / end and resolve them as left / right (layout direction is not taken into account).
4140             // Padding from the background drawable is stored at this point in mUserPaddingLeftInitial
4141             // and mUserPaddingRightInitial) so drawable padding will be used as ultimate default if
4142             // defined.
4143             if (!mLeftPaddingDefined && startPaddingDefined) {
4144                 leftPadding = startPadding;
4145             }
4146             mUserPaddingLeftInitial = (leftPadding >= 0) ? leftPadding : mUserPaddingLeftInitial;
4147             if (!mRightPaddingDefined && endPaddingDefined) {
4148                 rightPadding = endPadding;
4149             }
4150             mUserPaddingRightInitial = (rightPadding >= 0) ? rightPadding : mUserPaddingRightInitial;
4151         } else {
4152             // Jelly Bean MR1 and after case: if start/end defined, they will override any left/right
4153             // values defined. Otherwise, left /right values are used.
4154             // Padding from the background drawable is stored at this point in mUserPaddingLeftInitial
4155             // and mUserPaddingRightInitial) so drawable padding will be used as ultimate default if
4156             // defined.
4157             final boolean hasRelativePadding = startPaddingDefined || endPaddingDefined;
4158
4159             if (mLeftPaddingDefined && !hasRelativePadding) {
4160                 mUserPaddingLeftInitial = leftPadding;
4161             }
4162             if (mRightPaddingDefined && !hasRelativePadding) {
4163                 mUserPaddingRightInitial = rightPadding;
4164             }
4165         }
4166
4167         internalSetPadding(
4168                 mUserPaddingLeftInitial,
4169                 topPadding >= 0 ? topPadding : mPaddingTop,
4170                 mUserPaddingRightInitial,
4171                 bottomPadding >= 0 ? bottomPadding : mPaddingBottom);
4172
4173         if (viewFlagMasks != 0) {
4174             setFlags(viewFlagValues, viewFlagMasks);
4175         }
4176
4177         if (initializeScrollbars) {
4178             initializeScrollbarsInternal(a);
4179         }
4180
4181         a.recycle();
4182
4183         // Needs to be called after mViewFlags is set
4184         if (scrollbarStyle != SCROLLBARS_INSIDE_OVERLAY) {
4185             recomputePadding();
4186         }
4187
4188         if (x != 0 || y != 0) {
4189             scrollTo(x, y);
4190         }
4191
4192         if (transformSet) {
4193             setTranslationX(tx);
4194             setTranslationY(ty);
4195             setTranslationZ(tz);
4196             setElevation(elevation);
4197             setRotation(rotation);
4198             setRotationX(rotationX);
4199             setRotationY(rotationY);
4200             setScaleX(sx);
4201             setScaleY(sy);
4202         }
4203
4204         if (!setScrollContainer && (viewFlagValues&SCROLLBARS_VERTICAL) != 0) {
4205             setScrollContainer(true);
4206         }
4207
4208         computeOpaqueFlags();
4209     }
4210
4211     /**
4212      * An implementation of OnClickListener that attempts to lazily load a
4213      * named click handling method from a parent or ancestor context.
4214      */
4215     private static class DeclaredOnClickListener implements OnClickListener {
4216         private final View mHostView;
4217         private final String mMethodName;
4218
4219         private Method mMethod;
4220
4221         public DeclaredOnClickListener(@NonNull View hostView, @NonNull String methodName) {
4222             mHostView = hostView;
4223             mMethodName = methodName;
4224         }
4225
4226         @Override
4227         public void onClick(@NonNull View v) {
4228             if (mMethod == null) {
4229                 mMethod = resolveMethod(mHostView.getContext(), mMethodName);
4230             }
4231
4232             try {
4233                 mMethod.invoke(mHostView.getContext(), v);
4234             } catch (IllegalAccessException e) {
4235                 throw new IllegalStateException(
4236                         "Could not execute non-public method for android:onClick", e);
4237             } catch (InvocationTargetException e) {
4238                 throw new IllegalStateException(
4239                         "Could not execute method for android:onClick", e);
4240             }
4241         }
4242
4243         @NonNull
4244         private Method resolveMethod(@Nullable Context context, @NonNull String name) {
4245             while (context != null) {
4246                 try {
4247                     if (!context.isRestricted()) {
4248                         return context.getClass().getMethod(mMethodName, View.class);
4249                     }
4250                 } catch (NoSuchMethodException e) {
4251                     // Failed to find method, keep searching up the hierarchy.
4252                 }
4253
4254                 if (context instanceof ContextWrapper) {
4255                     context = ((ContextWrapper) context).getBaseContext();
4256                 } else {
4257                     // Can't search up the hierarchy, null out and fail.
4258                     context = null;
4259                 }
4260             }
4261
4262             final int id = mHostView.getId();
4263             final String idText = id == NO_ID ? "" : " with id '"
4264                     + mHostView.getContext().getResources().getResourceEntryName(id) + "'";
4265             throw new IllegalStateException("Could not find method " + mMethodName
4266                     + "(View) in a parent or ancestor Context for android:onClick "
4267                     + "attribute defined on view " + mHostView.getClass() + idText);
4268         }
4269     }
4270
4271     /**
4272      * Non-public constructor for use in testing
4273      */
4274     View() {
4275         mResources = null;
4276         mRenderNode = RenderNode.create(getClass().getName(), this);
4277     }
4278
4279     private static SparseArray<String> getAttributeMap() {
4280         if (mAttributeMap == null) {
4281             mAttributeMap = new SparseArray<String>();
4282         }
4283         return mAttributeMap;
4284     }
4285
4286     private void saveAttributeData(AttributeSet attrs, TypedArray a) {
4287         int length = ((attrs == null ? 0 : attrs.getAttributeCount()) + a.getIndexCount()) * 2;
4288         mAttributes = new String[length];
4289
4290         int i = 0;
4291         if (attrs != null) {
4292             for (i = 0; i < attrs.getAttributeCount(); i += 2) {
4293                 mAttributes[i] = attrs.getAttributeName(i);
4294                 mAttributes[i + 1] = attrs.getAttributeValue(i);
4295             }
4296
4297         }
4298
4299         SparseArray<String> attributeMap = getAttributeMap();
4300         for (int j = 0; j < a.length(); ++j) {
4301             if (a.hasValue(j)) {
4302                 try {
4303                     int resourceId = a.getResourceId(j, 0);
4304                     if (resourceId == 0) {
4305                         continue;
4306                     }
4307
4308                     String resourceName = attributeMap.get(resourceId);
4309                     if (resourceName == null) {
4310                         resourceName = a.getResources().getResourceName(resourceId);
4311                         attributeMap.put(resourceId, resourceName);
4312                     }
4313
4314                     mAttributes[i] = resourceName;
4315                     mAttributes[i + 1] = a.getText(j).toString();
4316                     i += 2;
4317                 } catch (Resources.NotFoundException e) {
4318                     // if we can't get the resource name, we just ignore it
4319                 }
4320             }
4321         }
4322     }
4323
4324     public String toString() {
4325         StringBuilder out = new StringBuilder(128);
4326         out.append(getClass().getName());
4327         out.append('{');
4328         out.append(Integer.toHexString(System.identityHashCode(this)));
4329         out.append(' ');
4330         switch (mViewFlags&VISIBILITY_MASK) {
4331             case VISIBLE: out.append('V'); break;
4332             case INVISIBLE: out.append('I'); break;
4333             case GONE: out.append('G'); break;
4334             default: out.append('.'); break;
4335         }
4336         out.append((mViewFlags&FOCUSABLE_MASK) == FOCUSABLE ? 'F' : '.');
4337         out.append((mViewFlags&ENABLED_MASK) == ENABLED ? 'E' : '.');
4338         out.append((mViewFlags&DRAW_MASK) == WILL_NOT_DRAW ? '.' : 'D');
4339         out.append((mViewFlags&SCROLLBARS_HORIZONTAL) != 0 ? 'H' : '.');
4340         out.append((mViewFlags&SCROLLBARS_VERTICAL) != 0 ? 'V' : '.');
4341         out.append((mViewFlags&CLICKABLE) != 0 ? 'C' : '.');
4342         out.append((mViewFlags&LONG_CLICKABLE) != 0 ? 'L' : '.');
4343         out.append(' ');
4344         out.append((mPrivateFlags&PFLAG_IS_ROOT_NAMESPACE) != 0 ? 'R' : '.');
4345         out.append((mPrivateFlags&PFLAG_FOCUSED) != 0 ? 'F' : '.');
4346         out.append((mPrivateFlags&PFLAG_SELECTED) != 0 ? 'S' : '.');
4347         if ((mPrivateFlags&PFLAG_PREPRESSED) != 0) {
4348             out.append('p');
4349         } else {
4350             out.append((mPrivateFlags&PFLAG_PRESSED) != 0 ? 'P' : '.');
4351         }
4352         out.append((mPrivateFlags&PFLAG_HOVERED) != 0 ? 'H' : '.');
4353         out.append((mPrivateFlags&PFLAG_ACTIVATED) != 0 ? 'A' : '.');
4354         out.append((mPrivateFlags&PFLAG_INVALIDATED) != 0 ? 'I' : '.');
4355         out.append((mPrivateFlags&PFLAG_DIRTY_MASK) != 0 ? 'D' : '.');
4356         out.append(' ');
4357         out.append(mLeft);
4358         out.append(',');
4359         out.append(mTop);
4360         out.append('-');
4361         out.append(mRight);
4362         out.append(',');
4363         out.append(mBottom);
4364         final int id = getId();
4365         if (id != NO_ID) {
4366             out.append(" #");
4367             out.append(Integer.toHexString(id));
4368             final Resources r = mResources;
4369             if (Resources.resourceHasPackage(id) && r != null) {
4370                 try {
4371                     String pkgname;
4372                     switch (id&0xff000000) {
4373                         case 0x7f000000:
4374                             pkgname="app";
4375                             break;
4376                         case 0x01000000:
4377                             pkgname="android";
4378                             break;
4379                         default:
4380                             pkgname = r.getResourcePackageName(id);
4381                             break;
4382                     }
4383                     String typename = r.getResourceTypeName(id);
4384                     String entryname = r.getResourceEntryName(id);
4385                     out.append(" ");
4386                     out.append(pkgname);
4387                     out.append(":");
4388                     out.append(typename);
4389                     out.append("/");
4390                     out.append(entryname);
4391                 } catch (Resources.NotFoundException e) {
4392                 }
4393             }
4394         }
4395         out.append("}");
4396         return out.toString();
4397     }
4398
4399     /**
4400      * <p>
4401      * Initializes the fading edges from a given set of styled attributes. This
4402      * method should be called by subclasses that need fading edges and when an
4403      * instance of these subclasses is created programmatically rather than
4404      * being inflated from XML. This method is automatically called when the XML
4405      * is inflated.
4406      * </p>
4407      *
4408      * @param a the styled attributes set to initialize the fading edges from
4409      *
4410      * @removed
4411      */
4412     protected void initializeFadingEdge(TypedArray a) {
4413         // This method probably shouldn't have been included in the SDK to begin with.
4414         // It relies on 'a' having been initialized using an attribute filter array that is
4415         // not publicly available to the SDK. The old method has been renamed
4416         // to initializeFadingEdgeInternal and hidden for framework use only;
4417         // this one initializes using defaults to make it safe to call for apps.
4418
4419         TypedArray arr = mContext.obtainStyledAttributes(com.android.internal.R.styleable.View);
4420
4421         initializeFadingEdgeInternal(arr);
4422
4423         arr.recycle();
4424     }
4425
4426     /**
4427      * <p>
4428      * Initializes the fading edges from a given set of styled attributes. This
4429      * method should be called by subclasses that need fading edges and when an
4430      * instance of these subclasses is created programmatically rather than
4431      * being inflated from XML. This method is automatically called when the XML
4432      * is inflated.
4433      * </p>
4434      *
4435      * @param a the styled attributes set to initialize the fading edges from
4436      * @hide This is the real method; the public one is shimmed to be safe to call from apps.
4437      */
4438     protected void initializeFadingEdgeInternal(TypedArray a) {
4439         initScrollCache();
4440
4441         mScrollCache.fadingEdgeLength = a.getDimensionPixelSize(
4442                 R.styleable.View_fadingEdgeLength,
4443                 ViewConfiguration.get(mContext).getScaledFadingEdgeLength());
4444     }
4445
4446     /**
4447      * Returns the size of the vertical faded edges used to indicate that more
4448      * content in this view is visible.
4449      *
4450      * @return The size in pixels of the vertical faded edge or 0 if vertical
4451      *         faded edges are not enabled for this view.
4452      * @attr ref android.R.styleable#View_fadingEdgeLength
4453      */
4454     public int getVerticalFadingEdgeLength() {
4455         if (isVerticalFadingEdgeEnabled()) {
4456             ScrollabilityCache cache = mScrollCache;
4457             if (cache != null) {
4458                 return cache.fadingEdgeLength;
4459             }
4460         }
4461         return 0;
4462     }
4463
4464     /**
4465      * Set the size of the faded edge used to indicate that more content in this
4466      * view is available.  Will not change whether the fading edge is enabled; use
4467      * {@link #setVerticalFadingEdgeEnabled(boolean)} or
4468      * {@link #setHorizontalFadingEdgeEnabled(boolean)} to enable the fading edge
4469      * for the vertical or horizontal fading edges.
4470      *
4471      * @param length The size in pixels of the faded edge used to indicate that more
4472      *        content in this view is visible.
4473      */
4474     public void setFadingEdgeLength(int length) {
4475         initScrollCache();
4476         mScrollCache.fadingEdgeLength = length;
4477     }
4478
4479     /**
4480      * Returns the size of the horizontal faded edges used to indicate that more
4481      * content in this view is visible.
4482      *
4483      * @return The size in pixels of the horizontal faded edge or 0 if horizontal
4484      *         faded edges are not enabled for this view.
4485      * @attr ref android.R.styleable#View_fadingEdgeLength
4486      */
4487     public int getHorizontalFadingEdgeLength() {
4488         if (isHorizontalFadingEdgeEnabled()) {
4489             ScrollabilityCache cache = mScrollCache;
4490             if (cache != null) {
4491                 return cache.fadingEdgeLength;
4492             }
4493         }
4494         return 0;
4495     }
4496
4497     /**
4498      * Returns the width of the vertical scrollbar.
4499      *
4500      * @return The width in pixels of the vertical scrollbar or 0 if there
4501      *         is no vertical scrollbar.
4502      */
4503     public int getVerticalScrollbarWidth() {
4504         ScrollabilityCache cache = mScrollCache;
4505         if (cache != null) {
4506             ScrollBarDrawable scrollBar = cache.scrollBar;
4507             if (scrollBar != null) {
4508                 int size = scrollBar.getSize(true);
4509                 if (size <= 0) {
4510                     size = cache.scrollBarSize;
4511                 }
4512                 return size;
4513             }
4514             return 0;
4515         }
4516         return 0;
4517     }
4518
4519     /**
4520      * Returns the height of the horizontal scrollbar.
4521      *
4522      * @return The height in pixels of the horizontal scrollbar or 0 if
4523      *         there is no horizontal scrollbar.
4524      */
4525     protected int getHorizontalScrollbarHeight() {
4526         ScrollabilityCache cache = mScrollCache;
4527         if (cache != null) {
4528             ScrollBarDrawable scrollBar = cache.scrollBar;
4529             if (scrollBar != null) {
4530                 int size = scrollBar.getSize(false);
4531                 if (size <= 0) {
4532                     size = cache.scrollBarSize;
4533                 }
4534                 return size;
4535             }
4536             return 0;
4537         }
4538         return 0;
4539     }
4540
4541     /**
4542      * <p>
4543      * Initializes the scrollbars from a given set of styled attributes. This
4544      * method should be called by subclasses that need scrollbars and when an
4545      * instance of these subclasses is created programmatically rather than
4546      * being inflated from XML. This method is automatically called when the XML
4547      * is inflated.
4548      * </p>
4549      *
4550      * @param a the styled attributes set to initialize the scrollbars from
4551      *
4552      * @removed
4553      */
4554     protected void initializeScrollbars(TypedArray a) {
4555         // It's not safe to use this method from apps. The parameter 'a' must have been obtained
4556         // using the View filter array which is not available to the SDK. As such, internal
4557         // framework usage now uses initializeScrollbarsInternal and we grab a default
4558         // TypedArray with the right filter instead here.
4559         TypedArray arr = mContext.obtainStyledAttributes(com.android.internal.R.styleable.View);
4560
4561         initializeScrollbarsInternal(arr);
4562
4563         // We ignored the method parameter. Recycle the one we actually did use.
4564         arr.recycle();
4565     }
4566
4567     /**
4568      * <p>
4569      * Initializes the scrollbars from a given set of styled attributes. This
4570      * method should be called by subclasses that need scrollbars and when an
4571      * instance of these subclasses is created programmatically rather than
4572      * being inflated from XML. This method is automatically called when the XML
4573      * is inflated.
4574      * </p>
4575      *
4576      * @param a the styled attributes set to initialize the scrollbars from
4577      * @hide
4578      */
4579     protected void initializeScrollbarsInternal(TypedArray a) {
4580         initScrollCache();
4581
4582         final ScrollabilityCache scrollabilityCache = mScrollCache;
4583
4584         if (scrollabilityCache.scrollBar == null) {
4585             scrollabilityCache.scrollBar = new ScrollBarDrawable();
4586             scrollabilityCache.scrollBar.setCallback(this);
4587             scrollabilityCache.scrollBar.setState(getDrawableState());
4588         }
4589
4590         final boolean fadeScrollbars = a.getBoolean(R.styleable.View_fadeScrollbars, true);
4591
4592         if (!fadeScrollbars) {
4593             scrollabilityCache.state = ScrollabilityCache.ON;
4594         }
4595         scrollabilityCache.fadeScrollBars = fadeScrollbars;
4596
4597
4598         scrollabilityCache.scrollBarFadeDuration = a.getInt(
4599                 R.styleable.View_scrollbarFadeDuration, ViewConfiguration
4600                         .getScrollBarFadeDuration());
4601         scrollabilityCache.scrollBarDefaultDelayBeforeFade = a.getInt(
4602                 R.styleable.View_scrollbarDefaultDelayBeforeFade,
4603                 ViewConfiguration.getScrollDefaultDelay());
4604
4605
4606         scrollabilityCache.scrollBarSize = a.getDimensionPixelSize(
4607                 com.android.internal.R.styleable.View_scrollbarSize,
4608                 ViewConfiguration.get(mContext).getScaledScrollBarSize());
4609
4610         Drawable track = a.getDrawable(R.styleable.View_scrollbarTrackHorizontal);
4611         scrollabilityCache.scrollBar.setHorizontalTrackDrawable(track);
4612
4613         Drawable thumb = a.getDrawable(R.styleable.View_scrollbarThumbHorizontal);
4614         if (thumb != null) {
4615             scrollabilityCache.scrollBar.setHorizontalThumbDrawable(thumb);
4616         }
4617
4618         boolean alwaysDraw = a.getBoolean(R.styleable.View_scrollbarAlwaysDrawHorizontalTrack,
4619                 false);
4620         if (alwaysDraw) {
4621             scrollabilityCache.scrollBar.setAlwaysDrawHorizontalTrack(true);
4622         }
4623
4624         track = a.getDrawable(R.styleable.View_scrollbarTrackVertical);
4625         scrollabilityCache.scrollBar.setVerticalTrackDrawable(track);
4626
4627         thumb = a.getDrawable(R.styleable.View_scrollbarThumbVertical);
4628         if (thumb != null) {
4629             scrollabilityCache.scrollBar.setVerticalThumbDrawable(thumb);
4630         }
4631
4632         alwaysDraw = a.getBoolean(R.styleable.View_scrollbarAlwaysDrawVerticalTrack,
4633                 false);
4634         if (alwaysDraw) {
4635             scrollabilityCache.scrollBar.setAlwaysDrawVerticalTrack(true);
4636         }
4637
4638         // Apply layout direction to the new Drawables if needed
4639         final int layoutDirection = getLayoutDirection();
4640         if (track != null) {
4641             track.setLayoutDirection(layoutDirection);
4642         }
4643         if (thumb != null) {
4644             thumb.setLayoutDirection(layoutDirection);
4645         }
4646
4647         // Re-apply user/background padding so that scrollbar(s) get added
4648         resolvePadding();
4649     }
4650
4651     /**
4652      * <p>
4653      * Initalizes the scrollability cache if necessary.
4654      * </p>
4655      */
4656     private void initScrollCache() {
4657         if (mScrollCache == null) {
4658             mScrollCache = new ScrollabilityCache(ViewConfiguration.get(mContext), this);
4659         }
4660     }
4661
4662     private ScrollabilityCache getScrollCache() {
4663         initScrollCache();
4664         return mScrollCache;
4665     }
4666
4667     /**
4668      * Set the position of the vertical scroll bar. Should be one of
4669      * {@link #SCROLLBAR_POSITION_DEFAULT}, {@link #SCROLLBAR_POSITION_LEFT} or
4670      * {@link #SCROLLBAR_POSITION_RIGHT}.
4671      *
4672      * @param position Where the vertical scroll bar should be positioned.
4673      */
4674     public void setVerticalScrollbarPosition(int position) {
4675         if (mVerticalScrollbarPosition != position) {
4676             mVerticalScrollbarPosition = position;
4677             computeOpaqueFlags();
4678             resolvePadding();
4679         }
4680     }
4681
4682     /**
4683      * @return The position where the vertical scroll bar will show, if applicable.
4684      * @see #setVerticalScrollbarPosition(int)
4685      */
4686     public int getVerticalScrollbarPosition() {
4687         return mVerticalScrollbarPosition;
4688     }
4689
4690     ListenerInfo getListenerInfo() {
4691         if (mListenerInfo != null) {
4692             return mListenerInfo;
4693         }
4694         mListenerInfo = new ListenerInfo();
4695         return mListenerInfo;
4696     }
4697
4698     /**
4699      * Register a callback to be invoked when the scroll X or Y positions of
4700      * this view change.
4701      * <p>
4702      * <b>Note:</b> Some views handle scrolling independently from View and may
4703      * have their own separate listeners for scroll-type events. For example,
4704      * {@link android.widget.ListView ListView} allows clients to register an
4705      * {@link android.widget.ListView#setOnScrollListener(android.widget.AbsListView.OnScrollListener) AbsListView.OnScrollListener}
4706      * to listen for changes in list scroll position.
4707      *
4708      * @param l The listener to notify when the scroll X or Y position changes.
4709      * @see android.view.View#getScrollX()
4710      * @see android.view.View#getScrollY()
4711      */
4712     public void setOnScrollChangeListener(OnScrollChangeListener l) {
4713         getListenerInfo().mOnScrollChangeListener = l;
4714     }
4715
4716     /**
4717      * Register a callback to be invoked when focus of this view changed.
4718      *
4719      * @param l The callback that will run.
4720      */
4721     public void setOnFocusChangeListener(OnFocusChangeListener l) {
4722         getListenerInfo().mOnFocusChangeListener = l;
4723     }
4724
4725     /**
4726      * Add a listener that will be called when the bounds of the view change due to
4727      * layout processing.
4728      *
4729      * @param listener The listener that will be called when layout bounds change.
4730      */
4731     public void addOnLayoutChangeListener(OnLayoutChangeListener listener) {
4732         ListenerInfo li = getListenerInfo();
4733         if (li.mOnLayoutChangeListeners == null) {
4734             li.mOnLayoutChangeListeners = new ArrayList<OnLayoutChangeListener>();
4735         }
4736         if (!li.mOnLayoutChangeListeners.contains(listener)) {
4737             li.mOnLayoutChangeListeners.add(listener);
4738         }
4739     }
4740
4741     /**
4742      * Remove a listener for layout changes.
4743      *
4744      * @param listener The listener for layout bounds change.
4745      */
4746     public void removeOnLayoutChangeListener(OnLayoutChangeListener listener) {
4747         ListenerInfo li = mListenerInfo;
4748         if (li == null || li.mOnLayoutChangeListeners == null) {
4749             return;
4750         }
4751         li.mOnLayoutChangeListeners.remove(listener);
4752     }
4753
4754     /**
4755      * Add a listener for attach state changes.
4756      *
4757      * This listener will be called whenever this view is attached or detached
4758      * from a window. Remove the listener using
4759      * {@link #removeOnAttachStateChangeListener(OnAttachStateChangeListener)}.
4760      *
4761      * @param listener Listener to attach
4762      * @see #removeOnAttachStateChangeListener(OnAttachStateChangeListener)
4763      */
4764     public void addOnAttachStateChangeListener(OnAttachStateChangeListener listener) {
4765         ListenerInfo li = getListenerInfo();
4766         if (li.mOnAttachStateChangeListeners == null) {
4767             li.mOnAttachStateChangeListeners
4768                     = new CopyOnWriteArrayList<OnAttachStateChangeListener>();
4769         }
4770         li.mOnAttachStateChangeListeners.add(listener);
4771     }
4772
4773     /**
4774      * Remove a listener for attach state changes. The listener will receive no further
4775      * notification of window attach/detach events.
4776      *
4777      * @param listener Listener to remove
4778      * @see #addOnAttachStateChangeListener(OnAttachStateChangeListener)
4779      */
4780     public void removeOnAttachStateChangeListener(OnAttachStateChangeListener listener) {
4781         ListenerInfo li = mListenerInfo;
4782         if (li == null || li.mOnAttachStateChangeListeners == null) {
4783             return;
4784         }
4785         li.mOnAttachStateChangeListeners.remove(listener);
4786     }
4787
4788     /**
4789      * Returns the focus-change callback registered for this view.
4790      *
4791      * @return The callback, or null if one is not registered.
4792      */
4793     public OnFocusChangeListener getOnFocusChangeListener() {
4794         ListenerInfo li = mListenerInfo;
4795         return li != null ? li.mOnFocusChangeListener : null;
4796     }
4797
4798     /**
4799      * Register a callback to be invoked when this view is clicked. If this view is not
4800      * clickable, it becomes clickable.
4801      *
4802      * @param l The callback that will run
4803      *
4804      * @see #setClickable(boolean)
4805      */
4806     public void setOnClickListener(@Nullable OnClickListener l) {
4807         if (!isClickable()) {
4808             setClickable(true);
4809         }
4810         getListenerInfo().mOnClickListener = l;
4811     }
4812
4813     /**
4814      * Return whether this view has an attached OnClickListener.  Returns
4815      * true if there is a listener, false if there is none.
4816      */
4817     public boolean hasOnClickListeners() {
4818         ListenerInfo li = mListenerInfo;
4819         return (li != null && li.mOnClickListener != null);
4820     }
4821
4822     /**
4823      * Register a callback to be invoked when this view is clicked and held. If this view is not
4824      * long clickable, it becomes long clickable.
4825      *
4826      * @param l The callback that will run
4827      *
4828      * @see #setLongClickable(boolean)
4829      */
4830     public void setOnLongClickListener(@Nullable OnLongClickListener l) {
4831         if (!isLongClickable()) {
4832             setLongClickable(true);
4833         }
4834         getListenerInfo().mOnLongClickListener = l;
4835     }
4836
4837     /**
4838      * Register a callback to be invoked when the context menu for this view is
4839      * being built. If this view is not long clickable, it becomes long clickable.
4840      *
4841      * @param l The callback that will run
4842      *
4843      */
4844     public void setOnCreateContextMenuListener(OnCreateContextMenuListener l) {
4845         if (!isLongClickable()) {
4846             setLongClickable(true);
4847         }
4848         getListenerInfo().mOnCreateContextMenuListener = l;
4849     }
4850
4851     /**
4852      * Call this view's OnClickListener, if it is defined.  Performs all normal
4853      * actions associated with clicking: reporting accessibility event, playing
4854      * a sound, etc.
4855      *
4856      * @return True there was an assigned OnClickListener that was called, false
4857      *         otherwise is returned.
4858      */
4859     public boolean performClick() {
4860         final boolean result;
4861         final ListenerInfo li = mListenerInfo;
4862         if (li != null && li.mOnClickListener != null) {
4863             playSoundEffect(SoundEffectConstants.CLICK);
4864             li.mOnClickListener.onClick(this);
4865             result = true;
4866         } else {
4867             result = false;
4868         }
4869
4870         sendAccessibilityEvent(AccessibilityEvent.TYPE_VIEW_CLICKED);
4871         return result;
4872     }
4873
4874     /**
4875      * Directly call any attached OnClickListener.  Unlike {@link #performClick()},
4876      * this only calls the listener, and does not do any associated clicking
4877      * actions like reporting an accessibility event.
4878      *
4879      * @return True there was an assigned OnClickListener that was called, false
4880      *         otherwise is returned.
4881      */
4882     public boolean callOnClick() {
4883         ListenerInfo li = mListenerInfo;
4884         if (li != null && li.mOnClickListener != null) {
4885             li.mOnClickListener.onClick(this);
4886             return true;
4887         }
4888         return false;
4889     }
4890
4891     /**
4892      * Call this view's OnLongClickListener, if it is defined. Invokes the context menu if the
4893      * OnLongClickListener did not consume the event.
4894      *
4895      * @return True if one of the above receivers consumed the event, false otherwise.
4896      */
4897     public boolean performLongClick() {
4898         sendAccessibilityEvent(AccessibilityEvent.TYPE_VIEW_LONG_CLICKED);
4899
4900         boolean handled = false;
4901         ListenerInfo li = mListenerInfo;
4902         if (li != null && li.mOnLongClickListener != null) {
4903             handled = li.mOnLongClickListener.onLongClick(View.this);
4904         }
4905         if (!handled) {
4906             handled = showContextMenu();
4907         }
4908         if (handled) {
4909             performHapticFeedback(HapticFeedbackConstants.LONG_PRESS);
4910         }
4911         return handled;
4912     }
4913
4914     /**
4915      * Performs button-related actions during a touch down event.
4916      *
4917      * @param event The event.
4918      * @return True if the down was consumed.
4919      *
4920      * @hide
4921      */
4922     protected boolean performButtonActionOnTouchDown(MotionEvent event) {
4923         if (event.getToolType(0) == MotionEvent.TOOL_TYPE_MOUSE &&
4924             (event.getButtonState() & MotionEvent.BUTTON_SECONDARY) != 0) {
4925             showContextMenu(event.getX(), event.getY(), event.getMetaState());
4926             mPrivateFlags |= PFLAG_CANCEL_NEXT_UP_EVENT;
4927             return true;
4928         }
4929         return false;
4930     }
4931
4932     /**
4933      * Bring up the context menu for this view.
4934      *
4935      * @return Whether a context menu was displayed.
4936      */
4937     public boolean showContextMenu() {
4938         return getParent().showContextMenuForChild(this);
4939     }
4940
4941     /**
4942      * Bring up the context menu for this view, referring to the item under the specified point.
4943      *
4944      * @param x The referenced x coordinate.
4945      * @param y The referenced y coordinate.
4946      * @param metaState The keyboard modifiers that were pressed.
4947      * @return Whether a context menu was displayed.
4948      *
4949      * @hide
4950      */
4951     public boolean showContextMenu(float x, float y, int metaState) {
4952         return showContextMenu();
4953     }
4954
4955     /**
4956      * Start an action mode with the default type {@link ActionMode#TYPE_PRIMARY}.
4957      *
4958      * @param callback Callback that will control the lifecycle of the action mode
4959      * @return The new action mode if it is started, null otherwise
4960      *
4961      * @see ActionMode
4962      * @see #startActionMode(android.view.ActionMode.Callback, int)
4963      */
4964     public ActionMode startActionMode(ActionMode.Callback callback) {
4965         return startActionMode(callback, ActionMode.TYPE_PRIMARY);
4966     }
4967
4968     /**
4969      * Start an action mode with the given type.
4970      *
4971      * @param callback Callback that will control the lifecycle of the action mode
4972      * @param type One of {@link ActionMode#TYPE_PRIMARY} or {@link ActionMode#TYPE_FLOATING}.
4973      * @return The new action mode if it is started, null otherwise
4974      *
4975      * @see ActionMode
4976      */
4977     public ActionMode startActionMode(ActionMode.Callback callback, int type) {
4978         ViewParent parent = getParent();
4979         if (parent == null) return null;
4980         try {
4981             return parent.startActionModeForChild(this, callback, type);
4982         } catch (AbstractMethodError ame) {
4983             // Older implementations of custom views might not implement this.
4984             return parent.startActionModeForChild(this, callback);
4985         }
4986     }
4987
4988     /**
4989      * Call {@link Context#startActivityForResult(String, Intent, int, Bundle)} for the View's
4990      * Context, creating a unique View identifier to retrieve the result.
4991      *
4992      * @param intent The Intent to be started.
4993      * @param requestCode The request code to use.
4994      * @hide
4995      */
4996     public void startActivityForResult(Intent intent, int requestCode) {
4997         mStartActivityRequestWho = "@android:view:" + System.identityHashCode(this);
4998         getContext().startActivityForResult(mStartActivityRequestWho, intent, requestCode, null);
4999     }
5000
5001     /**
5002      * If this View corresponds to the calling who, dispatches the activity result.
5003      * @param who The identifier for the targeted View to receive the result.
5004      * @param requestCode The integer request code originally supplied to
5005      *                    startActivityForResult(), allowing you to identify who this
5006      *                    result came from.
5007      * @param resultCode The integer result code returned by the child activity
5008      *                   through its setResult().
5009      * @param data An Intent, which can return result data to the caller
5010      *               (various data can be attached to Intent "extras").
5011      * @return {@code true} if the activity result was dispatched.
5012      * @hide
5013      */
5014     public boolean dispatchActivityResult(
5015             String who, int requestCode, int resultCode, Intent data) {
5016         if (mStartActivityRequestWho != null && mStartActivityRequestWho.equals(who)) {
5017             onActivityResult(requestCode, resultCode, data);
5018             mStartActivityRequestWho = null;
5019             return true;
5020         }
5021         return false;
5022     }
5023
5024     /**
5025      * Receive the result from a previous call to {@link #startActivityForResult(Intent, int)}.
5026      *
5027      * @param requestCode The integer request code originally supplied to
5028      *                    startActivityForResult(), allowing you to identify who this
5029      *                    result came from.
5030      * @param resultCode The integer result code returned by the child activity
5031      *                   through its setResult().
5032      * @param data An Intent, which can return result data to the caller
5033      *               (various data can be attached to Intent "extras").
5034      * @hide
5035      */
5036     public void onActivityResult(int requestCode, int resultCode, Intent data) {
5037         // Do nothing.
5038     }
5039
5040     /**
5041      * Register a callback to be invoked when a hardware key is pressed in this view.
5042      * Key presses in software input methods will generally not trigger the methods of
5043      * this listener.
5044      * @param l the key listener to attach to this view
5045      */
5046     public void setOnKeyListener(OnKeyListener l) {
5047         getListenerInfo().mOnKeyListener = l;
5048     }
5049
5050     /**
5051      * Register a callback to be invoked when a touch event is sent to this view.
5052      * @param l the touch listener to attach to this view
5053      */
5054     public void setOnTouchListener(OnTouchListener l) {
5055         getListenerInfo().mOnTouchListener = l;
5056     }
5057
5058     /**
5059      * Register a callback to be invoked when a generic motion event is sent to this view.
5060      * @param l the generic motion listener to attach to this view
5061      */
5062     public void setOnGenericMotionListener(OnGenericMotionListener l) {
5063         getListenerInfo().mOnGenericMotionListener = l;
5064     }
5065
5066     /**
5067      * Register a callback to be invoked when a hover event is sent to this view.
5068      * @param l the hover listener to attach to this view
5069      */
5070     public void setOnHoverListener(OnHoverListener l) {
5071         getListenerInfo().mOnHoverListener = l;
5072     }
5073
5074     /**
5075      * Register a drag event listener callback object for this View. The parameter is
5076      * an implementation of {@link android.view.View.OnDragListener}. To send a drag event to a
5077      * View, the system calls the
5078      * {@link android.view.View.OnDragListener#onDrag(View,DragEvent)} method.
5079      * @param l An implementation of {@link android.view.View.OnDragListener}.
5080      */
5081     public void setOnDragListener(OnDragListener l) {
5082         getListenerInfo().mOnDragListener = l;
5083     }
5084
5085     /**
5086      * Give this view focus. This will cause
5087      * {@link #onFocusChanged(boolean, int, android.graphics.Rect)} to be called.
5088      *
5089      * Note: this does not check whether this {@link View} should get focus, it just
5090      * gives it focus no matter what.  It should only be called internally by framework
5091      * code that knows what it is doing, namely {@link #requestFocus(int, Rect)}.
5092      *
5093      * @param direction values are {@link View#FOCUS_UP}, {@link View#FOCUS_DOWN},
5094      *        {@link View#FOCUS_LEFT} or {@link View#FOCUS_RIGHT}. This is the direction which
5095      *        focus moved when requestFocus() is called. It may not always
5096      *        apply, in which case use the default View.FOCUS_DOWN.
5097      * @param previouslyFocusedRect The rectangle of the view that had focus
5098      *        prior in this View's coordinate system.
5099      */
5100     void handleFocusGainInternal(@FocusRealDirection int direction, Rect previouslyFocusedRect) {
5101         if (DBG) {
5102             System.out.println(this + " requestFocus()");
5103         }
5104
5105         if ((mPrivateFlags & PFLAG_FOCUSED) == 0) {
5106             mPrivateFlags |= PFLAG_FOCUSED;
5107
5108             View oldFocus = (mAttachInfo != null) ? getRootView().findFocus() : null;
5109
5110             if (mParent != null) {
5111                 mParent.requestChildFocus(this, this);
5112             }
5113
5114             if (mAttachInfo != null) {
5115                 mAttachInfo.mTreeObserver.dispatchOnGlobalFocusChange(oldFocus, this);
5116             }
5117
5118             onFocusChanged(true, direction, previouslyFocusedRect);
5119             refreshDrawableState();
5120         }
5121     }
5122
5123     /**
5124      * Populates <code>outRect</code> with the hotspot bounds. By default,
5125      * the hotspot bounds are identical to the screen bounds.
5126      *
5127      * @param outRect rect to populate with hotspot bounds
5128      * @hide Only for internal use by views and widgets.
5129      */
5130     public void getHotspotBounds(Rect outRect) {
5131         final Drawable background = getBackground();
5132         if (background != null) {
5133             background.getHotspotBounds(outRect);
5134         } else {
5135             getBoundsOnScreen(outRect);
5136         }
5137     }
5138
5139     /**
5140      * Request that a rectangle of this view be visible on the screen,
5141      * scrolling if necessary just enough.
5142      *
5143      * <p>A View should call this if it maintains some notion of which part
5144      * of its content is interesting.  For example, a text editing view
5145      * should call this when its cursor moves.
5146      *
5147      * @param rectangle The rectangle.
5148      * @return Whether any parent scrolled.
5149      */
5150     public boolean requestRectangleOnScreen(Rect rectangle) {
5151         return requestRectangleOnScreen(rectangle, false);
5152     }
5153
5154     /**
5155      * Request that a rectangle of this view be visible on the screen,
5156      * scrolling if necessary just enough.
5157      *
5158      * <p>A View should call this if it maintains some notion of which part
5159      * of its content is interesting.  For example, a text editing view
5160      * should call this when its cursor moves.
5161      *
5162      * <p>When <code>immediate</code> is set to true, scrolling will not be
5163      * animated.
5164      *
5165      * @param rectangle The rectangle.
5166      * @param immediate True to forbid animated scrolling, false otherwise
5167      * @return Whether any parent scrolled.
5168      */
5169     public boolean requestRectangleOnScreen(Rect rectangle, boolean immediate) {
5170         if (mParent == null) {
5171             return false;
5172         }
5173
5174         View child = this;
5175
5176         RectF position = (mAttachInfo != null) ? mAttachInfo.mTmpTransformRect : new RectF();
5177         position.set(rectangle);
5178
5179         ViewParent parent = mParent;
5180         boolean scrolled = false;
5181         while (parent != null) {
5182             rectangle.set((int) position.left, (int) position.top,
5183                     (int) position.right, (int) position.bottom);
5184
5185             scrolled |= parent.requestChildRectangleOnScreen(child,
5186                     rectangle, immediate);
5187
5188             if (!child.hasIdentityMatrix()) {
5189                 child.getMatrix().mapRect(position);
5190             }
5191
5192             position.offset(child.mLeft, child.mTop);
5193
5194             if (!(parent instanceof View)) {
5195                 break;
5196             }
5197
5198             View parentView = (View) parent;
5199
5200             position.offset(-parentView.getScrollX(), -parentView.getScrollY());
5201
5202             child = parentView;
5203             parent = child.getParent();
5204         }
5205
5206         return scrolled;
5207     }
5208
5209     /**
5210      * Called when this view wants to give up focus. If focus is cleared
5211      * {@link #onFocusChanged(boolean, int, android.graphics.Rect)} is called.
5212      * <p>
5213      * <strong>Note:</strong> When a View clears focus the framework is trying
5214      * to give focus to the first focusable View from the top. Hence, if this
5215      * View is the first from the top that can take focus, then all callbacks
5216      * related to clearing focus will be invoked after which the framework will
5217      * give focus to this view.
5218      * </p>
5219      */
5220     public void clearFocus() {
5221         if (DBG) {
5222             System.out.println(this + " clearFocus()");
5223         }
5224
5225         clearFocusInternal(null, true, true);
5226     }
5227
5228     /**
5229      * Clears focus from the view, optionally propagating the change up through
5230      * the parent hierarchy and requesting that the root view place new focus.
5231      *
5232      * @param propagate whether to propagate the change up through the parent
5233      *            hierarchy
5234      * @param refocus when propagate is true, specifies whether to request the
5235      *            root view place new focus
5236      */
5237     void clearFocusInternal(View focused, boolean propagate, boolean refocus) {
5238         if ((mPrivateFlags & PFLAG_FOCUSED) != 0) {
5239             mPrivateFlags &= ~PFLAG_FOCUSED;
5240
5241             if (propagate && mParent != null) {
5242                 mParent.clearChildFocus(this);
5243             }
5244
5245             onFocusChanged(false, 0, null);
5246             refreshDrawableState();
5247
5248             if (propagate && (!refocus || !rootViewRequestFocus())) {
5249                 notifyGlobalFocusCleared(this);
5250             }
5251         }
5252     }
5253
5254     void notifyGlobalFocusCleared(View oldFocus) {
5255         if (oldFocus != null && mAttachInfo != null) {
5256             mAttachInfo.mTreeObserver.dispatchOnGlobalFocusChange(oldFocus, null);
5257         }
5258     }
5259
5260     boolean rootViewRequestFocus() {
5261         final View root = getRootView();
5262         return root != null && root.requestFocus();
5263     }
5264
5265     /**
5266      * Called internally by the view system when a new view is getting focus.
5267      * This is what clears the old focus.
5268      * <p>
5269      * <b>NOTE:</b> The parent view's focused child must be updated manually
5270      * after calling this method. Otherwise, the view hierarchy may be left in
5271      * an inconstent state.
5272      */
5273     void unFocus(View focused) {
5274         if (DBG) {
5275             System.out.println(this + " unFocus()");
5276         }
5277
5278         clearFocusInternal(focused, false, false);
5279     }
5280
5281     /**
5282      * Returns true if this view has focus itself, or is the ancestor of the
5283      * view that has focus.
5284      *
5285      * @return True if this view has or contains focus, false otherwise.
5286      */
5287     @ViewDebug.ExportedProperty(category = "focus")
5288     public boolean hasFocus() {
5289         return (mPrivateFlags & PFLAG_FOCUSED) != 0;
5290     }
5291
5292     /**
5293      * Returns true if this view is focusable or if it contains a reachable View
5294      * for which {@link #hasFocusable()} returns true. A "reachable hasFocusable()"
5295      * is a View whose parents do not block descendants focus.
5296      *
5297      * Only {@link #VISIBLE} views are considered focusable.
5298      *
5299      * @return True if the view is focusable or if the view contains a focusable
5300      *         View, false otherwise.
5301      *
5302      * @see ViewGroup#FOCUS_BLOCK_DESCENDANTS
5303      * @see ViewGroup#getTouchscreenBlocksFocus()
5304      */
5305     public boolean hasFocusable() {
5306         if (!isFocusableInTouchMode()) {
5307             for (ViewParent p = mParent; p instanceof ViewGroup; p = p.getParent()) {
5308                 final ViewGroup g = (ViewGroup) p;
5309                 if (g.shouldBlockFocusForTouchscreen()) {
5310                     return false;
5311                 }
5312             }
5313         }
5314         return (mViewFlags & VISIBILITY_MASK) == VISIBLE && isFocusable();
5315     }
5316
5317     /**
5318      * Called by the view system when the focus state of this view changes.
5319      * When the focus change event is caused by directional navigation, direction
5320      * and previouslyFocusedRect provide insight into where the focus is coming from.
5321      * When overriding, be sure to call up through to the super class so that
5322      * the standard focus handling will occur.
5323      *
5324      * @param gainFocus True if the View has focus; false otherwise.
5325      * @param direction The direction focus has moved when requestFocus()
5326      *                  is called to give this view focus. Values are
5327      *                  {@link #FOCUS_UP}, {@link #FOCUS_DOWN}, {@link #FOCUS_LEFT},
5328      *                  {@link #FOCUS_RIGHT}, {@link #FOCUS_FORWARD}, or {@link #FOCUS_BACKWARD}.
5329      *                  It may not always apply, in which case use the default.
5330      * @param previouslyFocusedRect The rectangle, in this view's coordinate
5331      *        system, of the previously focused view.  If applicable, this will be
5332      *        passed in as finer grained information about where the focus is coming
5333      *        from (in addition to direction).  Will be <code>null</code> otherwise.
5334      */
5335     @CallSuper
5336     protected void onFocusChanged(boolean gainFocus, @FocusDirection int direction,
5337             @Nullable Rect previouslyFocusedRect) {
5338         if (gainFocus) {
5339             sendAccessibilityEvent(AccessibilityEvent.TYPE_VIEW_FOCUSED);
5340         } else {
5341             notifyViewAccessibilityStateChangedIfNeeded(
5342                     AccessibilityEvent.CONTENT_CHANGE_TYPE_UNDEFINED);
5343         }
5344
5345         InputMethodManager imm = InputMethodManager.peekInstance();
5346         if (!gainFocus) {
5347             if (isPressed()) {
5348                 setPressed(false);
5349             }
5350             if (imm != null && mAttachInfo != null
5351                     && mAttachInfo.mHasWindowFocus) {
5352                 imm.focusOut(this);
5353             }
5354             onFocusLost();
5355         } else if (imm != null && mAttachInfo != null
5356                 && mAttachInfo.mHasWindowFocus) {
5357             imm.focusIn(this);
5358         }
5359
5360         invalidate(true);
5361         ListenerInfo li = mListenerInfo;
5362         if (li != null && li.mOnFocusChangeListener != null) {
5363             li.mOnFocusChangeListener.onFocusChange(this, gainFocus);
5364         }
5365
5366         if (mAttachInfo != null) {
5367             mAttachInfo.mKeyDispatchState.reset(this);
5368         }
5369     }
5370
5371     /**
5372      * Sends an accessibility event of the given type. If accessibility is
5373      * not enabled this method has no effect. The default implementation calls
5374      * {@link #onInitializeAccessibilityEvent(AccessibilityEvent)} first
5375      * to populate information about the event source (this View), then calls
5376      * {@link #dispatchPopulateAccessibilityEvent(AccessibilityEvent)} to
5377      * populate the text content of the event source including its descendants,
5378      * and last calls
5379      * {@link ViewParent#requestSendAccessibilityEvent(View, AccessibilityEvent)}
5380      * on its parent to request sending of the event to interested parties.
5381      * <p>
5382      * If an {@link AccessibilityDelegate} has been specified via calling
5383      * {@link #setAccessibilityDelegate(AccessibilityDelegate)} its
5384      * {@link AccessibilityDelegate#sendAccessibilityEvent(View, int)} is
5385      * responsible for handling this call.
5386      * </p>
5387      *
5388      * @param eventType The type of the event to send, as defined by several types from
5389      * {@link android.view.accessibility.AccessibilityEvent}, such as
5390      * {@link android.view.accessibility.AccessibilityEvent#TYPE_VIEW_CLICKED} or
5391      * {@link android.view.accessibility.AccessibilityEvent#TYPE_VIEW_HOVER_ENTER}.
5392      *
5393      * @see #onInitializeAccessibilityEvent(AccessibilityEvent)
5394      * @see #dispatchPopulateAccessibilityEvent(AccessibilityEvent)
5395      * @see ViewParent#requestSendAccessibilityEvent(View, AccessibilityEvent)
5396      * @see AccessibilityDelegate
5397      */
5398     public void sendAccessibilityEvent(int eventType) {
5399         if (mAccessibilityDelegate != null) {
5400             mAccessibilityDelegate.sendAccessibilityEvent(this, eventType);
5401         } else {
5402             sendAccessibilityEventInternal(eventType);
5403         }
5404     }
5405
5406     /**
5407      * Convenience method for sending a {@link AccessibilityEvent#TYPE_ANNOUNCEMENT}
5408      * {@link AccessibilityEvent} to make an announcement which is related to some
5409      * sort of a context change for which none of the events representing UI transitions
5410      * is a good fit. For example, announcing a new page in a book. If accessibility
5411      * is not enabled this method does nothing.
5412      *
5413      * @param text The announcement text.
5414      */
5415     public void announceForAccessibility(CharSequence text) {
5416         if (AccessibilityManager.getInstance(mContext).isEnabled() && mParent != null) {
5417             AccessibilityEvent event = AccessibilityEvent.obtain(
5418                     AccessibilityEvent.TYPE_ANNOUNCEMENT);
5419             onInitializeAccessibilityEvent(event);
5420             event.getText().add(text);
5421             event.setContentDescription(null);
5422             mParent.requestSendAccessibilityEvent(this, event);
5423         }
5424     }
5425
5426     /**
5427      * @see #sendAccessibilityEvent(int)
5428      *
5429      * Note: Called from the default {@link AccessibilityDelegate}.
5430      *
5431      * @hide
5432      */
5433     public void sendAccessibilityEventInternal(int eventType) {
5434         if (AccessibilityManager.getInstance(mContext).isEnabled()) {
5435             sendAccessibilityEventUnchecked(AccessibilityEvent.obtain(eventType));
5436         }
5437     }
5438
5439     /**
5440      * This method behaves exactly as {@link #sendAccessibilityEvent(int)} but
5441      * takes as an argument an empty {@link AccessibilityEvent} and does not
5442      * perform a check whether accessibility is enabled.
5443      * <p>
5444      * If an {@link AccessibilityDelegate} has been specified via calling
5445      * {@link #setAccessibilityDelegate(AccessibilityDelegate)} its
5446      * {@link AccessibilityDelegate#sendAccessibilityEventUnchecked(View, AccessibilityEvent)}
5447      * is responsible for handling this call.
5448      * </p>
5449      *
5450      * @param event The event to send.
5451      *
5452      * @see #sendAccessibilityEvent(int)
5453      */
5454     public void sendAccessibilityEventUnchecked(AccessibilityEvent event) {
5455         if (mAccessibilityDelegate != null) {
5456             mAccessibilityDelegate.sendAccessibilityEventUnchecked(this, event);
5457         } else {
5458             sendAccessibilityEventUncheckedInternal(event);
5459         }
5460     }
5461
5462     /**
5463      * @see #sendAccessibilityEventUnchecked(AccessibilityEvent)
5464      *
5465      * Note: Called from the default {@link AccessibilityDelegate}.
5466      *
5467      * @hide
5468      */
5469     public void sendAccessibilityEventUncheckedInternal(AccessibilityEvent event) {
5470         if (!isShown()) {
5471             return;
5472         }
5473         onInitializeAccessibilityEvent(event);
5474         // Only a subset of accessibility events populates text content.
5475         if ((event.getEventType() & POPULATING_ACCESSIBILITY_EVENT_TYPES) != 0) {
5476             dispatchPopulateAccessibilityEvent(event);
5477         }
5478         // In the beginning we called #isShown(), so we know that getParent() is not null.
5479         getParent().requestSendAccessibilityEvent(this, event);
5480     }
5481
5482     /**
5483      * Dispatches an {@link AccessibilityEvent} to the {@link View} first and then
5484      * to its children for adding their text content to the event. Note that the
5485      * event text is populated in a separate dispatch path since we add to the
5486      * event not only the text of the source but also the text of all its descendants.
5487      * A typical implementation will call
5488      * {@link #onPopulateAccessibilityEvent(AccessibilityEvent)} on the this view
5489      * and then call the {@link #dispatchPopulateAccessibilityEvent(AccessibilityEvent)}
5490      * on each child. Override this method if custom population of the event text
5491      * content is required.
5492      * <p>
5493      * If an {@link AccessibilityDelegate} has been specified via calling
5494      * {@link #setAccessibilityDelegate(AccessibilityDelegate)} its
5495      * {@link AccessibilityDelegate#dispatchPopulateAccessibilityEvent(View, AccessibilityEvent)}
5496      * is responsible for handling this call.
5497      * </p>
5498      * <p>
5499      * <em>Note:</em> Accessibility events of certain types are not dispatched for
5500      * populating the event text via this method. For details refer to {@link AccessibilityEvent}.
5501      * </p>
5502      *
5503      * @param event The event.
5504      *
5505      * @return True if the event population was completed.
5506      */
5507     public boolean dispatchPopulateAccessibilityEvent(AccessibilityEvent event) {
5508         if (mAccessibilityDelegate != null) {
5509             return mAccessibilityDelegate.dispatchPopulateAccessibilityEvent(this, event);
5510         } else {
5511             return dispatchPopulateAccessibilityEventInternal(event);
5512         }
5513     }
5514
5515     /**
5516      * @see #dispatchPopulateAccessibilityEvent(AccessibilityEvent)
5517      *
5518      * Note: Called from the default {@link AccessibilityDelegate}.
5519      *
5520      * @hide
5521      */
5522     public boolean dispatchPopulateAccessibilityEventInternal(AccessibilityEvent event) {
5523         onPopulateAccessibilityEvent(event);
5524         return false;
5525     }
5526
5527     /**
5528      * Called from {@link #dispatchPopulateAccessibilityEvent(AccessibilityEvent)}
5529      * giving a chance to this View to populate the accessibility event with its
5530      * text content. While this method is free to modify event
5531      * attributes other than text content, doing so should normally be performed in
5532      * {@link #onInitializeAccessibilityEvent(AccessibilityEvent)}.
5533      * <p>
5534      * Example: Adding formatted date string to an accessibility event in addition
5535      *          to the text added by the super implementation:
5536      * <pre> public void onPopulateAccessibilityEvent(AccessibilityEvent event) {
5537      *     super.onPopulateAccessibilityEvent(event);
5538      *     final int flags = DateUtils.FORMAT_SHOW_DATE | DateUtils.FORMAT_SHOW_WEEKDAY;
5539      *     String selectedDateUtterance = DateUtils.formatDateTime(mContext,
5540      *         mCurrentDate.getTimeInMillis(), flags);
5541      *     event.getText().add(selectedDateUtterance);
5542      * }</pre>
5543      * <p>
5544      * If an {@link AccessibilityDelegate} has been specified via calling
5545      * {@link #setAccessibilityDelegate(AccessibilityDelegate)} its
5546      * {@link AccessibilityDelegate#onPopulateAccessibilityEvent(View, AccessibilityEvent)}
5547      * is responsible for handling this call.
5548      * </p>
5549      * <p class="note"><strong>Note:</strong> Always call the super implementation before adding
5550      * information to the event, in case the default implementation has basic information to add.
5551      * </p>
5552      *
5553      * @param event The accessibility event which to populate.
5554      *
5555      * @see #sendAccessibilityEvent(int)
5556      * @see #dispatchPopulateAccessibilityEvent(AccessibilityEvent)
5557      */
5558     @CallSuper
5559     public void onPopulateAccessibilityEvent(AccessibilityEvent event) {
5560         if (mAccessibilityDelegate != null) {
5561             mAccessibilityDelegate.onPopulateAccessibilityEvent(this, event);
5562         } else {
5563             onPopulateAccessibilityEventInternal(event);
5564         }
5565     }
5566
5567     /**
5568      * @see #onPopulateAccessibilityEvent(AccessibilityEvent)
5569      *
5570      * Note: Called from the default {@link AccessibilityDelegate}.
5571      *
5572      * @hide
5573      */
5574     public void onPopulateAccessibilityEventInternal(AccessibilityEvent event) {
5575     }
5576
5577     /**
5578      * Initializes an {@link AccessibilityEvent} with information about
5579      * this View which is the event source. In other words, the source of
5580      * an accessibility event is the view whose state change triggered firing
5581      * the event.
5582      * <p>
5583      * Example: Setting the password property of an event in addition
5584      *          to properties set by the super implementation:
5585      * <pre> public void onInitializeAccessibilityEvent(AccessibilityEvent event) {
5586      *     super.onInitializeAccessibilityEvent(event);
5587      *     event.setPassword(true);
5588      * }</pre>
5589      * <p>
5590      * If an {@link AccessibilityDelegate} has been specified via calling
5591      * {@link #setAccessibilityDelegate(AccessibilityDelegate)} its
5592      * {@link AccessibilityDelegate#onInitializeAccessibilityEvent(View, AccessibilityEvent)}
5593      * is responsible for handling this call.
5594      * </p>
5595      * <p class="note"><strong>Note:</strong> Always call the super implementation before adding
5596      * information to the event, in case the default implementation has basic information to add.
5597      * </p>
5598      * @param event The event to initialize.
5599      *
5600      * @see #sendAccessibilityEvent(int)
5601      * @see #dispatchPopulateAccessibilityEvent(AccessibilityEvent)
5602      */
5603     @CallSuper
5604     public void onInitializeAccessibilityEvent(AccessibilityEvent event) {
5605         if (mAccessibilityDelegate != null) {
5606             mAccessibilityDelegate.onInitializeAccessibilityEvent(this, event);
5607         } else {
5608             onInitializeAccessibilityEventInternal(event);
5609         }
5610     }
5611
5612     /**
5613      * @see #onInitializeAccessibilityEvent(AccessibilityEvent)
5614      *
5615      * Note: Called from the default {@link AccessibilityDelegate}.
5616      *
5617      * @hide
5618      */
5619     public void onInitializeAccessibilityEventInternal(AccessibilityEvent event) {
5620         event.setSource(this);
5621         event.setClassName(getAccessibilityClassName());
5622         event.setPackageName(getContext().getPackageName());
5623         event.setEnabled(isEnabled());
5624         event.setContentDescription(mContentDescription);
5625
5626         switch (event.getEventType()) {
5627             case AccessibilityEvent.TYPE_VIEW_FOCUSED: {
5628                 ArrayList<View> focusablesTempList = (mAttachInfo != null)
5629                         ? mAttachInfo.mTempArrayList : new ArrayList<View>();
5630                 getRootView().addFocusables(focusablesTempList, View.FOCUS_FORWARD, FOCUSABLES_ALL);
5631                 event.setItemCount(focusablesTempList.size());
5632                 event.setCurrentItemIndex(focusablesTempList.indexOf(this));
5633                 if (mAttachInfo != null) {
5634                     focusablesTempList.clear();
5635                 }
5636             } break;
5637             case AccessibilityEvent.TYPE_VIEW_TEXT_SELECTION_CHANGED: {
5638                 CharSequence text = getIterableTextForAccessibility();
5639                 if (text != null && text.length() > 0) {
5640                     event.setFromIndex(getAccessibilitySelectionStart());
5641                     event.setToIndex(getAccessibilitySelectionEnd());
5642                     event.setItemCount(text.length());
5643                 }
5644             } break;
5645         }
5646     }
5647
5648     /**
5649      * Returns an {@link AccessibilityNodeInfo} representing this view from the
5650      * point of view of an {@link android.accessibilityservice.AccessibilityService}.
5651      * This method is responsible for obtaining an accessibility node info from a
5652      * pool of reusable instances and calling
5653      * {@link #onInitializeAccessibilityNodeInfo(AccessibilityNodeInfo)} on this view to
5654      * initialize the former.
5655      * <p>
5656      * Note: The client is responsible for recycling the obtained instance by calling
5657      *       {@link AccessibilityNodeInfo#recycle()} to minimize object creation.
5658      * </p>
5659      *
5660      * @return A populated {@link AccessibilityNodeInfo}.
5661      *
5662      * @see AccessibilityNodeInfo
5663      */
5664     public AccessibilityNodeInfo createAccessibilityNodeInfo() {
5665         if (mAccessibilityDelegate != null) {
5666             return mAccessibilityDelegate.createAccessibilityNodeInfo(this);
5667         } else {
5668             return createAccessibilityNodeInfoInternal();
5669         }
5670     }
5671
5672     /**
5673      * @see #createAccessibilityNodeInfo()
5674      *
5675      * @hide
5676      */
5677     public AccessibilityNodeInfo createAccessibilityNodeInfoInternal() {
5678         AccessibilityNodeProvider provider = getAccessibilityNodeProvider();
5679         if (provider != null) {
5680             return provider.createAccessibilityNodeInfo(View.NO_ID);
5681         } else {
5682             AccessibilityNodeInfo info = AccessibilityNodeInfo.obtain(this);
5683             onInitializeAccessibilityNodeInfo(info);
5684             return info;
5685         }
5686     }
5687
5688     /**
5689      * Initializes an {@link AccessibilityNodeInfo} with information about this view.
5690      * The base implementation sets:
5691      * <ul>
5692      *   <li>{@link AccessibilityNodeInfo#setParent(View)},</li>
5693      *   <li>{@link AccessibilityNodeInfo#setBoundsInParent(Rect)},</li>
5694      *   <li>{@link AccessibilityNodeInfo#setBoundsInScreen(Rect)},</li>
5695      *   <li>{@link AccessibilityNodeInfo#setPackageName(CharSequence)},</li>
5696      *   <li>{@link AccessibilityNodeInfo#setClassName(CharSequence)},</li>
5697      *   <li>{@link AccessibilityNodeInfo#setContentDescription(CharSequence)},</li>
5698      *   <li>{@link AccessibilityNodeInfo#setEnabled(boolean)},</li>
5699      *   <li>{@link AccessibilityNodeInfo#setClickable(boolean)},</li>
5700      *   <li>{@link AccessibilityNodeInfo#setFocusable(boolean)},</li>
5701      *   <li>{@link AccessibilityNodeInfo#setFocused(boolean)},</li>
5702      *   <li>{@link AccessibilityNodeInfo#setLongClickable(boolean)},</li>
5703      *   <li>{@link AccessibilityNodeInfo#setSelected(boolean)},</li>
5704      * </ul>
5705      * <p>
5706      * Subclasses should override this method, call the super implementation,
5707      * and set additional attributes.
5708      * </p>
5709      * <p>
5710      * If an {@link AccessibilityDelegate} has been specified via calling
5711      * {@link #setAccessibilityDelegate(AccessibilityDelegate)} its
5712      * {@link AccessibilityDelegate#onInitializeAccessibilityNodeInfo(View, AccessibilityNodeInfo)}
5713      * is responsible for handling this call.
5714      * </p>
5715      *
5716      * @param info The instance to initialize.
5717      */
5718     @CallSuper
5719     public void onInitializeAccessibilityNodeInfo(AccessibilityNodeInfo info) {
5720         if (mAccessibilityDelegate != null) {
5721             mAccessibilityDelegate.onInitializeAccessibilityNodeInfo(this, info);
5722         } else {
5723             onInitializeAccessibilityNodeInfoInternal(info);
5724         }
5725     }
5726
5727     /**
5728      * Gets the location of this view in screen coordinates.
5729      *
5730      * @param outRect The output location
5731      * @hide
5732      */
5733     public void getBoundsOnScreen(Rect outRect) {
5734         getBoundsOnScreen(outRect, false);
5735     }
5736
5737     /**
5738      * Gets the location of this view in screen coordinates.
5739      *
5740      * @param outRect The output location
5741      * @param clipToParent Whether to clip child bounds to the parent ones.
5742      * @hide
5743      */
5744     public void getBoundsOnScreen(Rect outRect, boolean clipToParent) {
5745         if (mAttachInfo == null) {
5746             return;
5747         }
5748
5749         RectF position = mAttachInfo.mTmpTransformRect;
5750         position.set(0, 0, mRight - mLeft, mBottom - mTop);
5751
5752         if (!hasIdentityMatrix()) {
5753             getMatrix().mapRect(position);
5754         }
5755
5756         position.offset(mLeft, mTop);
5757
5758         ViewParent parent = mParent;
5759         while (parent instanceof View) {
5760             View parentView = (View) parent;
5761
5762             position.offset(-parentView.mScrollX, -parentView.mScrollY);
5763
5764             if (clipToParent) {
5765                 position.left = Math.max(position.left, 0);
5766                 position.top = Math.max(position.top, 0);
5767                 position.right = Math.min(position.right, parentView.getWidth());
5768                 position.bottom = Math.min(position.bottom, parentView.getHeight());
5769             }
5770
5771             if (!parentView.hasIdentityMatrix()) {
5772                 parentView.getMatrix().mapRect(position);
5773             }
5774
5775             position.offset(parentView.mLeft, parentView.mTop);
5776
5777             parent = parentView.mParent;
5778         }
5779
5780         if (parent instanceof ViewRootImpl) {
5781             ViewRootImpl viewRootImpl = (ViewRootImpl) parent;
5782             position.offset(0, -viewRootImpl.mCurScrollY);
5783         }
5784
5785         position.offset(mAttachInfo.mWindowLeft, mAttachInfo.mWindowTop);
5786
5787         outRect.set((int) (position.left + 0.5f), (int) (position.top + 0.5f),
5788                 (int) (position.right + 0.5f), (int) (position.bottom + 0.5f));
5789     }
5790
5791     /**
5792      * Return the class name of this object to be used for accessibility purposes.
5793      * Subclasses should only override this if they are implementing something that
5794      * should be seen as a completely new class of view when used by accessibility,
5795      * unrelated to the class it is deriving from.  This is used to fill in
5796      * {@link AccessibilityNodeInfo#setClassName AccessibilityNodeInfo.setClassName}.
5797      */
5798     public CharSequence getAccessibilityClassName() {
5799         return View.class.getName();
5800     }
5801
5802     /**
5803      * Called when assist structure is being retrieved from a view as part of
5804      * {@link android.app.Activity#onProvideAssistData Activity.onProvideAssistData}.
5805      * @param structure Fill in with structured view data.  The default implementation
5806      * fills in all data that can be inferred from the view itself.
5807      */
5808     public void onProvideAssistStructure(ViewAssistStructure structure) {
5809         final int id = mID;
5810         if (id > 0 && (id&0xff000000) != 0 && (id&0x00ff0000) != 0
5811                 && (id&0x0000ffff) != 0) {
5812             String pkg, type, entry;
5813             try {
5814                 final Resources res = getResources();
5815                 entry = res.getResourceEntryName(id);
5816                 type = res.getResourceTypeName(id);
5817                 pkg = res.getResourcePackageName(id);
5818             } catch (Resources.NotFoundException e) {
5819                 entry = type = pkg = null;
5820             }
5821             structure.setId(id, pkg, type, entry);
5822         } else {
5823             structure.setId(id, null, null, null);
5824         }
5825         structure.setDimens(mLeft, mTop, mScrollX, mScrollY, mRight - mLeft, mBottom - mTop);
5826         structure.setVisibility(getVisibility());
5827         structure.setEnabled(isEnabled());
5828         if (isClickable()) {
5829             structure.setClickable(true);
5830         }
5831         if (isFocusable()) {
5832             structure.setFocusable(true);
5833         }
5834         if (isFocused()) {
5835             structure.setFocused(true);
5836         }
5837         if (isAccessibilityFocused()) {
5838             structure.setAccessibilityFocused(true);
5839         }
5840         if (isSelected()) {
5841             structure.setSelected(true);
5842         }
5843         if (isActivated()) {
5844             structure.setActivated(true);
5845         }
5846         if (isLongClickable()) {
5847             structure.setLongClickable(true);
5848         }
5849         if (this instanceof Checkable) {
5850             structure.setCheckable(true);
5851             if (((Checkable)this).isChecked()) {
5852                 structure.setChecked(true);
5853             }
5854         }
5855         structure.setClassName(getAccessibilityClassName().toString());
5856         structure.setContentDescription(getContentDescription());
5857     }
5858
5859     /**
5860      * Called when assist structure is being retrieved from a view as part of
5861      * {@link android.app.Activity#onProvideAssistData Activity.onProvideAssistData} to
5862      * generate additional virtual structure under this view.  The defaullt implementation
5863      * uses {@link #getAccessibilityNodeProvider()} to try to generate this from the
5864      * view's virtual accessibility nodes, if any.  You can override this for a more
5865      * optimal implementation providing this data.
5866      */
5867     public void onProvideVirtualAssistStructure(ViewAssistStructure structure) {
5868         AccessibilityNodeProvider provider = getAccessibilityNodeProvider();
5869         if (provider != null) {
5870             AccessibilityNodeInfo info = createAccessibilityNodeInfo();
5871             Log.i("View", "Provider of " + this + ": children=" + info.getChildCount());
5872             structure.setChildCount(1);
5873             ViewAssistStructure root = structure.newChild(0);
5874             populateVirtualAssistStructure(root, provider, info);
5875             info.recycle();
5876         }
5877     }
5878
5879     private void populateVirtualAssistStructure(ViewAssistStructure structure,
5880             AccessibilityNodeProvider provider, AccessibilityNodeInfo info) {
5881         structure.setId(AccessibilityNodeInfo.getVirtualDescendantId(info.getSourceNodeId()),
5882                 null, null, null);
5883         Rect rect = structure.getTempRect();
5884         info.getBoundsInParent(rect);
5885         structure.setDimens(rect.left, rect.top, 0, 0, rect.width(), rect.height());
5886         structure.setVisibility(VISIBLE);
5887         structure.setEnabled(info.isEnabled());
5888         if (info.isClickable()) {
5889             structure.setClickable(true);
5890         }
5891         if (info.isFocusable()) {
5892             structure.setFocusable(true);
5893         }
5894         if (info.isFocused()) {
5895             structure.setFocused(true);
5896         }
5897         if (info.isAccessibilityFocused()) {
5898             structure.setAccessibilityFocused(true);
5899         }
5900         if (info.isSelected()) {
5901             structure.setSelected(true);
5902         }
5903         if (info.isLongClickable()) {
5904             structure.setLongClickable(true);
5905         }
5906         if (info.isCheckable()) {
5907             structure.setCheckable(true);
5908             if (info.isChecked()) {
5909                 structure.setChecked(true);
5910             }
5911         }
5912         CharSequence cname = info.getClassName();
5913         structure.setClassName(cname != null ? cname.toString() : null);
5914         structure.setContentDescription(info.getContentDescription());
5915         Log.i("View", "vassist " + cname + " @ " + rect.toShortString()
5916                 + " text=" + info.getText() + " cd=" + info.getContentDescription());
5917         if (info.getText() != null || info.getError() != null) {
5918             structure.setText(info.getText(), info.getTextSelectionStart(),
5919                     info.getTextSelectionEnd());
5920         }
5921         final int NCHILDREN = info.getChildCount();
5922         if (NCHILDREN > 0) {
5923             structure.setChildCount(NCHILDREN);
5924             for (int i=0; i<NCHILDREN; i++) {
5925                 AccessibilityNodeInfo cinfo = provider.createAccessibilityNodeInfo(
5926                         AccessibilityNodeInfo.getVirtualDescendantId(info.getChildId(i)));
5927                 ViewAssistStructure child = structure.newChild(i);
5928                 populateVirtualAssistStructure(child, provider, cinfo);
5929                 cinfo.recycle();
5930             }
5931         }
5932     }
5933
5934     /**
5935      * Dispatch creation of {@link ViewAssistStructure} down the hierarchy.  The default
5936      * implementation calls {@link #onProvideAssistStructure} and
5937      * {@link #onProvideVirtualAssistStructure}.
5938      */
5939     public void dispatchProvideAssistStructure(ViewAssistStructure structure) {
5940         if (!isAssistBlocked()) {
5941             onProvideAssistStructure(structure);
5942             onProvideVirtualAssistStructure(structure);
5943         } else {
5944             structure.setClassName(getAccessibilityClassName().toString());
5945             structure.setAssistBlocked(true);
5946         }
5947     }
5948
5949     /**
5950      * @see #onInitializeAccessibilityNodeInfo(AccessibilityNodeInfo)
5951      *
5952      * Note: Called from the default {@link AccessibilityDelegate}.
5953      *
5954      * @hide
5955      */
5956     public void onInitializeAccessibilityNodeInfoInternal(AccessibilityNodeInfo info) {
5957         Rect bounds = mAttachInfo.mTmpInvalRect;
5958
5959         getDrawingRect(bounds);
5960         info.setBoundsInParent(bounds);
5961
5962         getBoundsOnScreen(bounds, true);
5963         info.setBoundsInScreen(bounds);
5964
5965         ViewParent parent = getParentForAccessibility();
5966         if (parent instanceof View) {
5967             info.setParent((View) parent);
5968         }
5969
5970         if (mID != View.NO_ID) {
5971             View rootView = getRootView();
5972             if (rootView == null) {
5973                 rootView = this;
5974             }
5975
5976             View label = rootView.findLabelForView(this, mID);
5977             if (label != null) {
5978                 info.setLabeledBy(label);
5979             }
5980
5981             if ((mAttachInfo.mAccessibilityFetchFlags
5982                     & AccessibilityNodeInfo.FLAG_REPORT_VIEW_IDS) != 0
5983                     && Resources.resourceHasPackage(mID)) {
5984                 try {
5985                     String viewId = getResources().getResourceName(mID);
5986                     info.setViewIdResourceName(viewId);
5987                 } catch (Resources.NotFoundException nfe) {
5988                     /* ignore */
5989                 }
5990             }
5991         }
5992
5993         if (mLabelForId != View.NO_ID) {
5994             View rootView = getRootView();
5995             if (rootView == null) {
5996                 rootView = this;
5997             }
5998             View labeled = rootView.findViewInsideOutShouldExist(this, mLabelForId);
5999             if (labeled != null) {
6000                 info.setLabelFor(labeled);
6001             }
6002         }
6003
6004         if (mAccessibilityTraversalBeforeId != View.NO_ID) {
6005             View rootView = getRootView();
6006             if (rootView == null) {
6007                 rootView = this;
6008             }
6009             View next = rootView.findViewInsideOutShouldExist(this,
6010                     mAccessibilityTraversalBeforeId);
6011             if (next != null) {
6012                 info.setTraversalBefore(next);
6013             }
6014         }
6015
6016         if (mAccessibilityTraversalAfterId != View.NO_ID) {
6017             View rootView = getRootView();
6018             if (rootView == null) {
6019                 rootView = this;
6020             }
6021             View next = rootView.findViewInsideOutShouldExist(this,
6022                     mAccessibilityTraversalAfterId);
6023             if (next != null) {
6024                 info.setTraversalAfter(next);
6025             }
6026         }
6027
6028         info.setVisibleToUser(isVisibleToUser());
6029
6030         info.setPackageName(mContext.getPackageName());
6031         info.setClassName(getAccessibilityClassName());
6032         info.setContentDescription(getContentDescription());
6033
6034         info.setEnabled(isEnabled());
6035         info.setClickable(isClickable());
6036         info.setFocusable(isFocusable());
6037         info.setFocused(isFocused());
6038         info.setAccessibilityFocused(isAccessibilityFocused());
6039         info.setSelected(isSelected());
6040         info.setLongClickable(isLongClickable());
6041         info.setLiveRegion(getAccessibilityLiveRegion());
6042
6043         // TODO: These make sense only if we are in an AdapterView but all
6044         // views can be selected. Maybe from accessibility perspective
6045         // we should report as selectable view in an AdapterView.
6046         info.addAction(AccessibilityNodeInfo.ACTION_SELECT);
6047         info.addAction(AccessibilityNodeInfo.ACTION_CLEAR_SELECTION);
6048
6049         if (isFocusable()) {
6050             if (isFocused()) {
6051                 info.addAction(AccessibilityNodeInfo.ACTION_CLEAR_FOCUS);
6052             } else {
6053                 info.addAction(AccessibilityNodeInfo.ACTION_FOCUS);
6054             }
6055         }
6056
6057         if (!isAccessibilityFocused()) {
6058             info.addAction(AccessibilityNodeInfo.ACTION_ACCESSIBILITY_FOCUS);
6059         } else {
6060             info.addAction(AccessibilityNodeInfo.ACTION_CLEAR_ACCESSIBILITY_FOCUS);
6061         }
6062
6063         if (isClickable() && isEnabled()) {
6064             info.addAction(AccessibilityNodeInfo.ACTION_CLICK);
6065         }
6066
6067         if (isLongClickable() && isEnabled()) {
6068             info.addAction(AccessibilityNodeInfo.ACTION_LONG_CLICK);
6069         }
6070
6071         CharSequence text = getIterableTextForAccessibility();
6072         if (text != null && text.length() > 0) {
6073             info.setTextSelection(getAccessibilitySelectionStart(), getAccessibilitySelectionEnd());
6074
6075             info.addAction(AccessibilityNodeInfo.ACTION_SET_SELECTION);
6076             info.addAction(AccessibilityNodeInfo.ACTION_NEXT_AT_MOVEMENT_GRANULARITY);
6077             info.addAction(AccessibilityNodeInfo.ACTION_PREVIOUS_AT_MOVEMENT_GRANULARITY);
6078             info.setMovementGranularities(AccessibilityNodeInfo.MOVEMENT_GRANULARITY_CHARACTER
6079                     | AccessibilityNodeInfo.MOVEMENT_GRANULARITY_WORD
6080                     | AccessibilityNodeInfo.MOVEMENT_GRANULARITY_PARAGRAPH);
6081         }
6082
6083         info.addAction(AccessibilityAction.ACTION_SHOW_ON_SCREEN);
6084     }
6085
6086     private View findLabelForView(View view, int labeledId) {
6087         if (mMatchLabelForPredicate == null) {
6088             mMatchLabelForPredicate = new MatchLabelForPredicate();
6089         }
6090         mMatchLabelForPredicate.mLabeledId = labeledId;
6091         return findViewByPredicateInsideOut(view, mMatchLabelForPredicate);
6092     }
6093
6094     /**
6095      * Computes whether this view is visible to the user. Such a view is
6096      * attached, visible, all its predecessors are visible, it is not clipped
6097      * entirely by its predecessors, and has an alpha greater than zero.
6098      *
6099      * @return Whether the view is visible on the screen.
6100      *
6101      * @hide
6102      */
6103     protected boolean isVisibleToUser() {
6104         return isVisibleToUser(null);
6105     }
6106
6107     /**
6108      * Computes whether the given portion of this view is visible to the user.
6109      * Such a view is attached, visible, all its predecessors are visible,
6110      * has an alpha greater than zero, and the specified portion is not
6111      * clipped entirely by its predecessors.
6112      *
6113      * @param boundInView the portion of the view to test; coordinates should be relative; may be
6114      *                    <code>null</code>, and the entire view will be tested in this case.
6115      *                    When <code>true</code> is returned by the function, the actual visible
6116      *                    region will be stored in this parameter; that is, if boundInView is fully
6117      *                    contained within the view, no modification will be made, otherwise regions
6118      *                    outside of the visible area of the view will be clipped.
6119      *
6120      * @return Whether the specified portion of the view is visible on the screen.
6121      *
6122      * @hide
6123      */
6124     protected boolean isVisibleToUser(Rect boundInView) {
6125         if (mAttachInfo != null) {
6126             // Attached to invisible window means this view is not visible.
6127             if (mAttachInfo.mWindowVisibility != View.VISIBLE) {
6128                 return false;
6129             }
6130             // An invisible predecessor or one with alpha zero means
6131             // that this view is not visible to the user.
6132             Object current = this;
6133             while (current instanceof View) {
6134                 View view = (View) current;
6135                 // We have attach info so this view is attached and there is no
6136                 // need to check whether we reach to ViewRootImpl on the way up.
6137                 if (view.getAlpha() <= 0 || view.getTransitionAlpha() <= 0 ||
6138                         view.getVisibility() != VISIBLE) {
6139                     return false;
6140                 }
6141                 current = view.mParent;
6142             }
6143             // Check if the view is entirely covered by its predecessors.
6144             Rect visibleRect = mAttachInfo.mTmpInvalRect;
6145             Point offset = mAttachInfo.mPoint;
6146             if (!getGlobalVisibleRect(visibleRect, offset)) {
6147                 return false;
6148             }
6149             // Check if the visible portion intersects the rectangle of interest.
6150             if (boundInView != null) {
6151                 visibleRect.offset(-offset.x, -offset.y);
6152                 return boundInView.intersect(visibleRect);
6153             }
6154             return true;
6155         }
6156         return false;
6157     }
6158
6159     /**
6160      * Returns the delegate for implementing accessibility support via
6161      * composition. For more details see {@link AccessibilityDelegate}.
6162      *
6163      * @return The delegate, or null if none set.
6164      *
6165      * @hide
6166      */
6167     public AccessibilityDelegate getAccessibilityDelegate() {
6168         return mAccessibilityDelegate;
6169     }
6170
6171     /**
6172      * Sets a delegate for implementing accessibility support via composition as
6173      * opposed to inheritance. The delegate's primary use is for implementing
6174      * backwards compatible widgets. For more details see {@link AccessibilityDelegate}.
6175      *
6176      * @param delegate The delegate instance.
6177      *
6178      * @see AccessibilityDelegate
6179      */
6180     public void setAccessibilityDelegate(@Nullable AccessibilityDelegate delegate) {
6181         mAccessibilityDelegate = delegate;
6182     }
6183
6184     /**
6185      * Gets the provider for managing a virtual view hierarchy rooted at this View
6186      * and reported to {@link android.accessibilityservice.AccessibilityService}s
6187      * that explore the window content.
6188      * <p>
6189      * If this method returns an instance, this instance is responsible for managing
6190      * {@link AccessibilityNodeInfo}s describing the virtual sub-tree rooted at this
6191      * View including the one representing the View itself. Similarly the returned
6192      * instance is responsible for performing accessibility actions on any virtual
6193      * view or the root view itself.
6194      * </p>
6195      * <p>
6196      * If an {@link AccessibilityDelegate} has been specified via calling
6197      * {@link #setAccessibilityDelegate(AccessibilityDelegate)} its
6198      * {@link AccessibilityDelegate#getAccessibilityNodeProvider(View)}
6199      * is responsible for handling this call.
6200      * </p>
6201      *
6202      * @return The provider.
6203      *
6204      * @see AccessibilityNodeProvider
6205      */
6206     public AccessibilityNodeProvider getAccessibilityNodeProvider() {
6207         if (mAccessibilityDelegate != null) {
6208             return mAccessibilityDelegate.getAccessibilityNodeProvider(this);
6209         } else {
6210             return null;
6211         }
6212     }
6213
6214     /**
6215      * Gets the unique identifier of this view on the screen for accessibility purposes.
6216      * If this {@link View} is not attached to any window, {@value #NO_ID} is returned.
6217      *
6218      * @return The view accessibility id.
6219      *
6220      * @hide
6221      */
6222     public int getAccessibilityViewId() {
6223         if (mAccessibilityViewId == NO_ID) {
6224             mAccessibilityViewId = sNextAccessibilityViewId++;
6225         }
6226         return mAccessibilityViewId;
6227     }
6228
6229     /**
6230      * Gets the unique identifier of the window in which this View reseides.
6231      *
6232      * @return The window accessibility id.
6233      *
6234      * @hide
6235      */
6236     public int getAccessibilityWindowId() {
6237         return mAttachInfo != null ? mAttachInfo.mAccessibilityWindowId
6238                 : AccessibilityNodeInfo.UNDEFINED_ITEM_ID;
6239     }
6240
6241     /**
6242      * Gets the {@link View} description. It briefly describes the view and is
6243      * primarily used for accessibility support. Set this property to enable
6244      * better accessibility support for your application. This is especially
6245      * true for views that do not have textual representation (For example,
6246      * ImageButton).
6247      *
6248      * @return The content description.
6249      *
6250      * @attr ref android.R.styleable#View_contentDescription
6251      */
6252     @ViewDebug.ExportedProperty(category = "accessibility")
6253     public CharSequence getContentDescription() {
6254         return mContentDescription;
6255     }
6256
6257     /**
6258      * Sets the {@link View} description. It briefly describes the view and is
6259      * primarily used for accessibility support. Set this property to enable
6260      * better accessibility support for your application. This is especially
6261      * true for views that do not have textual representation (For example,
6262      * ImageButton).
6263      *
6264      * @param contentDescription The content description.
6265      *
6266      * @attr ref android.R.styleable#View_contentDescription
6267      */
6268     @RemotableViewMethod
6269     public void setContentDescription(CharSequence contentDescription) {
6270         if (mContentDescription == null) {
6271             if (contentDescription == null) {
6272                 return;
6273             }
6274         } else if (mContentDescription.equals(contentDescription)) {
6275             return;
6276         }
6277         mContentDescription = contentDescription;
6278         final boolean nonEmptyDesc = contentDescription != null && contentDescription.length() > 0;
6279         if (nonEmptyDesc && getImportantForAccessibility() == IMPORTANT_FOR_ACCESSIBILITY_AUTO) {
6280             setImportantForAccessibility(IMPORTANT_FOR_ACCESSIBILITY_YES);
6281             notifySubtreeAccessibilityStateChangedIfNeeded();
6282         } else {
6283             notifyViewAccessibilityStateChangedIfNeeded(
6284                     AccessibilityEvent.CONTENT_CHANGE_TYPE_CONTENT_DESCRIPTION);
6285         }
6286     }
6287
6288     /**
6289      * Sets the id of a view before which this one is visited in accessibility traversal.
6290      * A screen-reader must visit the content of this view before the content of the one
6291      * it precedes. For example, if view B is set to be before view A, then a screen-reader
6292      * will traverse the entire content of B before traversing the entire content of A,
6293      * regardles of what traversal strategy it is using.
6294      * <p>
6295      * Views that do not have specified before/after relationships are traversed in order
6296      * determined by the screen-reader.
6297      * </p>
6298      * <p>
6299      * Setting that this view is before a view that is not important for accessibility
6300      * or if this view is not important for accessibility will have no effect as the
6301      * screen-reader is not aware of unimportant views.
6302      * </p>
6303      *
6304      * @param beforeId The id of a view this one precedes in accessibility traversal.
6305      *
6306      * @attr ref android.R.styleable#View_accessibilityTraversalBefore
6307      *
6308      * @see #setImportantForAccessibility(int)
6309      */
6310     @RemotableViewMethod
6311     public void setAccessibilityTraversalBefore(int beforeId) {
6312         if (mAccessibilityTraversalBeforeId == beforeId) {
6313             return;
6314         }
6315         mAccessibilityTraversalBeforeId = beforeId;
6316         notifyViewAccessibilityStateChangedIfNeeded(
6317                 AccessibilityEvent.CONTENT_CHANGE_TYPE_UNDEFINED);
6318     }
6319
6320     /**
6321      * Gets the id of a view before which this one is visited in accessibility traversal.
6322      *
6323      * @return The id of a view this one precedes in accessibility traversal if
6324      *         specified, otherwise {@link #NO_ID}.
6325      *
6326      * @see #setAccessibilityTraversalBefore(int)
6327      */
6328     public int getAccessibilityTraversalBefore() {
6329         return mAccessibilityTraversalBeforeId;
6330     }
6331
6332     /**
6333      * Sets the id of a view after which this one is visited in accessibility traversal.
6334      * A screen-reader must visit the content of the other view before the content of this
6335      * one. For example, if view B is set to be after view A, then a screen-reader
6336      * will traverse the entire content of A before traversing the entire content of B,
6337      * regardles of what traversal strategy it is using.
6338      * <p>
6339      * Views that do not have specified before/after relationships are traversed in order
6340      * determined by the screen-reader.
6341      * </p>
6342      * <p>
6343      * Setting that this view is after a view that is not important for accessibility
6344      * or if this view is not important for accessibility will have no effect as the
6345      * screen-reader is not aware of unimportant views.
6346      * </p>
6347      *
6348      * @param afterId The id of a view this one succedees in accessibility traversal.
6349      *
6350      * @attr ref android.R.styleable#View_accessibilityTraversalAfter
6351      *
6352      * @see #setImportantForAccessibility(int)
6353      */
6354     @RemotableViewMethod
6355     public void setAccessibilityTraversalAfter(int afterId) {
6356         if (mAccessibilityTraversalAfterId == afterId) {
6357             return;
6358         }
6359         mAccessibilityTraversalAfterId = afterId;
6360         notifyViewAccessibilityStateChangedIfNeeded(
6361                 AccessibilityEvent.CONTENT_CHANGE_TYPE_UNDEFINED);
6362     }
6363
6364     /**
6365      * Gets the id of a view after which this one is visited in accessibility traversal.
6366      *
6367      * @return The id of a view this one succeedes in accessibility traversal if
6368      *         specified, otherwise {@link #NO_ID}.
6369      *
6370      * @see #setAccessibilityTraversalAfter(int)
6371      */
6372     public int getAccessibilityTraversalAfter() {
6373         return mAccessibilityTraversalAfterId;
6374     }
6375
6376     /**
6377      * Gets the id of a view for which this view serves as a label for
6378      * accessibility purposes.
6379      *
6380      * @return The labeled view id.
6381      */
6382     @ViewDebug.ExportedProperty(category = "accessibility")
6383     public int getLabelFor() {
6384         return mLabelForId;
6385     }
6386
6387     /**
6388      * Sets the id of a view for which this view serves as a label for
6389      * accessibility purposes.
6390      *
6391      * @param id The labeled view id.
6392      */
6393     @RemotableViewMethod
6394     public void setLabelFor(@IdRes int id) {
6395         if (mLabelForId == id) {
6396             return;
6397         }
6398         mLabelForId = id;
6399         if (mLabelForId != View.NO_ID
6400                 && mID == View.NO_ID) {
6401             mID = generateViewId();
6402         }
6403         notifyViewAccessibilityStateChangedIfNeeded(
6404                 AccessibilityEvent.CONTENT_CHANGE_TYPE_UNDEFINED);
6405     }
6406
6407     /**
6408      * Invoked whenever this view loses focus, either by losing window focus or by losing
6409      * focus within its window. This method can be used to clear any state tied to the
6410      * focus. For instance, if a button is held pressed with the trackball and the window
6411      * loses focus, this method can be used to cancel the press.
6412      *
6413      * Subclasses of View overriding this method should always call super.onFocusLost().
6414      *
6415      * @see #onFocusChanged(boolean, int, android.graphics.Rect)
6416      * @see #onWindowFocusChanged(boolean)
6417      *
6418      * @hide pending API council approval
6419      */
6420     @CallSuper
6421     protected void onFocusLost() {
6422         resetPressedState();
6423     }
6424
6425     private void resetPressedState() {
6426         if ((mViewFlags & ENABLED_MASK) == DISABLED) {
6427             return;
6428         }
6429
6430         if (isPressed()) {
6431             setPressed(false);
6432
6433             if (!mHasPerformedLongPress) {
6434                 removeLongPressCallback();
6435             }
6436         }
6437     }
6438
6439     /**
6440      * Returns true if this view has focus
6441      *
6442      * @return True if this view has focus, false otherwise.
6443      */
6444     @ViewDebug.ExportedProperty(category = "focus")
6445     public boolean isFocused() {
6446         return (mPrivateFlags & PFLAG_FOCUSED) != 0;
6447     }
6448
6449     /**
6450      * Find the view in the hierarchy rooted at this view that currently has
6451      * focus.
6452      *
6453      * @return The view that currently has focus, or null if no focused view can
6454      *         be found.
6455      */
6456     public View findFocus() {
6457         return (mPrivateFlags & PFLAG_FOCUSED) != 0 ? this : null;
6458     }
6459
6460     /**
6461      * Indicates whether this view is one of the set of scrollable containers in
6462      * its window.
6463      *
6464      * @return whether this view is one of the set of scrollable containers in
6465      * its window
6466      *
6467      * @attr ref android.R.styleable#View_isScrollContainer
6468      */
6469     public boolean isScrollContainer() {
6470         return (mPrivateFlags & PFLAG_SCROLL_CONTAINER_ADDED) != 0;
6471     }
6472
6473     /**
6474      * Change whether this view is one of the set of scrollable containers in
6475      * its window.  This will be used to determine whether the window can
6476      * resize or must pan when a soft input area is open -- scrollable
6477      * containers allow the window to use resize mode since the container
6478      * will appropriately shrink.
6479      *
6480      * @attr ref android.R.styleable#View_isScrollContainer
6481      */
6482     public void setScrollContainer(boolean isScrollContainer) {
6483         if (isScrollContainer) {
6484             if (mAttachInfo != null && (mPrivateFlags&PFLAG_SCROLL_CONTAINER_ADDED) == 0) {
6485                 mAttachInfo.mScrollContainers.add(this);
6486                 mPrivateFlags |= PFLAG_SCROLL_CONTAINER_ADDED;
6487             }
6488             mPrivateFlags |= PFLAG_SCROLL_CONTAINER;
6489         } else {
6490             if ((mPrivateFlags&PFLAG_SCROLL_CONTAINER_ADDED) != 0) {
6491                 mAttachInfo.mScrollContainers.remove(this);
6492             }
6493             mPrivateFlags &= ~(PFLAG_SCROLL_CONTAINER|PFLAG_SCROLL_CONTAINER_ADDED);
6494         }
6495     }
6496
6497     /**
6498      * Returns the quality of the drawing cache.
6499      *
6500      * @return One of {@link #DRAWING_CACHE_QUALITY_AUTO},
6501      *         {@link #DRAWING_CACHE_QUALITY_LOW}, or {@link #DRAWING_CACHE_QUALITY_HIGH}
6502      *
6503      * @see #setDrawingCacheQuality(int)
6504      * @see #setDrawingCacheEnabled(boolean)
6505      * @see #isDrawingCacheEnabled()
6506      *
6507      * @attr ref android.R.styleable#View_drawingCacheQuality
6508      */
6509     @DrawingCacheQuality
6510     public int getDrawingCacheQuality() {
6511         return mViewFlags & DRAWING_CACHE_QUALITY_MASK;
6512     }
6513
6514     /**
6515      * Set the drawing cache quality of this view. This value is used only when the
6516      * drawing cache is enabled
6517      *
6518      * @param quality One of {@link #DRAWING_CACHE_QUALITY_AUTO},
6519      *        {@link #DRAWING_CACHE_QUALITY_LOW}, or {@link #DRAWING_CACHE_QUALITY_HIGH}
6520      *
6521      * @see #getDrawingCacheQuality()
6522      * @see #setDrawingCacheEnabled(boolean)
6523      * @see #isDrawingCacheEnabled()
6524      *
6525      * @attr ref android.R.styleable#View_drawingCacheQuality
6526      */
6527     public void setDrawingCacheQuality(@DrawingCacheQuality int quality) {
6528         setFlags(quality, DRAWING_CACHE_QUALITY_MASK);
6529     }
6530
6531     /**
6532      * Returns whether the screen should remain on, corresponding to the current
6533      * value of {@link #KEEP_SCREEN_ON}.
6534      *
6535      * @return Returns true if {@link #KEEP_SCREEN_ON} is set.
6536      *
6537      * @see #setKeepScreenOn(boolean)
6538      *
6539      * @attr ref android.R.styleable#View_keepScreenOn
6540      */
6541     public boolean getKeepScreenOn() {
6542         return (mViewFlags & KEEP_SCREEN_ON) != 0;
6543     }
6544
6545     /**
6546      * Controls whether the screen should remain on, modifying the
6547      * value of {@link #KEEP_SCREEN_ON}.
6548      *
6549      * @param keepScreenOn Supply true to set {@link #KEEP_SCREEN_ON}.
6550      *
6551      * @see #getKeepScreenOn()
6552      *
6553      * @attr ref android.R.styleable#View_keepScreenOn
6554      */
6555     public void setKeepScreenOn(boolean keepScreenOn) {
6556         setFlags(keepScreenOn ? KEEP_SCREEN_ON : 0, KEEP_SCREEN_ON);
6557     }
6558
6559     /**
6560      * Gets the id of the view to use when the next focus is {@link #FOCUS_LEFT}.
6561      * @return The next focus ID, or {@link #NO_ID} if the framework should decide automatically.
6562      *
6563      * @attr ref android.R.styleable#View_nextFocusLeft
6564      */
6565     public int getNextFocusLeftId() {
6566         return mNextFocusLeftId;
6567     }
6568
6569     /**
6570      * Sets the id of the view to use when the next focus is {@link #FOCUS_LEFT}.
6571      * @param nextFocusLeftId The next focus ID, or {@link #NO_ID} if the framework should
6572      * decide automatically.
6573      *
6574      * @attr ref android.R.styleable#View_nextFocusLeft
6575      */
6576     public void setNextFocusLeftId(int nextFocusLeftId) {
6577         mNextFocusLeftId = nextFocusLeftId;
6578     }
6579
6580     /**
6581      * Gets the id of the view to use when the next focus is {@link #FOCUS_RIGHT}.
6582      * @return The next focus ID, or {@link #NO_ID} if the framework should decide automatically.
6583      *
6584      * @attr ref android.R.styleable#View_nextFocusRight
6585      */
6586     public int getNextFocusRightId() {
6587         return mNextFocusRightId;
6588     }
6589
6590     /**
6591      * Sets the id of the view to use when the next focus is {@link #FOCUS_RIGHT}.
6592      * @param nextFocusRightId The next focus ID, or {@link #NO_ID} if the framework should
6593      * decide automatically.
6594      *
6595      * @attr ref android.R.styleable#View_nextFocusRight
6596      */
6597     public void setNextFocusRightId(int nextFocusRightId) {
6598         mNextFocusRightId = nextFocusRightId;
6599     }
6600
6601     /**
6602      * Gets the id of the view to use when the next focus is {@link #FOCUS_UP}.
6603      * @return The next focus ID, or {@link #NO_ID} if the framework should decide automatically.
6604      *
6605      * @attr ref android.R.styleable#View_nextFocusUp
6606      */
6607     public int getNextFocusUpId() {
6608         return mNextFocusUpId;
6609     }
6610
6611     /**
6612      * Sets the id of the view to use when the next focus is {@link #FOCUS_UP}.
6613      * @param nextFocusUpId The next focus ID, or {@link #NO_ID} if the framework should
6614      * decide automatically.
6615      *
6616      * @attr ref android.R.styleable#View_nextFocusUp
6617      */
6618     public void setNextFocusUpId(int nextFocusUpId) {
6619         mNextFocusUpId = nextFocusUpId;
6620     }
6621
6622     /**
6623      * Gets the id of the view to use when the next focus is {@link #FOCUS_DOWN}.
6624      * @return The next focus ID, or {@link #NO_ID} if the framework should decide automatically.
6625      *
6626      * @attr ref android.R.styleable#View_nextFocusDown
6627      */
6628     public int getNextFocusDownId() {
6629         return mNextFocusDownId;
6630     }
6631
6632     /**
6633      * Sets the id of the view to use when the next focus is {@link #FOCUS_DOWN}.
6634      * @param nextFocusDownId The next focus ID, or {@link #NO_ID} if the framework should
6635      * decide automatically.
6636      *
6637      * @attr ref android.R.styleable#View_nextFocusDown
6638      */
6639     public void setNextFocusDownId(int nextFocusDownId) {
6640         mNextFocusDownId = nextFocusDownId;
6641     }
6642
6643     /**
6644      * Gets the id of the view to use when the next focus is {@link #FOCUS_FORWARD}.
6645      * @return The next focus ID, or {@link #NO_ID} if the framework should decide automatically.
6646      *
6647      * @attr ref android.R.styleable#View_nextFocusForward
6648      */
6649     public int getNextFocusForwardId() {
6650         return mNextFocusForwardId;
6651     }
6652
6653     /**
6654      * Sets the id of the view to use when the next focus is {@link #FOCUS_FORWARD}.
6655      * @param nextFocusForwardId The next focus ID, or {@link #NO_ID} if the framework should
6656      * decide automatically.
6657      *
6658      * @attr ref android.R.styleable#View_nextFocusForward
6659      */
6660     public void setNextFocusForwardId(int nextFocusForwardId) {
6661         mNextFocusForwardId = nextFocusForwardId;
6662     }
6663
6664     /**
6665      * Returns the visibility of this view and all of its ancestors
6666      *
6667      * @return True if this view and all of its ancestors are {@link #VISIBLE}
6668      */
6669     public boolean isShown() {
6670         View current = this;
6671         //noinspection ConstantConditions
6672         do {
6673             if ((current.mViewFlags & VISIBILITY_MASK) != VISIBLE) {
6674                 return false;
6675             }
6676             ViewParent parent = current.mParent;
6677             if (parent == null) {
6678                 return false; // We are not attached to the view root
6679             }
6680             if (!(parent instanceof View)) {
6681                 return true;
6682             }
6683             current = (View) parent;
6684         } while (current != null);
6685
6686         return false;
6687     }
6688
6689     /**
6690      * Called by the view hierarchy when the content insets for a window have
6691      * changed, to allow it to adjust its content to fit within those windows.
6692      * The content insets tell you the space that the status bar, input method,
6693      * and other system windows infringe on the application's window.
6694      *
6695      * <p>You do not normally need to deal with this function, since the default
6696      * window decoration given to applications takes care of applying it to the
6697      * content of the window.  If you use {@link #SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN}
6698      * or {@link #SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION} this will not be the case,
6699      * and your content can be placed under those system elements.  You can then
6700      * use this method within your view hierarchy if you have parts of your UI
6701      * which you would like to ensure are not being covered.
6702      *
6703      * <p>The default implementation of this method simply applies the content
6704      * insets to the view's padding, consuming that content (modifying the
6705      * insets to be 0), and returning true.  This behavior is off by default, but can
6706      * be enabled through {@link #setFitsSystemWindows(boolean)}.
6707      *
6708      * <p>This function's traversal down the hierarchy is depth-first.  The same content
6709      * insets object is propagated down the hierarchy, so any changes made to it will
6710      * be seen by all following views (including potentially ones above in
6711      * the hierarchy since this is a depth-first traversal).  The first view
6712      * that returns true will abort the entire traversal.
6713      *
6714      * <p>The default implementation works well for a situation where it is
6715      * used with a container that covers the entire window, allowing it to
6716      * apply the appropriate insets to its content on all edges.  If you need
6717      * a more complicated layout (such as two different views fitting system
6718      * windows, one on the top of the window, and one on the bottom),
6719      * you can override the method and handle the insets however you would like.
6720      * Note that the insets provided by the framework are always relative to the
6721      * far edges of the window, not accounting for the location of the called view
6722      * within that window.  (In fact when this method is called you do not yet know
6723      * where the layout will place the view, as it is done before layout happens.)
6724      *
6725      * <p>Note: unlike many View methods, there is no dispatch phase to this
6726      * call.  If you are overriding it in a ViewGroup and want to allow the
6727      * call to continue to your children, you must be sure to call the super
6728      * implementation.
6729      *
6730      * <p>Here is a sample layout that makes use of fitting system windows
6731      * to have controls for a video view placed inside of the window decorations
6732      * that it hides and shows.  This can be used with code like the second
6733      * sample (video player) shown in {@link #setSystemUiVisibility(int)}.
6734      *
6735      * {@sample development/samples/ApiDemos/res/layout/video_player.xml complete}
6736      *
6737      * @param insets Current content insets of the window.  Prior to
6738      * {@link android.os.Build.VERSION_CODES#JELLY_BEAN} you must not modify
6739      * the insets or else you and Android will be unhappy.
6740      *
6741      * @return {@code true} if this view applied the insets and it should not
6742      * continue propagating further down the hierarchy, {@code false} otherwise.
6743      * @see #getFitsSystemWindows()
6744      * @see #setFitsSystemWindows(boolean)
6745      * @see #setSystemUiVisibility(int)
6746      *
6747      * @deprecated As of API 20 use {@link #dispatchApplyWindowInsets(WindowInsets)} to apply
6748      * insets to views. Views should override {@link #onApplyWindowInsets(WindowInsets)} or use
6749      * {@link #setOnApplyWindowInsetsListener(android.view.View.OnApplyWindowInsetsListener)}
6750      * to implement handling their own insets.
6751      */
6752     protected boolean fitSystemWindows(Rect insets) {
6753         if ((mPrivateFlags3 & PFLAG3_APPLYING_INSETS) == 0) {
6754             if (insets == null) {
6755                 // Null insets by definition have already been consumed.
6756                 // This call cannot apply insets since there are none to apply,
6757                 // so return false.
6758                 return false;
6759             }
6760             // If we're not in the process of dispatching the newer apply insets call,
6761             // that means we're not in the compatibility path. Dispatch into the newer
6762             // apply insets path and take things from there.
6763             try {
6764                 mPrivateFlags3 |= PFLAG3_FITTING_SYSTEM_WINDOWS;
6765                 return dispatchApplyWindowInsets(new WindowInsets(insets)).isConsumed();
6766             } finally {
6767                 mPrivateFlags3 &= ~PFLAG3_FITTING_SYSTEM_WINDOWS;
6768             }
6769         } else {
6770             // We're being called from the newer apply insets path.
6771             // Perform the standard fallback behavior.
6772             return fitSystemWindowsInt(insets);
6773         }
6774     }
6775
6776     private boolean fitSystemWindowsInt(Rect insets) {
6777         if ((mViewFlags & FITS_SYSTEM_WINDOWS) == FITS_SYSTEM_WINDOWS) {
6778             mUserPaddingStart = UNDEFINED_PADDING;
6779             mUserPaddingEnd = UNDEFINED_PADDING;
6780             Rect localInsets = sThreadLocal.get();
6781             if (localInsets == null) {
6782                 localInsets = new Rect();
6783                 sThreadLocal.set(localInsets);
6784             }
6785             boolean res = computeFitSystemWindows(insets, localInsets);
6786             mUserPaddingLeftInitial = localInsets.left;
6787             mUserPaddingRightInitial = localInsets.right;
6788             internalSetPadding(localInsets.left, localInsets.top,
6789                     localInsets.right, localInsets.bottom);
6790             return res;
6791         }
6792         return false;
6793     }
6794
6795     /**
6796      * Called when the view should apply {@link WindowInsets} according to its internal policy.
6797      *
6798      * <p>This method should be overridden by views that wish to apply a policy different from or
6799      * in addition to the default behavior. Clients that wish to force a view subtree
6800      * to apply insets should call {@link #dispatchApplyWindowInsets(WindowInsets)}.</p>
6801      *
6802      * <p>Clients may supply an {@link OnApplyWindowInsetsListener} to a view. If one is set
6803      * it will be called during dispatch instead of this method. The listener may optionally
6804      * call this method from its own implementation if it wishes to apply the view's default
6805      * insets policy in addition to its own.</p>
6806      *
6807      * <p>Implementations of this method should either return the insets parameter unchanged
6808      * or a new {@link WindowInsets} cloned from the supplied insets with any insets consumed
6809      * that this view applied itself. This allows new inset types added in future platform
6810      * versions to pass through existing implementations unchanged without being erroneously
6811      * consumed.</p>
6812      *
6813      * <p>By default if a view's {@link #setFitsSystemWindows(boolean) fitsSystemWindows}
6814      * property is set then the view will consume the system window insets and apply them
6815      * as padding for the view.</p>
6816      *
6817      * @param insets Insets to apply
6818      * @return The supplied insets with any applied insets consumed
6819      */
6820     public WindowInsets onApplyWindowInsets(WindowInsets insets) {
6821         if ((mPrivateFlags3 & PFLAG3_FITTING_SYSTEM_WINDOWS) == 0) {
6822             // We weren't called from within a direct call to fitSystemWindows,
6823             // call into it as a fallback in case we're in a class that overrides it
6824             // and has logic to perform.
6825             if (fitSystemWindows(insets.getSystemWindowInsets())) {
6826                 return insets.consumeSystemWindowInsets();
6827             }
6828         } else {
6829             // We were called from within a direct call to fitSystemWindows.
6830             if (fitSystemWindowsInt(insets.getSystemWindowInsets())) {
6831                 return insets.consumeSystemWindowInsets();
6832             }
6833         }
6834         return insets;
6835     }
6836
6837     /**
6838      * Set an {@link OnApplyWindowInsetsListener} to take over the policy for applying
6839      * window insets to this view. The listener's
6840      * {@link OnApplyWindowInsetsListener#onApplyWindowInsets(View, WindowInsets) onApplyWindowInsets}
6841      * method will be called instead of the view's
6842      * {@link #onApplyWindowInsets(WindowInsets) onApplyWindowInsets} method.
6843      *
6844      * @param listener Listener to set
6845      *
6846      * @see #onApplyWindowInsets(WindowInsets)
6847      */
6848     public void setOnApplyWindowInsetsListener(OnApplyWindowInsetsListener listener) {
6849         getListenerInfo().mOnApplyWindowInsetsListener = listener;
6850     }
6851
6852     /**
6853      * Request to apply the given window insets to this view or another view in its subtree.
6854      *
6855      * <p>This method should be called by clients wishing to apply insets corresponding to areas
6856      * obscured by window decorations or overlays. This can include the status and navigation bars,
6857      * action bars, input methods and more. New inset categories may be added in the future.
6858      * The method returns the insets provided minus any that were applied by this view or its
6859      * children.</p>
6860      *
6861      * <p>Clients wishing to provide custom behavior should override the
6862      * {@link #onApplyWindowInsets(WindowInsets)} method or alternatively provide a
6863      * {@link OnApplyWindowInsetsListener} via the
6864      * {@link #setOnApplyWindowInsetsListener(View.OnApplyWindowInsetsListener) setOnApplyWindowInsetsListener}
6865      * method.</p>
6866      *
6867      * <p>This method replaces the older {@link #fitSystemWindows(Rect) fitSystemWindows} method.
6868      * </p>
6869      *
6870      * @param insets Insets to apply
6871      * @return The provided insets minus the insets that were consumed
6872      */
6873     public WindowInsets dispatchApplyWindowInsets(WindowInsets insets) {
6874         try {
6875             mPrivateFlags3 |= PFLAG3_APPLYING_INSETS;
6876             if (mListenerInfo != null && mListenerInfo.mOnApplyWindowInsetsListener != null) {
6877                 return mListenerInfo.mOnApplyWindowInsetsListener.onApplyWindowInsets(this, insets);
6878             } else {
6879                 return onApplyWindowInsets(insets);
6880             }
6881         } finally {
6882             mPrivateFlags3 &= ~PFLAG3_APPLYING_INSETS;
6883         }
6884     }
6885
6886     /**
6887      * Provide original WindowInsets that are dispatched to the view hierarchy. The insets are
6888      * only available if the view is attached.
6889      *
6890      * @return WindowInsets from the top of the view hierarchy or null if View is detached
6891      */
6892     public WindowInsets getRootWindowInsets() {
6893         if (mAttachInfo != null) {
6894             return mAttachInfo.mViewRootImpl.getWindowInsets(false /* forceConstruct */);
6895         }
6896         return null;
6897     }
6898
6899     /**
6900      * @hide Compute the insets that should be consumed by this view and the ones
6901      * that should propagate to those under it.
6902      */
6903     protected boolean computeFitSystemWindows(Rect inoutInsets, Rect outLocalInsets) {
6904         if ((mViewFlags & OPTIONAL_FITS_SYSTEM_WINDOWS) == 0
6905                 || mAttachInfo == null
6906                 || ((mAttachInfo.mSystemUiVisibility & SYSTEM_UI_LAYOUT_FLAGS) == 0
6907                         && !mAttachInfo.mOverscanRequested)) {
6908             outLocalInsets.set(inoutInsets);
6909             inoutInsets.set(0, 0, 0, 0);
6910             return true;
6911         } else {
6912             // The application wants to take care of fitting system window for
6913             // the content...  however we still need to take care of any overscan here.
6914             final Rect overscan = mAttachInfo.mOverscanInsets;
6915             outLocalInsets.set(overscan);
6916             inoutInsets.left -= overscan.left;
6917             inoutInsets.top -= overscan.top;
6918             inoutInsets.right -= overscan.right;
6919             inoutInsets.bottom -= overscan.bottom;
6920             return false;
6921         }
6922     }
6923
6924     /**
6925      * Compute insets that should be consumed by this view and the ones that should propagate
6926      * to those under it.
6927      *
6928      * @param in Insets currently being processed by this View, likely received as a parameter
6929      *           to {@link #onApplyWindowInsets(WindowInsets)}.
6930      * @param outLocalInsets A Rect that will receive the insets that should be consumed
6931      *                       by this view
6932      * @return Insets that should be passed along to views under this one
6933      */
6934     public WindowInsets computeSystemWindowInsets(WindowInsets in, Rect outLocalInsets) {
6935         if ((mViewFlags & OPTIONAL_FITS_SYSTEM_WINDOWS) == 0
6936                 || mAttachInfo == null
6937                 || (mAttachInfo.mSystemUiVisibility & SYSTEM_UI_LAYOUT_FLAGS) == 0) {
6938             outLocalInsets.set(in.getSystemWindowInsets());
6939             return in.consumeSystemWindowInsets();
6940         } else {
6941             outLocalInsets.set(0, 0, 0, 0);
6942             return in;
6943         }
6944     }
6945
6946     /**
6947      * Sets whether or not this view should account for system screen decorations
6948      * such as the status bar and inset its content; that is, controlling whether
6949      * the default implementation of {@link #fitSystemWindows(Rect)} will be
6950      * executed.  See that method for more details.
6951      *
6952      * <p>Note that if you are providing your own implementation of
6953      * {@link #fitSystemWindows(Rect)}, then there is no need to set this
6954      * flag to true -- your implementation will be overriding the default
6955      * implementation that checks this flag.
6956      *
6957      * @param fitSystemWindows If true, then the default implementation of
6958      * {@link #fitSystemWindows(Rect)} will be executed.
6959      *
6960      * @attr ref android.R.styleable#View_fitsSystemWindows
6961      * @see #getFitsSystemWindows()
6962      * @see #fitSystemWindows(Rect)
6963      * @see #setSystemUiVisibility(int)
6964      */
6965     public void setFitsSystemWindows(boolean fitSystemWindows) {
6966         setFlags(fitSystemWindows ? FITS_SYSTEM_WINDOWS : 0, FITS_SYSTEM_WINDOWS);
6967     }
6968
6969     /**
6970      * Check for state of {@link #setFitsSystemWindows(boolean)}. If this method
6971      * returns {@code true}, the default implementation of {@link #fitSystemWindows(Rect)}
6972      * will be executed.
6973      *
6974      * @return {@code true} if the default implementation of
6975      * {@link #fitSystemWindows(Rect)} will be executed.
6976      *
6977      * @attr ref android.R.styleable#View_fitsSystemWindows
6978      * @see #setFitsSystemWindows(boolean)
6979      * @see #fitSystemWindows(Rect)
6980      * @see #setSystemUiVisibility(int)
6981      */
6982     @ViewDebug.ExportedProperty
6983     public boolean getFitsSystemWindows() {
6984         return (mViewFlags & FITS_SYSTEM_WINDOWS) == FITS_SYSTEM_WINDOWS;
6985     }
6986
6987     /** @hide */
6988     public boolean fitsSystemWindows() {
6989         return getFitsSystemWindows();
6990     }
6991
6992     /**
6993      * Ask that a new dispatch of {@link #fitSystemWindows(Rect)} be performed.
6994      * @deprecated Use {@link #requestApplyInsets()} for newer platform versions.
6995      */
6996     public void requestFitSystemWindows() {
6997         if (mParent != null) {
6998             mParent.requestFitSystemWindows();
6999         }
7000     }
7001
7002     /**
7003      * Ask that a new dispatch of {@link #onApplyWindowInsets(WindowInsets)} be performed.
7004      */
7005     public void requestApplyInsets() {
7006         requestFitSystemWindows();
7007     }
7008
7009     /**
7010      * For use by PhoneWindow to make its own system window fitting optional.
7011      * @hide
7012      */
7013     public void makeOptionalFitsSystemWindows() {
7014         setFlags(OPTIONAL_FITS_SYSTEM_WINDOWS, OPTIONAL_FITS_SYSTEM_WINDOWS);
7015     }
7016
7017     /**
7018      * Returns the visibility status for this view.
7019      *
7020      * @return One of {@link #VISIBLE}, {@link #INVISIBLE}, or {@link #GONE}.
7021      * @attr ref android.R.styleable#View_visibility
7022      */
7023     @ViewDebug.ExportedProperty(mapping = {
7024         @ViewDebug.IntToString(from = VISIBLE,   to = "VISIBLE"),
7025         @ViewDebug.IntToString(from = INVISIBLE, to = "INVISIBLE"),
7026         @ViewDebug.IntToString(from = GONE,      to = "GONE")
7027     })
7028     @Visibility
7029     public int getVisibility() {
7030         return mViewFlags & VISIBILITY_MASK;
7031     }
7032
7033     /**
7034      * Set the enabled state of this view.
7035      *
7036      * @param visibility One of {@link #VISIBLE}, {@link #INVISIBLE}, or {@link #GONE}.
7037      * @attr ref android.R.styleable#View_visibility
7038      */
7039     @RemotableViewMethod
7040     public void setVisibility(@Visibility int visibility) {
7041         setFlags(visibility, VISIBILITY_MASK);
7042     }
7043
7044     /**
7045      * Returns the enabled status for this view. The interpretation of the
7046      * enabled state varies by subclass.
7047      *
7048      * @return True if this view is enabled, false otherwise.
7049      */
7050     @ViewDebug.ExportedProperty
7051     public boolean isEnabled() {
7052         return (mViewFlags & ENABLED_MASK) == ENABLED;
7053     }
7054
7055     /**
7056      * Set the enabled state of this view. The interpretation of the enabled
7057      * state varies by subclass.
7058      *
7059      * @param enabled True if this view is enabled, false otherwise.
7060      */
7061     @RemotableViewMethod
7062     public void setEnabled(boolean enabled) {
7063         if (enabled == isEnabled()) return;
7064
7065         setFlags(enabled ? ENABLED : DISABLED, ENABLED_MASK);
7066
7067         /*
7068          * The View most likely has to change its appearance, so refresh
7069          * the drawable state.
7070          */
7071         refreshDrawableState();
7072
7073         // Invalidate too, since the default behavior for views is to be
7074         // be drawn at 50% alpha rather than to change the drawable.
7075         invalidate(true);
7076
7077         if (!enabled) {
7078             cancelPendingInputEvents();
7079         }
7080     }
7081
7082     /**
7083      * Set whether this view can receive the focus.
7084      *
7085      * Setting this to false will also ensure that this view is not focusable
7086      * in touch mode.
7087      *
7088      * @param focusable If true, this view can receive the focus.
7089      *
7090      * @see #setFocusableInTouchMode(boolean)
7091      * @attr ref android.R.styleable#View_focusable
7092      */
7093     public void setFocusable(boolean focusable) {
7094         if (!focusable) {
7095             setFlags(0, FOCUSABLE_IN_TOUCH_MODE);
7096         }
7097         setFlags(focusable ? FOCUSABLE : NOT_FOCUSABLE, FOCUSABLE_MASK);
7098     }
7099
7100     /**
7101      * Set whether this view can receive focus while in touch mode.
7102      *
7103      * Setting this to true will also ensure that this view is focusable.
7104      *
7105      * @param focusableInTouchMode If true, this view can receive the focus while
7106      *   in touch mode.
7107      *
7108      * @see #setFocusable(boolean)
7109      * @attr ref android.R.styleable#View_focusableInTouchMode
7110      */
7111     public void setFocusableInTouchMode(boolean focusableInTouchMode) {
7112         // Focusable in touch mode should always be set before the focusable flag
7113         // otherwise, setting the focusable flag will trigger a focusableViewAvailable()
7114         // which, in touch mode, will not successfully request focus on this view
7115         // because the focusable in touch mode flag is not set
7116         setFlags(focusableInTouchMode ? FOCUSABLE_IN_TOUCH_MODE : 0, FOCUSABLE_IN_TOUCH_MODE);
7117         if (focusableInTouchMode) {
7118             setFlags(FOCUSABLE, FOCUSABLE_MASK);
7119         }
7120     }
7121
7122     /**
7123      * Set whether this view should have sound effects enabled for events such as
7124      * clicking and touching.
7125      *
7126      * <p>You may wish to disable sound effects for a view if you already play sounds,
7127      * for instance, a dial key that plays dtmf tones.
7128      *
7129      * @param soundEffectsEnabled whether sound effects are enabled for this view.
7130      * @see #isSoundEffectsEnabled()
7131      * @see #playSoundEffect(int)
7132      * @attr ref android.R.styleable#View_soundEffectsEnabled
7133      */
7134     public void setSoundEffectsEnabled(boolean soundEffectsEnabled) {
7135         setFlags(soundEffectsEnabled ? SOUND_EFFECTS_ENABLED: 0, SOUND_EFFECTS_ENABLED);
7136     }
7137
7138     /**
7139      * @return whether this view should have sound effects enabled for events such as
7140      *     clicking and touching.
7141      *
7142      * @see #setSoundEffectsEnabled(boolean)
7143      * @see #playSoundEffect(int)
7144      * @attr ref android.R.styleable#View_soundEffectsEnabled
7145      */
7146     @ViewDebug.ExportedProperty
7147     public boolean isSoundEffectsEnabled() {
7148         return SOUND_EFFECTS_ENABLED == (mViewFlags & SOUND_EFFECTS_ENABLED);
7149     }
7150
7151     /**
7152      * Set whether this view should have haptic feedback for events such as
7153      * long presses.
7154      *
7155      * <p>You may wish to disable haptic feedback if your view already controls
7156      * its own haptic feedback.
7157      *
7158      * @param hapticFeedbackEnabled whether haptic feedback enabled for this view.
7159      * @see #isHapticFeedbackEnabled()
7160      * @see #performHapticFeedback(int)
7161      * @attr ref android.R.styleable#View_hapticFeedbackEnabled
7162      */
7163     public void setHapticFeedbackEnabled(boolean hapticFeedbackEnabled) {
7164         setFlags(hapticFeedbackEnabled ? HAPTIC_FEEDBACK_ENABLED: 0, HAPTIC_FEEDBACK_ENABLED);
7165     }
7166
7167     /**
7168      * @return whether this view should have haptic feedback enabled for events
7169      * long presses.
7170      *
7171      * @see #setHapticFeedbackEnabled(boolean)
7172      * @see #performHapticFeedback(int)
7173      * @attr ref android.R.styleable#View_hapticFeedbackEnabled
7174      */
7175     @ViewDebug.ExportedProperty
7176     public boolean isHapticFeedbackEnabled() {
7177         return HAPTIC_FEEDBACK_ENABLED == (mViewFlags & HAPTIC_FEEDBACK_ENABLED);
7178     }
7179
7180     /**
7181      * Returns the layout direction for this view.
7182      *
7183      * @return One of {@link #LAYOUT_DIRECTION_LTR},
7184      *   {@link #LAYOUT_DIRECTION_RTL},
7185      *   {@link #LAYOUT_DIRECTION_INHERIT} or
7186      *   {@link #LAYOUT_DIRECTION_LOCALE}.
7187      *
7188      * @attr ref android.R.styleable#View_layoutDirection
7189      *
7190      * @hide
7191      */
7192     @ViewDebug.ExportedProperty(category = "layout", mapping = {
7193         @ViewDebug.IntToString(from = LAYOUT_DIRECTION_LTR,     to = "LTR"),
7194         @ViewDebug.IntToString(from = LAYOUT_DIRECTION_RTL,     to = "RTL"),
7195         @ViewDebug.IntToString(from = LAYOUT_DIRECTION_INHERIT, to = "INHERIT"),
7196         @ViewDebug.IntToString(from = LAYOUT_DIRECTION_LOCALE,  to = "LOCALE")
7197     })
7198     @LayoutDir
7199     public int getRawLayoutDirection() {
7200         return (mPrivateFlags2 & PFLAG2_LAYOUT_DIRECTION_MASK) >> PFLAG2_LAYOUT_DIRECTION_MASK_SHIFT;
7201     }
7202
7203     /**
7204      * Set the layout direction for this view. This will propagate a reset of layout direction
7205      * resolution to the view's children and resolve layout direction for this view.
7206      *
7207      * @param layoutDirection the layout direction to set. Should be one of:
7208      *
7209      * {@link #LAYOUT_DIRECTION_LTR},
7210      * {@link #LAYOUT_DIRECTION_RTL},
7211      * {@link #LAYOUT_DIRECTION_INHERIT},
7212      * {@link #LAYOUT_DIRECTION_LOCALE}.
7213      *
7214      * Resolution will be done if the value is set to LAYOUT_DIRECTION_INHERIT. The resolution
7215      * proceeds up the parent chain of the view to get the value. If there is no parent, then it
7216      * will return the default {@link #LAYOUT_DIRECTION_LTR}.
7217      *
7218      * @attr ref android.R.styleable#View_layoutDirection
7219      */
7220     @RemotableViewMethod
7221     public void setLayoutDirection(@LayoutDir int layoutDirection) {
7222         if (getRawLayoutDirection() != layoutDirection) {
7223             // Reset the current layout direction and the resolved one
7224             mPrivateFlags2 &= ~PFLAG2_LAYOUT_DIRECTION_MASK;
7225             resetRtlProperties();
7226             // Set the new layout direction (filtered)
7227             mPrivateFlags2 |=
7228                     ((layoutDirection << PFLAG2_LAYOUT_DIRECTION_MASK_SHIFT) & PFLAG2_LAYOUT_DIRECTION_MASK);
7229             // We need to resolve all RTL properties as they all depend on layout direction
7230             resolveRtlPropertiesIfNeeded();
7231             requestLayout();
7232             invalidate(true);
7233         }
7234     }
7235
7236     /**
7237      * Returns the resolved layout direction for this view.
7238      *
7239      * @return {@link #LAYOUT_DIRECTION_RTL} if the layout direction is RTL or returns
7240      * {@link #LAYOUT_DIRECTION_LTR} if the layout direction is not RTL.
7241      *
7242      * For compatibility, this will return {@link #LAYOUT_DIRECTION_LTR} if API version
7243      * is lower than {@link android.os.Build.VERSION_CODES#JELLY_BEAN_MR1}.
7244      *
7245      * @attr ref android.R.styleable#View_layoutDirection
7246      */
7247     @ViewDebug.ExportedProperty(category = "layout", mapping = {
7248         @ViewDebug.IntToString(from = LAYOUT_DIRECTION_LTR, to = "RESOLVED_DIRECTION_LTR"),
7249         @ViewDebug.IntToString(from = LAYOUT_DIRECTION_RTL, to = "RESOLVED_DIRECTION_RTL")
7250     })
7251     @ResolvedLayoutDir
7252     public int getLayoutDirection() {
7253         final int targetSdkVersion = getContext().getApplicationInfo().targetSdkVersion;
7254         if (targetSdkVersion < JELLY_BEAN_MR1) {
7255             mPrivateFlags2 |= PFLAG2_LAYOUT_DIRECTION_RESOLVED;
7256             return LAYOUT_DIRECTION_RESOLVED_DEFAULT;
7257         }
7258         return ((mPrivateFlags2 & PFLAG2_LAYOUT_DIRECTION_RESOLVED_RTL) ==
7259                 PFLAG2_LAYOUT_DIRECTION_RESOLVED_RTL) ? LAYOUT_DIRECTION_RTL : LAYOUT_DIRECTION_LTR;
7260     }
7261
7262     /**
7263      * Indicates whether or not this view's layout is right-to-left. This is resolved from
7264      * layout attribute and/or the inherited value from the parent
7265      *
7266      * @return true if the layout is right-to-left.
7267      *
7268      * @hide
7269      */
7270     @ViewDebug.ExportedProperty(category = "layout")
7271     public boolean isLayoutRtl() {
7272         return (getLayoutDirection() == LAYOUT_DIRECTION_RTL);
7273     }
7274
7275     /**
7276      * Indicates whether the view is currently tracking transient state that the
7277      * app should not need to concern itself with saving and restoring, but that
7278      * the framework should take special note to preserve when possible.
7279      *
7280      * <p>A view with transient state cannot be trivially rebound from an external
7281      * data source, such as an adapter binding item views in a list. This may be
7282      * because the view is performing an animation, tracking user selection
7283      * of content, or similar.</p>
7284      *
7285      * @return true if the view has transient state
7286      */
7287     @ViewDebug.ExportedProperty(category = "layout")
7288     public boolean hasTransientState() {
7289         return (mPrivateFlags2 & PFLAG2_HAS_TRANSIENT_STATE) == PFLAG2_HAS_TRANSIENT_STATE;
7290     }
7291
7292     /**
7293      * Set whether this view is currently tracking transient state that the
7294      * framework should attempt to preserve when possible. This flag is reference counted,
7295      * so every call to setHasTransientState(true) should be paired with a later call
7296      * to setHasTransientState(false).
7297      *
7298      * <p>A view with transient state cannot be trivially rebound from an external
7299      * data source, such as an adapter binding item views in a list. This may be
7300      * because the view is performing an animation, tracking user selection
7301      * of content, or similar.</p>
7302      *
7303      * @param hasTransientState true if this view has transient state
7304      */
7305     public void setHasTransientState(boolean hasTransientState) {
7306         mTransientStateCount = hasTransientState ? mTransientStateCount + 1 :
7307                 mTransientStateCount - 1;
7308         if (mTransientStateCount < 0) {
7309             mTransientStateCount = 0;
7310             Log.e(VIEW_LOG_TAG, "hasTransientState decremented below 0: " +
7311                     "unmatched pair of setHasTransientState calls");
7312         } else if ((hasTransientState && mTransientStateCount == 1) ||
7313                 (!hasTransientState && mTransientStateCount == 0)) {
7314             // update flag if we've just incremented up from 0 or decremented down to 0
7315             mPrivateFlags2 = (mPrivateFlags2 & ~PFLAG2_HAS_TRANSIENT_STATE) |
7316                     (hasTransientState ? PFLAG2_HAS_TRANSIENT_STATE : 0);
7317             if (mParent != null) {
7318                 try {
7319                     mParent.childHasTransientStateChanged(this, hasTransientState);
7320                 } catch (AbstractMethodError e) {
7321                     Log.e(VIEW_LOG_TAG, mParent.getClass().getSimpleName() +
7322                             " does not fully implement ViewParent", e);
7323                 }
7324             }
7325         }
7326     }
7327
7328     /**
7329      * Returns true if this view is currently attached to a window.
7330      */
7331     public boolean isAttachedToWindow() {
7332         return mAttachInfo != null;
7333     }
7334
7335     /**
7336      * Returns true if this view has been through at least one layout since it
7337      * was last attached to or detached from a window.
7338      */
7339     public boolean isLaidOut() {
7340         return (mPrivateFlags3 & PFLAG3_IS_LAID_OUT) == PFLAG3_IS_LAID_OUT;
7341     }
7342
7343     /**
7344      * If this view doesn't do any drawing on its own, set this flag to
7345      * allow further optimizations. By default, this flag is not set on
7346      * View, but could be set on some View subclasses such as ViewGroup.
7347      *
7348      * Typically, if you override {@link #onDraw(android.graphics.Canvas)}
7349      * you should clear this flag.
7350      *
7351      * @param willNotDraw whether or not this View draw on its own
7352      */
7353     public void setWillNotDraw(boolean willNotDraw) {
7354         setFlags(willNotDraw ? WILL_NOT_DRAW : 0, DRAW_MASK);
7355     }
7356
7357     /**
7358      * Returns whether or not this View draws on its own.
7359      *
7360      * @return true if this view has nothing to draw, false otherwise
7361      */
7362     @ViewDebug.ExportedProperty(category = "drawing")
7363     public boolean willNotDraw() {
7364         return (mViewFlags & DRAW_MASK) == WILL_NOT_DRAW;
7365     }
7366
7367     /**
7368      * When a View's drawing cache is enabled, drawing is redirected to an
7369      * offscreen bitmap. Some views, like an ImageView, must be able to
7370      * bypass this mechanism if they already draw a single bitmap, to avoid
7371      * unnecessary usage of the memory.
7372      *
7373      * @param willNotCacheDrawing true if this view does not cache its
7374      *        drawing, false otherwise
7375      */
7376     public void setWillNotCacheDrawing(boolean willNotCacheDrawing) {
7377         setFlags(willNotCacheDrawing ? WILL_NOT_CACHE_DRAWING : 0, WILL_NOT_CACHE_DRAWING);
7378     }
7379
7380     /**
7381      * Returns whether or not this View can cache its drawing or not.
7382      *
7383      * @return true if this view does not cache its drawing, false otherwise
7384      */
7385     @ViewDebug.ExportedProperty(category = "drawing")
7386     public boolean willNotCacheDrawing() {
7387         return (mViewFlags & WILL_NOT_CACHE_DRAWING) == WILL_NOT_CACHE_DRAWING;
7388     }
7389
7390     /**
7391      * Indicates whether this view reacts to click events or not.
7392      *
7393      * @return true if the view is clickable, false otherwise
7394      *
7395      * @see #setClickable(boolean)
7396      * @attr ref android.R.styleable#View_clickable
7397      */
7398     @ViewDebug.ExportedProperty
7399     public boolean isClickable() {
7400         return (mViewFlags & CLICKABLE) == CLICKABLE;
7401     }
7402
7403     /**
7404      * Enables or disables click events for this view. When a view
7405      * is clickable it will change its state to "pressed" on every click.
7406      * Subclasses should set the view clickable to visually react to
7407      * user's clicks.
7408      *
7409      * @param clickable true to make the view clickable, false otherwise
7410      *
7411      * @see #isClickable()
7412      * @attr ref android.R.styleable#View_clickable
7413      */
7414     public void setClickable(boolean clickable) {
7415         setFlags(clickable ? CLICKABLE : 0, CLICKABLE);
7416     }
7417
7418     /**
7419      * Indicates whether this view reacts to long click events or not.
7420      *
7421      * @return true if the view is long clickable, false otherwise
7422      *
7423      * @see #setLongClickable(boolean)
7424      * @attr ref android.R.styleable#View_longClickable
7425      */
7426     public boolean isLongClickable() {
7427         return (mViewFlags & LONG_CLICKABLE) == LONG_CLICKABLE;
7428     }
7429
7430     /**
7431      * Enables or disables long click events for this view. When a view is long
7432      * clickable it reacts to the user holding down the button for a longer
7433      * duration than a tap. This event can either launch the listener or a
7434      * context menu.
7435      *
7436      * @param longClickable true to make the view long clickable, false otherwise
7437      * @see #isLongClickable()
7438      * @attr ref android.R.styleable#View_longClickable
7439      */
7440     public void setLongClickable(boolean longClickable) {
7441         setFlags(longClickable ? LONG_CLICKABLE : 0, LONG_CLICKABLE);
7442     }
7443
7444     /**
7445      * Sets the pressed state for this view and provides a touch coordinate for
7446      * animation hinting.
7447      *
7448      * @param pressed Pass true to set the View's internal state to "pressed",
7449      *            or false to reverts the View's internal state from a
7450      *            previously set "pressed" state.
7451      * @param x The x coordinate of the touch that caused the press
7452      * @param y The y coordinate of the touch that caused the press
7453      */
7454     private void setPressed(boolean pressed, float x, float y) {
7455         if (pressed) {
7456             drawableHotspotChanged(x, y);
7457         }
7458
7459         setPressed(pressed);
7460     }
7461
7462     /**
7463      * Sets the pressed state for this view.
7464      *
7465      * @see #isClickable()
7466      * @see #setClickable(boolean)
7467      *
7468      * @param pressed Pass true to set the View's internal state to "pressed", or false to reverts
7469      *        the View's internal state from a previously set "pressed" state.
7470      */
7471     public void setPressed(boolean pressed) {
7472         final boolean needsRefresh = pressed != ((mPrivateFlags & PFLAG_PRESSED) == PFLAG_PRESSED);
7473
7474         if (pressed) {
7475             mPrivateFlags |= PFLAG_PRESSED;
7476         } else {
7477             mPrivateFlags &= ~PFLAG_PRESSED;
7478         }
7479
7480         if (needsRefresh) {
7481             refreshDrawableState();
7482         }
7483         dispatchSetPressed(pressed);
7484     }
7485
7486     /**
7487      * Dispatch setPressed to all of this View's children.
7488      *
7489      * @see #setPressed(boolean)
7490      *
7491      * @param pressed The new pressed state
7492      */
7493     protected void dispatchSetPressed(boolean pressed) {
7494     }
7495
7496     /**
7497      * Indicates whether the view is currently in pressed state. Unless
7498      * {@link #setPressed(boolean)} is explicitly called, only clickable views can enter
7499      * the pressed state.
7500      *
7501      * @see #setPressed(boolean)
7502      * @see #isClickable()
7503      * @see #setClickable(boolean)
7504      *
7505      * @return true if the view is currently pressed, false otherwise
7506      */
7507     @ViewDebug.ExportedProperty
7508     public boolean isPressed() {
7509         return (mPrivateFlags & PFLAG_PRESSED) == PFLAG_PRESSED;
7510     }
7511
7512     /**
7513      * Indicates whether this view will participate in data collection through
7514      * {@link android.view.ViewAssistStructure}.  If true, it will not provide any data
7515      * for itself or its children.  If false, the normal data collection will be allowed.
7516      *
7517      * @return Returns false if assist data collection is not blocked, else true.
7518      *
7519      * @see #setAssistBlocked(boolean)
7520      * @attr ref android.R.styleable#View_assistBlocked
7521      */
7522     public boolean isAssistBlocked() {
7523         return (mPrivateFlags3 & PFLAG3_ASSIST_BLOCKED) != 0;
7524     }
7525
7526     /**
7527      * Controls whether assist data collection from this view and its children is enabled
7528      * (that is, whether {@link #onProvideAssistStructure} and
7529      * {@link #onProvideVirtualAssistStructure} will be called).  The default value is false,
7530      * allowing normal assist collection.  Setting this to false will disable assist collection.
7531      *
7532      * @param enabled Set to true to <em>disable</em> assist data collection, or false
7533      * (the default) to allow it.
7534      *
7535      * @see #isAssistBlocked()
7536      * @see #onProvideAssistStructure
7537      * @see #onProvideVirtualAssistStructure
7538      * @attr ref android.R.styleable#View_assistBlocked
7539      */
7540     public void setAssistBlocked(boolean enabled) {
7541         if (enabled) {
7542             mPrivateFlags3 |= PFLAG3_ASSIST_BLOCKED;
7543         } else {
7544             mPrivateFlags3 &= ~PFLAG3_ASSIST_BLOCKED;
7545         }
7546     }
7547
7548     /**
7549      * Indicates whether this view will save its state (that is,
7550      * whether its {@link #onSaveInstanceState} method will be called).
7551      *
7552      * @return Returns true if the view state saving is enabled, else false.
7553      *
7554      * @see #setSaveEnabled(boolean)
7555      * @attr ref android.R.styleable#View_saveEnabled
7556      */
7557     public boolean isSaveEnabled() {
7558         return (mViewFlags & SAVE_DISABLED_MASK) != SAVE_DISABLED;
7559     }
7560
7561     /**
7562      * Controls whether the saving of this view's state is
7563      * enabled (that is, whether its {@link #onSaveInstanceState} method
7564      * will be called).  Note that even if freezing is enabled, the
7565      * view still must have an id assigned to it (via {@link #setId(int)})
7566      * for its state to be saved.  This flag can only disable the
7567      * saving of this view; any child views may still have their state saved.
7568      *
7569      * @param enabled Set to false to <em>disable</em> state saving, or true
7570      * (the default) to allow it.
7571      *
7572      * @see #isSaveEnabled()
7573      * @see #setId(int)
7574      * @see #onSaveInstanceState()
7575      * @attr ref android.R.styleable#View_saveEnabled
7576      */
7577     public void setSaveEnabled(boolean enabled) {
7578         setFlags(enabled ? 0 : SAVE_DISABLED, SAVE_DISABLED_MASK);
7579     }
7580
7581     /**
7582      * Gets whether the framework should discard touches when the view's
7583      * window is obscured by another visible window.
7584      * Refer to the {@link View} security documentation for more details.
7585      *
7586      * @return True if touch filtering is enabled.
7587      *
7588      * @see #setFilterTouchesWhenObscured(boolean)
7589      * @attr ref android.R.styleable#View_filterTouchesWhenObscured
7590      */
7591     @ViewDebug.ExportedProperty
7592     public boolean getFilterTouchesWhenObscured() {
7593         return (mViewFlags & FILTER_TOUCHES_WHEN_OBSCURED) != 0;
7594     }
7595
7596     /**
7597      * Sets whether the framework should discard touches when the view's
7598      * window is obscured by another visible window.
7599      * Refer to the {@link View} security documentation for more details.
7600      *
7601      * @param enabled True if touch filtering should be enabled.
7602      *
7603      * @see #getFilterTouchesWhenObscured
7604      * @attr ref android.R.styleable#View_filterTouchesWhenObscured
7605      */
7606     public void setFilterTouchesWhenObscured(boolean enabled) {
7607         setFlags(enabled ? FILTER_TOUCHES_WHEN_OBSCURED : 0,
7608                 FILTER_TOUCHES_WHEN_OBSCURED);
7609     }
7610
7611     /**
7612      * Indicates whether the entire hierarchy under this view will save its
7613      * state when a state saving traversal occurs from its parent.  The default
7614      * is true; if false, these views will not be saved unless
7615      * {@link #saveHierarchyState(SparseArray)} is called directly on this view.
7616      *
7617      * @return Returns true if the view state saving from parent is enabled, else false.
7618      *
7619      * @see #setSaveFromParentEnabled(boolean)
7620      */
7621     public boolean isSaveFromParentEnabled() {
7622         return (mViewFlags & PARENT_SAVE_DISABLED_MASK) != PARENT_SAVE_DISABLED;
7623     }
7624
7625     /**
7626      * Controls whether the entire hierarchy under this view will save its
7627      * state when a state saving traversal occurs from its parent.  The default
7628      * is true; if false, these views will not be saved unless
7629      * {@link #saveHierarchyState(SparseArray)} is called directly on this view.
7630      *
7631      * @param enabled Set to false to <em>disable</em> state saving, or true
7632      * (the default) to allow it.
7633      *
7634      * @see #isSaveFromParentEnabled()
7635      * @see #setId(int)
7636      * @see #onSaveInstanceState()
7637      */
7638     public void setSaveFromParentEnabled(boolean enabled) {
7639         setFlags(enabled ? 0 : PARENT_SAVE_DISABLED, PARENT_SAVE_DISABLED_MASK);
7640     }
7641
7642
7643     /**
7644      * Returns whether this View is able to take focus.
7645      *
7646      * @return True if this view can take focus, or false otherwise.
7647      * @attr ref android.R.styleable#View_focusable
7648      */
7649     @ViewDebug.ExportedProperty(category = "focus")
7650     public final boolean isFocusable() {
7651         return FOCUSABLE == (mViewFlags & FOCUSABLE_MASK);
7652     }
7653
7654     /**
7655      * When a view is focusable, it may not want to take focus when in touch mode.
7656      * For example, a button would like focus when the user is navigating via a D-pad
7657      * so that the user can click on it, but once the user starts touching the screen,
7658      * the button shouldn't take focus
7659      * @return Whether the view is focusable in touch mode.
7660      * @attr ref android.R.styleable#View_focusableInTouchMode
7661      */
7662     @ViewDebug.ExportedProperty
7663     public final boolean isFocusableInTouchMode() {
7664         return FOCUSABLE_IN_TOUCH_MODE == (mViewFlags & FOCUSABLE_IN_TOUCH_MODE);
7665     }
7666
7667     /**
7668      * Find the nearest view in the specified direction that can take focus.
7669      * This does not actually give focus to that view.
7670      *
7671      * @param direction One of FOCUS_UP, FOCUS_DOWN, FOCUS_LEFT, and FOCUS_RIGHT
7672      *
7673      * @return The nearest focusable in the specified direction, or null if none
7674      *         can be found.
7675      */
7676     public View focusSearch(@FocusRealDirection int direction) {
7677         if (mParent != null) {
7678             return mParent.focusSearch(this, direction);
7679         } else {
7680             return null;
7681         }
7682     }
7683
7684     /**
7685      * This method is the last chance for the focused view and its ancestors to
7686      * respond to an arrow key. This is called when the focused view did not
7687      * consume the key internally, nor could the view system find a new view in
7688      * the requested direction to give focus to.
7689      *
7690      * @param focused The currently focused view.
7691      * @param direction The direction focus wants to move. One of FOCUS_UP,
7692      *        FOCUS_DOWN, FOCUS_LEFT, and FOCUS_RIGHT.
7693      * @return True if the this view consumed this unhandled move.
7694      */
7695     public boolean dispatchUnhandledMove(View focused, @FocusRealDirection int direction) {
7696         return false;
7697     }
7698
7699     /**
7700      * If a user manually specified the next view id for a particular direction,
7701      * use the root to look up the view.
7702      * @param root The root view of the hierarchy containing this view.
7703      * @param direction One of FOCUS_UP, FOCUS_DOWN, FOCUS_LEFT, FOCUS_RIGHT, FOCUS_FORWARD,
7704      * or FOCUS_BACKWARD.
7705      * @return The user specified next view, or null if there is none.
7706      */
7707     View findUserSetNextFocus(View root, @FocusDirection int direction) {
7708         switch (direction) {
7709             case FOCUS_LEFT:
7710                 if (mNextFocusLeftId == View.NO_ID) return null;
7711                 return findViewInsideOutShouldExist(root, mNextFocusLeftId);
7712             case FOCUS_RIGHT:
7713                 if (mNextFocusRightId == View.NO_ID) return null;
7714                 return findViewInsideOutShouldExist(root, mNextFocusRightId);
7715             case FOCUS_UP:
7716                 if (mNextFocusUpId == View.NO_ID) return null;
7717                 return findViewInsideOutShouldExist(root, mNextFocusUpId);
7718             case FOCUS_DOWN:
7719                 if (mNextFocusDownId == View.NO_ID) return null;
7720                 return findViewInsideOutShouldExist(root, mNextFocusDownId);
7721             case FOCUS_FORWARD:
7722                 if (mNextFocusForwardId == View.NO_ID) return null;
7723                 return findViewInsideOutShouldExist(root, mNextFocusForwardId);
7724             case FOCUS_BACKWARD: {
7725                 if (mID == View.NO_ID) return null;
7726                 final int id = mID;
7727                 return root.findViewByPredicateInsideOut(this, new Predicate<View>() {
7728                     @Override
7729                     public boolean apply(View t) {
7730                         return t.mNextFocusForwardId == id;
7731                     }
7732                 });
7733             }
7734         }
7735         return null;
7736     }
7737
7738     private View findViewInsideOutShouldExist(View root, int id) {
7739         if (mMatchIdPredicate == null) {
7740             mMatchIdPredicate = new MatchIdPredicate();
7741         }
7742         mMatchIdPredicate.mId = id;
7743         View result = root.findViewByPredicateInsideOut(this, mMatchIdPredicate);
7744         if (result == null) {
7745             Log.w(VIEW_LOG_TAG, "couldn't find view with id " + id);
7746         }
7747         return result;
7748     }
7749
7750     /**
7751      * Find and return all focusable views that are descendants of this view,
7752      * possibly including this view if it is focusable itself.
7753      *
7754      * @param direction The direction of the focus
7755      * @return A list of focusable views
7756      */
7757     public ArrayList<View> getFocusables(@FocusDirection int direction) {
7758         ArrayList<View> result = new ArrayList<View>(24);
7759         addFocusables(result, direction);
7760         return result;
7761     }
7762
7763     /**
7764      * Add any focusable views that are descendants of this view (possibly
7765      * including this view if it is focusable itself) to views.  If we are in touch mode,
7766      * only add views that are also focusable in touch mode.
7767      *
7768      * @param views Focusable views found so far
7769      * @param direction The direction of the focus
7770      */
7771     public void addFocusables(ArrayList<View> views, @FocusDirection int direction) {
7772         addFocusables(views, direction, FOCUSABLES_TOUCH_MODE);
7773     }
7774
7775     /**
7776      * Adds any focusable views that are descendants of this view (possibly
7777      * including this view if it is focusable itself) to views. This method
7778      * adds all focusable views regardless if we are in touch mode or
7779      * only views focusable in touch mode if we are in touch mode or
7780      * only views that can take accessibility focus if accessibility is enabled
7781      * depending on the focusable mode parameter.
7782      *
7783      * @param views Focusable views found so far or null if all we are interested is
7784      *        the number of focusables.
7785      * @param direction The direction of the focus.
7786      * @param focusableMode The type of focusables to be added.
7787      *
7788      * @see #FOCUSABLES_ALL
7789      * @see #FOCUSABLES_TOUCH_MODE
7790      */
7791     public void addFocusables(ArrayList<View> views, @FocusDirection int direction,
7792             @FocusableMode int focusableMode) {
7793         if (views == null) {
7794             return;
7795         }
7796         if (!isFocusable()) {
7797             return;
7798         }
7799         if ((focusableMode & FOCUSABLES_TOUCH_MODE) == FOCUSABLES_TOUCH_MODE
7800                 && isInTouchMode() && !isFocusableInTouchMode()) {
7801             return;
7802         }
7803         views.add(this);
7804     }
7805
7806     /**
7807      * Finds the Views that contain given text. The containment is case insensitive.
7808      * The search is performed by either the text that the View renders or the content
7809      * description that describes the view for accessibility purposes and the view does
7810      * not render or both. Clients can specify how the search is to be performed via
7811      * passing the {@link #FIND_VIEWS_WITH_TEXT} and
7812      * {@link #FIND_VIEWS_WITH_CONTENT_DESCRIPTION} flags.
7813      *
7814      * @param outViews The output list of matching Views.
7815      * @param searched The text to match against.
7816      *
7817      * @see #FIND_VIEWS_WITH_TEXT
7818      * @see #FIND_VIEWS_WITH_CONTENT_DESCRIPTION
7819      * @see #setContentDescription(CharSequence)
7820      */
7821     public void findViewsWithText(ArrayList<View> outViews, CharSequence searched,
7822             @FindViewFlags int flags) {
7823         if (getAccessibilityNodeProvider() != null) {
7824             if ((flags & FIND_VIEWS_WITH_ACCESSIBILITY_NODE_PROVIDERS) != 0) {
7825                 outViews.add(this);
7826             }
7827         } else if ((flags & FIND_VIEWS_WITH_CONTENT_DESCRIPTION) != 0
7828                 && (searched != null && searched.length() > 0)
7829                 && (mContentDescription != null && mContentDescription.length() > 0)) {
7830             String searchedLowerCase = searched.toString().toLowerCase();
7831             String contentDescriptionLowerCase = mContentDescription.toString().toLowerCase();
7832             if (contentDescriptionLowerCase.contains(searchedLowerCase)) {
7833                 outViews.add(this);
7834             }
7835         }
7836     }
7837
7838     /**
7839      * Find and return all touchable views that are descendants of this view,
7840      * possibly including this view if it is touchable itself.
7841      *
7842      * @return A list of touchable views
7843      */
7844     public ArrayList<View> getTouchables() {
7845         ArrayList<View> result = new ArrayList<View>();
7846         addTouchables(result);
7847         return result;
7848     }
7849
7850     /**
7851      * Add any touchable views that are descendants of this view (possibly
7852      * including this view if it is touchable itself) to views.
7853      *
7854      * @param views Touchable views found so far
7855      */
7856     public void addTouchables(ArrayList<View> views) {
7857         final int viewFlags = mViewFlags;
7858
7859         if (((viewFlags & CLICKABLE) == CLICKABLE || (viewFlags & LONG_CLICKABLE) == LONG_CLICKABLE)
7860                 && (viewFlags & ENABLED_MASK) == ENABLED) {
7861             views.add(this);
7862         }
7863     }
7864
7865     /**
7866      * Returns whether this View is accessibility focused.
7867      *
7868      * @return True if this View is accessibility focused.
7869      */
7870     public boolean isAccessibilityFocused() {
7871         return (mPrivateFlags2 & PFLAG2_ACCESSIBILITY_FOCUSED) != 0;
7872     }
7873
7874     /**
7875      * Call this to try to give accessibility focus to this view.
7876      *
7877      * A view will not actually take focus if {@link AccessibilityManager#isEnabled()}
7878      * returns false or the view is no visible or the view already has accessibility
7879      * focus.
7880      *
7881      * See also {@link #focusSearch(int)}, which is what you call to say that you
7882      * have focus, and you want your parent to look for the next one.
7883      *
7884      * @return Whether this view actually took accessibility focus.
7885      *
7886      * @hide
7887      */
7888     public boolean requestAccessibilityFocus() {
7889         AccessibilityManager manager = AccessibilityManager.getInstance(mContext);
7890         if (!manager.isEnabled() || !manager.isTouchExplorationEnabled()) {
7891             return false;
7892         }
7893         if ((mViewFlags & VISIBILITY_MASK) != VISIBLE) {
7894             return false;
7895         }
7896         if ((mPrivateFlags2 & PFLAG2_ACCESSIBILITY_FOCUSED) == 0) {
7897             mPrivateFlags2 |= PFLAG2_ACCESSIBILITY_FOCUSED;
7898             ViewRootImpl viewRootImpl = getViewRootImpl();
7899             if (viewRootImpl != null) {
7900                 viewRootImpl.setAccessibilityFocus(this, null);
7901             }
7902             invalidate();
7903             sendAccessibilityEvent(AccessibilityEvent.TYPE_VIEW_ACCESSIBILITY_FOCUSED);
7904             return true;
7905         }
7906         return false;
7907     }
7908
7909     /**
7910      * Call this to try to clear accessibility focus of this view.
7911      *
7912      * See also {@link #focusSearch(int)}, which is what you call to say that you
7913      * have focus, and you want your parent to look for the next one.
7914      *
7915      * @hide
7916      */
7917     public void clearAccessibilityFocus() {
7918         clearAccessibilityFocusNoCallbacks();
7919         // Clear the global reference of accessibility focus if this
7920         // view or any of its descendants had accessibility focus.
7921         ViewRootImpl viewRootImpl = getViewRootImpl();
7922         if (viewRootImpl != null) {
7923             View focusHost = viewRootImpl.getAccessibilityFocusedHost();
7924             if (focusHost != null && ViewRootImpl.isViewDescendantOf(focusHost, this)) {
7925                 viewRootImpl.setAccessibilityFocus(null, null);
7926             }
7927         }
7928     }
7929
7930     private void sendAccessibilityHoverEvent(int eventType) {
7931         // Since we are not delivering to a client accessibility events from not
7932         // important views (unless the clinet request that) we need to fire the
7933         // event from the deepest view exposed to the client. As a consequence if
7934         // the user crosses a not exposed view the client will see enter and exit
7935         // of the exposed predecessor followed by and enter and exit of that same
7936         // predecessor when entering and exiting the not exposed descendant. This
7937         // is fine since the client has a clear idea which view is hovered at the
7938         // price of a couple more events being sent. This is a simple and
7939         // working solution.
7940         View source = this;
7941         while (true) {
7942             if (source.includeForAccessibility()) {
7943                 source.sendAccessibilityEvent(eventType);
7944                 return;
7945             }
7946             ViewParent parent = source.getParent();
7947             if (parent instanceof View) {
7948                 source = (View) parent;
7949             } else {
7950                 return;
7951             }
7952         }
7953     }
7954
7955     /**
7956      * Clears accessibility focus without calling any callback methods
7957      * normally invoked in {@link #clearAccessibilityFocus()}. This method
7958      * is used for clearing accessibility focus when giving this focus to
7959      * another view.
7960      */
7961     void clearAccessibilityFocusNoCallbacks() {
7962         if ((mPrivateFlags2 & PFLAG2_ACCESSIBILITY_FOCUSED) != 0) {
7963             mPrivateFlags2 &= ~PFLAG2_ACCESSIBILITY_FOCUSED;
7964             invalidate();
7965             sendAccessibilityEvent(AccessibilityEvent.TYPE_VIEW_ACCESSIBILITY_FOCUS_CLEARED);
7966         }
7967     }
7968
7969     /**
7970      * Call this to try to give focus to a specific view or to one of its
7971      * descendants.
7972      *
7973      * A view will not actually take focus if it is not focusable ({@link #isFocusable} returns
7974      * false), or if it is focusable and it is not focusable in touch mode
7975      * ({@link #isFocusableInTouchMode}) while the device is in touch mode.
7976      *
7977      * See also {@link #focusSearch(int)}, which is what you call to say that you
7978      * have focus, and you want your parent to look for the next one.
7979      *
7980      * This is equivalent to calling {@link #requestFocus(int, Rect)} with arguments
7981      * {@link #FOCUS_DOWN} and <code>null</code>.
7982      *
7983      * @return Whether this view or one of its descendants actually took focus.
7984      */
7985     public final boolean requestFocus() {
7986         return requestFocus(View.FOCUS_DOWN);
7987     }
7988
7989     /**
7990      * Call this to try to give focus to a specific view or to one of its
7991      * descendants and give it a hint about what direction focus is heading.
7992      *
7993      * A view will not actually take focus if it is not focusable ({@link #isFocusable} returns
7994      * false), or if it is focusable and it is not focusable in touch mode
7995      * ({@link #isFocusableInTouchMode}) while the device is in touch mode.
7996      *
7997      * See also {@link #focusSearch(int)}, which is what you call to say that you
7998      * have focus, and you want your parent to look for the next one.
7999      *
8000      * This is equivalent to calling {@link #requestFocus(int, Rect)} with
8001      * <code>null</code> set for the previously focused rectangle.
8002      *
8003      * @param direction One of FOCUS_UP, FOCUS_DOWN, FOCUS_LEFT, and FOCUS_RIGHT
8004      * @return Whether this view or one of its descendants actually took focus.
8005      */
8006     public final boolean requestFocus(int direction) {
8007         return requestFocus(direction, null);
8008     }
8009
8010     /**
8011      * Call this to try to give focus to a specific view or to one of its descendants
8012      * and give it hints about the direction and a specific rectangle that the focus
8013      * is coming from.  The rectangle can help give larger views a finer grained hint
8014      * about where focus is coming from, and therefore, where to show selection, or
8015      * forward focus change internally.
8016      *
8017      * A view will not actually take focus if it is not focusable ({@link #isFocusable} returns
8018      * false), or if it is focusable and it is not focusable in touch mode
8019      * ({@link #isFocusableInTouchMode}) while the device is in touch mode.
8020      *
8021      * A View will not take focus if it is not visible.
8022      *
8023      * A View will not take focus if one of its parents has
8024      * {@link android.view.ViewGroup#getDescendantFocusability()} equal to
8025      * {@link ViewGroup#FOCUS_BLOCK_DESCENDANTS}.
8026      *
8027      * See also {@link #focusSearch(int)}, which is what you call to say that you
8028      * have focus, and you want your parent to look for the next one.
8029      *
8030      * You may wish to override this method if your custom {@link View} has an internal
8031      * {@link View} that it wishes to forward the request to.
8032      *
8033      * @param direction One of FOCUS_UP, FOCUS_DOWN, FOCUS_LEFT, and FOCUS_RIGHT
8034      * @param previouslyFocusedRect The rectangle (in this View's coordinate system)
8035      *        to give a finer grained hint about where focus is coming from.  May be null
8036      *        if there is no hint.
8037      * @return Whether this view or one of its descendants actually took focus.
8038      */
8039     public boolean requestFocus(int direction, Rect previouslyFocusedRect) {
8040         return requestFocusNoSearch(direction, previouslyFocusedRect);
8041     }
8042
8043     private boolean requestFocusNoSearch(int direction, Rect previouslyFocusedRect) {
8044         // need to be focusable
8045         if ((mViewFlags & FOCUSABLE_MASK) != FOCUSABLE ||
8046                 (mViewFlags & VISIBILITY_MASK) != VISIBLE) {
8047             return false;
8048         }
8049
8050         // need to be focusable in touch mode if in touch mode
8051         if (isInTouchMode() &&
8052             (FOCUSABLE_IN_TOUCH_MODE != (mViewFlags & FOCUSABLE_IN_TOUCH_MODE))) {
8053                return false;
8054         }
8055
8056         // need to not have any parents blocking us
8057         if (hasAncestorThatBlocksDescendantFocus()) {
8058             return false;
8059         }
8060
8061         handleFocusGainInternal(direction, previouslyFocusedRect);
8062         return true;
8063     }
8064
8065     /**
8066      * Call this to try to give focus to a specific view or to one of its descendants. This is a
8067      * special variant of {@link #requestFocus() } that will allow views that are not focusable in
8068      * touch mode to request focus when they are touched.
8069      *
8070      * @return Whether this view or one of its descendants actually took focus.
8071      *
8072      * @see #isInTouchMode()
8073      *
8074      */
8075     public final boolean requestFocusFromTouch() {
8076         // Leave touch mode if we need to
8077         if (isInTouchMode()) {
8078             ViewRootImpl viewRoot = getViewRootImpl();
8079             if (viewRoot != null) {
8080                 viewRoot.ensureTouchMode(false);
8081             }
8082         }
8083         return requestFocus(View.FOCUS_DOWN);
8084     }
8085
8086     /**
8087      * @return Whether any ancestor of this view blocks descendant focus.
8088      */
8089     private boolean hasAncestorThatBlocksDescendantFocus() {
8090         final boolean focusableInTouchMode = isFocusableInTouchMode();
8091         ViewParent ancestor = mParent;
8092         while (ancestor instanceof ViewGroup) {
8093             final ViewGroup vgAncestor = (ViewGroup) ancestor;
8094             if (vgAncestor.getDescendantFocusability() == ViewGroup.FOCUS_BLOCK_DESCENDANTS
8095                     || (!focusableInTouchMode && vgAncestor.shouldBlockFocusForTouchscreen())) {
8096                 return true;
8097             } else {
8098                 ancestor = vgAncestor.getParent();
8099             }
8100         }
8101         return false;
8102     }
8103
8104     /**
8105      * Gets the mode for determining whether this View is important for accessibility
8106      * which is if it fires accessibility events and if it is reported to
8107      * accessibility services that query the screen.
8108      *
8109      * @return The mode for determining whether a View is important for accessibility.
8110      *
8111      * @attr ref android.R.styleable#View_importantForAccessibility
8112      *
8113      * @see #IMPORTANT_FOR_ACCESSIBILITY_YES
8114      * @see #IMPORTANT_FOR_ACCESSIBILITY_NO
8115      * @see #IMPORTANT_FOR_ACCESSIBILITY_NO_HIDE_DESCENDANTS
8116      * @see #IMPORTANT_FOR_ACCESSIBILITY_AUTO
8117      */
8118     @ViewDebug.ExportedProperty(category = "accessibility", mapping = {
8119             @ViewDebug.IntToString(from = IMPORTANT_FOR_ACCESSIBILITY_AUTO, to = "auto"),
8120             @ViewDebug.IntToString(from = IMPORTANT_FOR_ACCESSIBILITY_YES, to = "yes"),
8121             @ViewDebug.IntToString(from = IMPORTANT_FOR_ACCESSIBILITY_NO, to = "no"),
8122             @ViewDebug.IntToString(from = IMPORTANT_FOR_ACCESSIBILITY_NO_HIDE_DESCENDANTS,
8123                     to = "noHideDescendants")
8124         })
8125     public int getImportantForAccessibility() {
8126         return (mPrivateFlags2 & PFLAG2_IMPORTANT_FOR_ACCESSIBILITY_MASK)
8127                 >> PFLAG2_IMPORTANT_FOR_ACCESSIBILITY_SHIFT;
8128     }
8129
8130     /**
8131      * Sets the live region mode for this view. This indicates to accessibility
8132      * services whether they should automatically notify the user about changes
8133      * to the view's content description or text, or to the content descriptions
8134      * or text of the view's children (where applicable).
8135      * <p>
8136      * For example, in a login screen with a TextView that displays an "incorrect
8137      * password" notification, that view should be marked as a live region with
8138      * mode {@link #ACCESSIBILITY_LIVE_REGION_POLITE}.
8139      * <p>
8140      * To disable change notifications for this view, use
8141      * {@link #ACCESSIBILITY_LIVE_REGION_NONE}. This is the default live region
8142      * mode for most views.
8143      * <p>
8144      * To indicate that the user should be notified of changes, use
8145      * {@link #ACCESSIBILITY_LIVE_REGION_POLITE}.
8146      * <p>
8147      * If the view's changes should interrupt ongoing speech and notify the user
8148      * immediately, use {@link #ACCESSIBILITY_LIVE_REGION_ASSERTIVE}.
8149      *
8150      * @param mode The live region mode for this view, one of:
8151      *        <ul>
8152      *        <li>{@link #ACCESSIBILITY_LIVE_REGION_NONE}
8153      *        <li>{@link #ACCESSIBILITY_LIVE_REGION_POLITE}
8154      *        <li>{@link #ACCESSIBILITY_LIVE_REGION_ASSERTIVE}
8155      *        </ul>
8156      * @attr ref android.R.styleable#View_accessibilityLiveRegion
8157      */
8158     public void setAccessibilityLiveRegion(int mode) {
8159         if (mode != getAccessibilityLiveRegion()) {
8160             mPrivateFlags2 &= ~PFLAG2_ACCESSIBILITY_LIVE_REGION_MASK;
8161             mPrivateFlags2 |= (mode << PFLAG2_ACCESSIBILITY_LIVE_REGION_SHIFT)
8162                     & PFLAG2_ACCESSIBILITY_LIVE_REGION_MASK;
8163             notifyViewAccessibilityStateChangedIfNeeded(
8164                     AccessibilityEvent.CONTENT_CHANGE_TYPE_UNDEFINED);
8165         }
8166     }
8167
8168     /**
8169      * Gets the live region mode for this View.
8170      *
8171      * @return The live region mode for the view.
8172      *
8173      * @attr ref android.R.styleable#View_accessibilityLiveRegion
8174      *
8175      * @see #setAccessibilityLiveRegion(int)
8176      */
8177     public int getAccessibilityLiveRegion() {
8178         return (mPrivateFlags2 & PFLAG2_ACCESSIBILITY_LIVE_REGION_MASK)
8179                 >> PFLAG2_ACCESSIBILITY_LIVE_REGION_SHIFT;
8180     }
8181
8182     /**
8183      * Sets how to determine whether this view is important for accessibility
8184      * which is if it fires accessibility events and if it is reported to
8185      * accessibility services that query the screen.
8186      *
8187      * @param mode How to determine whether this view is important for accessibility.
8188      *
8189      * @attr ref android.R.styleable#View_importantForAccessibility
8190      *
8191      * @see #IMPORTANT_FOR_ACCESSIBILITY_YES
8192      * @see #IMPORTANT_FOR_ACCESSIBILITY_NO
8193      * @see #IMPORTANT_FOR_ACCESSIBILITY_NO_HIDE_DESCENDANTS
8194      * @see #IMPORTANT_FOR_ACCESSIBILITY_AUTO
8195      */
8196     public void setImportantForAccessibility(int mode) {
8197         final int oldMode = getImportantForAccessibility();
8198         if (mode != oldMode) {
8199             // If we're moving between AUTO and another state, we might not need
8200             // to send a subtree changed notification. We'll store the computed
8201             // importance, since we'll need to check it later to make sure.
8202             final boolean maySkipNotify = oldMode == IMPORTANT_FOR_ACCESSIBILITY_AUTO
8203                     || mode == IMPORTANT_FOR_ACCESSIBILITY_AUTO;
8204             final boolean oldIncludeForAccessibility = maySkipNotify && includeForAccessibility();
8205             mPrivateFlags2 &= ~PFLAG2_IMPORTANT_FOR_ACCESSIBILITY_MASK;
8206             mPrivateFlags2 |= (mode << PFLAG2_IMPORTANT_FOR_ACCESSIBILITY_SHIFT)
8207                     & PFLAG2_IMPORTANT_FOR_ACCESSIBILITY_MASK;
8208             if (!maySkipNotify || oldIncludeForAccessibility != includeForAccessibility()) {
8209                 notifySubtreeAccessibilityStateChangedIfNeeded();
8210             } else {
8211                 notifyViewAccessibilityStateChangedIfNeeded(
8212                         AccessibilityEvent.CONTENT_CHANGE_TYPE_UNDEFINED);
8213             }
8214         }
8215     }
8216
8217     /**
8218      * Computes whether this view should be exposed for accessibility. In
8219      * general, views that are interactive or provide information are exposed
8220      * while views that serve only as containers are hidden.
8221      * <p>
8222      * If an ancestor of this view has importance
8223      * {@link #IMPORTANT_FOR_ACCESSIBILITY_NO_HIDE_DESCENDANTS}, this method
8224      * returns <code>false</code>.
8225      * <p>
8226      * Otherwise, the value is computed according to the view's
8227      * {@link #getImportantForAccessibility()} value:
8228      * <ol>
8229      * <li>{@link #IMPORTANT_FOR_ACCESSIBILITY_NO} or
8230      * {@link #IMPORTANT_FOR_ACCESSIBILITY_NO_HIDE_DESCENDANTS}, return <code>false
8231      * </code>
8232      * <li>{@link #IMPORTANT_FOR_ACCESSIBILITY_YES}, return <code>true</code>
8233      * <li>{@link #IMPORTANT_FOR_ACCESSIBILITY_AUTO}, return <code>true</code> if
8234      * view satisfies any of the following:
8235      * <ul>
8236      * <li>Is actionable, e.g. {@link #isClickable()},
8237      * {@link #isLongClickable()}, or {@link #isFocusable()}
8238      * <li>Has an {@link AccessibilityDelegate}
8239      * <li>Has an interaction listener, e.g. {@link OnTouchListener},
8240      * {@link OnKeyListener}, etc.
8241      * <li>Is an accessibility live region, e.g.
8242      * {@link #getAccessibilityLiveRegion()} is not
8243      * {@link #ACCESSIBILITY_LIVE_REGION_NONE}.
8244      * </ul>
8245      * </ol>
8246      *
8247      * @return Whether the view is exposed for accessibility.
8248      * @see #setImportantForAccessibility(int)
8249      * @see #getImportantForAccessibility()
8250      */
8251     public boolean isImportantForAccessibility() {
8252         final int mode = (mPrivateFlags2 & PFLAG2_IMPORTANT_FOR_ACCESSIBILITY_MASK)
8253                 >> PFLAG2_IMPORTANT_FOR_ACCESSIBILITY_SHIFT;
8254         if (mode == IMPORTANT_FOR_ACCESSIBILITY_NO
8255                 || mode == IMPORTANT_FOR_ACCESSIBILITY_NO_HIDE_DESCENDANTS) {
8256             return false;
8257         }
8258
8259         // Check parent mode to ensure we're not hidden.
8260         ViewParent parent = mParent;
8261         while (parent instanceof View) {
8262             if (((View) parent).getImportantForAccessibility()
8263                     == IMPORTANT_FOR_ACCESSIBILITY_NO_HIDE_DESCENDANTS) {
8264                 return false;
8265             }
8266             parent = parent.getParent();
8267         }
8268
8269         return mode == IMPORTANT_FOR_ACCESSIBILITY_YES || isActionableForAccessibility()
8270                 || hasListenersForAccessibility() || getAccessibilityNodeProvider() != null
8271                 || getAccessibilityLiveRegion() != ACCESSIBILITY_LIVE_REGION_NONE;
8272     }
8273
8274     /**
8275      * Gets the parent for accessibility purposes. Note that the parent for
8276      * accessibility is not necessary the immediate parent. It is the first
8277      * predecessor that is important for accessibility.
8278      *
8279      * @return The parent for accessibility purposes.
8280      */
8281     public ViewParent getParentForAccessibility() {
8282         if (mParent instanceof View) {
8283             View parentView = (View) mParent;
8284             if (parentView.includeForAccessibility()) {
8285                 return mParent;
8286             } else {
8287                 return mParent.getParentForAccessibility();
8288             }
8289         }
8290         return null;
8291     }
8292
8293     /**
8294      * Adds the children of a given View for accessibility. Since some Views are
8295      * not important for accessibility the children for accessibility are not
8296      * necessarily direct children of the view, rather they are the first level of
8297      * descendants important for accessibility.
8298      *
8299      * @param children The list of children for accessibility.
8300      */
8301     public void addChildrenForAccessibility(ArrayList<View> children) {
8302
8303     }
8304
8305     /**
8306      * Whether to regard this view for accessibility. A view is regarded for
8307      * accessibility if it is important for accessibility or the querying
8308      * accessibility service has explicitly requested that view not
8309      * important for accessibility are regarded.
8310      *
8311      * @return Whether to regard the view for accessibility.
8312      *
8313      * @hide
8314      */
8315     public boolean includeForAccessibility() {
8316         if (mAttachInfo != null) {
8317             return (mAttachInfo.mAccessibilityFetchFlags
8318                     & AccessibilityNodeInfo.FLAG_INCLUDE_NOT_IMPORTANT_VIEWS) != 0
8319                     || isImportantForAccessibility();
8320         }
8321         return false;
8322     }
8323
8324     /**
8325      * Returns whether the View is considered actionable from
8326      * accessibility perspective. Such view are important for
8327      * accessibility.
8328      *
8329      * @return True if the view is actionable for accessibility.
8330      *
8331      * @hide
8332      */
8333     public boolean isActionableForAccessibility() {
8334         return (isClickable() || isLongClickable() || isFocusable());
8335     }
8336
8337     /**
8338      * Returns whether the View has registered callbacks which makes it
8339      * important for accessibility.
8340      *
8341      * @return True if the view is actionable for accessibility.
8342      */
8343     private boolean hasListenersForAccessibility() {
8344         ListenerInfo info = getListenerInfo();
8345         return mTouchDelegate != null || info.mOnKeyListener != null
8346                 || info.mOnTouchListener != null || info.mOnGenericMotionListener != null
8347                 || info.mOnHoverListener != null || info.mOnDragListener != null;
8348     }
8349
8350     /**
8351      * Notifies that the accessibility state of this view changed. The change
8352      * is local to this view and does not represent structural changes such
8353      * as children and parent. For example, the view became focusable. The
8354      * notification is at at most once every
8355      * {@link ViewConfiguration#getSendRecurringAccessibilityEventsInterval()}
8356      * to avoid unnecessary load to the system. Also once a view has a pending
8357      * notification this method is a NOP until the notification has been sent.
8358      *
8359      * @hide
8360      */
8361     public void notifyViewAccessibilityStateChangedIfNeeded(int changeType) {
8362         if (!AccessibilityManager.getInstance(mContext).isEnabled()) {
8363             return;
8364         }
8365         if (mSendViewStateChangedAccessibilityEvent == null) {
8366             mSendViewStateChangedAccessibilityEvent =
8367                     new SendViewStateChangedAccessibilityEvent();
8368         }
8369         mSendViewStateChangedAccessibilityEvent.runOrPost(changeType);
8370     }
8371
8372     /**
8373      * Notifies that the accessibility state of this view changed. The change
8374      * is *not* local to this view and does represent structural changes such
8375      * as children and parent. For example, the view size changed. The
8376      * notification is at at most once every
8377      * {@link ViewConfiguration#getSendRecurringAccessibilityEventsInterval()}
8378      * to avoid unnecessary load to the system. Also once a view has a pending
8379      * notification this method is a NOP until the notification has been sent.
8380      *
8381      * @hide
8382      */
8383     public void notifySubtreeAccessibilityStateChangedIfNeeded() {
8384         if (!AccessibilityManager.getInstance(mContext).isEnabled()) {
8385             return;
8386         }
8387         if ((mPrivateFlags2 & PFLAG2_SUBTREE_ACCESSIBILITY_STATE_CHANGED) == 0) {
8388             mPrivateFlags2 |= PFLAG2_SUBTREE_ACCESSIBILITY_STATE_CHANGED;
8389             if (mParent != null) {
8390                 try {
8391                     mParent.notifySubtreeAccessibilityStateChanged(
8392                             this, this, AccessibilityEvent.CONTENT_CHANGE_TYPE_SUBTREE);
8393                 } catch (AbstractMethodError e) {
8394                     Log.e(VIEW_LOG_TAG, mParent.getClass().getSimpleName() +
8395                             " does not fully implement ViewParent", e);
8396                 }
8397             }
8398         }
8399     }
8400
8401     /**
8402      * Reset the flag indicating the accessibility state of the subtree rooted
8403      * at this view changed.
8404      */
8405     void resetSubtreeAccessibilityStateChanged() {
8406         mPrivateFlags2 &= ~PFLAG2_SUBTREE_ACCESSIBILITY_STATE_CHANGED;
8407     }
8408
8409     /**
8410      * Report an accessibility action to this view's parents for delegated processing.
8411      *
8412      * <p>Implementations of {@link #performAccessibilityAction(int, Bundle)} may internally
8413      * call this method to delegate an accessibility action to a supporting parent. If the parent
8414      * returns true from its
8415      * {@link ViewParent#onNestedPrePerformAccessibilityAction(View, int, android.os.Bundle)}
8416      * method this method will return true to signify that the action was consumed.</p>
8417      *
8418      * <p>This method is useful for implementing nested scrolling child views. If
8419      * {@link #isNestedScrollingEnabled()} returns true and the action is a scrolling action
8420      * a custom view implementation may invoke this method to allow a parent to consume the
8421      * scroll first. If this method returns true the custom view should skip its own scrolling
8422      * behavior.</p>
8423      *
8424      * @param action Accessibility action to delegate
8425      * @param arguments Optional action arguments
8426      * @return true if the action was consumed by a parent
8427      */
8428     public boolean dispatchNestedPrePerformAccessibilityAction(int action, Bundle arguments) {
8429         for (ViewParent p = getParent(); p != null; p = p.getParent()) {
8430             if (p.onNestedPrePerformAccessibilityAction(this, action, arguments)) {
8431                 return true;
8432             }
8433         }
8434         return false;
8435     }
8436
8437     /**
8438      * Performs the specified accessibility action on the view. For
8439      * possible accessibility actions look at {@link AccessibilityNodeInfo}.
8440      * <p>
8441      * If an {@link AccessibilityDelegate} has been specified via calling
8442      * {@link #setAccessibilityDelegate(AccessibilityDelegate)} its
8443      * {@link AccessibilityDelegate#performAccessibilityAction(View, int, Bundle)}
8444      * is responsible for handling this call.
8445      * </p>
8446      *
8447      * <p>The default implementation will delegate
8448      * {@link AccessibilityNodeInfo#ACTION_SCROLL_BACKWARD} and
8449      * {@link AccessibilityNodeInfo#ACTION_SCROLL_FORWARD} to nested scrolling parents if
8450      * {@link #isNestedScrollingEnabled() nested scrolling is enabled} on this view.</p>
8451      *
8452      * @param action The action to perform.
8453      * @param arguments Optional action arguments.
8454      * @return Whether the action was performed.
8455      */
8456     public boolean performAccessibilityAction(int action, Bundle arguments) {
8457       if (mAccessibilityDelegate != null) {
8458           return mAccessibilityDelegate.performAccessibilityAction(this, action, arguments);
8459       } else {
8460           return performAccessibilityActionInternal(action, arguments);
8461       }
8462     }
8463
8464    /**
8465     * @see #performAccessibilityAction(int, Bundle)
8466     *
8467     * Note: Called from the default {@link AccessibilityDelegate}.
8468     *
8469     * @hide
8470     */
8471     public boolean performAccessibilityActionInternal(int action, Bundle arguments) {
8472         if (isNestedScrollingEnabled()
8473                 && (action == AccessibilityNodeInfo.ACTION_SCROLL_BACKWARD
8474                 || action == AccessibilityNodeInfo.ACTION_SCROLL_FORWARD)) {
8475             if (dispatchNestedPrePerformAccessibilityAction(action, arguments)) {
8476                 return true;
8477             }
8478         }
8479
8480         switch (action) {
8481             case AccessibilityNodeInfo.ACTION_CLICK: {
8482                 if (isClickable()) {
8483                     performClick();
8484                     return true;
8485                 }
8486             } break;
8487             case AccessibilityNodeInfo.ACTION_LONG_CLICK: {
8488                 if (isLongClickable()) {
8489                     performLongClick();
8490                     return true;
8491                 }
8492             } break;
8493             case AccessibilityNodeInfo.ACTION_FOCUS: {
8494                 if (!hasFocus()) {
8495                     // Get out of touch mode since accessibility
8496                     // wants to move focus around.
8497                     getViewRootImpl().ensureTouchMode(false);
8498                     return requestFocus();
8499                 }
8500             } break;
8501             case AccessibilityNodeInfo.ACTION_CLEAR_FOCUS: {
8502                 if (hasFocus()) {
8503                     clearFocus();
8504                     return !isFocused();
8505                 }
8506             } break;
8507             case AccessibilityNodeInfo.ACTION_SELECT: {
8508                 if (!isSelected()) {
8509                     setSelected(true);
8510                     return isSelected();
8511                 }
8512             } break;
8513             case AccessibilityNodeInfo.ACTION_CLEAR_SELECTION: {
8514                 if (isSelected()) {
8515                     setSelected(false);
8516                     return !isSelected();
8517                 }
8518             } break;
8519             case AccessibilityNodeInfo.ACTION_ACCESSIBILITY_FOCUS: {
8520                 if (!isAccessibilityFocused()) {
8521                     return requestAccessibilityFocus();
8522                 }
8523             } break;
8524             case AccessibilityNodeInfo.ACTION_CLEAR_ACCESSIBILITY_FOCUS: {
8525                 if (isAccessibilityFocused()) {
8526                     clearAccessibilityFocus();
8527                     return true;
8528                 }
8529             } break;
8530             case AccessibilityNodeInfo.ACTION_NEXT_AT_MOVEMENT_GRANULARITY: {
8531                 if (arguments != null) {
8532                     final int granularity = arguments.getInt(
8533                             AccessibilityNodeInfo.ACTION_ARGUMENT_MOVEMENT_GRANULARITY_INT);
8534                     final boolean extendSelection = arguments.getBoolean(
8535                             AccessibilityNodeInfo.ACTION_ARGUMENT_EXTEND_SELECTION_BOOLEAN);
8536                     return traverseAtGranularity(granularity, true, extendSelection);
8537                 }
8538             } break;
8539             case AccessibilityNodeInfo.ACTION_PREVIOUS_AT_MOVEMENT_GRANULARITY: {
8540                 if (arguments != null) {
8541                     final int granularity = arguments.getInt(
8542                             AccessibilityNodeInfo.ACTION_ARGUMENT_MOVEMENT_GRANULARITY_INT);
8543                     final boolean extendSelection = arguments.getBoolean(
8544                             AccessibilityNodeInfo.ACTION_ARGUMENT_EXTEND_SELECTION_BOOLEAN);
8545                     return traverseAtGranularity(granularity, false, extendSelection);
8546                 }
8547             } break;
8548             case AccessibilityNodeInfo.ACTION_SET_SELECTION: {
8549                 CharSequence text = getIterableTextForAccessibility();
8550                 if (text == null) {
8551                     return false;
8552                 }
8553                 final int start = (arguments != null) ? arguments.getInt(
8554                         AccessibilityNodeInfo.ACTION_ARGUMENT_SELECTION_START_INT, -1) : -1;
8555                 final int end = (arguments != null) ? arguments.getInt(
8556                 AccessibilityNodeInfo.ACTION_ARGUMENT_SELECTION_END_INT, -1) : -1;
8557                 // Only cursor position can be specified (selection length == 0)
8558                 if ((getAccessibilitySelectionStart() != start
8559                         || getAccessibilitySelectionEnd() != end)
8560                         && (start == end)) {
8561                     setAccessibilitySelection(start, end);
8562                     notifyViewAccessibilityStateChangedIfNeeded(
8563                             AccessibilityEvent.CONTENT_CHANGE_TYPE_UNDEFINED);
8564                     return true;
8565                 }
8566             } break;
8567             case R.id.accessibilityActionShowOnScreen: {
8568                 if (mAttachInfo != null) {
8569                     final Rect r = mAttachInfo.mTmpInvalRect;
8570                     getDrawingRect(r);
8571                     return requestRectangleOnScreen(r, true);
8572                 }
8573             } break;
8574         }
8575         return false;
8576     }
8577
8578     private boolean traverseAtGranularity(int granularity, boolean forward,
8579             boolean extendSelection) {
8580         CharSequence text = getIterableTextForAccessibility();
8581         if (text == null || text.length() == 0) {
8582             return false;
8583         }
8584         TextSegmentIterator iterator = getIteratorForGranularity(granularity);
8585         if (iterator == null) {
8586             return false;
8587         }
8588         int current = getAccessibilitySelectionEnd();
8589         if (current == ACCESSIBILITY_CURSOR_POSITION_UNDEFINED) {
8590             current = forward ? 0 : text.length();
8591         }
8592         final int[] range = forward ? iterator.following(current) : iterator.preceding(current);
8593         if (range == null) {
8594             return false;
8595         }
8596         final int segmentStart = range[0];
8597         final int segmentEnd = range[1];
8598         int selectionStart;
8599         int selectionEnd;
8600         if (extendSelection && isAccessibilitySelectionExtendable()) {
8601             selectionStart = getAccessibilitySelectionStart();
8602             if (selectionStart == ACCESSIBILITY_CURSOR_POSITION_UNDEFINED) {
8603                 selectionStart = forward ? segmentStart : segmentEnd;
8604             }
8605             selectionEnd = forward ? segmentEnd : segmentStart;
8606         } else {
8607             selectionStart = selectionEnd= forward ? segmentEnd : segmentStart;
8608         }
8609         setAccessibilitySelection(selectionStart, selectionEnd);
8610         final int action = forward ? AccessibilityNodeInfo.ACTION_NEXT_AT_MOVEMENT_GRANULARITY
8611                 : AccessibilityNodeInfo.ACTION_PREVIOUS_AT_MOVEMENT_GRANULARITY;
8612         sendViewTextTraversedAtGranularityEvent(action, granularity, segmentStart, segmentEnd);
8613         return true;
8614     }
8615
8616     /**
8617      * Gets the text reported for accessibility purposes.
8618      *
8619      * @return The accessibility text.
8620      *
8621      * @hide
8622      */
8623     public CharSequence getIterableTextForAccessibility() {
8624         return getContentDescription();
8625     }
8626
8627     /**
8628      * Gets whether accessibility selection can be extended.
8629      *
8630      * @return If selection is extensible.
8631      *
8632      * @hide
8633      */
8634     public boolean isAccessibilitySelectionExtendable() {
8635         return false;
8636     }
8637
8638     /**
8639      * @hide
8640      */
8641     public int getAccessibilitySelectionStart() {
8642         return mAccessibilityCursorPosition;
8643     }
8644
8645     /**
8646      * @hide
8647      */
8648     public int getAccessibilitySelectionEnd() {
8649         return getAccessibilitySelectionStart();
8650     }
8651
8652     /**
8653      * @hide
8654      */
8655     public void setAccessibilitySelection(int start, int end) {
8656         if (start ==  end && end == mAccessibilityCursorPosition) {
8657             return;
8658         }
8659         if (start >= 0 && start == end && end <= getIterableTextForAccessibility().length()) {
8660             mAccessibilityCursorPosition = start;
8661         } else {
8662             mAccessibilityCursorPosition = ACCESSIBILITY_CURSOR_POSITION_UNDEFINED;
8663         }
8664         sendAccessibilityEvent(AccessibilityEvent.TYPE_VIEW_TEXT_SELECTION_CHANGED);
8665     }
8666
8667     private void sendViewTextTraversedAtGranularityEvent(int action, int granularity,
8668             int fromIndex, int toIndex) {
8669         if (mParent == null) {
8670             return;
8671         }
8672         AccessibilityEvent event = AccessibilityEvent.obtain(
8673                 AccessibilityEvent.TYPE_VIEW_TEXT_TRAVERSED_AT_MOVEMENT_GRANULARITY);
8674         onInitializeAccessibilityEvent(event);
8675         onPopulateAccessibilityEvent(event);
8676         event.setFromIndex(fromIndex);
8677         event.setToIndex(toIndex);
8678         event.setAction(action);
8679         event.setMovementGranularity(granularity);
8680         mParent.requestSendAccessibilityEvent(this, event);
8681     }
8682
8683     /**
8684      * @hide
8685      */
8686     public TextSegmentIterator getIteratorForGranularity(int granularity) {
8687         switch (granularity) {
8688             case AccessibilityNodeInfo.MOVEMENT_GRANULARITY_CHARACTER: {
8689                 CharSequence text = getIterableTextForAccessibility();
8690                 if (text != null && text.length() > 0) {
8691                     CharacterTextSegmentIterator iterator =
8692                         CharacterTextSegmentIterator.getInstance(
8693                                 mContext.getResources().getConfiguration().locale);
8694                     iterator.initialize(text.toString());
8695                     return iterator;
8696                 }
8697             } break;
8698             case AccessibilityNodeInfo.MOVEMENT_GRANULARITY_WORD: {
8699                 CharSequence text = getIterableTextForAccessibility();
8700                 if (text != null && text.length() > 0) {
8701                     WordTextSegmentIterator iterator =
8702                         WordTextSegmentIterator.getInstance(
8703                                 mContext.getResources().getConfiguration().locale);
8704                     iterator.initialize(text.toString());
8705                     return iterator;
8706                 }
8707             } break;
8708             case AccessibilityNodeInfo.MOVEMENT_GRANULARITY_PARAGRAPH: {
8709                 CharSequence text = getIterableTextForAccessibility();
8710                 if (text != null && text.length() > 0) {
8711                     ParagraphTextSegmentIterator iterator =
8712                         ParagraphTextSegmentIterator.getInstance();
8713                     iterator.initialize(text.toString());
8714                     return iterator;
8715                 }
8716             } break;
8717         }
8718         return null;
8719     }
8720
8721     /**
8722      * @hide
8723      */
8724     public void dispatchStartTemporaryDetach() {
8725         onStartTemporaryDetach();
8726     }
8727
8728     /**
8729      * This is called when a container is going to temporarily detach a child, with
8730      * {@link ViewGroup#detachViewFromParent(View) ViewGroup.detachViewFromParent}.
8731      * It will either be followed by {@link #onFinishTemporaryDetach()} or
8732      * {@link #onDetachedFromWindow()} when the container is done.
8733      */
8734     public void onStartTemporaryDetach() {
8735         removeUnsetPressCallback();
8736         mPrivateFlags |= PFLAG_CANCEL_NEXT_UP_EVENT;
8737     }
8738
8739     /**
8740      * @hide
8741      */
8742     public void dispatchFinishTemporaryDetach() {
8743         onFinishTemporaryDetach();
8744     }
8745
8746     /**
8747      * Called after {@link #onStartTemporaryDetach} when the container is done
8748      * changing the view.
8749      */
8750     public void onFinishTemporaryDetach() {
8751     }
8752
8753     /**
8754      * Return the global {@link KeyEvent.DispatcherState KeyEvent.DispatcherState}
8755      * for this view's window.  Returns null if the view is not currently attached
8756      * to the window.  Normally you will not need to use this directly, but
8757      * just use the standard high-level event callbacks like
8758      * {@link #onKeyDown(int, KeyEvent)}.
8759      */
8760     public KeyEvent.DispatcherState getKeyDispatcherState() {
8761         return mAttachInfo != null ? mAttachInfo.mKeyDispatchState : null;
8762     }
8763
8764     /**
8765      * Dispatch a key event before it is processed by any input method
8766      * associated with the view hierarchy.  This can be used to intercept
8767      * key events in special situations before the IME consumes them; a
8768      * typical example would be handling the BACK key to update the application's
8769      * UI instead of allowing the IME to see it and close itself.
8770      *
8771      * @param event The key event to be dispatched.
8772      * @return True if the event was handled, false otherwise.
8773      */
8774     public boolean dispatchKeyEventPreIme(KeyEvent event) {
8775         return onKeyPreIme(event.getKeyCode(), event);
8776     }
8777
8778     /**
8779      * Dispatch a key event to the next view on the focus path. This path runs
8780      * from the top of the view tree down to the currently focused view. If this
8781      * view has focus, it will dispatch to itself. Otherwise it will dispatch
8782      * the next node down the focus path. This method also fires any key
8783      * listeners.
8784      *
8785      * @param event The key event to be dispatched.
8786      * @return True if the event was handled, false otherwise.
8787      */
8788     public boolean dispatchKeyEvent(KeyEvent event) {
8789         if (mInputEventConsistencyVerifier != null) {
8790             mInputEventConsistencyVerifier.onKeyEvent(event, 0);
8791         }
8792
8793         // Give any attached key listener a first crack at the event.
8794         //noinspection SimplifiableIfStatement
8795         ListenerInfo li = mListenerInfo;
8796         if (li != null && li.mOnKeyListener != null && (mViewFlags & ENABLED_MASK) == ENABLED
8797                 && li.mOnKeyListener.onKey(this, event.getKeyCode(), event)) {
8798             return true;
8799         }
8800
8801         if (event.dispatch(this, mAttachInfo != null
8802                 ? mAttachInfo.mKeyDispatchState : null, this)) {
8803             return true;
8804         }
8805
8806         if (mInputEventConsistencyVerifier != null) {
8807             mInputEventConsistencyVerifier.onUnhandledEvent(event, 0);
8808         }
8809         return false;
8810     }
8811
8812     /**
8813      * Dispatches a key shortcut event.
8814      *
8815      * @param event The key event to be dispatched.
8816      * @return True if the event was handled by the view, false otherwise.
8817      */
8818     public boolean dispatchKeyShortcutEvent(KeyEvent event) {
8819         return onKeyShortcut(event.getKeyCode(), event);
8820     }
8821
8822     /**
8823      * Pass the touch screen motion event down to the target view, or this
8824      * view if it is the target.
8825      *
8826      * @param event The motion event to be dispatched.
8827      * @return True if the event was handled by the view, false otherwise.
8828      */
8829     public boolean dispatchTouchEvent(MotionEvent event) {
8830         // If the event should be handled by accessibility focus first.
8831         if (event.isTargetAccessibilityFocus()) {
8832             // We don't have focus or no virtual descendant has it, do not handle the event.
8833             if (!isAccessibilityFocusedViewOrHost()) {
8834                 return false;
8835             }
8836             // We have focus and got the event, then use normal event dispatch.
8837             event.setTargetAccessibilityFocus(false);
8838         }
8839
8840         boolean result = false;
8841
8842         if (mInputEventConsistencyVerifier != null) {
8843             mInputEventConsistencyVerifier.onTouchEvent(event, 0);
8844         }
8845
8846         final int actionMasked = event.getActionMasked();
8847         if (actionMasked == MotionEvent.ACTION_DOWN) {
8848             // Defensive cleanup for new gesture
8849             stopNestedScroll();
8850         }
8851
8852         if (onFilterTouchEventForSecurity(event)) {
8853             //noinspection SimplifiableIfStatement
8854             ListenerInfo li = mListenerInfo;
8855             if (li != null && li.mOnTouchListener != null
8856                     && (mViewFlags & ENABLED_MASK) == ENABLED
8857                     && li.mOnTouchListener.onTouch(this, event)) {
8858                 result = true;
8859             }
8860
8861             if (!result && onTouchEvent(event)) {
8862                 result = true;
8863             }
8864         }
8865
8866         if (!result && mInputEventConsistencyVerifier != null) {
8867             mInputEventConsistencyVerifier.onUnhandledEvent(event, 0);
8868         }
8869
8870         // Clean up after nested scrolls if this is the end of a gesture;
8871         // also cancel it if we tried an ACTION_DOWN but we didn't want the rest
8872         // of the gesture.
8873         if (actionMasked == MotionEvent.ACTION_UP ||
8874                 actionMasked == MotionEvent.ACTION_CANCEL ||
8875                 (actionMasked == MotionEvent.ACTION_DOWN && !result)) {
8876             stopNestedScroll();
8877         }
8878
8879         return result;
8880     }
8881
8882     boolean isAccessibilityFocusedViewOrHost() {
8883         return isAccessibilityFocused() || (getViewRootImpl() != null && getViewRootImpl()
8884                 .getAccessibilityFocusedHost() == this);
8885     }
8886
8887     /**
8888      * Filter the touch event to apply security policies.
8889      *
8890      * @param event The motion event to be filtered.
8891      * @return True if the event should be dispatched, false if the event should be dropped.
8892      *
8893      * @see #getFilterTouchesWhenObscured
8894      */
8895     public boolean onFilterTouchEventForSecurity(MotionEvent event) {
8896         //noinspection RedundantIfStatement
8897         if ((mViewFlags & FILTER_TOUCHES_WHEN_OBSCURED) != 0
8898                 && (event.getFlags() & MotionEvent.FLAG_WINDOW_IS_OBSCURED) != 0) {
8899             // Window is obscured, drop this touch.
8900             return false;
8901         }
8902         return true;
8903     }
8904
8905     /**
8906      * Pass a trackball motion event down to the focused view.
8907      *
8908      * @param event The motion event to be dispatched.
8909      * @return True if the event was handled by the view, false otherwise.
8910      */
8911     public boolean dispatchTrackballEvent(MotionEvent event) {
8912         if (mInputEventConsistencyVerifier != null) {
8913             mInputEventConsistencyVerifier.onTrackballEvent(event, 0);
8914         }
8915
8916         return onTrackballEvent(event);
8917     }
8918
8919     /**
8920      * Dispatch a generic motion event.
8921      * <p>
8922      * Generic motion events with source class {@link InputDevice#SOURCE_CLASS_POINTER}
8923      * are delivered to the view under the pointer.  All other generic motion events are
8924      * delivered to the focused view.  Hover events are handled specially and are delivered
8925      * to {@link #onHoverEvent(MotionEvent)}.
8926      * </p>
8927      *
8928      * @param event The motion event to be dispatched.
8929      * @return True if the event was handled by the view, false otherwise.
8930      */
8931     public boolean dispatchGenericMotionEvent(MotionEvent event) {
8932         if (mInputEventConsistencyVerifier != null) {
8933             mInputEventConsistencyVerifier.onGenericMotionEvent(event, 0);
8934         }
8935
8936         final int source = event.getSource();
8937         if ((source & InputDevice.SOURCE_CLASS_POINTER) != 0) {
8938             final int action = event.getAction();
8939             if (action == MotionEvent.ACTION_HOVER_ENTER
8940                     || action == MotionEvent.ACTION_HOVER_MOVE
8941                     || action == MotionEvent.ACTION_HOVER_EXIT) {
8942                 if (dispatchHoverEvent(event)) {
8943                     return true;
8944                 }
8945             } else if (dispatchGenericPointerEvent(event)) {
8946                 return true;
8947             }
8948         } else if (dispatchGenericFocusedEvent(event)) {
8949             return true;
8950         }
8951
8952         if (dispatchGenericMotionEventInternal(event)) {
8953             return true;
8954         }
8955
8956         if (mInputEventConsistencyVerifier != null) {
8957             mInputEventConsistencyVerifier.onUnhandledEvent(event, 0);
8958         }
8959         return false;
8960     }
8961
8962     private boolean dispatchGenericMotionEventInternal(MotionEvent event) {
8963         //noinspection SimplifiableIfStatement
8964         ListenerInfo li = mListenerInfo;
8965         if (li != null && li.mOnGenericMotionListener != null
8966                 && (mViewFlags & ENABLED_MASK) == ENABLED
8967                 && li.mOnGenericMotionListener.onGenericMotion(this, event)) {
8968             return true;
8969         }
8970
8971         if (onGenericMotionEvent(event)) {
8972             return true;
8973         }
8974
8975         if (mInputEventConsistencyVerifier != null) {
8976             mInputEventConsistencyVerifier.onUnhandledEvent(event, 0);
8977         }
8978         return false;
8979     }
8980
8981     /**
8982      * Dispatch a hover event.
8983      * <p>
8984      * Do not call this method directly.
8985      * Call {@link #dispatchGenericMotionEvent(MotionEvent)} instead.
8986      * </p>
8987      *
8988      * @param event The motion event to be dispatched.
8989      * @return True if the event was handled by the view, false otherwise.
8990      */
8991     protected boolean dispatchHoverEvent(MotionEvent event) {
8992         ListenerInfo li = mListenerInfo;
8993         //noinspection SimplifiableIfStatement
8994         if (li != null && li.mOnHoverListener != null
8995                 && (mViewFlags & ENABLED_MASK) == ENABLED
8996                 && li.mOnHoverListener.onHover(this, event)) {
8997             return true;
8998         }
8999
9000         return onHoverEvent(event);
9001     }
9002
9003     /**
9004      * Returns true if the view has a child to which it has recently sent
9005      * {@link MotionEvent#ACTION_HOVER_ENTER}.  If this view is hovered and
9006      * it does not have a hovered child, then it must be the innermost hovered view.
9007      * @hide
9008      */
9009     protected boolean hasHoveredChild() {
9010         return false;
9011     }
9012
9013     /**
9014      * Dispatch a generic motion event to the view under the first pointer.
9015      * <p>
9016      * Do not call this method directly.
9017      * Call {@link #dispatchGenericMotionEvent(MotionEvent)} instead.
9018      * </p>
9019      *
9020      * @param event The motion event to be dispatched.
9021      * @return True if the event was handled by the view, false otherwise.
9022      */
9023     protected boolean dispatchGenericPointerEvent(MotionEvent event) {
9024         return false;
9025     }
9026
9027     /**
9028      * Dispatch a generic motion event to the currently focused view.
9029      * <p>
9030      * Do not call this method directly.
9031      * Call {@link #dispatchGenericMotionEvent(MotionEvent)} instead.
9032      * </p>
9033      *
9034      * @param event The motion event to be dispatched.
9035      * @return True if the event was handled by the view, false otherwise.
9036      */
9037     protected boolean dispatchGenericFocusedEvent(MotionEvent event) {
9038         return false;
9039     }
9040
9041     /**
9042      * Dispatch a pointer event.
9043      * <p>
9044      * Dispatches touch related pointer events to {@link #onTouchEvent(MotionEvent)} and all
9045      * other events to {@link #onGenericMotionEvent(MotionEvent)}.  This separation of concerns
9046      * reinforces the invariant that {@link #onTouchEvent(MotionEvent)} is really about touches
9047      * and should not be expected to handle other pointing device features.
9048      * </p>
9049      *
9050      * @param event The motion event to be dispatched.
9051      * @return True if the event was handled by the view, false otherwise.
9052      * @hide
9053      */
9054     public final boolean dispatchPointerEvent(MotionEvent event) {
9055         if (event.isTouchEvent()) {
9056             return dispatchTouchEvent(event);
9057         } else {
9058             return dispatchGenericMotionEvent(event);
9059         }
9060     }
9061
9062     /**
9063      * Called when the window containing this view gains or loses window focus.
9064      * ViewGroups should override to route to their children.
9065      *
9066      * @param hasFocus True if the window containing this view now has focus,
9067      *        false otherwise.
9068      */
9069     public void dispatchWindowFocusChanged(boolean hasFocus) {
9070         onWindowFocusChanged(hasFocus);
9071     }
9072
9073     /**
9074      * Called when the window containing this view gains or loses focus.  Note
9075      * that this is separate from view focus: to receive key events, both
9076      * your view and its window must have focus.  If a window is displayed
9077      * on top of yours that takes input focus, then your own window will lose
9078      * focus but the view focus will remain unchanged.
9079      *
9080      * @param hasWindowFocus True if the window containing this view now has
9081      *        focus, false otherwise.
9082      */
9083     public void onWindowFocusChanged(boolean hasWindowFocus) {
9084         InputMethodManager imm = InputMethodManager.peekInstance();
9085         if (!hasWindowFocus) {
9086             if (isPressed()) {
9087                 setPressed(false);
9088             }
9089             if (imm != null && (mPrivateFlags & PFLAG_FOCUSED) != 0) {
9090                 imm.focusOut(this);
9091             }
9092             removeLongPressCallback();
9093             removeTapCallback();
9094             onFocusLost();
9095         } else if (imm != null && (mPrivateFlags & PFLAG_FOCUSED) != 0) {
9096             imm.focusIn(this);
9097         }
9098         refreshDrawableState();
9099     }
9100
9101     /**
9102      * Returns true if this view is in a window that currently has window focus.
9103      * Note that this is not the same as the view itself having focus.
9104      *
9105      * @return True if this view is in a window that currently has window focus.
9106      */
9107     public boolean hasWindowFocus() {
9108         return mAttachInfo != null && mAttachInfo.mHasWindowFocus;
9109     }
9110
9111     /**
9112      * Dispatch a view visibility change down the view hierarchy.
9113      * ViewGroups should override to route to their children.
9114      * @param changedView The view whose visibility changed. Could be 'this' or
9115      * an ancestor view.
9116      * @param visibility The new visibility of changedView: {@link #VISIBLE},
9117      * {@link #INVISIBLE} or {@link #GONE}.
9118      */
9119     protected void dispatchVisibilityChanged(@NonNull View changedView,
9120             @Visibility int visibility) {
9121         onVisibilityChanged(changedView, visibility);
9122     }
9123
9124     /**
9125      * Called when the visibility of the view or an ancestor of the view has
9126      * changed.
9127      *
9128      * @param changedView The view whose visibility changed. May be
9129      *                    {@code this} or an ancestor view.
9130      * @param visibility The new visibility, one of {@link #VISIBLE},
9131      *                   {@link #INVISIBLE} or {@link #GONE}.
9132      */
9133     protected void onVisibilityChanged(@NonNull View changedView, @Visibility int visibility) {
9134         final boolean visible = visibility == VISIBLE && getVisibility() == VISIBLE;
9135         if (visible) {
9136             if (mAttachInfo != null) {
9137                 initialAwakenScrollBars();
9138             } else {
9139                 mPrivateFlags |= PFLAG_AWAKEN_SCROLL_BARS_ON_ATTACH;
9140             }
9141         }
9142
9143         final Drawable dr = mBackground;
9144         if (dr != null && visible != dr.isVisible()) {
9145             dr.setVisible(visible, false);
9146         }
9147         final Drawable fg = mForegroundInfo != null ? mForegroundInfo.mDrawable : null;
9148         if (fg != null && visible != fg.isVisible()) {
9149             fg.setVisible(visible, false);
9150         }
9151     }
9152
9153     /**
9154      * Dispatch a hint about whether this view is displayed. For instance, when
9155      * a View moves out of the screen, it might receives a display hint indicating
9156      * the view is not displayed. Applications should not <em>rely</em> on this hint
9157      * as there is no guarantee that they will receive one.
9158      *
9159      * @param hint A hint about whether or not this view is displayed:
9160      * {@link #VISIBLE} or {@link #INVISIBLE}.
9161      */
9162     public void dispatchDisplayHint(@Visibility int hint) {
9163         onDisplayHint(hint);
9164     }
9165
9166     /**
9167      * Gives this view a hint about whether is displayed or not. For instance, when
9168      * a View moves out of the screen, it might receives a display hint indicating
9169      * the view is not displayed. Applications should not <em>rely</em> on this hint
9170      * as there is no guarantee that they will receive one.
9171      *
9172      * @param hint A hint about whether or not this view is displayed:
9173      * {@link #VISIBLE} or {@link #INVISIBLE}.
9174      */
9175     protected void onDisplayHint(@Visibility int hint) {
9176     }
9177
9178     /**
9179      * Dispatch a window visibility change down the view hierarchy.
9180      * ViewGroups should override to route to their children.
9181      *
9182      * @param visibility The new visibility of the window.
9183      *
9184      * @see #onWindowVisibilityChanged(int)
9185      */
9186     public void dispatchWindowVisibilityChanged(@Visibility int visibility) {
9187         onWindowVisibilityChanged(visibility);
9188     }
9189
9190     /**
9191      * Called when the window containing has change its visibility
9192      * (between {@link #GONE}, {@link #INVISIBLE}, and {@link #VISIBLE}).  Note
9193      * that this tells you whether or not your window is being made visible
9194      * to the window manager; this does <em>not</em> tell you whether or not
9195      * your window is obscured by other windows on the screen, even if it
9196      * is itself visible.
9197      *
9198      * @param visibility The new visibility of the window.
9199      */
9200     protected void onWindowVisibilityChanged(@Visibility int visibility) {
9201         if (visibility == VISIBLE) {
9202             initialAwakenScrollBars();
9203         }
9204     }
9205
9206     /**
9207      * Returns the current visibility of the window this view is attached to
9208      * (either {@link #GONE}, {@link #INVISIBLE}, or {@link #VISIBLE}).
9209      *
9210      * @return Returns the current visibility of the view's window.
9211      */
9212     @Visibility
9213     public int getWindowVisibility() {
9214         return mAttachInfo != null ? mAttachInfo.mWindowVisibility : GONE;
9215     }
9216
9217     /**
9218      * Retrieve the overall visible display size in which the window this view is
9219      * attached to has been positioned in.  This takes into account screen
9220      * decorations above the window, for both cases where the window itself
9221      * is being position inside of them or the window is being placed under
9222      * then and covered insets are used for the window to position its content
9223      * inside.  In effect, this tells you the available area where content can
9224      * be placed and remain visible to users.
9225      *
9226      * <p>This function requires an IPC back to the window manager to retrieve
9227      * the requested information, so should not be used in performance critical
9228      * code like drawing.
9229      *
9230      * @param outRect Filled in with the visible display frame.  If the view
9231      * is not attached to a window, this is simply the raw display size.
9232      */
9233     public void getWindowVisibleDisplayFrame(Rect outRect) {
9234         if (mAttachInfo != null) {
9235             try {
9236                 mAttachInfo.mSession.getDisplayFrame(mAttachInfo.mWindow, outRect);
9237             } catch (RemoteException e) {
9238                 return;
9239             }
9240             // XXX This is really broken, and probably all needs to be done
9241             // in the window manager, and we need to know more about whether
9242             // we want the area behind or in front of the IME.
9243             final Rect insets = mAttachInfo.mVisibleInsets;
9244             outRect.left += insets.left;
9245             outRect.top += insets.top;
9246             outRect.right -= insets.right;
9247             outRect.bottom -= insets.bottom;
9248             return;
9249         }
9250         // The view is not attached to a display so we don't have a context.
9251         // Make a best guess about the display size.
9252         Display d = DisplayManagerGlobal.getInstance().getRealDisplay(Display.DEFAULT_DISPLAY);
9253         d.getRectSize(outRect);
9254     }
9255
9256     /**
9257      * Dispatch a notification about a resource configuration change down
9258      * the view hierarchy.
9259      * ViewGroups should override to route to their children.
9260      *
9261      * @param newConfig The new resource configuration.
9262      *
9263      * @see #onConfigurationChanged(android.content.res.Configuration)
9264      */
9265     public void dispatchConfigurationChanged(Configuration newConfig) {
9266         onConfigurationChanged(newConfig);
9267     }
9268
9269     /**
9270      * Called when the current configuration of the resources being used
9271      * by the application have changed.  You can use this to decide when
9272      * to reload resources that can changed based on orientation and other
9273      * configuration characteristics.  You only need to use this if you are
9274      * not relying on the normal {@link android.app.Activity} mechanism of
9275      * recreating the activity instance upon a configuration change.
9276      *
9277      * @param newConfig The new resource configuration.
9278      */
9279     protected void onConfigurationChanged(Configuration newConfig) {
9280     }
9281
9282     /**
9283      * Private function to aggregate all per-view attributes in to the view
9284      * root.
9285      */
9286     void dispatchCollectViewAttributes(AttachInfo attachInfo, int visibility) {
9287         performCollectViewAttributes(attachInfo, visibility);
9288     }
9289
9290     void performCollectViewAttributes(AttachInfo attachInfo, int visibility) {
9291         if ((visibility & VISIBILITY_MASK) == VISIBLE) {
9292             if ((mViewFlags & KEEP_SCREEN_ON) == KEEP_SCREEN_ON) {
9293                 attachInfo.mKeepScreenOn = true;
9294             }
9295             attachInfo.mSystemUiVisibility |= mSystemUiVisibility;
9296             ListenerInfo li = mListenerInfo;
9297             if (li != null && li.mOnSystemUiVisibilityChangeListener != null) {
9298                 attachInfo.mHasSystemUiListeners = true;
9299             }
9300         }
9301     }
9302
9303     void needGlobalAttributesUpdate(boolean force) {
9304         final AttachInfo ai = mAttachInfo;
9305         if (ai != null && !ai.mRecomputeGlobalAttributes) {
9306             if (force || ai.mKeepScreenOn || (ai.mSystemUiVisibility != 0)
9307                     || ai.mHasSystemUiListeners) {
9308                 ai.mRecomputeGlobalAttributes = true;
9309             }
9310         }
9311     }
9312
9313     /**
9314      * Returns whether the device is currently in touch mode.  Touch mode is entered
9315      * once the user begins interacting with the device by touch, and affects various
9316      * things like whether focus is always visible to the user.
9317      *
9318      * @return Whether the device is in touch mode.
9319      */
9320     @ViewDebug.ExportedProperty
9321     public boolean isInTouchMode() {
9322         if (mAttachInfo != null) {
9323             return mAttachInfo.mInTouchMode;
9324         } else {
9325             return ViewRootImpl.isInTouchMode();
9326         }
9327     }
9328
9329     /**
9330      * Returns the context the view is running in, through which it can
9331      * access the current theme, resources, etc.
9332      *
9333      * @return The view's Context.
9334      */
9335     @ViewDebug.CapturedViewProperty
9336     public final Context getContext() {
9337         return mContext;
9338     }
9339
9340     /**
9341      * Handle a key event before it is processed by any input method
9342      * associated with the view hierarchy.  This can be used to intercept
9343      * key events in special situations before the IME consumes them; a
9344      * typical example would be handling the BACK key to update the application's
9345      * UI instead of allowing the IME to see it and close itself.
9346      *
9347      * @param keyCode The value in event.getKeyCode().
9348      * @param event Description of the key event.
9349      * @return If you handled the event, return true. If you want to allow the
9350      *         event to be handled by the next receiver, return false.
9351      */
9352     public boolean onKeyPreIme(int keyCode, KeyEvent event) {
9353         return false;
9354     }
9355
9356     /**
9357      * Default implementation of {@link KeyEvent.Callback#onKeyDown(int, KeyEvent)
9358      * KeyEvent.Callback.onKeyDown()}: perform press of the view
9359      * when {@link KeyEvent#KEYCODE_DPAD_CENTER} or {@link KeyEvent#KEYCODE_ENTER}
9360      * is released, if the view is enabled and clickable.
9361      *
9362      * <p>Key presses in software keyboards will generally NOT trigger this listener,
9363      * although some may elect to do so in some situations. Do not rely on this to
9364      * catch software key presses.
9365      *
9366      * @param keyCode A key code that represents the button pressed, from
9367      *                {@link android.view.KeyEvent}.
9368      * @param event   The KeyEvent object that defines the button action.
9369      */
9370     public boolean onKeyDown(int keyCode, KeyEvent event) {
9371         boolean result = false;
9372
9373         if (KeyEvent.isConfirmKey(keyCode)) {
9374             if ((mViewFlags & ENABLED_MASK) == DISABLED) {
9375                 return true;
9376             }
9377             // Long clickable items don't necessarily have to be clickable
9378             if (((mViewFlags & CLICKABLE) == CLICKABLE ||
9379                     (mViewFlags & LONG_CLICKABLE) == LONG_CLICKABLE) &&
9380                     (event.getRepeatCount() == 0)) {
9381                 setPressed(true);
9382                 checkForLongClick(0);
9383                 return true;
9384             }
9385         }
9386         return result;
9387     }
9388
9389     /**
9390      * Default implementation of {@link KeyEvent.Callback#onKeyLongPress(int, KeyEvent)
9391      * KeyEvent.Callback.onKeyLongPress()}: always returns false (doesn't handle
9392      * the event).
9393      * <p>Key presses in software keyboards will generally NOT trigger this listener,
9394      * although some may elect to do so in some situations. Do not rely on this to
9395      * catch software key presses.
9396      */
9397     public boolean onKeyLongPress(int keyCode, KeyEvent event) {
9398         return false;
9399     }
9400
9401     /**
9402      * Default implementation of {@link KeyEvent.Callback#onKeyUp(int, KeyEvent)
9403      * KeyEvent.Callback.onKeyUp()}: perform clicking of the view
9404      * when {@link KeyEvent#KEYCODE_DPAD_CENTER} or
9405      * {@link KeyEvent#KEYCODE_ENTER} is released.
9406      * <p>Key presses in software keyboards will generally NOT trigger this listener,
9407      * although some may elect to do so in some situations. Do not rely on this to
9408      * catch software key presses.
9409      *
9410      * @param keyCode A key code that represents the button pressed, from
9411      *                {@link android.view.KeyEvent}.
9412      * @param event   The KeyEvent object that defines the button action.
9413      */
9414     public boolean onKeyUp(int keyCode, KeyEvent event) {
9415         if (KeyEvent.isConfirmKey(keyCode)) {
9416             if ((mViewFlags & ENABLED_MASK) == DISABLED) {
9417                 return true;
9418             }
9419             if ((mViewFlags & CLICKABLE) == CLICKABLE && isPressed()) {
9420                 setPressed(false);
9421
9422                 if (!mHasPerformedLongPress) {
9423                     // This is a tap, so remove the longpress check
9424                     removeLongPressCallback();
9425                     return performClick();
9426                 }
9427             }
9428         }
9429         return false;
9430     }
9431
9432     /**
9433      * Default implementation of {@link KeyEvent.Callback#onKeyMultiple(int, int, KeyEvent)
9434      * KeyEvent.Callback.onKeyMultiple()}: always returns false (doesn't handle
9435      * the event).
9436      * <p>Key presses in software keyboards will generally NOT trigger this listener,
9437      * although some may elect to do so in some situations. Do not rely on this to
9438      * catch software key presses.
9439      *
9440      * @param keyCode     A key code that represents the button pressed, from
9441      *                    {@link android.view.KeyEvent}.
9442      * @param repeatCount The number of times the action was made.
9443      * @param event       The KeyEvent object that defines the button action.
9444      */
9445     public boolean onKeyMultiple(int keyCode, int repeatCount, KeyEvent event) {
9446         return false;
9447     }
9448
9449     /**
9450      * Called on the focused view when a key shortcut event is not handled.
9451      * Override this method to implement local key shortcuts for the View.
9452      * Key shortcuts can also be implemented by setting the
9453      * {@link MenuItem#setShortcut(char, char) shortcut} property of menu items.
9454      *
9455      * @param keyCode The value in event.getKeyCode().
9456      * @param event Description of the key event.
9457      * @return If you handled the event, return true. If you want to allow the
9458      *         event to be handled by the next receiver, return false.
9459      */
9460     public boolean onKeyShortcut(int keyCode, KeyEvent event) {
9461         return false;
9462     }
9463
9464     /**
9465      * Check whether the called view is a text editor, in which case it
9466      * would make sense to automatically display a soft input window for
9467      * it.  Subclasses should override this if they implement
9468      * {@link #onCreateInputConnection(EditorInfo)} to return true if
9469      * a call on that method would return a non-null InputConnection, and
9470      * they are really a first-class editor that the user would normally
9471      * start typing on when the go into a window containing your view.
9472      *
9473      * <p>The default implementation always returns false.  This does
9474      * <em>not</em> mean that its {@link #onCreateInputConnection(EditorInfo)}
9475      * will not be called or the user can not otherwise perform edits on your
9476      * view; it is just a hint to the system that this is not the primary
9477      * purpose of this view.
9478      *
9479      * @return Returns true if this view is a text editor, else false.
9480      */
9481     public boolean onCheckIsTextEditor() {
9482         return false;
9483     }
9484
9485     /**
9486      * Create a new InputConnection for an InputMethod to interact
9487      * with the view.  The default implementation returns null, since it doesn't
9488      * support input methods.  You can override this to implement such support.
9489      * This is only needed for views that take focus and text input.
9490      *
9491      * <p>When implementing this, you probably also want to implement
9492      * {@link #onCheckIsTextEditor()} to indicate you will return a
9493      * non-null InputConnection.</p>
9494      *
9495      * <p>Also, take good care to fill in the {@link android.view.inputmethod.EditorInfo}
9496      * object correctly and in its entirety, so that the connected IME can rely
9497      * on its values. For example, {@link android.view.inputmethod.EditorInfo#initialSelStart}
9498      * and  {@link android.view.inputmethod.EditorInfo#initialSelEnd} members
9499      * must be filled in with the correct cursor position for IMEs to work correctly
9500      * with your application.</p>
9501      *
9502      * @param outAttrs Fill in with attribute information about the connection.
9503      */
9504     public InputConnection onCreateInputConnection(EditorInfo outAttrs) {
9505         return null;
9506     }
9507
9508     /**
9509      * Called by the {@link android.view.inputmethod.InputMethodManager}
9510      * when a view who is not the current
9511      * input connection target is trying to make a call on the manager.  The
9512      * default implementation returns false; you can override this to return
9513      * true for certain views if you are performing InputConnection proxying
9514      * to them.
9515      * @param view The View that is making the InputMethodManager call.
9516      * @return Return true to allow the call, false to reject.
9517      */
9518     public boolean checkInputConnectionProxy(View view) {
9519         return false;
9520     }
9521
9522     /**
9523      * Show the context menu for this view. It is not safe to hold on to the
9524      * menu after returning from this method.
9525      *
9526      * You should normally not overload this method. Overload
9527      * {@link #onCreateContextMenu(ContextMenu)} or define an
9528      * {@link OnCreateContextMenuListener} to add items to the context menu.
9529      *
9530      * @param menu The context menu to populate
9531      */
9532     public void createContextMenu(ContextMenu menu) {
9533         ContextMenuInfo menuInfo = getContextMenuInfo();
9534
9535         // Sets the current menu info so all items added to menu will have
9536         // my extra info set.
9537         ((MenuBuilder)menu).setCurrentMenuInfo(menuInfo);
9538
9539         onCreateContextMenu(menu);
9540         ListenerInfo li = mListenerInfo;
9541         if (li != null && li.mOnCreateContextMenuListener != null) {
9542             li.mOnCreateContextMenuListener.onCreateContextMenu(menu, this, menuInfo);
9543         }
9544
9545         // Clear the extra information so subsequent items that aren't mine don't
9546         // have my extra info.
9547         ((MenuBuilder)menu).setCurrentMenuInfo(null);
9548
9549         if (mParent != null) {
9550             mParent.createContextMenu(menu);
9551         }
9552     }
9553
9554     /**
9555      * Views should implement this if they have extra information to associate
9556      * with the context menu. The return result is supplied as a parameter to
9557      * the {@link OnCreateContextMenuListener#onCreateContextMenu(ContextMenu, View, ContextMenuInfo)}
9558      * callback.
9559      *
9560      * @return Extra information about the item for which the context menu
9561      *         should be shown. This information will vary across different
9562      *         subclasses of View.
9563      */
9564     protected ContextMenuInfo getContextMenuInfo() {
9565         return null;
9566     }
9567
9568     /**
9569      * Views should implement this if the view itself is going to add items to
9570      * the context menu.
9571      *
9572      * @param menu the context menu to populate
9573      */
9574     protected void onCreateContextMenu(ContextMenu menu) {
9575     }
9576
9577     /**
9578      * Implement this method to handle trackball motion events.  The
9579      * <em>relative</em> movement of the trackball since the last event
9580      * can be retrieve with {@link MotionEvent#getX MotionEvent.getX()} and
9581      * {@link MotionEvent#getY MotionEvent.getY()}.  These are normalized so
9582      * that a movement of 1 corresponds to the user pressing one DPAD key (so
9583      * they will often be fractional values, representing the more fine-grained
9584      * movement information available from a trackball).
9585      *
9586      * @param event The motion event.
9587      * @return True if the event was handled, false otherwise.
9588      */
9589     public boolean onTrackballEvent(MotionEvent event) {
9590         return false;
9591     }
9592
9593     /**
9594      * Implement this method to handle generic motion events.
9595      * <p>
9596      * Generic motion events describe joystick movements, mouse hovers, track pad
9597      * touches, scroll wheel movements and other input events.  The
9598      * {@link MotionEvent#getSource() source} of the motion event specifies
9599      * the class of input that was received.  Implementations of this method
9600      * must examine the bits in the source before processing the event.
9601      * The following code example shows how this is done.
9602      * </p><p>
9603      * Generic motion events with source class {@link InputDevice#SOURCE_CLASS_POINTER}
9604      * are delivered to the view under the pointer.  All other generic motion events are
9605      * delivered to the focused view.
9606      * </p>
9607      * <pre> public boolean onGenericMotionEvent(MotionEvent event) {
9608      *     if (event.isFromSource(InputDevice.SOURCE_CLASS_JOYSTICK)) {
9609      *         if (event.getAction() == MotionEvent.ACTION_MOVE) {
9610      *             // process the joystick movement...
9611      *             return true;
9612      *         }
9613      *     }
9614      *     if (event.isFromSource(InputDevice.SOURCE_CLASS_POINTER)) {
9615      *         switch (event.getAction()) {
9616      *             case MotionEvent.ACTION_HOVER_MOVE:
9617      *                 // process the mouse hover movement...
9618      *                 return true;
9619      *             case MotionEvent.ACTION_SCROLL:
9620      *                 // process the scroll wheel movement...
9621      *                 return true;
9622      *         }
9623      *     }
9624      *     return super.onGenericMotionEvent(event);
9625      * }</pre>
9626      *
9627      * @param event The generic motion event being processed.
9628      * @return True if the event was handled, false otherwise.
9629      */
9630     public boolean onGenericMotionEvent(MotionEvent event) {
9631         return false;
9632     }
9633
9634     /**
9635      * Implement this method to handle hover events.
9636      * <p>
9637      * This method is called whenever a pointer is hovering into, over, or out of the
9638      * bounds of a view and the view is not currently being touched.
9639      * Hover events are represented as pointer events with action
9640      * {@link MotionEvent#ACTION_HOVER_ENTER}, {@link MotionEvent#ACTION_HOVER_MOVE},
9641      * or {@link MotionEvent#ACTION_HOVER_EXIT}.
9642      * </p>
9643      * <ul>
9644      * <li>The view receives a hover event with action {@link MotionEvent#ACTION_HOVER_ENTER}
9645      * when the pointer enters the bounds of the view.</li>
9646      * <li>The view receives a hover event with action {@link MotionEvent#ACTION_HOVER_MOVE}
9647      * when the pointer has already entered the bounds of the view and has moved.</li>
9648      * <li>The view receives a hover event with action {@link MotionEvent#ACTION_HOVER_EXIT}
9649      * when the pointer has exited the bounds of the view or when the pointer is
9650      * about to go down due to a button click, tap, or similar user action that
9651      * causes the view to be touched.</li>
9652      * </ul>
9653      * <p>
9654      * The view should implement this method to return true to indicate that it is
9655      * handling the hover event, such as by changing its drawable state.
9656      * </p><p>
9657      * The default implementation calls {@link #setHovered} to update the hovered state
9658      * of the view when a hover enter or hover exit event is received, if the view
9659      * is enabled and is clickable.  The default implementation also sends hover
9660      * accessibility events.
9661      * </p>
9662      *
9663      * @param event The motion event that describes the hover.
9664      * @return True if the view handled the hover event.
9665      *
9666      * @see #isHovered
9667      * @see #setHovered
9668      * @see #onHoverChanged
9669      */
9670     public boolean onHoverEvent(MotionEvent event) {
9671         // The root view may receive hover (or touch) events that are outside the bounds of
9672         // the window.  This code ensures that we only send accessibility events for
9673         // hovers that are actually within the bounds of the root view.
9674         final int action = event.getActionMasked();
9675         if (!mSendingHoverAccessibilityEvents) {
9676             if ((action == MotionEvent.ACTION_HOVER_ENTER
9677                     || action == MotionEvent.ACTION_HOVER_MOVE)
9678                     && !hasHoveredChild()
9679                     && pointInView(event.getX(), event.getY())) {
9680                 sendAccessibilityHoverEvent(AccessibilityEvent.TYPE_VIEW_HOVER_ENTER);
9681                 mSendingHoverAccessibilityEvents = true;
9682             }
9683         } else {
9684             if (action == MotionEvent.ACTION_HOVER_EXIT
9685                     || (action == MotionEvent.ACTION_MOVE
9686                             && !pointInView(event.getX(), event.getY()))) {
9687                 mSendingHoverAccessibilityEvents = false;
9688                 sendAccessibilityHoverEvent(AccessibilityEvent.TYPE_VIEW_HOVER_EXIT);
9689             }
9690         }
9691
9692         if (isHoverable()) {
9693             switch (action) {
9694                 case MotionEvent.ACTION_HOVER_ENTER:
9695                     setHovered(true);
9696                     break;
9697                 case MotionEvent.ACTION_HOVER_EXIT:
9698                     setHovered(false);
9699                     break;
9700             }
9701
9702             // Dispatch the event to onGenericMotionEvent before returning true.
9703             // This is to provide compatibility with existing applications that
9704             // handled HOVER_MOVE events in onGenericMotionEvent and that would
9705             // break because of the new default handling for hoverable views
9706             // in onHoverEvent.
9707             // Note that onGenericMotionEvent will be called by default when
9708             // onHoverEvent returns false (refer to dispatchGenericMotionEvent).
9709             dispatchGenericMotionEventInternal(event);
9710             // The event was already handled by calling setHovered(), so always
9711             // return true.
9712             return true;
9713         }
9714
9715         return false;
9716     }
9717
9718     /**
9719      * Returns true if the view should handle {@link #onHoverEvent}
9720      * by calling {@link #setHovered} to change its hovered state.
9721      *
9722      * @return True if the view is hoverable.
9723      */
9724     private boolean isHoverable() {
9725         final int viewFlags = mViewFlags;
9726         if ((viewFlags & ENABLED_MASK) == DISABLED) {
9727             return false;
9728         }
9729
9730         return (viewFlags & CLICKABLE) == CLICKABLE
9731                 || (viewFlags & LONG_CLICKABLE) == LONG_CLICKABLE;
9732     }
9733
9734     /**
9735      * Returns true if the view is currently hovered.
9736      *
9737      * @return True if the view is currently hovered.
9738      *
9739      * @see #setHovered
9740      * @see #onHoverChanged
9741      */
9742     @ViewDebug.ExportedProperty
9743     public boolean isHovered() {
9744         return (mPrivateFlags & PFLAG_HOVERED) != 0;
9745     }
9746
9747     /**
9748      * Sets whether the view is currently hovered.
9749      * <p>
9750      * Calling this method also changes the drawable state of the view.  This
9751      * enables the view to react to hover by using different drawable resources
9752      * to change its appearance.
9753      * </p><p>
9754      * The {@link #onHoverChanged} method is called when the hovered state changes.
9755      * </p>
9756      *
9757      * @param hovered True if the view is hovered.
9758      *
9759      * @see #isHovered
9760      * @see #onHoverChanged
9761      */
9762     public void setHovered(boolean hovered) {
9763         if (hovered) {
9764             if ((mPrivateFlags & PFLAG_HOVERED) == 0) {
9765                 mPrivateFlags |= PFLAG_HOVERED;
9766                 refreshDrawableState();
9767                 onHoverChanged(true);
9768             }
9769         } else {
9770             if ((mPrivateFlags & PFLAG_HOVERED) != 0) {
9771                 mPrivateFlags &= ~PFLAG_HOVERED;
9772                 refreshDrawableState();
9773                 onHoverChanged(false);
9774             }
9775         }
9776     }
9777
9778     /**
9779      * Implement this method to handle hover state changes.
9780      * <p>
9781      * This method is called whenever the hover state changes as a result of a
9782      * call to {@link #setHovered}.
9783      * </p>
9784      *
9785      * @param hovered The current hover state, as returned by {@link #isHovered}.
9786      *
9787      * @see #isHovered
9788      * @see #setHovered
9789      */
9790     public void onHoverChanged(boolean hovered) {
9791     }
9792
9793     /**
9794      * Implement this method to handle touch screen motion events.
9795      * <p>
9796      * If this method is used to detect click actions, it is recommended that
9797      * the actions be performed by implementing and calling
9798      * {@link #performClick()}. This will ensure consistent system behavior,
9799      * including:
9800      * <ul>
9801      * <li>obeying click sound preferences
9802      * <li>dispatching OnClickListener calls
9803      * <li>handling {@link AccessibilityNodeInfo#ACTION_CLICK ACTION_CLICK} when
9804      * accessibility features are enabled
9805      * </ul>
9806      *
9807      * @param event The motion event.
9808      * @return True if the event was handled, false otherwise.
9809      */
9810     public boolean onTouchEvent(MotionEvent event) {
9811         final float x = event.getX();
9812         final float y = event.getY();
9813         final int viewFlags = mViewFlags;
9814
9815         if ((viewFlags & ENABLED_MASK) == DISABLED) {
9816             if (event.getAction() == MotionEvent.ACTION_UP && (mPrivateFlags & PFLAG_PRESSED) != 0) {
9817                 setPressed(false);
9818             }
9819             // A disabled view that is clickable still consumes the touch
9820             // events, it just doesn't respond to them.
9821             return (((viewFlags & CLICKABLE) == CLICKABLE ||
9822                     (viewFlags & LONG_CLICKABLE) == LONG_CLICKABLE));
9823         }
9824
9825         if (mTouchDelegate != null) {
9826             if (mTouchDelegate.onTouchEvent(event)) {
9827                 return true;
9828             }
9829         }
9830
9831         if (((viewFlags & CLICKABLE) == CLICKABLE ||
9832                 (viewFlags & LONG_CLICKABLE) == LONG_CLICKABLE)) {
9833             switch (event.getAction()) {
9834                 case MotionEvent.ACTION_UP:
9835                     boolean prepressed = (mPrivateFlags & PFLAG_PREPRESSED) != 0;
9836                     if ((mPrivateFlags & PFLAG_PRESSED) != 0 || prepressed) {
9837                         // take focus if we don't have it already and we should in
9838                         // touch mode.
9839                         boolean focusTaken = false;
9840                         if (isFocusable() && isFocusableInTouchMode() && !isFocused()) {
9841                             focusTaken = requestFocus();
9842                         }
9843
9844                         if (prepressed) {
9845                             // The button is being released before we actually
9846                             // showed it as pressed.  Make it show the pressed
9847                             // state now (before scheduling the click) to ensure
9848                             // the user sees it.
9849                             setPressed(true, x, y);
9850                        }
9851
9852                         if (!mHasPerformedLongPress) {
9853                             // This is a tap, so remove the longpress check
9854                             removeLongPressCallback();
9855
9856                             // Only perform take click actions if we were in the pressed state
9857                             if (!focusTaken) {
9858                                 // Use a Runnable and post this rather than calling
9859                                 // performClick directly. This lets other visual state
9860                                 // of the view update before click actions start.
9861                                 if (mPerformClick == null) {
9862                                     mPerformClick = new PerformClick();
9863                                 }
9864                                 if (!post(mPerformClick)) {
9865                                     performClick();
9866                                 }
9867                             }
9868                         }
9869
9870                         if (mUnsetPressedState == null) {
9871                             mUnsetPressedState = new UnsetPressedState();
9872                         }
9873
9874                         if (prepressed) {
9875                             postDelayed(mUnsetPressedState,
9876                                     ViewConfiguration.getPressedStateDuration());
9877                         } else if (!post(mUnsetPressedState)) {
9878                             // If the post failed, unpress right now
9879                             mUnsetPressedState.run();
9880                         }
9881
9882                         removeTapCallback();
9883                     }
9884                     break;
9885
9886                 case MotionEvent.ACTION_DOWN:
9887                     mHasPerformedLongPress = false;
9888
9889                     if (performButtonActionOnTouchDown(event)) {
9890                         break;
9891                     }
9892
9893                     // Walk up the hierarchy to determine if we're inside a scrolling container.
9894                     boolean isInScrollingContainer = isInScrollingContainer();
9895
9896                     // For views inside a scrolling container, delay the pressed feedback for
9897                     // a short period in case this is a scroll.
9898                     if (isInScrollingContainer) {
9899                         mPrivateFlags |= PFLAG_PREPRESSED;
9900                         if (mPendingCheckForTap == null) {
9901                             mPendingCheckForTap = new CheckForTap();
9902                         }
9903                         mPendingCheckForTap.x = event.getX();
9904                         mPendingCheckForTap.y = event.getY();
9905                         postDelayed(mPendingCheckForTap, ViewConfiguration.getTapTimeout());
9906                     } else {
9907                         // Not inside a scrolling container, so show the feedback right away
9908                         setPressed(true, x, y);
9909                         checkForLongClick(0);
9910                     }
9911                     break;
9912
9913                 case MotionEvent.ACTION_CANCEL:
9914                     setPressed(false);
9915                     removeTapCallback();
9916                     removeLongPressCallback();
9917                     break;
9918
9919                 case MotionEvent.ACTION_MOVE:
9920                     drawableHotspotChanged(x, y);
9921
9922                     // Be lenient about moving outside of buttons
9923                     if (!pointInView(x, y, mTouchSlop)) {
9924                         // Outside button
9925                         removeTapCallback();
9926                         if ((mPrivateFlags & PFLAG_PRESSED) != 0) {
9927                             // Remove any future long press/tap checks
9928                             removeLongPressCallback();
9929
9930                             setPressed(false);
9931                         }
9932                     }
9933                     break;
9934             }
9935
9936             return true;
9937         }
9938
9939         return false;
9940     }
9941
9942     /**
9943      * @hide
9944      */
9945     public boolean isInScrollingContainer() {
9946         ViewParent p = getParent();
9947         while (p != null && p instanceof ViewGroup) {
9948             if (((ViewGroup) p).shouldDelayChildPressedState()) {
9949                 return true;
9950             }
9951             p = p.getParent();
9952         }
9953         return false;
9954     }
9955
9956     /**
9957      * Remove the longpress detection timer.
9958      */
9959     private void removeLongPressCallback() {
9960         if (mPendingCheckForLongPress != null) {
9961           removeCallbacks(mPendingCheckForLongPress);
9962         }
9963     }
9964
9965     /**
9966      * Remove the pending click action
9967      */
9968     private void removePerformClickCallback() {
9969         if (mPerformClick != null) {
9970             removeCallbacks(mPerformClick);
9971         }
9972     }
9973
9974     /**
9975      * Remove the prepress detection timer.
9976      */
9977     private void removeUnsetPressCallback() {
9978         if ((mPrivateFlags & PFLAG_PRESSED) != 0 && mUnsetPressedState != null) {
9979             setPressed(false);
9980             removeCallbacks(mUnsetPressedState);
9981         }
9982     }
9983
9984     /**
9985      * Remove the tap detection timer.
9986      */
9987     private void removeTapCallback() {
9988         if (mPendingCheckForTap != null) {
9989             mPrivateFlags &= ~PFLAG_PREPRESSED;
9990             removeCallbacks(mPendingCheckForTap);
9991         }
9992     }
9993
9994     /**
9995      * Cancels a pending long press.  Your subclass can use this if you
9996      * want the context menu to come up if the user presses and holds
9997      * at the same place, but you don't want it to come up if they press
9998      * and then move around enough to cause scrolling.
9999      */
10000     public void cancelLongPress() {
10001         removeLongPressCallback();
10002
10003         /*
10004          * The prepressed state handled by the tap callback is a display
10005          * construct, but the tap callback will post a long press callback
10006          * less its own timeout. Remove it here.
10007          */
10008         removeTapCallback();
10009     }
10010
10011     /**
10012      * Remove the pending callback for sending a
10013      * {@link AccessibilityEvent#TYPE_VIEW_SCROLLED} accessibility event.
10014      */
10015     private void removeSendViewScrolledAccessibilityEventCallback() {
10016         if (mSendViewScrolledAccessibilityEvent != null) {
10017             removeCallbacks(mSendViewScrolledAccessibilityEvent);
10018             mSendViewScrolledAccessibilityEvent.mIsPending = false;
10019         }
10020     }
10021
10022     /**
10023      * Sets the TouchDelegate for this View.
10024      */
10025     public void setTouchDelegate(TouchDelegate delegate) {
10026         mTouchDelegate = delegate;
10027     }
10028
10029     /**
10030      * Gets the TouchDelegate for this View.
10031      */
10032     public TouchDelegate getTouchDelegate() {
10033         return mTouchDelegate;
10034     }
10035
10036     /**
10037      * Request unbuffered dispatch of the given stream of MotionEvents to this View.
10038      *
10039      * Until this View receives a corresponding {@link MotionEvent#ACTION_UP}, ask that the input
10040      * system not batch {@link MotionEvent}s but instead deliver them as soon as they're
10041      * available. This method should only be called for touch events.
10042      *
10043      * <p class="note">This api is not intended for most applications. Buffered dispatch
10044      * provides many of benefits, and just requesting unbuffered dispatch on most MotionEvent
10045      * streams will not improve your input latency. Side effects include: increased latency,
10046      * jittery scrolls and inability to take advantage of system resampling. Talk to your input
10047      * professional to see if {@link #requestUnbufferedDispatch(MotionEvent)} is right for
10048      * you.</p>
10049      */
10050     public final void requestUnbufferedDispatch(MotionEvent event) {
10051         final int action = event.getAction();
10052         if (mAttachInfo == null
10053                 || action != MotionEvent.ACTION_DOWN && action != MotionEvent.ACTION_MOVE
10054                 || !event.isTouchEvent()) {
10055             return;
10056         }
10057         mAttachInfo.mUnbufferedDispatchRequested = true;
10058     }
10059
10060     /**
10061      * Set flags controlling behavior of this view.
10062      *
10063      * @param flags Constant indicating the value which should be set
10064      * @param mask Constant indicating the bit range that should be changed
10065      */
10066     void setFlags(int flags, int mask) {
10067         final boolean accessibilityEnabled =
10068                 AccessibilityManager.getInstance(mContext).isEnabled();
10069         final boolean oldIncludeForAccessibility = accessibilityEnabled && includeForAccessibility();
10070
10071         int old = mViewFlags;
10072         mViewFlags = (mViewFlags & ~mask) | (flags & mask);
10073
10074         int changed = mViewFlags ^ old;
10075         if (changed == 0) {
10076             return;
10077         }
10078         int privateFlags = mPrivateFlags;
10079
10080         /* Check if the FOCUSABLE bit has changed */
10081         if (((changed & FOCUSABLE_MASK) != 0) &&
10082                 ((privateFlags & PFLAG_HAS_BOUNDS) !=0)) {
10083             if (((old & FOCUSABLE_MASK) == FOCUSABLE)
10084                     && ((privateFlags & PFLAG_FOCUSED) != 0)) {
10085                 /* Give up focus if we are no longer focusable */
10086                 clearFocus();
10087             } else if (((old & FOCUSABLE_MASK) == NOT_FOCUSABLE)
10088                     && ((privateFlags & PFLAG_FOCUSED) == 0)) {
10089                 /*
10090                  * Tell the view system that we are now available to take focus
10091                  * if no one else already has it.
10092                  */
10093                 if (mParent != null) mParent.focusableViewAvailable(this);
10094             }
10095         }
10096
10097         final int newVisibility = flags & VISIBILITY_MASK;
10098         if (newVisibility == VISIBLE) {
10099             if ((changed & VISIBILITY_MASK) != 0) {
10100                 /*
10101                  * If this view is becoming visible, invalidate it in case it changed while
10102                  * it was not visible. Marking it drawn ensures that the invalidation will
10103                  * go through.
10104                  */
10105                 mPrivateFlags |= PFLAG_DRAWN;
10106                 invalidate(true);
10107
10108                 needGlobalAttributesUpdate(true);
10109
10110                 // a view becoming visible is worth notifying the parent
10111                 // about in case nothing has focus.  even if this specific view
10112                 // isn't focusable, it may contain something that is, so let
10113                 // the root view try to give this focus if nothing else does.
10114                 if ((mParent != null) && (mBottom > mTop) && (mRight > mLeft)) {
10115                     mParent.focusableViewAvailable(this);
10116                 }
10117             }
10118         }
10119
10120         /* Check if the GONE bit has changed */
10121         if ((changed & GONE) != 0) {
10122             needGlobalAttributesUpdate(false);
10123             requestLayout();
10124
10125             if (((mViewFlags & VISIBILITY_MASK) == GONE)) {
10126                 if (hasFocus()) clearFocus();
10127                 clearAccessibilityFocus();
10128                 destroyDrawingCache();
10129                 if (mParent instanceof View) {
10130                     // GONE views noop invalidation, so invalidate the parent
10131                     ((View) mParent).invalidate(true);
10132                 }
10133                 // Mark the view drawn to ensure that it gets invalidated properly the next
10134                 // time it is visible and gets invalidated
10135                 mPrivateFlags |= PFLAG_DRAWN;
10136             }
10137             if (mAttachInfo != null) {
10138                 mAttachInfo.mViewVisibilityChanged = true;
10139             }
10140         }
10141
10142         /* Check if the VISIBLE bit has changed */
10143         if ((changed & INVISIBLE) != 0) {
10144             needGlobalAttributesUpdate(false);
10145             /*
10146              * If this view is becoming invisible, set the DRAWN flag so that
10147              * the next invalidate() will not be skipped.
10148              */
10149             mPrivateFlags |= PFLAG_DRAWN;
10150
10151             if (((mViewFlags & VISIBILITY_MASK) == INVISIBLE)) {
10152                 // root view becoming invisible shouldn't clear focus and accessibility focus
10153                 if (getRootView() != this) {
10154                     if (hasFocus()) clearFocus();
10155                     clearAccessibilityFocus();
10156                 }
10157             }
10158             if (mAttachInfo != null) {
10159                 mAttachInfo.mViewVisibilityChanged = true;
10160             }
10161         }
10162
10163         if ((changed & VISIBILITY_MASK) != 0) {
10164             // If the view is invisible, cleanup its display list to free up resources
10165             if (newVisibility != VISIBLE && mAttachInfo != null) {
10166                 cleanupDraw();
10167             }
10168
10169             if (mParent instanceof ViewGroup) {
10170                 ((ViewGroup) mParent).onChildVisibilityChanged(this,
10171                         (changed & VISIBILITY_MASK), newVisibility);
10172                 ((View) mParent).invalidate(true);
10173             } else if (mParent != null) {
10174                 mParent.invalidateChild(this, null);
10175             }
10176             dispatchVisibilityChanged(this, newVisibility);
10177
10178             notifySubtreeAccessibilityStateChangedIfNeeded();
10179         }
10180
10181         if ((changed & WILL_NOT_CACHE_DRAWING) != 0) {
10182             destroyDrawingCache();
10183         }
10184
10185         if ((changed & DRAWING_CACHE_ENABLED) != 0) {
10186             destroyDrawingCache();
10187             mPrivateFlags &= ~PFLAG_DRAWING_CACHE_VALID;
10188             invalidateParentCaches();
10189         }
10190
10191         if ((changed & DRAWING_CACHE_QUALITY_MASK) != 0) {
10192             destroyDrawingCache();
10193             mPrivateFlags &= ~PFLAG_DRAWING_CACHE_VALID;
10194         }
10195
10196         if ((changed & DRAW_MASK) != 0) {
10197             if ((mViewFlags & WILL_NOT_DRAW) != 0) {
10198                 if (mBackground != null) {
10199                     mPrivateFlags &= ~PFLAG_SKIP_DRAW;
10200                     mPrivateFlags |= PFLAG_ONLY_DRAWS_BACKGROUND;
10201                 } else {
10202                     mPrivateFlags |= PFLAG_SKIP_DRAW;
10203                 }
10204             } else {
10205                 mPrivateFlags &= ~PFLAG_SKIP_DRAW;
10206             }
10207             requestLayout();
10208             invalidate(true);
10209         }
10210
10211         if ((changed & KEEP_SCREEN_ON) != 0) {
10212             if (mParent != null && mAttachInfo != null && !mAttachInfo.mRecomputeGlobalAttributes) {
10213                 mParent.recomputeViewAttributes(this);
10214             }
10215         }
10216
10217         if (accessibilityEnabled) {
10218             if ((changed & FOCUSABLE_MASK) != 0 || (changed & VISIBILITY_MASK) != 0
10219                     || (changed & CLICKABLE) != 0 || (changed & LONG_CLICKABLE) != 0) {
10220                 if (oldIncludeForAccessibility != includeForAccessibility()) {
10221                     notifySubtreeAccessibilityStateChangedIfNeeded();
10222                 } else {
10223                     notifyViewAccessibilityStateChangedIfNeeded(
10224                             AccessibilityEvent.CONTENT_CHANGE_TYPE_UNDEFINED);
10225                 }
10226             } else if ((changed & ENABLED_MASK) != 0) {
10227                 notifyViewAccessibilityStateChangedIfNeeded(
10228                         AccessibilityEvent.CONTENT_CHANGE_TYPE_UNDEFINED);
10229             }
10230         }
10231     }
10232
10233     /**
10234      * Change the view's z order in the tree, so it's on top of other sibling
10235      * views. This ordering change may affect layout, if the parent container
10236      * uses an order-dependent layout scheme (e.g., LinearLayout). Prior
10237      * to {@link android.os.Build.VERSION_CODES#KITKAT} this
10238      * method should be followed by calls to {@link #requestLayout()} and
10239      * {@link View#invalidate()} on the view's parent to force the parent to redraw
10240      * with the new child ordering.
10241      *
10242      * @see ViewGroup#bringChildToFront(View)
10243      */
10244     public void bringToFront() {
10245         if (mParent != null) {
10246             mParent.bringChildToFront(this);
10247         }
10248     }
10249
10250     /**
10251      * This is called in response to an internal scroll in this view (i.e., the
10252      * view scrolled its own contents). This is typically as a result of
10253      * {@link #scrollBy(int, int)} or {@link #scrollTo(int, int)} having been
10254      * called.
10255      *
10256      * @param l Current horizontal scroll origin.
10257      * @param t Current vertical scroll origin.
10258      * @param oldl Previous horizontal scroll origin.
10259      * @param oldt Previous vertical scroll origin.
10260      */
10261     protected void onScrollChanged(int l, int t, int oldl, int oldt) {
10262         notifySubtreeAccessibilityStateChangedIfNeeded();
10263
10264         if (AccessibilityManager.getInstance(mContext).isEnabled()) {
10265             postSendViewScrolledAccessibilityEventCallback();
10266         }
10267
10268         mBackgroundSizeChanged = true;
10269         if (mForegroundInfo != null) {
10270             mForegroundInfo.mBoundsChanged = true;
10271         }
10272
10273         final AttachInfo ai = mAttachInfo;
10274         if (ai != null) {
10275             ai.mViewScrollChanged = true;
10276         }
10277
10278         if (mListenerInfo != null && mListenerInfo.mOnScrollChangeListener != null) {
10279             mListenerInfo.mOnScrollChangeListener.onScrollChange(this, l, t, oldl, oldt);
10280         }
10281     }
10282
10283     /**
10284      * Interface definition for a callback to be invoked when the scroll
10285      * X or Y positions of a view change.
10286      * <p>
10287      * <b>Note:</b> Some views handle scrolling independently from View and may
10288      * have their own separate listeners for scroll-type events. For example,
10289      * {@link android.widget.ListView ListView} allows clients to register an
10290      * {@link android.widget.ListView#setOnScrollListener(android.widget.AbsListView.OnScrollListener) AbsListView.OnScrollListener}
10291      * to listen for changes in list scroll position.
10292      *
10293      * @see #setOnScrollChangeListener(View.OnScrollChangeListener)
10294      */
10295     public interface OnScrollChangeListener {
10296         /**
10297          * Called when the scroll position of a view changes.
10298          *
10299          * @param v The view whose scroll position has changed.
10300          * @param scrollX Current horizontal scroll origin.
10301          * @param scrollY Current vertical scroll origin.
10302          * @param oldScrollX Previous horizontal scroll origin.
10303          * @param oldScrollY Previous vertical scroll origin.
10304          */
10305         void onScrollChange(View v, int scrollX, int scrollY, int oldScrollX, int oldScrollY);
10306     }
10307
10308     /**
10309      * Interface definition for a callback to be invoked when the layout bounds of a view
10310      * changes due to layout processing.
10311      */
10312     public interface OnLayoutChangeListener {
10313         /**
10314          * Called when the layout bounds of a view changes due to layout processing.
10315          *
10316          * @param v The view whose bounds have changed.
10317          * @param left The new value of the view's left property.
10318          * @param top The new value of the view's top property.
10319          * @param right The new value of the view's right property.
10320          * @param bottom The new value of the view's bottom property.
10321          * @param oldLeft The previous value of the view's left property.
10322          * @param oldTop The previous value of the view's top property.
10323          * @param oldRight The previous value of the view's right property.
10324          * @param oldBottom The previous value of the view's bottom property.
10325          */
10326         void onLayoutChange(View v, int left, int top, int right, int bottom,
10327             int oldLeft, int oldTop, int oldRight, int oldBottom);
10328     }
10329
10330     /**
10331      * This is called during layout when the size of this view has changed. If
10332      * you were just added to the view hierarchy, you're called with the old
10333      * values of 0.
10334      *
10335      * @param w Current width of this view.
10336      * @param h Current height of this view.
10337      * @param oldw Old width of this view.
10338      * @param oldh Old height of this view.
10339      */
10340     protected void onSizeChanged(int w, int h, int oldw, int oldh) {
10341     }
10342
10343     /**
10344      * Called by draw to draw the child views. This may be overridden
10345      * by derived classes to gain control just before its children are drawn
10346      * (but after its own view has been drawn).
10347      * @param canvas the canvas on which to draw the view
10348      */
10349     protected void dispatchDraw(Canvas canvas) {
10350
10351     }
10352
10353     /**
10354      * Gets the parent of this view. Note that the parent is a
10355      * ViewParent and not necessarily a View.
10356      *
10357      * @return Parent of this view.
10358      */
10359     public final ViewParent getParent() {
10360         return mParent;
10361     }
10362
10363     /**
10364      * Set the horizontal scrolled position of your view. This will cause a call to
10365      * {@link #onScrollChanged(int, int, int, int)} and the view will be
10366      * invalidated.
10367      * @param value the x position to scroll to
10368      */
10369     public void setScrollX(int value) {
10370         scrollTo(value, mScrollY);
10371     }
10372
10373     /**
10374      * Set the vertical scrolled position of your view. This will cause a call to
10375      * {@link #onScrollChanged(int, int, int, int)} and the view will be
10376      * invalidated.
10377      * @param value the y position to scroll to
10378      */
10379     public void setScrollY(int value) {
10380         scrollTo(mScrollX, value);
10381     }
10382
10383     /**
10384      * Return the scrolled left position of this view. This is the left edge of
10385      * the displayed part of your view. You do not need to draw any pixels
10386      * farther left, since those are outside of the frame of your view on
10387      * screen.
10388      *
10389      * @return The left edge of the displayed part of your view, in pixels.
10390      */
10391     public final int getScrollX() {
10392         return mScrollX;
10393     }
10394
10395     /**
10396      * Return the scrolled top position of this view. This is the top edge of
10397      * the displayed part of your view. You do not need to draw any pixels above
10398      * it, since those are outside of the frame of your view on screen.
10399      *
10400      * @return The top edge of the displayed part of your view, in pixels.
10401      */
10402     public final int getScrollY() {
10403         return mScrollY;
10404     }
10405
10406     /**
10407      * Return the width of the your view.
10408      *
10409      * @return The width of your view, in pixels.
10410      */
10411     @ViewDebug.ExportedProperty(category = "layout")
10412     public final int getWidth() {
10413         return mRight - mLeft;
10414     }
10415
10416     /**
10417      * Return the height of your view.
10418      *
10419      * @return The height of your view, in pixels.
10420      */
10421     @ViewDebug.ExportedProperty(category = "layout")
10422     public final int getHeight() {
10423         return mBottom - mTop;
10424     }
10425
10426     /**
10427      * Return the visible drawing bounds of your view. Fills in the output
10428      * rectangle with the values from getScrollX(), getScrollY(),
10429      * getWidth(), and getHeight(). These bounds do not account for any
10430      * transformation properties currently set on the view, such as
10431      * {@link #setScaleX(float)} or {@link #setRotation(float)}.
10432      *
10433      * @param outRect The (scrolled) drawing bounds of the view.
10434      */
10435     public void getDrawingRect(Rect outRect) {
10436         outRect.left = mScrollX;
10437         outRect.top = mScrollY;
10438         outRect.right = mScrollX + (mRight - mLeft);
10439         outRect.bottom = mScrollY + (mBottom - mTop);
10440     }
10441
10442     /**
10443      * Like {@link #getMeasuredWidthAndState()}, but only returns the
10444      * raw width component (that is the result is masked by
10445      * {@link #MEASURED_SIZE_MASK}).
10446      *
10447      * @return The raw measured width of this view.
10448      */
10449     public final int getMeasuredWidth() {
10450         return mMeasuredWidth & MEASURED_SIZE_MASK;
10451     }
10452
10453     /**
10454      * Return the full width measurement information for this view as computed
10455      * by the most recent call to {@link #measure(int, int)}.  This result is a bit mask
10456      * as defined by {@link #MEASURED_SIZE_MASK} and {@link #MEASURED_STATE_TOO_SMALL}.
10457      * This should be used during measurement and layout calculations only. Use
10458      * {@link #getWidth()} to see how wide a view is after layout.
10459      *
10460      * @return The measured width of this view as a bit mask.
10461      */
10462     @ViewDebug.ExportedProperty(category = "measurement", flagMapping = {
10463             @ViewDebug.FlagToString(mask = MEASURED_STATE_MASK, equals = MEASURED_STATE_TOO_SMALL,
10464                     name = "MEASURED_STATE_TOO_SMALL"),
10465     })
10466     public final int getMeasuredWidthAndState() {
10467         return mMeasuredWidth;
10468     }
10469
10470     /**
10471      * Like {@link #getMeasuredHeightAndState()}, but only returns the
10472      * raw width component (that is the result is masked by
10473      * {@link #MEASURED_SIZE_MASK}).
10474      *
10475      * @return The raw measured height of this view.
10476      */
10477     public final int getMeasuredHeight() {
10478         return mMeasuredHeight & MEASURED_SIZE_MASK;
10479     }
10480
10481     /**
10482      * Return the full height measurement information for this view as computed
10483      * by the most recent call to {@link #measure(int, int)}.  This result is a bit mask
10484      * as defined by {@link #MEASURED_SIZE_MASK} and {@link #MEASURED_STATE_TOO_SMALL}.
10485      * This should be used during measurement and layout calculations only. Use
10486      * {@link #getHeight()} to see how wide a view is after layout.
10487      *
10488      * @return The measured width of this view as a bit mask.
10489      */
10490     @ViewDebug.ExportedProperty(category = "measurement", flagMapping = {
10491             @ViewDebug.FlagToString(mask = MEASURED_STATE_MASK, equals = MEASURED_STATE_TOO_SMALL,
10492                     name = "MEASURED_STATE_TOO_SMALL"),
10493     })
10494     public final int getMeasuredHeightAndState() {
10495         return mMeasuredHeight;
10496     }
10497
10498     /**
10499      * Return only the state bits of {@link #getMeasuredWidthAndState()}
10500      * and {@link #getMeasuredHeightAndState()}, combined into one integer.
10501      * The width component is in the regular bits {@link #MEASURED_STATE_MASK}
10502      * and the height component is at the shifted bits
10503      * {@link #MEASURED_HEIGHT_STATE_SHIFT}>>{@link #MEASURED_STATE_MASK}.
10504      */
10505     public final int getMeasuredState() {
10506         return (mMeasuredWidth&MEASURED_STATE_MASK)
10507                 | ((mMeasuredHeight>>MEASURED_HEIGHT_STATE_SHIFT)
10508                         & (MEASURED_STATE_MASK>>MEASURED_HEIGHT_STATE_SHIFT));
10509     }
10510
10511     /**
10512      * The transform matrix of this view, which is calculated based on the current
10513      * rotation, scale, and pivot properties.
10514      *
10515      * @see #getRotation()
10516      * @see #getScaleX()
10517      * @see #getScaleY()
10518      * @see #getPivotX()
10519      * @see #getPivotY()
10520      * @return The current transform matrix for the view
10521      */
10522     public Matrix getMatrix() {
10523         ensureTransformationInfo();
10524         final Matrix matrix = mTransformationInfo.mMatrix;
10525         mRenderNode.getMatrix(matrix);
10526         return matrix;
10527     }
10528
10529     /**
10530      * Returns true if the transform matrix is the identity matrix.
10531      * Recomputes the matrix if necessary.
10532      *
10533      * @return True if the transform matrix is the identity matrix, false otherwise.
10534      */
10535     final boolean hasIdentityMatrix() {
10536         return mRenderNode.hasIdentityMatrix();
10537     }
10538
10539     void ensureTransformationInfo() {
10540         if (mTransformationInfo == null) {
10541             mTransformationInfo = new TransformationInfo();
10542         }
10543     }
10544
10545    /**
10546      * Utility method to retrieve the inverse of the current mMatrix property.
10547      * We cache the matrix to avoid recalculating it when transform properties
10548      * have not changed.
10549      *
10550      * @return The inverse of the current matrix of this view.
10551      * @hide
10552      */
10553     public final Matrix getInverseMatrix() {
10554         ensureTransformationInfo();
10555         if (mTransformationInfo.mInverseMatrix == null) {
10556             mTransformationInfo.mInverseMatrix = new Matrix();
10557         }
10558         final Matrix matrix = mTransformationInfo.mInverseMatrix;
10559         mRenderNode.getInverseMatrix(matrix);
10560         return matrix;
10561     }
10562
10563     /**
10564      * Gets the distance along the Z axis from the camera to this view.
10565      *
10566      * @see #setCameraDistance(float)
10567      *
10568      * @return The distance along the Z axis.
10569      */
10570     public float getCameraDistance() {
10571         final float dpi = mResources.getDisplayMetrics().densityDpi;
10572         return -(mRenderNode.getCameraDistance() * dpi);
10573     }
10574
10575     /**
10576      * <p>Sets the distance along the Z axis (orthogonal to the X/Y plane on which
10577      * views are drawn) from the camera to this view. The camera's distance
10578      * affects 3D transformations, for instance rotations around the X and Y
10579      * axis. If the rotationX or rotationY properties are changed and this view is
10580      * large (more than half the size of the screen), it is recommended to always
10581      * use a camera distance that's greater than the height (X axis rotation) or
10582      * the width (Y axis rotation) of this view.</p>
10583      *
10584      * <p>The distance of the camera from the view plane can have an affect on the
10585      * perspective distortion of the view when it is rotated around the x or y axis.
10586      * For example, a large distance will result in a large viewing angle, and there
10587      * will not be much perspective distortion of the view as it rotates. A short
10588      * distance may cause much more perspective distortion upon rotation, and can
10589      * also result in some drawing artifacts if the rotated view ends up partially
10590      * behind the camera (which is why the recommendation is to use a distance at
10591      * least as far as the size of the view, if the view is to be rotated.)</p>
10592      *
10593      * <p>The distance is expressed in "depth pixels." The default distance depends
10594      * on the screen density. For instance, on a medium density display, the
10595      * default distance is 1280. On a high density display, the default distance
10596      * is 1920.</p>
10597      *
10598      * <p>If you want to specify a distance that leads to visually consistent
10599      * results across various densities, use the following formula:</p>
10600      * <pre>
10601      * float scale = context.getResources().getDisplayMetrics().density;
10602      * view.setCameraDistance(distance * scale);
10603      * </pre>
10604      *
10605      * <p>The density scale factor of a high density display is 1.5,
10606      * and 1920 = 1280 * 1.5.</p>
10607      *
10608      * @param distance The distance in "depth pixels", if negative the opposite
10609      *        value is used
10610      *
10611      * @see #setRotationX(float)
10612      * @see #setRotationY(float)
10613      */
10614     public void setCameraDistance(float distance) {
10615         final float dpi = mResources.getDisplayMetrics().densityDpi;
10616
10617         invalidateViewProperty(true, false);
10618         mRenderNode.setCameraDistance(-Math.abs(distance) / dpi);
10619         invalidateViewProperty(false, false);
10620
10621         invalidateParentIfNeededAndWasQuickRejected();
10622     }
10623
10624     /**
10625      * The degrees that the view is rotated around the pivot point.
10626      *
10627      * @see #setRotation(float)
10628      * @see #getPivotX()
10629      * @see #getPivotY()
10630      *
10631      * @return The degrees of rotation.
10632      */
10633     @ViewDebug.ExportedProperty(category = "drawing")
10634     public float getRotation() {
10635         return mRenderNode.getRotation();
10636     }
10637
10638     /**
10639      * Sets the degrees that the view is rotated around the pivot point. Increasing values
10640      * result in clockwise rotation.
10641      *
10642      * @param rotation The degrees of rotation.
10643      *
10644      * @see #getRotation()
10645      * @see #getPivotX()
10646      * @see #getPivotY()
10647      * @see #setRotationX(float)
10648      * @see #setRotationY(float)
10649      *
10650      * @attr ref android.R.styleable#View_rotation
10651      */
10652     public void setRotation(float rotation) {
10653         if (rotation != getRotation()) {
10654             // Double-invalidation is necessary to capture view's old and new areas
10655             invalidateViewProperty(true, false);
10656             mRenderNode.setRotation(rotation);
10657             invalidateViewProperty(false, true);
10658
10659             invalidateParentIfNeededAndWasQuickRejected();
10660             notifySubtreeAccessibilityStateChangedIfNeeded();
10661         }
10662     }
10663
10664     /**
10665      * The degrees that the view is rotated around the vertical axis through the pivot point.
10666      *
10667      * @see #getPivotX()
10668      * @see #getPivotY()
10669      * @see #setRotationY(float)
10670      *
10671      * @return The degrees of Y rotation.
10672      */
10673     @ViewDebug.ExportedProperty(category = "drawing")
10674     public float getRotationY() {
10675         return mRenderNode.getRotationY();
10676     }
10677
10678     /**
10679      * Sets the degrees that the view is rotated around the vertical axis through the pivot point.
10680      * Increasing values result in counter-clockwise rotation from the viewpoint of looking
10681      * down the y axis.
10682      *
10683      * When rotating large views, it is recommended to adjust the camera distance
10684      * accordingly. Refer to {@link #setCameraDistance(float)} for more information.
10685      *
10686      * @param rotationY The degrees of Y rotation.
10687      *
10688      * @see #getRotationY()
10689      * @see #getPivotX()
10690      * @see #getPivotY()
10691      * @see #setRotation(float)
10692      * @see #setRotationX(float)
10693      * @see #setCameraDistance(float)
10694      *
10695      * @attr ref android.R.styleable#View_rotationY
10696      */
10697     public void setRotationY(float rotationY) {
10698         if (rotationY != getRotationY()) {
10699             invalidateViewProperty(true, false);
10700             mRenderNode.setRotationY(rotationY);
10701             invalidateViewProperty(false, true);
10702
10703             invalidateParentIfNeededAndWasQuickRejected();
10704             notifySubtreeAccessibilityStateChangedIfNeeded();
10705         }
10706     }
10707
10708     /**
10709      * The degrees that the view is rotated around the horizontal axis through the pivot point.
10710      *
10711      * @see #getPivotX()
10712      * @see #getPivotY()
10713      * @see #setRotationX(float)
10714      *
10715      * @return The degrees of X rotation.
10716      */
10717     @ViewDebug.ExportedProperty(category = "drawing")
10718     public float getRotationX() {
10719         return mRenderNode.getRotationX();
10720     }
10721
10722     /**
10723      * Sets the degrees that the view is rotated around the horizontal axis through the pivot point.
10724      * Increasing values result in clockwise rotation from the viewpoint of looking down the
10725      * x axis.
10726      *
10727      * When rotating large views, it is recommended to adjust the camera distance
10728      * accordingly. Refer to {@link #setCameraDistance(float)} for more information.
10729      *
10730      * @param rotationX The degrees of X rotation.
10731      *
10732      * @see #getRotationX()
10733      * @see #getPivotX()
10734      * @see #getPivotY()
10735      * @see #setRotation(float)
10736      * @see #setRotationY(float)
10737      * @see #setCameraDistance(float)
10738      *
10739      * @attr ref android.R.styleable#View_rotationX
10740      */
10741     public void setRotationX(float rotationX) {
10742         if (rotationX != getRotationX()) {
10743             invalidateViewProperty(true, false);
10744             mRenderNode.setRotationX(rotationX);
10745             invalidateViewProperty(false, true);
10746
10747             invalidateParentIfNeededAndWasQuickRejected();
10748             notifySubtreeAccessibilityStateChangedIfNeeded();
10749         }
10750     }
10751
10752     /**
10753      * The amount that the view is scaled in x around the pivot point, as a proportion of
10754      * the view's unscaled width. A value of 1, the default, means that no scaling is applied.
10755      *
10756      * <p>By default, this is 1.0f.
10757      *
10758      * @see #getPivotX()
10759      * @see #getPivotY()
10760      * @return The scaling factor.
10761      */
10762     @ViewDebug.ExportedProperty(category = "drawing")
10763     public float getScaleX() {
10764         return mRenderNode.getScaleX();
10765     }
10766
10767     /**
10768      * Sets the amount that the view is scaled in x around the pivot point, as a proportion of
10769      * the view's unscaled width. A value of 1 means that no scaling is applied.
10770      *
10771      * @param scaleX The scaling factor.
10772      * @see #getPivotX()
10773      * @see #getPivotY()
10774      *
10775      * @attr ref android.R.styleable#View_scaleX
10776      */
10777     public void setScaleX(float scaleX) {
10778         if (scaleX != getScaleX()) {
10779             invalidateViewProperty(true, false);
10780             mRenderNode.setScaleX(scaleX);
10781             invalidateViewProperty(false, true);
10782
10783             invalidateParentIfNeededAndWasQuickRejected();
10784             notifySubtreeAccessibilityStateChangedIfNeeded();
10785         }
10786     }
10787
10788     /**
10789      * The amount that the view is scaled in y around the pivot point, as a proportion of
10790      * the view's unscaled height. A value of 1, the default, means that no scaling is applied.
10791      *
10792      * <p>By default, this is 1.0f.
10793      *
10794      * @see #getPivotX()
10795      * @see #getPivotY()
10796      * @return The scaling factor.
10797      */
10798     @ViewDebug.ExportedProperty(category = "drawing")
10799     public float getScaleY() {
10800         return mRenderNode.getScaleY();
10801     }
10802
10803     /**
10804      * Sets the amount that the view is scaled in Y around the pivot point, as a proportion of
10805      * the view's unscaled width. A value of 1 means that no scaling is applied.
10806      *
10807      * @param scaleY The scaling factor.
10808      * @see #getPivotX()
10809      * @see #getPivotY()
10810      *
10811      * @attr ref android.R.styleable#View_scaleY
10812      */
10813     public void setScaleY(float scaleY) {
10814         if (scaleY != getScaleY()) {
10815             invalidateViewProperty(true, false);
10816             mRenderNode.setScaleY(scaleY);
10817             invalidateViewProperty(false, true);
10818
10819             invalidateParentIfNeededAndWasQuickRejected();
10820             notifySubtreeAccessibilityStateChangedIfNeeded();
10821         }
10822     }
10823
10824     /**
10825      * The x location of the point around which the view is {@link #setRotation(float) rotated}
10826      * and {@link #setScaleX(float) scaled}.
10827      *
10828      * @see #getRotation()
10829      * @see #getScaleX()
10830      * @see #getScaleY()
10831      * @see #getPivotY()
10832      * @return The x location of the pivot point.
10833      *
10834      * @attr ref android.R.styleable#View_transformPivotX
10835      */
10836     @ViewDebug.ExportedProperty(category = "drawing")
10837     public float getPivotX() {
10838         return mRenderNode.getPivotX();
10839     }
10840
10841     /**
10842      * Sets the x location of the point around which the view is
10843      * {@link #setRotation(float) rotated} and {@link #setScaleX(float) scaled}.
10844      * By default, the pivot point is centered on the object.
10845      * Setting this property disables this behavior and causes the view to use only the
10846      * explicitly set pivotX and pivotY values.
10847      *
10848      * @param pivotX The x location of the pivot point.
10849      * @see #getRotation()
10850      * @see #getScaleX()
10851      * @see #getScaleY()
10852      * @see #getPivotY()
10853      *
10854      * @attr ref android.R.styleable#View_transformPivotX
10855      */
10856     public void setPivotX(float pivotX) {
10857         if (!mRenderNode.isPivotExplicitlySet() || pivotX != getPivotX()) {
10858             invalidateViewProperty(true, false);
10859             mRenderNode.setPivotX(pivotX);
10860             invalidateViewProperty(false, true);
10861
10862             invalidateParentIfNeededAndWasQuickRejected();
10863         }
10864     }
10865
10866     /**
10867      * The y location of the point around which the view is {@link #setRotation(float) rotated}
10868      * and {@link #setScaleY(float) scaled}.
10869      *
10870      * @see #getRotation()
10871      * @see #getScaleX()
10872      * @see #getScaleY()
10873      * @see #getPivotY()
10874      * @return The y location of the pivot point.
10875      *
10876      * @attr ref android.R.styleable#View_transformPivotY
10877      */
10878     @ViewDebug.ExportedProperty(category = "drawing")
10879     public float getPivotY() {
10880         return mRenderNode.getPivotY();
10881     }
10882
10883     /**
10884      * Sets the y location of the point around which the view is {@link #setRotation(float) rotated}
10885      * and {@link #setScaleY(float) scaled}. By default, the pivot point is centered on the object.
10886      * Setting this property disables this behavior and causes the view to use only the
10887      * explicitly set pivotX and pivotY values.
10888      *
10889      * @param pivotY The y location of the pivot point.
10890      * @see #getRotation()
10891      * @see #getScaleX()
10892      * @see #getScaleY()
10893      * @see #getPivotY()
10894      *
10895      * @attr ref android.R.styleable#View_transformPivotY
10896      */
10897     public void setPivotY(float pivotY) {
10898         if (!mRenderNode.isPivotExplicitlySet() || pivotY != getPivotY()) {
10899             invalidateViewProperty(true, false);
10900             mRenderNode.setPivotY(pivotY);
10901             invalidateViewProperty(false, true);
10902
10903             invalidateParentIfNeededAndWasQuickRejected();
10904         }
10905     }
10906
10907     /**
10908      * The opacity of the view. This is a value from 0 to 1, where 0 means the view is
10909      * completely transparent and 1 means the view is completely opaque.
10910      *
10911      * <p>By default this is 1.0f.
10912      * @return The opacity of the view.
10913      */
10914     @ViewDebug.ExportedProperty(category = "drawing")
10915     public float getAlpha() {
10916         return mTransformationInfo != null ? mTransformationInfo.mAlpha : 1;
10917     }
10918
10919     /**
10920      * Returns whether this View has content which overlaps.
10921      *
10922      * <p>This function, intended to be overridden by specific View types, is an optimization when
10923      * alpha is set on a view. If rendering overlaps in a view with alpha < 1, that view is drawn to
10924      * an offscreen buffer and then composited into place, which can be expensive. If the view has
10925      * no overlapping rendering, the view can draw each primitive with the appropriate alpha value
10926      * directly. An example of overlapping rendering is a TextView with a background image, such as
10927      * a Button. An example of non-overlapping rendering is a TextView with no background, or an
10928      * ImageView with only the foreground image. The default implementation returns true; subclasses
10929      * should override if they have cases which can be optimized.</p>
10930      *
10931      * <p>The current implementation of the saveLayer and saveLayerAlpha methods in {@link Canvas}
10932      * necessitates that a View return true if it uses the methods internally without passing the
10933      * {@link Canvas#CLIP_TO_LAYER_SAVE_FLAG}.</p>
10934      *
10935      * @return true if the content in this view might overlap, false otherwise.
10936      */
10937     @ViewDebug.ExportedProperty(category = "drawing")
10938     public boolean hasOverlappingRendering() {
10939         return true;
10940     }
10941
10942     /**
10943      * <p>Sets the opacity of the view. This is a value from 0 to 1, where 0 means the view is
10944      * completely transparent and 1 means the view is completely opaque.</p>
10945      *
10946      * <p> Note that setting alpha to a translucent value (0 < alpha < 1) can have significant
10947      * performance implications, especially for large views. It is best to use the alpha property
10948      * sparingly and transiently, as in the case of fading animations.</p>
10949      *
10950      * <p>For a view with a frequently changing alpha, such as during a fading animation, it is
10951      * strongly recommended for performance reasons to either override
10952      * {@link #hasOverlappingRendering()} to return false if appropriate, or setting a
10953      * {@link #setLayerType(int, android.graphics.Paint) layer type} on the view.</p>
10954      *
10955      * <p>If this view overrides {@link #onSetAlpha(int)} to return true, then this view is
10956      * responsible for applying the opacity itself.</p>
10957      *
10958      * <p>Note that if the view is backed by a
10959      * {@link #setLayerType(int, android.graphics.Paint) layer} and is associated with a
10960      * {@link #setLayerPaint(android.graphics.Paint) layer paint}, setting an alpha value less than
10961      * 1.0 will supersede the alpha of the layer paint.</p>
10962      *
10963      * @param alpha The opacity of the view.
10964      *
10965      * @see #hasOverlappingRendering()
10966      * @see #setLayerType(int, android.graphics.Paint)
10967      *
10968      * @attr ref android.R.styleable#View_alpha
10969      */
10970     public void setAlpha(@FloatRange(from=0.0, to=1.0) float alpha) {
10971         ensureTransformationInfo();
10972         if (mTransformationInfo.mAlpha != alpha) {
10973             mTransformationInfo.mAlpha = alpha;
10974             if (onSetAlpha((int) (alpha * 255))) {
10975                 mPrivateFlags |= PFLAG_ALPHA_SET;
10976                 // subclass is handling alpha - don't optimize rendering cache invalidation
10977                 invalidateParentCaches();
10978                 invalidate(true);
10979             } else {
10980                 mPrivateFlags &= ~PFLAG_ALPHA_SET;
10981                 invalidateViewProperty(true, false);
10982                 mRenderNode.setAlpha(getFinalAlpha());
10983                 notifyViewAccessibilityStateChangedIfNeeded(
10984                         AccessibilityEvent.CONTENT_CHANGE_TYPE_UNDEFINED);
10985             }
10986         }
10987     }
10988
10989     /**
10990      * Faster version of setAlpha() which performs the same steps except there are
10991      * no calls to invalidate(). The caller of this function should perform proper invalidation
10992      * on the parent and this object. The return value indicates whether the subclass handles
10993      * alpha (the return value for onSetAlpha()).
10994      *
10995      * @param alpha The new value for the alpha property
10996      * @return true if the View subclass handles alpha (the return value for onSetAlpha()) and
10997      *         the new value for the alpha property is different from the old value
10998      */
10999     boolean setAlphaNoInvalidation(float alpha) {
11000         ensureTransformationInfo();
11001         if (mTransformationInfo.mAlpha != alpha) {
11002             mTransformationInfo.mAlpha = alpha;
11003             boolean subclassHandlesAlpha = onSetAlpha((int) (alpha * 255));
11004             if (subclassHandlesAlpha) {
11005                 mPrivateFlags |= PFLAG_ALPHA_SET;
11006                 return true;
11007             } else {
11008                 mPrivateFlags &= ~PFLAG_ALPHA_SET;
11009                 mRenderNode.setAlpha(getFinalAlpha());
11010             }
11011         }
11012         return false;
11013     }
11014
11015     /**
11016      * This property is hidden and intended only for use by the Fade transition, which
11017      * animates it to produce a visual translucency that does not side-effect (or get
11018      * affected by) the real alpha property. This value is composited with the other
11019      * alpha value (and the AlphaAnimation value, when that is present) to produce
11020      * a final visual translucency result, which is what is passed into the DisplayList.
11021      *
11022      * @hide
11023      */
11024     public void setTransitionAlpha(float alpha) {
11025         ensureTransformationInfo();
11026         if (mTransformationInfo.mTransitionAlpha != alpha) {
11027             mTransformationInfo.mTransitionAlpha = alpha;
11028             mPrivateFlags &= ~PFLAG_ALPHA_SET;
11029             invalidateViewProperty(true, false);
11030             mRenderNode.setAlpha(getFinalAlpha());
11031         }
11032     }
11033
11034     /**
11035      * Calculates the visual alpha of this view, which is a combination of the actual
11036      * alpha value and the transitionAlpha value (if set).
11037      */
11038     private float getFinalAlpha() {
11039         if (mTransformationInfo != null) {
11040             return mTransformationInfo.mAlpha * mTransformationInfo.mTransitionAlpha;
11041         }
11042         return 1;
11043     }
11044
11045     /**
11046      * This property is hidden and intended only for use by the Fade transition, which
11047      * animates it to produce a visual translucency that does not side-effect (or get
11048      * affected by) the real alpha property. This value is composited with the other
11049      * alpha value (and the AlphaAnimation value, when that is present) to produce
11050      * a final visual translucency result, which is what is passed into the DisplayList.
11051      *
11052      * @hide
11053      */
11054     @ViewDebug.ExportedProperty(category = "drawing")
11055     public float getTransitionAlpha() {
11056         return mTransformationInfo != null ? mTransformationInfo.mTransitionAlpha : 1;
11057     }
11058
11059     /**
11060      * Top position of this view relative to its parent.
11061      *
11062      * @return The top of this view, in pixels.
11063      */
11064     @ViewDebug.CapturedViewProperty
11065     public final int getTop() {
11066         return mTop;
11067     }
11068
11069     /**
11070      * Sets the top position of this view relative to its parent. This method is meant to be called
11071      * by the layout system and should not generally be called otherwise, because the property
11072      * may be changed at any time by the layout.
11073      *
11074      * @param top The top of this view, in pixels.
11075      */
11076     public final void setTop(int top) {
11077         if (top != mTop) {
11078             final boolean matrixIsIdentity = hasIdentityMatrix();
11079             if (matrixIsIdentity) {
11080                 if (mAttachInfo != null) {
11081                     int minTop;
11082                     int yLoc;
11083                     if (top < mTop) {
11084                         minTop = top;
11085                         yLoc = top - mTop;
11086                     } else {
11087                         minTop = mTop;
11088                         yLoc = 0;
11089                     }
11090                     invalidate(0, yLoc, mRight - mLeft, mBottom - minTop);
11091                 }
11092             } else {
11093                 // Double-invalidation is necessary to capture view's old and new areas
11094                 invalidate(true);
11095             }
11096
11097             int width = mRight - mLeft;
11098             int oldHeight = mBottom - mTop;
11099
11100             mTop = top;
11101             mRenderNode.setTop(mTop);
11102
11103             sizeChange(width, mBottom - mTop, width, oldHeight);
11104
11105             if (!matrixIsIdentity) {
11106                 mPrivateFlags |= PFLAG_DRAWN; // force another invalidation with the new orientation
11107                 invalidate(true);
11108             }
11109             mBackgroundSizeChanged = true;
11110             if (mForegroundInfo != null) {
11111                 mForegroundInfo.mBoundsChanged = true;
11112             }
11113             invalidateParentIfNeeded();
11114             if ((mPrivateFlags2 & PFLAG2_VIEW_QUICK_REJECTED) == PFLAG2_VIEW_QUICK_REJECTED) {
11115                 // View was rejected last time it was drawn by its parent; this may have changed
11116                 invalidateParentIfNeeded();
11117             }
11118         }
11119     }
11120
11121     /**
11122      * Bottom position of this view relative to its parent.
11123      *
11124      * @return The bottom of this view, in pixels.
11125      */
11126     @ViewDebug.CapturedViewProperty
11127     public final int getBottom() {
11128         return mBottom;
11129     }
11130
11131     /**
11132      * True if this view has changed since the last time being drawn.
11133      *
11134      * @return The dirty state of this view.
11135      */
11136     public boolean isDirty() {
11137         return (mPrivateFlags & PFLAG_DIRTY_MASK) != 0;
11138     }
11139
11140     /**
11141      * Sets the bottom position of this view relative to its parent. This method is meant to be
11142      * called by the layout system and should not generally be called otherwise, because the
11143      * property may be changed at any time by the layout.
11144      *
11145      * @param bottom The bottom of this view, in pixels.
11146      */
11147     public final void setBottom(int bottom) {
11148         if (bottom != mBottom) {
11149             final boolean matrixIsIdentity = hasIdentityMatrix();
11150             if (matrixIsIdentity) {
11151                 if (mAttachInfo != null) {
11152                     int maxBottom;
11153                     if (bottom < mBottom) {
11154                         maxBottom = mBottom;
11155                     } else {
11156                         maxBottom = bottom;
11157                     }
11158                     invalidate(0, 0, mRight - mLeft, maxBottom - mTop);
11159                 }
11160             } else {
11161                 // Double-invalidation is necessary to capture view's old and new areas
11162                 invalidate(true);
11163             }
11164
11165             int width = mRight - mLeft;
11166             int oldHeight = mBottom - mTop;
11167
11168             mBottom = bottom;
11169             mRenderNode.setBottom(mBottom);
11170
11171             sizeChange(width, mBottom - mTop, width, oldHeight);
11172
11173             if (!matrixIsIdentity) {
11174                 mPrivateFlags |= PFLAG_DRAWN; // force another invalidation with the new orientation
11175                 invalidate(true);
11176             }
11177             mBackgroundSizeChanged = true;
11178             if (mForegroundInfo != null) {
11179                 mForegroundInfo.mBoundsChanged = true;
11180             }
11181             invalidateParentIfNeeded();
11182             if ((mPrivateFlags2 & PFLAG2_VIEW_QUICK_REJECTED) == PFLAG2_VIEW_QUICK_REJECTED) {
11183                 // View was rejected last time it was drawn by its parent; this may have changed
11184                 invalidateParentIfNeeded();
11185             }
11186         }
11187     }
11188
11189     /**
11190      * Left position of this view relative to its parent.
11191      *
11192      * @return The left edge of this view, in pixels.
11193      */
11194     @ViewDebug.CapturedViewProperty
11195     public final int getLeft() {
11196         return mLeft;
11197     }
11198
11199     /**
11200      * Sets the left position of this view relative to its parent. This method is meant to be called
11201      * by the layout system and should not generally be called otherwise, because the property
11202      * may be changed at any time by the layout.
11203      *
11204      * @param left The left of this view, in pixels.
11205      */
11206     public final void setLeft(int left) {
11207         if (left != mLeft) {
11208             final boolean matrixIsIdentity = hasIdentityMatrix();
11209             if (matrixIsIdentity) {
11210                 if (mAttachInfo != null) {
11211                     int minLeft;
11212                     int xLoc;
11213                     if (left < mLeft) {
11214                         minLeft = left;
11215                         xLoc = left - mLeft;
11216                     } else {
11217                         minLeft = mLeft;
11218                         xLoc = 0;
11219                     }
11220                     invalidate(xLoc, 0, mRight - minLeft, mBottom - mTop);
11221                 }
11222             } else {
11223                 // Double-invalidation is necessary to capture view's old and new areas
11224                 invalidate(true);
11225             }
11226
11227             int oldWidth = mRight - mLeft;
11228             int height = mBottom - mTop;
11229
11230             mLeft = left;
11231             mRenderNode.setLeft(left);
11232
11233             sizeChange(mRight - mLeft, height, oldWidth, height);
11234
11235             if (!matrixIsIdentity) {
11236                 mPrivateFlags |= PFLAG_DRAWN; // force another invalidation with the new orientation
11237                 invalidate(true);
11238             }
11239             mBackgroundSizeChanged = true;
11240             if (mForegroundInfo != null) {
11241                 mForegroundInfo.mBoundsChanged = true;
11242             }
11243             invalidateParentIfNeeded();
11244             if ((mPrivateFlags2 & PFLAG2_VIEW_QUICK_REJECTED) == PFLAG2_VIEW_QUICK_REJECTED) {
11245                 // View was rejected last time it was drawn by its parent; this may have changed
11246                 invalidateParentIfNeeded();
11247             }
11248         }
11249     }
11250
11251     /**
11252      * Right position of this view relative to its parent.
11253      *
11254      * @return The right edge of this view, in pixels.
11255      */
11256     @ViewDebug.CapturedViewProperty
11257     public final int getRight() {
11258         return mRight;
11259     }
11260
11261     /**
11262      * Sets the right position of this view relative to its parent. This method is meant to be called
11263      * by the layout system and should not generally be called otherwise, because the property
11264      * may be changed at any time by the layout.
11265      *
11266      * @param right The right of this view, in pixels.
11267      */
11268     public final void setRight(int right) {
11269         if (right != mRight) {
11270             final boolean matrixIsIdentity = hasIdentityMatrix();
11271             if (matrixIsIdentity) {
11272                 if (mAttachInfo != null) {
11273                     int maxRight;
11274                     if (right < mRight) {
11275                         maxRight = mRight;
11276                     } else {
11277                         maxRight = right;
11278                     }
11279                     invalidate(0, 0, maxRight - mLeft, mBottom - mTop);
11280                 }
11281             } else {
11282                 // Double-invalidation is necessary to capture view's old and new areas
11283                 invalidate(true);
11284             }
11285
11286             int oldWidth = mRight - mLeft;
11287             int height = mBottom - mTop;
11288
11289             mRight = right;
11290             mRenderNode.setRight(mRight);
11291
11292             sizeChange(mRight - mLeft, height, oldWidth, height);
11293
11294             if (!matrixIsIdentity) {
11295                 mPrivateFlags |= PFLAG_DRAWN; // force another invalidation with the new orientation
11296                 invalidate(true);
11297             }
11298             mBackgroundSizeChanged = true;
11299             if (mForegroundInfo != null) {
11300                 mForegroundInfo.mBoundsChanged = true;
11301             }
11302             invalidateParentIfNeeded();
11303             if ((mPrivateFlags2 & PFLAG2_VIEW_QUICK_REJECTED) == PFLAG2_VIEW_QUICK_REJECTED) {
11304                 // View was rejected last time it was drawn by its parent; this may have changed
11305                 invalidateParentIfNeeded();
11306             }
11307         }
11308     }
11309
11310     /**
11311      * The visual x position of this view, in pixels. This is equivalent to the
11312      * {@link #setTranslationX(float) translationX} property plus the current
11313      * {@link #getLeft() left} property.
11314      *
11315      * @return The visual x position of this view, in pixels.
11316      */
11317     @ViewDebug.ExportedProperty(category = "drawing")
11318     public float getX() {
11319         return mLeft + getTranslationX();
11320     }
11321
11322     /**
11323      * Sets the visual x position of this view, in pixels. This is equivalent to setting the
11324      * {@link #setTranslationX(float) translationX} property to be the difference between
11325      * the x value passed in and the current {@link #getLeft() left} property.
11326      *
11327      * @param x The visual x position of this view, in pixels.
11328      */
11329     public void setX(float x) {
11330         setTranslationX(x - mLeft);
11331     }
11332
11333     /**
11334      * The visual y position of this view, in pixels. This is equivalent to the
11335      * {@link #setTranslationY(float) translationY} property plus the current
11336      * {@link #getTop() top} property.
11337      *
11338      * @return The visual y position of this view, in pixels.
11339      */
11340     @ViewDebug.ExportedProperty(category = "drawing")
11341     public float getY() {
11342         return mTop + getTranslationY();
11343     }
11344
11345     /**
11346      * Sets the visual y position of this view, in pixels. This is equivalent to setting the
11347      * {@link #setTranslationY(float) translationY} property to be the difference between
11348      * the y value passed in and the current {@link #getTop() top} property.
11349      *
11350      * @param y The visual y position of this view, in pixels.
11351      */
11352     public void setY(float y) {
11353         setTranslationY(y - mTop);
11354     }
11355
11356     /**
11357      * The visual z position of this view, in pixels. This is equivalent to the
11358      * {@link #setTranslationZ(float) translationZ} property plus the current
11359      * {@link #getElevation() elevation} property.
11360      *
11361      * @return The visual z position of this view, in pixels.
11362      */
11363     @ViewDebug.ExportedProperty(category = "drawing")
11364     public float getZ() {
11365         return getElevation() + getTranslationZ();
11366     }
11367
11368     /**
11369      * Sets the visual z position of this view, in pixels. This is equivalent to setting the
11370      * {@link #setTranslationZ(float) translationZ} property to be the difference between
11371      * the x value passed in and the current {@link #getElevation() elevation} property.
11372      *
11373      * @param z The visual z position of this view, in pixels.
11374      */
11375     public void setZ(float z) {
11376         setTranslationZ(z - getElevation());
11377     }
11378
11379     /**
11380      * The base elevation of this view relative to its parent, in pixels.
11381      *
11382      * @return The base depth position of the view, in pixels.
11383      */
11384     @ViewDebug.ExportedProperty(category = "drawing")
11385     public float getElevation() {
11386         return mRenderNode.getElevation();
11387     }
11388
11389     /**
11390      * Sets the base elevation of this view, in pixels.
11391      *
11392      * @attr ref android.R.styleable#View_elevation
11393      */
11394     public void setElevation(float elevation) {
11395         if (elevation != getElevation()) {
11396             invalidateViewProperty(true, false);
11397             mRenderNode.setElevation(elevation);
11398             invalidateViewProperty(false, true);
11399
11400             invalidateParentIfNeededAndWasQuickRejected();
11401         }
11402     }
11403
11404     /**
11405      * The horizontal location of this view relative to its {@link #getLeft() left} position.
11406      * This position is post-layout, in addition to wherever the object's
11407      * layout placed it.
11408      *
11409      * @return The horizontal position of this view relative to its left position, in pixels.
11410      */
11411     @ViewDebug.ExportedProperty(category = "drawing")
11412     public float getTranslationX() {
11413         return mRenderNode.getTranslationX();
11414     }
11415
11416     /**
11417      * Sets the horizontal location of this view relative to its {@link #getLeft() left} position.
11418      * This effectively positions the object post-layout, in addition to wherever the object's
11419      * layout placed it.
11420      *
11421      * @param translationX The horizontal position of this view relative to its left position,
11422      * in pixels.
11423      *
11424      * @attr ref android.R.styleable#View_translationX
11425      */
11426     public void setTranslationX(float translationX) {
11427         if (translationX != getTranslationX()) {
11428             invalidateViewProperty(true, false);
11429             mRenderNode.setTranslationX(translationX);
11430             invalidateViewProperty(false, true);
11431
11432             invalidateParentIfNeededAndWasQuickRejected();
11433             notifySubtreeAccessibilityStateChangedIfNeeded();
11434         }
11435     }
11436
11437     /**
11438      * The vertical location of this view relative to its {@link #getTop() top} position.
11439      * This position is post-layout, in addition to wherever the object's
11440      * layout placed it.
11441      *
11442      * @return The vertical position of this view relative to its top position,
11443      * in pixels.
11444      */
11445     @ViewDebug.ExportedProperty(category = "drawing")
11446     public float getTranslationY() {
11447         return mRenderNode.getTranslationY();
11448     }
11449
11450     /**
11451      * Sets the vertical location of this view relative to its {@link #getTop() top} position.
11452      * This effectively positions the object post-layout, in addition to wherever the object's
11453      * layout placed it.
11454      *
11455      * @param translationY The vertical position of this view relative to its top position,
11456      * in pixels.
11457      *
11458      * @attr ref android.R.styleable#View_translationY
11459      */
11460     public void setTranslationY(float translationY) {
11461         if (translationY != getTranslationY()) {
11462             invalidateViewProperty(true, false);
11463             mRenderNode.setTranslationY(translationY);
11464             invalidateViewProperty(false, true);
11465
11466             invalidateParentIfNeededAndWasQuickRejected();
11467             notifySubtreeAccessibilityStateChangedIfNeeded();
11468         }
11469     }
11470
11471     /**
11472      * The depth location of this view relative to its {@link #getElevation() elevation}.
11473      *
11474      * @return The depth of this view relative to its elevation.
11475      */
11476     @ViewDebug.ExportedProperty(category = "drawing")
11477     public float getTranslationZ() {
11478         return mRenderNode.getTranslationZ();
11479     }
11480
11481     /**
11482      * Sets the depth location of this view relative to its {@link #getElevation() elevation}.
11483      *
11484      * @attr ref android.R.styleable#View_translationZ
11485      */
11486     public void setTranslationZ(float translationZ) {
11487         if (translationZ != getTranslationZ()) {
11488             invalidateViewProperty(true, false);
11489             mRenderNode.setTranslationZ(translationZ);
11490             invalidateViewProperty(false, true);
11491
11492             invalidateParentIfNeededAndWasQuickRejected();
11493         }
11494     }
11495
11496     /** @hide */
11497     public void setAnimationMatrix(Matrix matrix) {
11498         invalidateViewProperty(true, false);
11499         mRenderNode.setAnimationMatrix(matrix);
11500         invalidateViewProperty(false, true);
11501
11502         invalidateParentIfNeededAndWasQuickRejected();
11503     }
11504
11505     /**
11506      * Returns the current StateListAnimator if exists.
11507      *
11508      * @return StateListAnimator or null if it does not exists
11509      * @see    #setStateListAnimator(android.animation.StateListAnimator)
11510      */
11511     public StateListAnimator getStateListAnimator() {
11512         return mStateListAnimator;
11513     }
11514
11515     /**
11516      * Attaches the provided StateListAnimator to this View.
11517      * <p>
11518      * Any previously attached StateListAnimator will be detached.
11519      *
11520      * @param stateListAnimator The StateListAnimator to update the view
11521      * @see {@link android.animation.StateListAnimator}
11522      */
11523     public void setStateListAnimator(StateListAnimator stateListAnimator) {
11524         if (mStateListAnimator == stateListAnimator) {
11525             return;
11526         }
11527         if (mStateListAnimator != null) {
11528             mStateListAnimator.setTarget(null);
11529         }
11530         mStateListAnimator = stateListAnimator;
11531         if (stateListAnimator != null) {
11532             stateListAnimator.setTarget(this);
11533             if (isAttachedToWindow()) {
11534                 stateListAnimator.setState(getDrawableState());
11535             }
11536         }
11537     }
11538
11539     /**
11540      * Returns whether the Outline should be used to clip the contents of the View.
11541      * <p>
11542      * Note that this flag will only be respected if the View's Outline returns true from
11543      * {@link Outline#canClip()}.
11544      *
11545      * @see #setOutlineProvider(ViewOutlineProvider)
11546      * @see #setClipToOutline(boolean)
11547      */
11548     public final boolean getClipToOutline() {
11549         return mRenderNode.getClipToOutline();
11550     }
11551
11552     /**
11553      * Sets whether the View's Outline should be used to clip the contents of the View.
11554      * <p>
11555      * Only a single non-rectangular clip can be applied on a View at any time.
11556      * Circular clips from a {@link ViewAnimationUtils#createCircularReveal(View, int, int, float, float)
11557      * circular reveal} animation take priority over Outline clipping, and
11558      * child Outline clipping takes priority over Outline clipping done by a
11559      * parent.
11560      * <p>
11561      * Note that this flag will only be respected if the View's Outline returns true from
11562      * {@link Outline#canClip()}.
11563      *
11564      * @see #setOutlineProvider(ViewOutlineProvider)
11565      * @see #getClipToOutline()
11566      */
11567     public void setClipToOutline(boolean clipToOutline) {
11568         damageInParent();
11569         if (getClipToOutline() != clipToOutline) {
11570             mRenderNode.setClipToOutline(clipToOutline);
11571         }
11572     }
11573
11574     // correspond to the enum values of View_outlineProvider
11575     private static final int PROVIDER_BACKGROUND = 0;
11576     private static final int PROVIDER_NONE = 1;
11577     private static final int PROVIDER_BOUNDS = 2;
11578     private static final int PROVIDER_PADDED_BOUNDS = 3;
11579     private void setOutlineProviderFromAttribute(int providerInt) {
11580         switch (providerInt) {
11581             case PROVIDER_BACKGROUND:
11582                 setOutlineProvider(ViewOutlineProvider.BACKGROUND);
11583                 break;
11584             case PROVIDER_NONE:
11585                 setOutlineProvider(null);
11586                 break;
11587             case PROVIDER_BOUNDS:
11588                 setOutlineProvider(ViewOutlineProvider.BOUNDS);
11589                 break;
11590             case PROVIDER_PADDED_BOUNDS:
11591                 setOutlineProvider(ViewOutlineProvider.PADDED_BOUNDS);
11592                 break;
11593         }
11594     }
11595
11596     /**
11597      * Sets the {@link ViewOutlineProvider} of the view, which generates the Outline that defines
11598      * the shape of the shadow it casts, and enables outline clipping.
11599      * <p>
11600      * The default ViewOutlineProvider, {@link ViewOutlineProvider#BACKGROUND}, queries the Outline
11601      * from the View's background drawable, via {@link Drawable#getOutline(Outline)}. Changing the
11602      * outline provider with this method allows this behavior to be overridden.
11603      * <p>
11604      * If the ViewOutlineProvider is null, if querying it for an outline returns false,
11605      * or if the produced Outline is {@link Outline#isEmpty()}, shadows will not be cast.
11606      * <p>
11607      * Only outlines that return true from {@link Outline#canClip()} may be used for clipping.
11608      *
11609      * @see #setClipToOutline(boolean)
11610      * @see #getClipToOutline()
11611      * @see #getOutlineProvider()
11612      */
11613     public void setOutlineProvider(ViewOutlineProvider provider) {
11614         mOutlineProvider = provider;
11615         invalidateOutline();
11616     }
11617
11618     /**
11619      * Returns the current {@link ViewOutlineProvider} of the view, which generates the Outline
11620      * that defines the shape of the shadow it casts, and enables outline clipping.
11621      *
11622      * @see #setOutlineProvider(ViewOutlineProvider)
11623      */
11624     public ViewOutlineProvider getOutlineProvider() {
11625         return mOutlineProvider;
11626     }
11627
11628     /**
11629      * Called to rebuild this View's Outline from its {@link ViewOutlineProvider outline provider}
11630      *
11631      * @see #setOutlineProvider(ViewOutlineProvider)
11632      */
11633     public void invalidateOutline() {
11634         rebuildOutline();
11635
11636         notifySubtreeAccessibilityStateChangedIfNeeded();
11637         invalidateViewProperty(false, false);
11638     }
11639
11640     /**
11641      * Internal version of {@link #invalidateOutline()} which invalidates the
11642      * outline without invalidating the view itself. This is intended to be called from
11643      * within methods in the View class itself which are the result of the view being
11644      * invalidated already. For example, when we are drawing the background of a View,
11645      * we invalidate the outline in case it changed in the meantime, but we do not
11646      * need to invalidate the view because we're already drawing the background as part
11647      * of drawing the view in response to an earlier invalidation of the view.
11648      */
11649     private void rebuildOutline() {
11650         // Unattached views ignore this signal, and outline is recomputed in onAttachedToWindow()
11651         if (mAttachInfo == null) return;
11652
11653         if (mOutlineProvider == null) {
11654             // no provider, remove outline
11655             mRenderNode.setOutline(null);
11656         } else {
11657             final Outline outline = mAttachInfo.mTmpOutline;
11658             outline.setEmpty();
11659             outline.setAlpha(1.0f);
11660
11661             mOutlineProvider.getOutline(this, outline);
11662             mRenderNode.setOutline(outline);
11663         }
11664     }
11665
11666     /**
11667      * HierarchyViewer only
11668      *
11669      * @hide
11670      */
11671     @ViewDebug.ExportedProperty(category = "drawing")
11672     public boolean hasShadow() {
11673         return mRenderNode.hasShadow();
11674     }
11675
11676
11677     /** @hide */
11678     public void setRevealClip(boolean shouldClip, float x, float y, float radius) {
11679         mRenderNode.setRevealClip(shouldClip, x, y, radius);
11680         invalidateViewProperty(false, false);
11681     }
11682
11683     /**
11684      * Hit rectangle in parent's coordinates
11685      *
11686      * @param outRect The hit rectangle of the view.
11687      */
11688     public void getHitRect(Rect outRect) {
11689         if (hasIdentityMatrix() || mAttachInfo == null) {
11690             outRect.set(mLeft, mTop, mRight, mBottom);
11691         } else {
11692             final RectF tmpRect = mAttachInfo.mTmpTransformRect;
11693             tmpRect.set(0, 0, getWidth(), getHeight());
11694             getMatrix().mapRect(tmpRect); // TODO: mRenderNode.mapRect(tmpRect)
11695             outRect.set((int) tmpRect.left + mLeft, (int) tmpRect.top + mTop,
11696                     (int) tmpRect.right + mLeft, (int) tmpRect.bottom + mTop);
11697         }
11698     }
11699
11700     /**
11701      * Determines whether the given point, in local coordinates is inside the view.
11702      */
11703     /*package*/ final boolean pointInView(float localX, float localY) {
11704         return localX >= 0 && localX < (mRight - mLeft)
11705                 && localY >= 0 && localY < (mBottom - mTop);
11706     }
11707
11708     /**
11709      * Utility method to determine whether the given point, in local coordinates,
11710      * is inside the view, where the area of the view is expanded by the slop factor.
11711      * This method is called while processing touch-move events to determine if the event
11712      * is still within the view.
11713      *
11714      * @hide
11715      */
11716     public boolean pointInView(float localX, float localY, float slop) {
11717         return localX >= -slop && localY >= -slop && localX < ((mRight - mLeft) + slop) &&
11718                 localY < ((mBottom - mTop) + slop);
11719     }
11720
11721     /**
11722      * When a view has focus and the user navigates away from it, the next view is searched for
11723      * starting from the rectangle filled in by this method.
11724      *
11725      * By default, the rectangle is the {@link #getDrawingRect(android.graphics.Rect)})
11726      * of the view.  However, if your view maintains some idea of internal selection,
11727      * such as a cursor, or a selected row or column, you should override this method and
11728      * fill in a more specific rectangle.
11729      *
11730      * @param r The rectangle to fill in, in this view's coordinates.
11731      */
11732     public void getFocusedRect(Rect r) {
11733         getDrawingRect(r);
11734     }
11735
11736     /**
11737      * If some part of this view is not clipped by any of its parents, then
11738      * return that area in r in global (root) coordinates. To convert r to local
11739      * coordinates (without taking possible View rotations into account), offset
11740      * it by -globalOffset (e.g. r.offset(-globalOffset.x, -globalOffset.y)).
11741      * If the view is completely clipped or translated out, return false.
11742      *
11743      * @param r If true is returned, r holds the global coordinates of the
11744      *        visible portion of this view.
11745      * @param globalOffset If true is returned, globalOffset holds the dx,dy
11746      *        between this view and its root. globalOffet may be null.
11747      * @return true if r is non-empty (i.e. part of the view is visible at the
11748      *         root level.
11749      */
11750     public boolean getGlobalVisibleRect(Rect r, Point globalOffset) {
11751         int width = mRight - mLeft;
11752         int height = mBottom - mTop;
11753         if (width > 0 && height > 0) {
11754             r.set(0, 0, width, height);
11755             if (globalOffset != null) {
11756                 globalOffset.set(-mScrollX, -mScrollY);
11757             }
11758             return mParent == null || mParent.getChildVisibleRect(this, r, globalOffset);
11759         }
11760         return false;
11761     }
11762
11763     public final boolean getGlobalVisibleRect(Rect r) {
11764         return getGlobalVisibleRect(r, null);
11765     }
11766
11767     public final boolean getLocalVisibleRect(Rect r) {
11768         final Point offset = mAttachInfo != null ? mAttachInfo.mPoint : new Point();
11769         if (getGlobalVisibleRect(r, offset)) {
11770             r.offset(-offset.x, -offset.y); // make r local
11771             return true;
11772         }
11773         return false;
11774     }
11775
11776     /**
11777      * Offset this view's vertical location by the specified number of pixels.
11778      *
11779      * @param offset the number of pixels to offset the view by
11780      */
11781     public void offsetTopAndBottom(int offset) {
11782         if (offset != 0) {
11783             final boolean matrixIsIdentity = hasIdentityMatrix();
11784             if (matrixIsIdentity) {
11785                 if (isHardwareAccelerated()) {
11786                     invalidateViewProperty(false, false);
11787                 } else {
11788                     final ViewParent p = mParent;
11789                     if (p != null && mAttachInfo != null) {
11790                         final Rect r = mAttachInfo.mTmpInvalRect;
11791                         int minTop;
11792                         int maxBottom;
11793                         int yLoc;
11794                         if (offset < 0) {
11795                             minTop = mTop + offset;
11796                             maxBottom = mBottom;
11797                             yLoc = offset;
11798                         } else {
11799                             minTop = mTop;
11800                             maxBottom = mBottom + offset;
11801                             yLoc = 0;
11802                         }
11803                         r.set(0, yLoc, mRight - mLeft, maxBottom - minTop);
11804                         p.invalidateChild(this, r);
11805                     }
11806                 }
11807             } else {
11808                 invalidateViewProperty(false, false);
11809             }
11810
11811             mTop += offset;
11812             mBottom += offset;
11813             mRenderNode.offsetTopAndBottom(offset);
11814             if (isHardwareAccelerated()) {
11815                 invalidateViewProperty(false, false);
11816             } else {
11817                 if (!matrixIsIdentity) {
11818                     invalidateViewProperty(false, true);
11819                 }
11820                 invalidateParentIfNeeded();
11821             }
11822             notifySubtreeAccessibilityStateChangedIfNeeded();
11823         }
11824     }
11825
11826     /**
11827      * Offset this view's horizontal location by the specified amount of pixels.
11828      *
11829      * @param offset the number of pixels to offset the view by
11830      */
11831     public void offsetLeftAndRight(int offset) {
11832         if (offset != 0) {
11833             final boolean matrixIsIdentity = hasIdentityMatrix();
11834             if (matrixIsIdentity) {
11835                 if (isHardwareAccelerated()) {
11836                     invalidateViewProperty(false, false);
11837                 } else {
11838                     final ViewParent p = mParent;
11839                     if (p != null && mAttachInfo != null) {
11840                         final Rect r = mAttachInfo.mTmpInvalRect;
11841                         int minLeft;
11842                         int maxRight;
11843                         if (offset < 0) {
11844                             minLeft = mLeft + offset;
11845                             maxRight = mRight;
11846                         } else {
11847                             minLeft = mLeft;
11848                             maxRight = mRight + offset;
11849                         }
11850                         r.set(0, 0, maxRight - minLeft, mBottom - mTop);
11851                         p.invalidateChild(this, r);
11852                     }
11853                 }
11854             } else {
11855                 invalidateViewProperty(false, false);
11856             }
11857
11858             mLeft += offset;
11859             mRight += offset;
11860             mRenderNode.offsetLeftAndRight(offset);
11861             if (isHardwareAccelerated()) {
11862                 invalidateViewProperty(false, false);
11863             } else {
11864                 if (!matrixIsIdentity) {
11865                     invalidateViewProperty(false, true);
11866                 }
11867                 invalidateParentIfNeeded();
11868             }
11869             notifySubtreeAccessibilityStateChangedIfNeeded();
11870         }
11871     }
11872
11873     /**
11874      * Get the LayoutParams associated with this view. All views should have
11875      * layout parameters. These supply parameters to the <i>parent</i> of this
11876      * view specifying how it should be arranged. There are many subclasses of
11877      * ViewGroup.LayoutParams, and these correspond to the different subclasses
11878      * of ViewGroup that are responsible for arranging their children.
11879      *
11880      * This method may return null if this View is not attached to a parent
11881      * ViewGroup or {@link #setLayoutParams(android.view.ViewGroup.LayoutParams)}
11882      * was not invoked successfully. When a View is attached to a parent
11883      * ViewGroup, this method must not return null.
11884      *
11885      * @return The LayoutParams associated with this view, or null if no
11886      *         parameters have been set yet
11887      */
11888     @ViewDebug.ExportedProperty(deepExport = true, prefix = "layout_")
11889     public ViewGroup.LayoutParams getLayoutParams() {
11890         return mLayoutParams;
11891     }
11892
11893     /**
11894      * Set the layout parameters associated with this view. These supply
11895      * parameters to the <i>parent</i> of this view specifying how it should be
11896      * arranged. There are many subclasses of ViewGroup.LayoutParams, and these
11897      * correspond to the different subclasses of ViewGroup that are responsible
11898      * for arranging their children.
11899      *
11900      * @param params The layout parameters for this view, cannot be null
11901      */
11902     public void setLayoutParams(ViewGroup.LayoutParams params) {
11903         if (params == null) {
11904             throw new NullPointerException("Layout parameters cannot be null");
11905         }
11906         mLayoutParams = params;
11907         resolveLayoutParams();
11908         if (mParent instanceof ViewGroup) {
11909             ((ViewGroup) mParent).onSetLayoutParams(this, params);
11910         }
11911         requestLayout();
11912     }
11913
11914     /**
11915      * Resolve the layout parameters depending on the resolved layout direction
11916      *
11917      * @hide
11918      */
11919     public void resolveLayoutParams() {
11920         if (mLayoutParams != null) {
11921             mLayoutParams.resolveLayoutDirection(getLayoutDirection());
11922         }
11923     }
11924
11925     /**
11926      * Set the scrolled position of your view. This will cause a call to
11927      * {@link #onScrollChanged(int, int, int, int)} and the view will be
11928      * invalidated.
11929      * @param x the x position to scroll to
11930      * @param y the y position to scroll to
11931      */
11932     public void scrollTo(int x, int y) {
11933         if (mScrollX != x || mScrollY != y) {
11934             int oldX = mScrollX;
11935             int oldY = mScrollY;
11936             mScrollX = x;
11937             mScrollY = y;
11938             invalidateParentCaches();
11939             onScrollChanged(mScrollX, mScrollY, oldX, oldY);
11940             if (!awakenScrollBars()) {
11941                 postInvalidateOnAnimation();
11942             }
11943         }
11944     }
11945
11946     /**
11947      * Move the scrolled position of your view. This will cause a call to
11948      * {@link #onScrollChanged(int, int, int, int)} and the view will be
11949      * invalidated.
11950      * @param x the amount of pixels to scroll by horizontally
11951      * @param y the amount of pixels to scroll by vertically
11952      */
11953     public void scrollBy(int x, int y) {
11954         scrollTo(mScrollX + x, mScrollY + y);
11955     }
11956
11957     /**
11958      * <p>Trigger the scrollbars to draw. When invoked this method starts an
11959      * animation to fade the scrollbars out after a default delay. If a subclass
11960      * provides animated scrolling, the start delay should equal the duration
11961      * of the scrolling animation.</p>
11962      *
11963      * <p>The animation starts only if at least one of the scrollbars is
11964      * enabled, as specified by {@link #isHorizontalScrollBarEnabled()} and
11965      * {@link #isVerticalScrollBarEnabled()}. When the animation is started,
11966      * this method returns true, and false otherwise. If the animation is
11967      * started, this method calls {@link #invalidate()}; in that case the
11968      * caller should not call {@link #invalidate()}.</p>
11969      *
11970      * <p>This method should be invoked every time a subclass directly updates
11971      * the scroll parameters.</p>
11972      *
11973      * <p>This method is automatically invoked by {@link #scrollBy(int, int)}
11974      * and {@link #scrollTo(int, int)}.</p>
11975      *
11976      * @return true if the animation is played, false otherwise
11977      *
11978      * @see #awakenScrollBars(int)
11979      * @see #scrollBy(int, int)
11980      * @see #scrollTo(int, int)
11981      * @see #isHorizontalScrollBarEnabled()
11982      * @see #isVerticalScrollBarEnabled()
11983      * @see #setHorizontalScrollBarEnabled(boolean)
11984      * @see #setVerticalScrollBarEnabled(boolean)
11985      */
11986     protected boolean awakenScrollBars() {
11987         return mScrollCache != null &&
11988                 awakenScrollBars(mScrollCache.scrollBarDefaultDelayBeforeFade, true);
11989     }
11990
11991     /**
11992      * Trigger the scrollbars to draw.
11993      * This method differs from awakenScrollBars() only in its default duration.
11994      * initialAwakenScrollBars() will show the scroll bars for longer than
11995      * usual to give the user more of a chance to notice them.
11996      *
11997      * @return true if the animation is played, false otherwise.
11998      */
11999     private boolean initialAwakenScrollBars() {
12000         return mScrollCache != null &&
12001                 awakenScrollBars(mScrollCache.scrollBarDefaultDelayBeforeFade * 4, true);
12002     }
12003
12004     /**
12005      * <p>
12006      * Trigger the scrollbars to draw. When invoked this method starts an
12007      * animation to fade the scrollbars out after a fixed delay. If a subclass
12008      * provides animated scrolling, the start delay should equal the duration of
12009      * the scrolling animation.
12010      * </p>
12011      *
12012      * <p>
12013      * The animation starts only if at least one of the scrollbars is enabled,
12014      * as specified by {@link #isHorizontalScrollBarEnabled()} and
12015      * {@link #isVerticalScrollBarEnabled()}. When the animation is started,
12016      * this method returns true, and false otherwise. If the animation is
12017      * started, this method calls {@link #invalidate()}; in that case the caller
12018      * should not call {@link #invalidate()}.
12019      * </p>
12020      *
12021      * <p>
12022      * This method should be invoked every time a subclass directly updates the
12023      * scroll parameters.
12024      * </p>
12025      *
12026      * @param startDelay the delay, in milliseconds, after which the animation
12027      *        should start; when the delay is 0, the animation starts
12028      *        immediately
12029      * @return true if the animation is played, false otherwise
12030      *
12031      * @see #scrollBy(int, int)
12032      * @see #scrollTo(int, int)
12033      * @see #isHorizontalScrollBarEnabled()
12034      * @see #isVerticalScrollBarEnabled()
12035      * @see #setHorizontalScrollBarEnabled(boolean)
12036      * @see #setVerticalScrollBarEnabled(boolean)
12037      */
12038     protected boolean awakenScrollBars(int startDelay) {
12039         return awakenScrollBars(startDelay, true);
12040     }
12041
12042     /**
12043      * <p>
12044      * Trigger the scrollbars to draw. When invoked this method starts an
12045      * animation to fade the scrollbars out after a fixed delay. If a subclass
12046      * provides animated scrolling, the start delay should equal the duration of
12047      * the scrolling animation.
12048      * </p>
12049      *
12050      * <p>
12051      * The animation starts only if at least one of the scrollbars is enabled,
12052      * as specified by {@link #isHorizontalScrollBarEnabled()} and
12053      * {@link #isVerticalScrollBarEnabled()}. When the animation is started,
12054      * this method returns true, and false otherwise. If the animation is
12055      * started, this method calls {@link #invalidate()} if the invalidate parameter
12056      * is set to true; in that case the caller
12057      * should not call {@link #invalidate()}.
12058      * </p>
12059      *
12060      * <p>
12061      * This method should be invoked every time a subclass directly updates the
12062      * scroll parameters.
12063      * </p>
12064      *
12065      * @param startDelay the delay, in milliseconds, after which the animation
12066      *        should start; when the delay is 0, the animation starts
12067      *        immediately
12068      *
12069      * @param invalidate Whether this method should call invalidate
12070      *
12071      * @return true if the animation is played, false otherwise
12072      *
12073      * @see #scrollBy(int, int)
12074      * @see #scrollTo(int, int)
12075      * @see #isHorizontalScrollBarEnabled()
12076      * @see #isVerticalScrollBarEnabled()
12077      * @see #setHorizontalScrollBarEnabled(boolean)
12078      * @see #setVerticalScrollBarEnabled(boolean)
12079      */
12080     protected boolean awakenScrollBars(int startDelay, boolean invalidate) {
12081         final ScrollabilityCache scrollCache = mScrollCache;
12082
12083         if (scrollCache == null || !scrollCache.fadeScrollBars) {
12084             return false;
12085         }
12086
12087         if (scrollCache.scrollBar == null) {
12088             scrollCache.scrollBar = new ScrollBarDrawable();
12089             scrollCache.scrollBar.setCallback(this);
12090             scrollCache.scrollBar.setState(getDrawableState());
12091         }
12092
12093         if (isHorizontalScrollBarEnabled() || isVerticalScrollBarEnabled()) {
12094
12095             if (invalidate) {
12096                 // Invalidate to show the scrollbars
12097                 postInvalidateOnAnimation();
12098             }
12099
12100             if (scrollCache.state == ScrollabilityCache.OFF) {
12101                 // FIXME: this is copied from WindowManagerService.
12102                 // We should get this value from the system when it
12103                 // is possible to do so.
12104                 final int KEY_REPEAT_FIRST_DELAY = 750;
12105                 startDelay = Math.max(KEY_REPEAT_FIRST_DELAY, startDelay);
12106             }
12107
12108             // Tell mScrollCache when we should start fading. This may
12109             // extend the fade start time if one was already scheduled
12110             long fadeStartTime = AnimationUtils.currentAnimationTimeMillis() + startDelay;
12111             scrollCache.fadeStartTime = fadeStartTime;
12112             scrollCache.state = ScrollabilityCache.ON;
12113
12114             // Schedule our fader to run, unscheduling any old ones first
12115             if (mAttachInfo != null) {
12116                 mAttachInfo.mHandler.removeCallbacks(scrollCache);
12117                 mAttachInfo.mHandler.postAtTime(scrollCache, fadeStartTime);
12118             }
12119
12120             return true;
12121         }
12122
12123         return false;
12124     }
12125
12126     /**
12127      * Do not invalidate views which are not visible and which are not running an animation. They
12128      * will not get drawn and they should not set dirty flags as if they will be drawn
12129      */
12130     private boolean skipInvalidate() {
12131         return (mViewFlags & VISIBILITY_MASK) != VISIBLE && mCurrentAnimation == null &&
12132                 (!(mParent instanceof ViewGroup) ||
12133                         !((ViewGroup) mParent).isViewTransitioning(this));
12134     }
12135
12136     /**
12137      * Mark the area defined by dirty as needing to be drawn. If the view is
12138      * visible, {@link #onDraw(android.graphics.Canvas)} will be called at some
12139      * point in the future.
12140      * <p>
12141      * This must be called from a UI thread. To call from a non-UI thread, call
12142      * {@link #postInvalidate()}.
12143      * <p>
12144      * <b>WARNING:</b> In API 19 and below, this method may be destructive to
12145      * {@code dirty}.
12146      *
12147      * @param dirty the rectangle representing the bounds of the dirty region
12148      */
12149     public void invalidate(Rect dirty) {
12150         final int scrollX = mScrollX;
12151         final int scrollY = mScrollY;
12152         invalidateInternal(dirty.left - scrollX, dirty.top - scrollY,
12153                 dirty.right - scrollX, dirty.bottom - scrollY, true, false);
12154     }
12155
12156     /**
12157      * Mark the area defined by the rect (l,t,r,b) as needing to be drawn. The
12158      * coordinates of the dirty rect are relative to the view. If the view is
12159      * visible, {@link #onDraw(android.graphics.Canvas)} will be called at some
12160      * point in the future.
12161      * <p>
12162      * This must be called from a UI thread. To call from a non-UI thread, call
12163      * {@link #postInvalidate()}.
12164      *
12165      * @param l the left position of the dirty region
12166      * @param t the top position of the dirty region
12167      * @param r the right position of the dirty region
12168      * @param b the bottom position of the dirty region
12169      */
12170     public void invalidate(int l, int t, int r, int b) {
12171         final int scrollX = mScrollX;
12172         final int scrollY = mScrollY;
12173         invalidateInternal(l - scrollX, t - scrollY, r - scrollX, b - scrollY, true, false);
12174     }
12175
12176     /**
12177      * Invalidate the whole view. If the view is visible,
12178      * {@link #onDraw(android.graphics.Canvas)} will be called at some point in
12179      * the future.
12180      * <p>
12181      * This must be called from a UI thread. To call from a non-UI thread, call
12182      * {@link #postInvalidate()}.
12183      */
12184     public void invalidate() {
12185         invalidate(true);
12186     }
12187
12188     /**
12189      * This is where the invalidate() work actually happens. A full invalidate()
12190      * causes the drawing cache to be invalidated, but this function can be
12191      * called with invalidateCache set to false to skip that invalidation step
12192      * for cases that do not need it (for example, a component that remains at
12193      * the same dimensions with the same content).
12194      *
12195      * @param invalidateCache Whether the drawing cache for this view should be
12196      *            invalidated as well. This is usually true for a full
12197      *            invalidate, but may be set to false if the View's contents or
12198      *            dimensions have not changed.
12199      */
12200     void invalidate(boolean invalidateCache) {
12201         invalidateInternal(0, 0, mRight - mLeft, mBottom - mTop, invalidateCache, true);
12202     }
12203
12204     void invalidateInternal(int l, int t, int r, int b, boolean invalidateCache,
12205             boolean fullInvalidate) {
12206         if (mGhostView != null) {
12207             mGhostView.invalidate(true);
12208             return;
12209         }
12210
12211         if (skipInvalidate()) {
12212             return;
12213         }
12214
12215         if ((mPrivateFlags & (PFLAG_DRAWN | PFLAG_HAS_BOUNDS)) == (PFLAG_DRAWN | PFLAG_HAS_BOUNDS)
12216                 || (invalidateCache && (mPrivateFlags & PFLAG_DRAWING_CACHE_VALID) == PFLAG_DRAWING_CACHE_VALID)
12217                 || (mPrivateFlags & PFLAG_INVALIDATED) != PFLAG_INVALIDATED
12218                 || (fullInvalidate && isOpaque() != mLastIsOpaque)) {
12219             if (fullInvalidate) {
12220                 mLastIsOpaque = isOpaque();
12221                 mPrivateFlags &= ~PFLAG_DRAWN;
12222             }
12223
12224             mPrivateFlags |= PFLAG_DIRTY;
12225
12226             if (invalidateCache) {
12227                 mPrivateFlags |= PFLAG_INVALIDATED;
12228                 mPrivateFlags &= ~PFLAG_DRAWING_CACHE_VALID;
12229             }
12230
12231             // Propagate the damage rectangle to the parent view.
12232             final AttachInfo ai = mAttachInfo;
12233             final ViewParent p = mParent;
12234             if (p != null && ai != null && l < r && t < b) {
12235                 final Rect damage = ai.mTmpInvalRect;
12236                 damage.set(l, t, r, b);
12237                 p.invalidateChild(this, damage);
12238             }
12239
12240             // Damage the entire projection receiver, if necessary.
12241             if (mBackground != null && mBackground.isProjected()) {
12242                 final View receiver = getProjectionReceiver();
12243                 if (receiver != null) {
12244                     receiver.damageInParent();
12245                 }
12246             }
12247
12248             // Damage the entire IsolatedZVolume receiving this view's shadow.
12249             if (isHardwareAccelerated() && getZ() != 0) {
12250                 damageShadowReceiver();
12251             }
12252         }
12253     }
12254
12255     /**
12256      * @return this view's projection receiver, or {@code null} if none exists
12257      */
12258     private View getProjectionReceiver() {
12259         ViewParent p = getParent();
12260         while (p != null && p instanceof View) {
12261             final View v = (View) p;
12262             if (v.isProjectionReceiver()) {
12263                 return v;
12264             }
12265             p = p.getParent();
12266         }
12267
12268         return null;
12269     }
12270
12271     /**
12272      * @return whether the view is a projection receiver
12273      */
12274     private boolean isProjectionReceiver() {
12275         return mBackground != null;
12276     }
12277
12278     /**
12279      * Damage area of the screen that can be covered by this View's shadow.
12280      *
12281      * This method will guarantee that any changes to shadows cast by a View
12282      * are damaged on the screen for future redraw.
12283      */
12284     private void damageShadowReceiver() {
12285         final AttachInfo ai = mAttachInfo;
12286         if (ai != null) {
12287             ViewParent p = getParent();
12288             if (p != null && p instanceof ViewGroup) {
12289                 final ViewGroup vg = (ViewGroup) p;
12290                 vg.damageInParent();
12291             }
12292         }
12293     }
12294
12295     /**
12296      * Quick invalidation for View property changes (alpha, translationXY, etc.). We don't want to
12297      * set any flags or handle all of the cases handled by the default invalidation methods.
12298      * Instead, we just want to schedule a traversal in ViewRootImpl with the appropriate
12299      * dirty rect. This method calls into fast invalidation methods in ViewGroup that
12300      * walk up the hierarchy, transforming the dirty rect as necessary.
12301      *
12302      * The method also handles normal invalidation logic if display list properties are not
12303      * being used in this view. The invalidateParent and forceRedraw flags are used by that
12304      * backup approach, to handle these cases used in the various property-setting methods.
12305      *
12306      * @param invalidateParent Force a call to invalidateParentCaches() if display list properties
12307      * are not being used in this view
12308      * @param forceRedraw Mark the view as DRAWN to force the invalidation to propagate, if display
12309      * list properties are not being used in this view
12310      */
12311     void invalidateViewProperty(boolean invalidateParent, boolean forceRedraw) {
12312         if (!isHardwareAccelerated()
12313                 || !mRenderNode.isValid()
12314                 || (mPrivateFlags & PFLAG_DRAW_ANIMATION) != 0) {
12315             if (invalidateParent) {
12316                 invalidateParentCaches();
12317             }
12318             if (forceRedraw) {
12319                 mPrivateFlags |= PFLAG_DRAWN; // force another invalidation with the new orientation
12320             }
12321             invalidate(false);
12322         } else {
12323             damageInParent();
12324         }
12325         if (isHardwareAccelerated() && invalidateParent && getZ() != 0) {
12326             damageShadowReceiver();
12327         }
12328     }
12329
12330     /**
12331      * Tells the parent view to damage this view's bounds.
12332      *
12333      * @hide
12334      */
12335     protected void damageInParent() {
12336         final AttachInfo ai = mAttachInfo;
12337         final ViewParent p = mParent;
12338         if (p != null && ai != null) {
12339             final Rect r = ai.mTmpInvalRect;
12340             r.set(0, 0, mRight - mLeft, mBottom - mTop);
12341             if (mParent instanceof ViewGroup) {
12342                 ((ViewGroup) mParent).damageChild(this, r);
12343             } else {
12344                 mParent.invalidateChild(this, r);
12345             }
12346         }
12347     }
12348
12349     /**
12350      * Utility method to transform a given Rect by the current matrix of this view.
12351      */
12352     void transformRect(final Rect rect) {
12353         if (!getMatrix().isIdentity()) {
12354             RectF boundingRect = mAttachInfo.mTmpTransformRect;
12355             boundingRect.set(rect);
12356             getMatrix().mapRect(boundingRect);
12357             rect.set((int) Math.floor(boundingRect.left),
12358                     (int) Math.floor(boundingRect.top),
12359                     (int) Math.ceil(boundingRect.right),
12360                     (int) Math.ceil(boundingRect.bottom));
12361         }
12362     }
12363
12364     /**
12365      * Used to indicate that the parent of this view should clear its caches. This functionality
12366      * is used to force the parent to rebuild its display list (when hardware-accelerated),
12367      * which is necessary when various parent-managed properties of the view change, such as
12368      * alpha, translationX/Y, scrollX/Y, scaleX/Y, and rotation/X/Y. This method only
12369      * clears the parent caches and does not causes an invalidate event.
12370      *
12371      * @hide
12372      */
12373     protected void invalidateParentCaches() {
12374         if (mParent instanceof View) {
12375             ((View) mParent).mPrivateFlags |= PFLAG_INVALIDATED;
12376         }
12377     }
12378
12379     /**
12380      * Used to indicate that the parent of this view should be invalidated. This functionality
12381      * is used to force the parent to rebuild its display list (when hardware-accelerated),
12382      * which is necessary when various parent-managed properties of the view change, such as
12383      * alpha, translationX/Y, scrollX/Y, scaleX/Y, and rotation/X/Y. This method will propagate
12384      * an invalidation event to the parent.
12385      *
12386      * @hide
12387      */
12388     protected void invalidateParentIfNeeded() {
12389         if (isHardwareAccelerated() && mParent instanceof View) {
12390             ((View) mParent).invalidate(true);
12391         }
12392     }
12393
12394     /**
12395      * @hide
12396      */
12397     protected void invalidateParentIfNeededAndWasQuickRejected() {
12398         if ((mPrivateFlags2 & PFLAG2_VIEW_QUICK_REJECTED) != 0) {
12399             // View was rejected last time it was drawn by its parent; this may have changed
12400             invalidateParentIfNeeded();
12401         }
12402     }
12403
12404     /**
12405      * Indicates whether this View is opaque. An opaque View guarantees that it will
12406      * draw all the pixels overlapping its bounds using a fully opaque color.
12407      *
12408      * Subclasses of View should override this method whenever possible to indicate
12409      * whether an instance is opaque. Opaque Views are treated in a special way by
12410      * the View hierarchy, possibly allowing it to perform optimizations during
12411      * invalidate/draw passes.
12412      *
12413      * @return True if this View is guaranteed to be fully opaque, false otherwise.
12414      */
12415     @ViewDebug.ExportedProperty(category = "drawing")
12416     public boolean isOpaque() {
12417         return (mPrivateFlags & PFLAG_OPAQUE_MASK) == PFLAG_OPAQUE_MASK &&
12418                 getFinalAlpha() >= 1.0f;
12419     }
12420
12421     /**
12422      * @hide
12423      */
12424     protected void computeOpaqueFlags() {
12425         // Opaque if:
12426         //   - Has a background
12427         //   - Background is opaque
12428         //   - Doesn't have scrollbars or scrollbars overlay
12429
12430         if (mBackground != null && mBackground.getOpacity() == PixelFormat.OPAQUE) {
12431             mPrivateFlags |= PFLAG_OPAQUE_BACKGROUND;
12432         } else {
12433             mPrivateFlags &= ~PFLAG_OPAQUE_BACKGROUND;
12434         }
12435
12436         final int flags = mViewFlags;
12437         if (((flags & SCROLLBARS_VERTICAL) == 0 && (flags & SCROLLBARS_HORIZONTAL) == 0) ||
12438                 (flags & SCROLLBARS_STYLE_MASK) == SCROLLBARS_INSIDE_OVERLAY ||
12439                 (flags & SCROLLBARS_STYLE_MASK) == SCROLLBARS_OUTSIDE_OVERLAY) {
12440             mPrivateFlags |= PFLAG_OPAQUE_SCROLLBARS;
12441         } else {
12442             mPrivateFlags &= ~PFLAG_OPAQUE_SCROLLBARS;
12443         }
12444     }
12445
12446     /**
12447      * @hide
12448      */
12449     protected boolean hasOpaqueScrollbars() {
12450         return (mPrivateFlags & PFLAG_OPAQUE_SCROLLBARS) == PFLAG_OPAQUE_SCROLLBARS;
12451     }
12452
12453     /**
12454      * @return A handler associated with the thread running the View. This
12455      * handler can be used to pump events in the UI events queue.
12456      */
12457     public Handler getHandler() {
12458         final AttachInfo attachInfo = mAttachInfo;
12459         if (attachInfo != null) {
12460             return attachInfo.mHandler;
12461         }
12462         return null;
12463     }
12464
12465     /**
12466      * Gets the view root associated with the View.
12467      * @return The view root, or null if none.
12468      * @hide
12469      */
12470     public ViewRootImpl getViewRootImpl() {
12471         if (mAttachInfo != null) {
12472             return mAttachInfo.mViewRootImpl;
12473         }
12474         return null;
12475     }
12476
12477     /**
12478      * @hide
12479      */
12480     public HardwareRenderer getHardwareRenderer() {
12481         return mAttachInfo != null ? mAttachInfo.mHardwareRenderer : null;
12482     }
12483
12484     /**
12485      * <p>Causes the Runnable to be added to the message queue.
12486      * The runnable will be run on the user interface thread.</p>
12487      *
12488      * @param action The Runnable that will be executed.
12489      *
12490      * @return Returns true if the Runnable was successfully placed in to the
12491      *         message queue.  Returns false on failure, usually because the
12492      *         looper processing the message queue is exiting.
12493      *
12494      * @see #postDelayed
12495      * @see #removeCallbacks
12496      */
12497     public boolean post(Runnable action) {
12498         final AttachInfo attachInfo = mAttachInfo;
12499         if (attachInfo != null) {
12500             return attachInfo.mHandler.post(action);
12501         }
12502         // Assume that post will succeed later
12503         ViewRootImpl.getRunQueue().post(action);
12504         return true;
12505     }
12506
12507     /**
12508      * <p>Causes the Runnable to be added to the message queue, to be run
12509      * after the specified amount of time elapses.
12510      * The runnable will be run on the user interface thread.</p>
12511      *
12512      * @param action The Runnable that will be executed.
12513      * @param delayMillis The delay (in milliseconds) until the Runnable
12514      *        will be executed.
12515      *
12516      * @return true if the Runnable was successfully placed in to the
12517      *         message queue.  Returns false on failure, usually because the
12518      *         looper processing the message queue is exiting.  Note that a
12519      *         result of true does not mean the Runnable will be processed --
12520      *         if the looper is quit before the delivery time of the message
12521      *         occurs then the message will be dropped.
12522      *
12523      * @see #post
12524      * @see #removeCallbacks
12525      */
12526     public boolean postDelayed(Runnable action, long delayMillis) {
12527         final AttachInfo attachInfo = mAttachInfo;
12528         if (attachInfo != null) {
12529             return attachInfo.mHandler.postDelayed(action, delayMillis);
12530         }
12531         // Assume that post will succeed later
12532         ViewRootImpl.getRunQueue().postDelayed(action, delayMillis);
12533         return true;
12534     }
12535
12536     /**
12537      * <p>Causes the Runnable to execute on the next animation time step.
12538      * The runnable will be run on the user interface thread.</p>
12539      *
12540      * @param action The Runnable that will be executed.
12541      *
12542      * @see #postOnAnimationDelayed
12543      * @see #removeCallbacks
12544      */
12545     public void postOnAnimation(Runnable action) {
12546         final AttachInfo attachInfo = mAttachInfo;
12547         if (attachInfo != null) {
12548             attachInfo.mViewRootImpl.mChoreographer.postCallback(
12549                     Choreographer.CALLBACK_ANIMATION, action, null);
12550         } else {
12551             // Assume that post will succeed later
12552             ViewRootImpl.getRunQueue().post(action);
12553         }
12554     }
12555
12556     /**
12557      * <p>Causes the Runnable to execute on the next animation time step,
12558      * after the specified amount of time elapses.
12559      * The runnable will be run on the user interface thread.</p>
12560      *
12561      * @param action The Runnable that will be executed.
12562      * @param delayMillis The delay (in milliseconds) until the Runnable
12563      *        will be executed.
12564      *
12565      * @see #postOnAnimation
12566      * @see #removeCallbacks
12567      */
12568     public void postOnAnimationDelayed(Runnable action, long delayMillis) {
12569         final AttachInfo attachInfo = mAttachInfo;
12570         if (attachInfo != null) {
12571             attachInfo.mViewRootImpl.mChoreographer.postCallbackDelayed(
12572                     Choreographer.CALLBACK_ANIMATION, action, null, delayMillis);
12573         } else {
12574             // Assume that post will succeed later
12575             ViewRootImpl.getRunQueue().postDelayed(action, delayMillis);
12576         }
12577     }
12578
12579     /**
12580      * <p>Removes the specified Runnable from the message queue.</p>
12581      *
12582      * @param action The Runnable to remove from the message handling queue
12583      *
12584      * @return true if this view could ask the Handler to remove the Runnable,
12585      *         false otherwise. When the returned value is true, the Runnable
12586      *         may or may not have been actually removed from the message queue
12587      *         (for instance, if the Runnable was not in the queue already.)
12588      *
12589      * @see #post
12590      * @see #postDelayed
12591      * @see #postOnAnimation
12592      * @see #postOnAnimationDelayed
12593      */
12594     public boolean removeCallbacks(Runnable action) {
12595         if (action != null) {
12596             final AttachInfo attachInfo = mAttachInfo;
12597             if (attachInfo != null) {
12598                 attachInfo.mHandler.removeCallbacks(action);
12599                 attachInfo.mViewRootImpl.mChoreographer.removeCallbacks(
12600                         Choreographer.CALLBACK_ANIMATION, action, null);
12601             }
12602             // Assume that post will succeed later
12603             ViewRootImpl.getRunQueue().removeCallbacks(action);
12604         }
12605         return true;
12606     }
12607
12608     /**
12609      * <p>Cause an invalidate to happen on a subsequent cycle through the event loop.
12610      * Use this to invalidate the View from a non-UI thread.</p>
12611      *
12612      * <p>This method can be invoked from outside of the UI thread
12613      * only when this View is attached to a window.</p>
12614      *
12615      * @see #invalidate()
12616      * @see #postInvalidateDelayed(long)
12617      */
12618     public void postInvalidate() {
12619         postInvalidateDelayed(0);
12620     }
12621
12622     /**
12623      * <p>Cause an invalidate of the specified area to happen on a subsequent cycle
12624      * through the event loop. Use this to invalidate the View from a non-UI thread.</p>
12625      *
12626      * <p>This method can be invoked from outside of the UI thread
12627      * only when this View is attached to a window.</p>
12628      *
12629      * @param left The left coordinate of the rectangle to invalidate.
12630      * @param top The top coordinate of the rectangle to invalidate.
12631      * @param right The right coordinate of the rectangle to invalidate.
12632      * @param bottom The bottom coordinate of the rectangle to invalidate.
12633      *
12634      * @see #invalidate(int, int, int, int)
12635      * @see #invalidate(Rect)
12636      * @see #postInvalidateDelayed(long, int, int, int, int)
12637      */
12638     public void postInvalidate(int left, int top, int right, int bottom) {
12639         postInvalidateDelayed(0, left, top, right, bottom);
12640     }
12641
12642     /**
12643      * <p>Cause an invalidate to happen on a subsequent cycle through the event
12644      * loop. Waits for the specified amount of time.</p>
12645      *
12646      * <p>This method can be invoked from outside of the UI thread
12647      * only when this View is attached to a window.</p>
12648      *
12649      * @param delayMilliseconds the duration in milliseconds to delay the
12650      *         invalidation by
12651      *
12652      * @see #invalidate()
12653      * @see #postInvalidate()
12654      */
12655     public void postInvalidateDelayed(long delayMilliseconds) {
12656         // We try only with the AttachInfo because there's no point in invalidating
12657         // if we are not attached to our window
12658         final AttachInfo attachInfo = mAttachInfo;
12659         if (attachInfo != null) {
12660             attachInfo.mViewRootImpl.dispatchInvalidateDelayed(this, delayMilliseconds);
12661         }
12662     }
12663
12664     /**
12665      * <p>Cause an invalidate of the specified area to happen on a subsequent cycle
12666      * through the event loop. Waits for the specified amount of time.</p>
12667      *
12668      * <p>This method can be invoked from outside of the UI thread
12669      * only when this View is attached to a window.</p>
12670      *
12671      * @param delayMilliseconds the duration in milliseconds to delay the
12672      *         invalidation by
12673      * @param left The left coordinate of the rectangle to invalidate.
12674      * @param top The top coordinate of the rectangle to invalidate.
12675      * @param right The right coordinate of the rectangle to invalidate.
12676      * @param bottom The bottom coordinate of the rectangle to invalidate.
12677      *
12678      * @see #invalidate(int, int, int, int)
12679      * @see #invalidate(Rect)
12680      * @see #postInvalidate(int, int, int, int)
12681      */
12682     public void postInvalidateDelayed(long delayMilliseconds, int left, int top,
12683             int right, int bottom) {
12684
12685         // We try only with the AttachInfo because there's no point in invalidating
12686         // if we are not attached to our window
12687         final AttachInfo attachInfo = mAttachInfo;
12688         if (attachInfo != null) {
12689             final AttachInfo.InvalidateInfo info = AttachInfo.InvalidateInfo.obtain();
12690             info.target = this;
12691             info.left = left;
12692             info.top = top;
12693             info.right = right;
12694             info.bottom = bottom;
12695
12696             attachInfo.mViewRootImpl.dispatchInvalidateRectDelayed(info, delayMilliseconds);
12697         }
12698     }
12699
12700     /**
12701      * <p>Cause an invalidate to happen on the next animation time step, typically the
12702      * next display frame.</p>
12703      *
12704      * <p>This method can be invoked from outside of the UI thread
12705      * only when this View is attached to a window.</p>
12706      *
12707      * @see #invalidate()
12708      */
12709     public void postInvalidateOnAnimation() {
12710         // We try only with the AttachInfo because there's no point in invalidating
12711         // if we are not attached to our window
12712         final AttachInfo attachInfo = mAttachInfo;
12713         if (attachInfo != null) {
12714             attachInfo.mViewRootImpl.dispatchInvalidateOnAnimation(this);
12715         }
12716     }
12717
12718     /**
12719      * <p>Cause an invalidate of the specified area to happen on the next animation
12720      * time step, typically the next display frame.</p>
12721      *
12722      * <p>This method can be invoked from outside of the UI thread
12723      * only when this View is attached to a window.</p>
12724      *
12725      * @param left The left coordinate of the rectangle to invalidate.
12726      * @param top The top coordinate of the rectangle to invalidate.
12727      * @param right The right coordinate of the rectangle to invalidate.
12728      * @param bottom The bottom coordinate of the rectangle to invalidate.
12729      *
12730      * @see #invalidate(int, int, int, int)
12731      * @see #invalidate(Rect)
12732      */
12733     public void postInvalidateOnAnimation(int left, int top, int right, int bottom) {
12734         // We try only with the AttachInfo because there's no point in invalidating
12735         // if we are not attached to our window
12736         final AttachInfo attachInfo = mAttachInfo;
12737         if (attachInfo != null) {
12738             final AttachInfo.InvalidateInfo info = AttachInfo.InvalidateInfo.obtain();
12739             info.target = this;
12740             info.left = left;
12741             info.top = top;
12742             info.right = right;
12743             info.bottom = bottom;
12744
12745             attachInfo.mViewRootImpl.dispatchInvalidateRectOnAnimation(info);
12746         }
12747     }
12748
12749     /**
12750      * Post a callback to send a {@link AccessibilityEvent#TYPE_VIEW_SCROLLED} event.
12751      * This event is sent at most once every
12752      * {@link ViewConfiguration#getSendRecurringAccessibilityEventsInterval()}.
12753      */
12754     private void postSendViewScrolledAccessibilityEventCallback() {
12755         if (mSendViewScrolledAccessibilityEvent == null) {
12756             mSendViewScrolledAccessibilityEvent = new SendViewScrolledAccessibilityEvent();
12757         }
12758         if (!mSendViewScrolledAccessibilityEvent.mIsPending) {
12759             mSendViewScrolledAccessibilityEvent.mIsPending = true;
12760             postDelayed(mSendViewScrolledAccessibilityEvent,
12761                     ViewConfiguration.getSendRecurringAccessibilityEventsInterval());
12762         }
12763     }
12764
12765     /**
12766      * Called by a parent to request that a child update its values for mScrollX
12767      * and mScrollY if necessary. This will typically be done if the child is
12768      * animating a scroll using a {@link android.widget.Scroller Scroller}
12769      * object.
12770      */
12771     public void computeScroll() {
12772     }
12773
12774     /**
12775      * <p>Indicate whether the horizontal edges are faded when the view is
12776      * scrolled horizontally.</p>
12777      *
12778      * @return true if the horizontal edges should are faded on scroll, false
12779      *         otherwise
12780      *
12781      * @see #setHorizontalFadingEdgeEnabled(boolean)
12782      *
12783      * @attr ref android.R.styleable#View_requiresFadingEdge
12784      */
12785     public boolean isHorizontalFadingEdgeEnabled() {
12786         return (mViewFlags & FADING_EDGE_HORIZONTAL) == FADING_EDGE_HORIZONTAL;
12787     }
12788
12789     /**
12790      * <p>Define whether the horizontal edges should be faded when this view
12791      * is scrolled horizontally.</p>
12792      *
12793      * @param horizontalFadingEdgeEnabled true if the horizontal edges should
12794      *                                    be faded when the view is scrolled
12795      *                                    horizontally
12796      *
12797      * @see #isHorizontalFadingEdgeEnabled()
12798      *
12799      * @attr ref android.R.styleable#View_requiresFadingEdge
12800      */
12801     public void setHorizontalFadingEdgeEnabled(boolean horizontalFadingEdgeEnabled) {
12802         if (isHorizontalFadingEdgeEnabled() != horizontalFadingEdgeEnabled) {
12803             if (horizontalFadingEdgeEnabled) {
12804                 initScrollCache();
12805             }
12806
12807             mViewFlags ^= FADING_EDGE_HORIZONTAL;
12808         }
12809     }
12810
12811     /**
12812      * <p>Indicate whether the vertical edges are faded when the view is
12813      * scrolled horizontally.</p>
12814      *
12815      * @return true if the vertical edges should are faded on scroll, false
12816      *         otherwise
12817      *
12818      * @see #setVerticalFadingEdgeEnabled(boolean)
12819      *
12820      * @attr ref android.R.styleable#View_requiresFadingEdge
12821      */
12822     public boolean isVerticalFadingEdgeEnabled() {
12823         return (mViewFlags & FADING_EDGE_VERTICAL) == FADING_EDGE_VERTICAL;
12824     }
12825
12826     /**
12827      * <p>Define whether the vertical edges should be faded when this view
12828      * is scrolled vertically.</p>
12829      *
12830      * @param verticalFadingEdgeEnabled true if the vertical edges should
12831      *                                  be faded when the view is scrolled
12832      *                                  vertically
12833      *
12834      * @see #isVerticalFadingEdgeEnabled()
12835      *
12836      * @attr ref android.R.styleable#View_requiresFadingEdge
12837      */
12838     public void setVerticalFadingEdgeEnabled(boolean verticalFadingEdgeEnabled) {
12839         if (isVerticalFadingEdgeEnabled() != verticalFadingEdgeEnabled) {
12840             if (verticalFadingEdgeEnabled) {
12841                 initScrollCache();
12842             }
12843
12844             mViewFlags ^= FADING_EDGE_VERTICAL;
12845         }
12846     }
12847
12848     /**
12849      * Returns the strength, or intensity, of the top faded edge. The strength is
12850      * a value between 0.0 (no fade) and 1.0 (full fade). The default implementation
12851      * returns 0.0 or 1.0 but no value in between.
12852      *
12853      * Subclasses should override this method to provide a smoother fade transition
12854      * when scrolling occurs.
12855      *
12856      * @return the intensity of the top fade as a float between 0.0f and 1.0f
12857      */
12858     protected float getTopFadingEdgeStrength() {
12859         return computeVerticalScrollOffset() > 0 ? 1.0f : 0.0f;
12860     }
12861
12862     /**
12863      * Returns the strength, or intensity, of the bottom faded edge. The strength is
12864      * a value between 0.0 (no fade) and 1.0 (full fade). The default implementation
12865      * returns 0.0 or 1.0 but no value in between.
12866      *
12867      * Subclasses should override this method to provide a smoother fade transition
12868      * when scrolling occurs.
12869      *
12870      * @return the intensity of the bottom fade as a float between 0.0f and 1.0f
12871      */
12872     protected float getBottomFadingEdgeStrength() {
12873         return computeVerticalScrollOffset() + computeVerticalScrollExtent() <
12874                 computeVerticalScrollRange() ? 1.0f : 0.0f;
12875     }
12876
12877     /**
12878      * Returns the strength, or intensity, of the left faded edge. The strength is
12879      * a value between 0.0 (no fade) and 1.0 (full fade). The default implementation
12880      * returns 0.0 or 1.0 but no value in between.
12881      *
12882      * Subclasses should override this method to provide a smoother fade transition
12883      * when scrolling occurs.
12884      *
12885      * @return the intensity of the left fade as a float between 0.0f and 1.0f
12886      */
12887     protected float getLeftFadingEdgeStrength() {
12888         return computeHorizontalScrollOffset() > 0 ? 1.0f : 0.0f;
12889     }
12890
12891     /**
12892      * Returns the strength, or intensity, of the right faded edge. The strength is
12893      * a value between 0.0 (no fade) and 1.0 (full fade). The default implementation
12894      * returns 0.0 or 1.0 but no value in between.
12895      *
12896      * Subclasses should override this method to provide a smoother fade transition
12897      * when scrolling occurs.
12898      *
12899      * @return the intensity of the right fade as a float between 0.0f and 1.0f
12900      */
12901     protected float getRightFadingEdgeStrength() {
12902         return computeHorizontalScrollOffset() + computeHorizontalScrollExtent() <
12903                 computeHorizontalScrollRange() ? 1.0f : 0.0f;
12904     }
12905
12906     /**
12907      * <p>Indicate whether the horizontal scrollbar should be drawn or not. The
12908      * scrollbar is not drawn by default.</p>
12909      *
12910      * @return true if the horizontal scrollbar should be painted, false
12911      *         otherwise
12912      *
12913      * @see #setHorizontalScrollBarEnabled(boolean)
12914      */
12915     public boolean isHorizontalScrollBarEnabled() {
12916         return (mViewFlags & SCROLLBARS_HORIZONTAL) == SCROLLBARS_HORIZONTAL;
12917     }
12918
12919     /**
12920      * <p>Define whether the horizontal scrollbar should be drawn or not. The
12921      * scrollbar is not drawn by default.</p>
12922      *
12923      * @param horizontalScrollBarEnabled true if the horizontal scrollbar should
12924      *                                   be painted
12925      *
12926      * @see #isHorizontalScrollBarEnabled()
12927      */
12928     public void setHorizontalScrollBarEnabled(boolean horizontalScrollBarEnabled) {
12929         if (isHorizontalScrollBarEnabled() != horizontalScrollBarEnabled) {
12930             mViewFlags ^= SCROLLBARS_HORIZONTAL;
12931             computeOpaqueFlags();
12932             resolvePadding();
12933         }
12934     }
12935
12936     /**
12937      * <p>Indicate whether the vertical scrollbar should be drawn or not. The
12938      * scrollbar is not drawn by default.</p>
12939      *
12940      * @return true if the vertical scrollbar should be painted, false
12941      *         otherwise
12942      *
12943      * @see #setVerticalScrollBarEnabled(boolean)
12944      */
12945     public boolean isVerticalScrollBarEnabled() {
12946         return (mViewFlags & SCROLLBARS_VERTICAL) == SCROLLBARS_VERTICAL;
12947     }
12948
12949     /**
12950      * <p>Define whether the vertical scrollbar should be drawn or not. The
12951      * scrollbar is not drawn by default.</p>
12952      *
12953      * @param verticalScrollBarEnabled true if the vertical scrollbar should
12954      *                                 be painted
12955      *
12956      * @see #isVerticalScrollBarEnabled()
12957      */
12958     public void setVerticalScrollBarEnabled(boolean verticalScrollBarEnabled) {
12959         if (isVerticalScrollBarEnabled() != verticalScrollBarEnabled) {
12960             mViewFlags ^= SCROLLBARS_VERTICAL;
12961             computeOpaqueFlags();
12962             resolvePadding();
12963         }
12964     }
12965
12966     /**
12967      * @hide
12968      */
12969     protected void recomputePadding() {
12970         internalSetPadding(mUserPaddingLeft, mPaddingTop, mUserPaddingRight, mUserPaddingBottom);
12971     }
12972
12973     /**
12974      * Define whether scrollbars will fade when the view is not scrolling.
12975      *
12976      * @param fadeScrollbars whether to enable fading
12977      *
12978      * @attr ref android.R.styleable#View_fadeScrollbars
12979      */
12980     public void setScrollbarFadingEnabled(boolean fadeScrollbars) {
12981         initScrollCache();
12982         final ScrollabilityCache scrollabilityCache = mScrollCache;
12983         scrollabilityCache.fadeScrollBars = fadeScrollbars;
12984         if (fadeScrollbars) {
12985             scrollabilityCache.state = ScrollabilityCache.OFF;
12986         } else {
12987             scrollabilityCache.state = ScrollabilityCache.ON;
12988         }
12989     }
12990
12991     /**
12992      *
12993      * Returns true if scrollbars will fade when this view is not scrolling
12994      *
12995      * @return true if scrollbar fading is enabled
12996      *
12997      * @attr ref android.R.styleable#View_fadeScrollbars
12998      */
12999     public boolean isScrollbarFadingEnabled() {
13000         return mScrollCache != null && mScrollCache.fadeScrollBars;
13001     }
13002
13003     /**
13004      *
13005      * Returns the delay before scrollbars fade.
13006      *
13007      * @return the delay before scrollbars fade
13008      *
13009      * @attr ref android.R.styleable#View_scrollbarDefaultDelayBeforeFade
13010      */
13011     public int getScrollBarDefaultDelayBeforeFade() {
13012         return mScrollCache == null ? ViewConfiguration.getScrollDefaultDelay() :
13013                 mScrollCache.scrollBarDefaultDelayBeforeFade;
13014     }
13015
13016     /**
13017      * Define the delay before scrollbars fade.
13018      *
13019      * @param scrollBarDefaultDelayBeforeFade - the delay before scrollbars fade
13020      *
13021      * @attr ref android.R.styleable#View_scrollbarDefaultDelayBeforeFade
13022      */
13023     public void setScrollBarDefaultDelayBeforeFade(int scrollBarDefaultDelayBeforeFade) {
13024         getScrollCache().scrollBarDefaultDelayBeforeFade = scrollBarDefaultDelayBeforeFade;
13025     }
13026
13027     /**
13028      *
13029      * Returns the scrollbar fade duration.
13030      *
13031      * @return the scrollbar fade duration
13032      *
13033      * @attr ref android.R.styleable#View_scrollbarFadeDuration
13034      */
13035     public int getScrollBarFadeDuration() {
13036         return mScrollCache == null ? ViewConfiguration.getScrollBarFadeDuration() :
13037                 mScrollCache.scrollBarFadeDuration;
13038     }
13039
13040     /**
13041      * Define the scrollbar fade duration.
13042      *
13043      * @param scrollBarFadeDuration - the scrollbar fade duration
13044      *
13045      * @attr ref android.R.styleable#View_scrollbarFadeDuration
13046      */
13047     public void setScrollBarFadeDuration(int scrollBarFadeDuration) {
13048         getScrollCache().scrollBarFadeDuration = scrollBarFadeDuration;
13049     }
13050
13051     /**
13052      *
13053      * Returns the scrollbar size.
13054      *
13055      * @return the scrollbar size
13056      *
13057      * @attr ref android.R.styleable#View_scrollbarSize
13058      */
13059     public int getScrollBarSize() {
13060         return mScrollCache == null ? ViewConfiguration.get(mContext).getScaledScrollBarSize() :
13061                 mScrollCache.scrollBarSize;
13062     }
13063
13064     /**
13065      * Define the scrollbar size.
13066      *
13067      * @param scrollBarSize - the scrollbar size
13068      *
13069      * @attr ref android.R.styleable#View_scrollbarSize
13070      */
13071     public void setScrollBarSize(int scrollBarSize) {
13072         getScrollCache().scrollBarSize = scrollBarSize;
13073     }
13074
13075     /**
13076      * <p>Specify the style of the scrollbars. The scrollbars can be overlaid or
13077      * inset. When inset, they add to the padding of the view. And the scrollbars
13078      * can be drawn inside the padding area or on the edge of the view. For example,
13079      * if a view has a background drawable and you want to draw the scrollbars
13080      * inside the padding specified by the drawable, you can use
13081      * SCROLLBARS_INSIDE_OVERLAY or SCROLLBARS_INSIDE_INSET. If you want them to
13082      * appear at the edge of the view, ignoring the padding, then you can use
13083      * SCROLLBARS_OUTSIDE_OVERLAY or SCROLLBARS_OUTSIDE_INSET.</p>
13084      * @param style the style of the scrollbars. Should be one of
13085      * SCROLLBARS_INSIDE_OVERLAY, SCROLLBARS_INSIDE_INSET,
13086      * SCROLLBARS_OUTSIDE_OVERLAY or SCROLLBARS_OUTSIDE_INSET.
13087      * @see #SCROLLBARS_INSIDE_OVERLAY
13088      * @see #SCROLLBARS_INSIDE_INSET
13089      * @see #SCROLLBARS_OUTSIDE_OVERLAY
13090      * @see #SCROLLBARS_OUTSIDE_INSET
13091      *
13092      * @attr ref android.R.styleable#View_scrollbarStyle
13093      */
13094     public void setScrollBarStyle(@ScrollBarStyle int style) {
13095         if (style != (mViewFlags & SCROLLBARS_STYLE_MASK)) {
13096             mViewFlags = (mViewFlags & ~SCROLLBARS_STYLE_MASK) | (style & SCROLLBARS_STYLE_MASK);
13097             computeOpaqueFlags();
13098             resolvePadding();
13099         }
13100     }
13101
13102     /**
13103      * <p>Returns the current scrollbar style.</p>
13104      * @return the current scrollbar style
13105      * @see #SCROLLBARS_INSIDE_OVERLAY
13106      * @see #SCROLLBARS_INSIDE_INSET
13107      * @see #SCROLLBARS_OUTSIDE_OVERLAY
13108      * @see #SCROLLBARS_OUTSIDE_INSET
13109      *
13110      * @attr ref android.R.styleable#View_scrollbarStyle
13111      */
13112     @ViewDebug.ExportedProperty(mapping = {
13113             @ViewDebug.IntToString(from = SCROLLBARS_INSIDE_OVERLAY, to = "INSIDE_OVERLAY"),
13114             @ViewDebug.IntToString(from = SCROLLBARS_INSIDE_INSET, to = "INSIDE_INSET"),
13115             @ViewDebug.IntToString(from = SCROLLBARS_OUTSIDE_OVERLAY, to = "OUTSIDE_OVERLAY"),
13116             @ViewDebug.IntToString(from = SCROLLBARS_OUTSIDE_INSET, to = "OUTSIDE_INSET")
13117     })
13118     @ScrollBarStyle
13119     public int getScrollBarStyle() {
13120         return mViewFlags & SCROLLBARS_STYLE_MASK;
13121     }
13122
13123     /**
13124      * <p>Compute the horizontal range that the horizontal scrollbar
13125      * represents.</p>
13126      *
13127      * <p>The range is expressed in arbitrary units that must be the same as the
13128      * units used by {@link #computeHorizontalScrollExtent()} and
13129      * {@link #computeHorizontalScrollOffset()}.</p>
13130      *
13131      * <p>The default range is the drawing width of this view.</p>
13132      *
13133      * @return the total horizontal range represented by the horizontal
13134      *         scrollbar
13135      *
13136      * @see #computeHorizontalScrollExtent()
13137      * @see #computeHorizontalScrollOffset()
13138      * @see android.widget.ScrollBarDrawable
13139      */
13140     protected int computeHorizontalScrollRange() {
13141         return getWidth();
13142     }
13143
13144     /**
13145      * <p>Compute the horizontal offset of the horizontal scrollbar's thumb
13146      * within the horizontal range. This value is used to compute the position
13147      * of the thumb within the scrollbar's track.</p>
13148      *
13149      * <p>The range is expressed in arbitrary units that must be the same as the
13150      * units used by {@link #computeHorizontalScrollRange()} and
13151      * {@link #computeHorizontalScrollExtent()}.</p>
13152      *
13153      * <p>The default offset is the scroll offset of this view.</p>
13154      *
13155      * @return the horizontal offset of the scrollbar's thumb
13156      *
13157      * @see #computeHorizontalScrollRange()
13158      * @see #computeHorizontalScrollExtent()
13159      * @see android.widget.ScrollBarDrawable
13160      */
13161     protected int computeHorizontalScrollOffset() {
13162         return mScrollX;
13163     }
13164
13165     /**
13166      * <p>Compute the horizontal extent of the horizontal scrollbar's thumb
13167      * within the horizontal range. This value is used to compute the length
13168      * of the thumb within the scrollbar's track.</p>
13169      *
13170      * <p>The range is expressed in arbitrary units that must be the same as the
13171      * units used by {@link #computeHorizontalScrollRange()} and
13172      * {@link #computeHorizontalScrollOffset()}.</p>
13173      *
13174      * <p>The default extent is the drawing width of this view.</p>
13175      *
13176      * @return the horizontal extent of the scrollbar's thumb
13177      *
13178      * @see #computeHorizontalScrollRange()
13179      * @see #computeHorizontalScrollOffset()
13180      * @see android.widget.ScrollBarDrawable
13181      */
13182     protected int computeHorizontalScrollExtent() {
13183         return getWidth();
13184     }
13185
13186     /**
13187      * <p>Compute the vertical range that the vertical scrollbar represents.</p>
13188      *
13189      * <p>The range is expressed in arbitrary units that must be the same as the
13190      * units used by {@link #computeVerticalScrollExtent()} and
13191      * {@link #computeVerticalScrollOffset()}.</p>
13192      *
13193      * @return the total vertical range represented by the vertical scrollbar
13194      *
13195      * <p>The default range is the drawing height of this view.</p>
13196      *
13197      * @see #computeVerticalScrollExtent()
13198      * @see #computeVerticalScrollOffset()
13199      * @see android.widget.ScrollBarDrawable
13200      */
13201     protected int computeVerticalScrollRange() {
13202         return getHeight();
13203     }
13204
13205     /**
13206      * <p>Compute the vertical offset of the vertical scrollbar's thumb
13207      * within the horizontal range. This value is used to compute the position
13208      * of the thumb within the scrollbar's track.</p>
13209      *
13210      * <p>The range is expressed in arbitrary units that must be the same as the
13211      * units used by {@link #computeVerticalScrollRange()} and
13212      * {@link #computeVerticalScrollExtent()}.</p>
13213      *
13214      * <p>The default offset is the scroll offset of this view.</p>
13215      *
13216      * @return the vertical offset of the scrollbar's thumb
13217      *
13218      * @see #computeVerticalScrollRange()
13219      * @see #computeVerticalScrollExtent()
13220      * @see android.widget.ScrollBarDrawable
13221      */
13222     protected int computeVerticalScrollOffset() {
13223         return mScrollY;
13224     }
13225
13226     /**
13227      * <p>Compute the vertical extent of the vertical scrollbar's thumb
13228      * within the vertical range. This value is used to compute the length
13229      * of the thumb within the scrollbar's track.</p>
13230      *
13231      * <p>The range is expressed in arbitrary units that must be the same as the
13232      * units used by {@link #computeVerticalScrollRange()} and
13233      * {@link #computeVerticalScrollOffset()}.</p>
13234      *
13235      * <p>The default extent is the drawing height of this view.</p>
13236      *
13237      * @return the vertical extent of the scrollbar's thumb
13238      *
13239      * @see #computeVerticalScrollRange()
13240      * @see #computeVerticalScrollOffset()
13241      * @see android.widget.ScrollBarDrawable
13242      */
13243     protected int computeVerticalScrollExtent() {
13244         return getHeight();
13245     }
13246
13247     /**
13248      * Check if this view can be scrolled horizontally in a certain direction.
13249      *
13250      * @param direction Negative to check scrolling left, positive to check scrolling right.
13251      * @return true if this view can be scrolled in the specified direction, false otherwise.
13252      */
13253     public boolean canScrollHorizontally(int direction) {
13254         final int offset = computeHorizontalScrollOffset();
13255         final int range = computeHorizontalScrollRange() - computeHorizontalScrollExtent();
13256         if (range == 0) return false;
13257         if (direction < 0) {
13258             return offset > 0;
13259         } else {
13260             return offset < range - 1;
13261         }
13262     }
13263
13264     /**
13265      * Check if this view can be scrolled vertically in a certain direction.
13266      *
13267      * @param direction Negative to check scrolling up, positive to check scrolling down.
13268      * @return true if this view can be scrolled in the specified direction, false otherwise.
13269      */
13270     public boolean canScrollVertically(int direction) {
13271         final int offset = computeVerticalScrollOffset();
13272         final int range = computeVerticalScrollRange() - computeVerticalScrollExtent();
13273         if (range == 0) return false;
13274         if (direction < 0) {
13275             return offset > 0;
13276         } else {
13277             return offset < range - 1;
13278         }
13279     }
13280
13281     /**
13282      * <p>Request the drawing of the horizontal and the vertical scrollbar. The
13283      * scrollbars are painted only if they have been awakened first.</p>
13284      *
13285      * @param canvas the canvas on which to draw the scrollbars
13286      *
13287      * @see #awakenScrollBars(int)
13288      */
13289     protected final void onDrawScrollBars(Canvas canvas) {
13290         // scrollbars are drawn only when the animation is running
13291         final ScrollabilityCache cache = mScrollCache;
13292         if (cache != null) {
13293
13294             int state = cache.state;
13295
13296             if (state == ScrollabilityCache.OFF) {
13297                 return;
13298             }
13299
13300             boolean invalidate = false;
13301
13302             if (state == ScrollabilityCache.FADING) {
13303                 // We're fading -- get our fade interpolation
13304                 if (cache.interpolatorValues == null) {
13305                     cache.interpolatorValues = new float[1];
13306                 }
13307
13308                 float[] values = cache.interpolatorValues;
13309
13310                 // Stops the animation if we're done
13311                 if (cache.scrollBarInterpolator.timeToValues(values) ==
13312                         Interpolator.Result.FREEZE_END) {
13313                     cache.state = ScrollabilityCache.OFF;
13314                 } else {
13315                     cache.scrollBar.mutate().setAlpha(Math.round(values[0]));
13316                 }
13317
13318                 // This will make the scroll bars inval themselves after
13319                 // drawing. We only want this when we're fading so that
13320                 // we prevent excessive redraws
13321                 invalidate = true;
13322             } else {
13323                 // We're just on -- but we may have been fading before so
13324                 // reset alpha
13325                 cache.scrollBar.mutate().setAlpha(255);
13326             }
13327
13328
13329             final int viewFlags = mViewFlags;
13330
13331             final boolean drawHorizontalScrollBar =
13332                 (viewFlags & SCROLLBARS_HORIZONTAL) == SCROLLBARS_HORIZONTAL;
13333             final boolean drawVerticalScrollBar =
13334                 (viewFlags & SCROLLBARS_VERTICAL) == SCROLLBARS_VERTICAL
13335                 && !isVerticalScrollBarHidden();
13336
13337             if (drawVerticalScrollBar || drawHorizontalScrollBar) {
13338                 final int width = mRight - mLeft;
13339                 final int height = mBottom - mTop;
13340
13341                 final ScrollBarDrawable scrollBar = cache.scrollBar;
13342
13343                 final int scrollX = mScrollX;
13344                 final int scrollY = mScrollY;
13345                 final int inside = (viewFlags & SCROLLBARS_OUTSIDE_MASK) == 0 ? ~0 : 0;
13346
13347                 int left;
13348                 int top;
13349                 int right;
13350                 int bottom;
13351
13352                 if (drawHorizontalScrollBar) {
13353                     int size = scrollBar.getSize(false);
13354                     if (size <= 0) {
13355                         size = cache.scrollBarSize;
13356                     }
13357
13358                     scrollBar.setParameters(computeHorizontalScrollRange(),
13359                                             computeHorizontalScrollOffset(),
13360                                             computeHorizontalScrollExtent(), false);
13361                     final int verticalScrollBarGap = drawVerticalScrollBar ?
13362                             getVerticalScrollbarWidth() : 0;
13363                     top = scrollY + height - size - (mUserPaddingBottom & inside);
13364                     left = scrollX + (mPaddingLeft & inside);
13365                     right = scrollX + width - (mUserPaddingRight & inside) - verticalScrollBarGap;
13366                     bottom = top + size;
13367                     onDrawHorizontalScrollBar(canvas, scrollBar, left, top, right, bottom);
13368                     if (invalidate) {
13369                         invalidate(left, top, right, bottom);
13370                     }
13371                 }
13372
13373                 if (drawVerticalScrollBar) {
13374                     int size = scrollBar.getSize(true);
13375                     if (size <= 0) {
13376                         size = cache.scrollBarSize;
13377                     }
13378
13379                     scrollBar.setParameters(computeVerticalScrollRange(),
13380                                             computeVerticalScrollOffset(),
13381                                             computeVerticalScrollExtent(), true);
13382                     int verticalScrollbarPosition = mVerticalScrollbarPosition;
13383                     if (verticalScrollbarPosition == SCROLLBAR_POSITION_DEFAULT) {
13384                         verticalScrollbarPosition = isLayoutRtl() ?
13385                                 SCROLLBAR_POSITION_LEFT : SCROLLBAR_POSITION_RIGHT;
13386                     }
13387                     switch (verticalScrollbarPosition) {
13388                         default:
13389                         case SCROLLBAR_POSITION_RIGHT:
13390                             left = scrollX + width - size - (mUserPaddingRight & inside);
13391                             break;
13392                         case SCROLLBAR_POSITION_LEFT:
13393                             left = scrollX + (mUserPaddingLeft & inside);
13394                             break;
13395                     }
13396                     top = scrollY + (mPaddingTop & inside);
13397                     right = left + size;
13398                     bottom = scrollY + height - (mUserPaddingBottom & inside);
13399                     onDrawVerticalScrollBar(canvas, scrollBar, left, top, right, bottom);
13400                     if (invalidate) {
13401                         invalidate(left, top, right, bottom);
13402                     }
13403                 }
13404             }
13405         }
13406     }
13407
13408     /**
13409      * Override this if the vertical scrollbar needs to be hidden in a subclass, like when
13410      * FastScroller is visible.
13411      * @return whether to temporarily hide the vertical scrollbar
13412      * @hide
13413      */
13414     protected boolean isVerticalScrollBarHidden() {
13415         return false;
13416     }
13417
13418     /**
13419      * <p>Draw the horizontal scrollbar if
13420      * {@link #isHorizontalScrollBarEnabled()} returns true.</p>
13421      *
13422      * @param canvas the canvas on which to draw the scrollbar
13423      * @param scrollBar the scrollbar's drawable
13424      *
13425      * @see #isHorizontalScrollBarEnabled()
13426      * @see #computeHorizontalScrollRange()
13427      * @see #computeHorizontalScrollExtent()
13428      * @see #computeHorizontalScrollOffset()
13429      * @see android.widget.ScrollBarDrawable
13430      * @hide
13431      */
13432     protected void onDrawHorizontalScrollBar(Canvas canvas, Drawable scrollBar,
13433             int l, int t, int r, int b) {
13434         scrollBar.setBounds(l, t, r, b);
13435         scrollBar.draw(canvas);
13436     }
13437
13438     /**
13439      * <p>Draw the vertical scrollbar if {@link #isVerticalScrollBarEnabled()}
13440      * returns true.</p>
13441      *
13442      * @param canvas the canvas on which to draw the scrollbar
13443      * @param scrollBar the scrollbar's drawable
13444      *
13445      * @see #isVerticalScrollBarEnabled()
13446      * @see #computeVerticalScrollRange()
13447      * @see #computeVerticalScrollExtent()
13448      * @see #computeVerticalScrollOffset()
13449      * @see android.widget.ScrollBarDrawable
13450      * @hide
13451      */
13452     protected void onDrawVerticalScrollBar(Canvas canvas, Drawable scrollBar,
13453             int l, int t, int r, int b) {
13454         scrollBar.setBounds(l, t, r, b);
13455         scrollBar.draw(canvas);
13456     }
13457
13458     /**
13459      * Implement this to do your drawing.
13460      *
13461      * @param canvas the canvas on which the background will be drawn
13462      */
13463     protected void onDraw(Canvas canvas) {
13464     }
13465
13466     /*
13467      * Caller is responsible for calling requestLayout if necessary.
13468      * (This allows addViewInLayout to not request a new layout.)
13469      */
13470     void assignParent(ViewParent parent) {
13471         if (mParent == null) {
13472             mParent = parent;
13473         } else if (parent == null) {
13474             mParent = null;
13475         } else {
13476             throw new RuntimeException("view " + this + " being added, but"
13477                     + " it already has a parent");
13478         }
13479     }
13480
13481     /**
13482      * This is called when the view is attached to a window.  At this point it
13483      * has a Surface and will start drawing.  Note that this function is
13484      * guaranteed to be called before {@link #onDraw(android.graphics.Canvas)},
13485      * however it may be called any time before the first onDraw -- including
13486      * before or after {@link #onMeasure(int, int)}.
13487      *
13488      * @see #onDetachedFromWindow()
13489      */
13490     @CallSuper
13491     protected void onAttachedToWindow() {
13492         if ((mPrivateFlags & PFLAG_REQUEST_TRANSPARENT_REGIONS) != 0) {
13493             mParent.requestTransparentRegion(this);
13494         }
13495
13496         if ((mPrivateFlags & PFLAG_AWAKEN_SCROLL_BARS_ON_ATTACH) != 0) {
13497             initialAwakenScrollBars();
13498             mPrivateFlags &= ~PFLAG_AWAKEN_SCROLL_BARS_ON_ATTACH;
13499         }
13500
13501         mPrivateFlags3 &= ~PFLAG3_IS_LAID_OUT;
13502
13503         jumpDrawablesToCurrentState();
13504
13505         resetSubtreeAccessibilityStateChanged();
13506
13507         // rebuild, since Outline not maintained while View is detached
13508         rebuildOutline();
13509
13510         if (isFocused()) {
13511             InputMethodManager imm = InputMethodManager.peekInstance();
13512             if (imm != null) {
13513                 imm.focusIn(this);
13514             }
13515         }
13516     }
13517
13518     /**
13519      * Resolve all RTL related properties.
13520      *
13521      * @return true if resolution of RTL properties has been done
13522      *
13523      * @hide
13524      */
13525     public boolean resolveRtlPropertiesIfNeeded() {
13526         if (!needRtlPropertiesResolution()) return false;
13527
13528         // Order is important here: LayoutDirection MUST be resolved first
13529         if (!isLayoutDirectionResolved()) {
13530             resolveLayoutDirection();
13531             resolveLayoutParams();
13532         }
13533         // ... then we can resolve the others properties depending on the resolved LayoutDirection.
13534         if (!isTextDirectionResolved()) {
13535             resolveTextDirection();
13536         }
13537         if (!isTextAlignmentResolved()) {
13538             resolveTextAlignment();
13539         }
13540         // Should resolve Drawables before Padding because we need the layout direction of the
13541         // Drawable to correctly resolve Padding.
13542         if (!areDrawablesResolved()) {
13543             resolveDrawables();
13544         }
13545         if (!isPaddingResolved()) {
13546             resolvePadding();
13547         }
13548         onRtlPropertiesChanged(getLayoutDirection());
13549         return true;
13550     }
13551
13552     /**
13553      * Reset resolution of all RTL related properties.
13554      *
13555      * @hide
13556      */
13557     public void resetRtlProperties() {
13558         resetResolvedLayoutDirection();
13559         resetResolvedTextDirection();
13560         resetResolvedTextAlignment();
13561         resetResolvedPadding();
13562         resetResolvedDrawables();
13563     }
13564
13565     /**
13566      * @see #onScreenStateChanged(int)
13567      */
13568     void dispatchScreenStateChanged(int screenState) {
13569         onScreenStateChanged(screenState);
13570     }
13571
13572     /**
13573      * This method is called whenever the state of the screen this view is
13574      * attached to changes. A state change will usually occurs when the screen
13575      * turns on or off (whether it happens automatically or the user does it
13576      * manually.)
13577      *
13578      * @param screenState The new state of the screen. Can be either
13579      *                    {@link #SCREEN_STATE_ON} or {@link #SCREEN_STATE_OFF}
13580      */
13581     public void onScreenStateChanged(int screenState) {
13582     }
13583
13584     /**
13585      * Return true if the application tag in the AndroidManifest has set "supportRtl" to true
13586      */
13587     private boolean hasRtlSupport() {
13588         return mContext.getApplicationInfo().hasRtlSupport();
13589     }
13590
13591     /**
13592      * Return true if we are in RTL compatibility mode (either before Jelly Bean MR1 or
13593      * RTL not supported)
13594      */
13595     private boolean isRtlCompatibilityMode() {
13596         final int targetSdkVersion = getContext().getApplicationInfo().targetSdkVersion;
13597         return targetSdkVersion < JELLY_BEAN_MR1 || !hasRtlSupport();
13598     }
13599
13600     /**
13601      * @return true if RTL properties need resolution.
13602      *
13603      */
13604     private boolean needRtlPropertiesResolution() {
13605         return (mPrivateFlags2 & ALL_RTL_PROPERTIES_RESOLVED) != ALL_RTL_PROPERTIES_RESOLVED;
13606     }
13607
13608     /**
13609      * Called when any RTL property (layout direction or text direction or text alignment) has
13610      * been changed.
13611      *
13612      * Subclasses need to override this method to take care of cached information that depends on the
13613      * resolved layout direction, or to inform child views that inherit their layout direction.
13614      *
13615      * The default implementation does nothing.
13616      *
13617      * @param layoutDirection the direction of the layout
13618      *
13619      * @see #LAYOUT_DIRECTION_LTR
13620      * @see #LAYOUT_DIRECTION_RTL
13621      */
13622     public void onRtlPropertiesChanged(@ResolvedLayoutDir int layoutDirection) {
13623     }
13624
13625     /**
13626      * Resolve and cache the layout direction. LTR is set initially. This is implicitly supposing
13627      * that the parent directionality can and will be resolved before its children.
13628      *
13629      * @return true if resolution has been done, false otherwise.
13630      *
13631      * @hide
13632      */
13633     public boolean resolveLayoutDirection() {
13634         // Clear any previous layout direction resolution
13635         mPrivateFlags2 &= ~PFLAG2_LAYOUT_DIRECTION_RESOLVED_MASK;
13636
13637         if (hasRtlSupport()) {
13638             // Set resolved depending on layout direction
13639             switch ((mPrivateFlags2 & PFLAG2_LAYOUT_DIRECTION_MASK) >>
13640                     PFLAG2_LAYOUT_DIRECTION_MASK_SHIFT) {
13641                 case LAYOUT_DIRECTION_INHERIT:
13642                     // We cannot resolve yet. LTR is by default and let the resolution happen again
13643                     // later to get the correct resolved value
13644                     if (!canResolveLayoutDirection()) return false;
13645
13646                     // Parent has not yet resolved, LTR is still the default
13647                     try {
13648                         if (!mParent.isLayoutDirectionResolved()) return false;
13649
13650                         if (mParent.getLayoutDirection() == LAYOUT_DIRECTION_RTL) {
13651                             mPrivateFlags2 |= PFLAG2_LAYOUT_DIRECTION_RESOLVED_RTL;
13652                         }
13653                     } catch (AbstractMethodError e) {
13654                         Log.e(VIEW_LOG_TAG, mParent.getClass().getSimpleName() +
13655                                 " does not fully implement ViewParent", e);
13656                     }
13657                     break;
13658                 case LAYOUT_DIRECTION_RTL:
13659                     mPrivateFlags2 |= PFLAG2_LAYOUT_DIRECTION_RESOLVED_RTL;
13660                     break;
13661                 case LAYOUT_DIRECTION_LOCALE:
13662                     if((LAYOUT_DIRECTION_RTL ==
13663                             TextUtils.getLayoutDirectionFromLocale(Locale.getDefault()))) {
13664                         mPrivateFlags2 |= PFLAG2_LAYOUT_DIRECTION_RESOLVED_RTL;
13665                     }
13666                     break;
13667                 default:
13668                     // Nothing to do, LTR by default
13669             }
13670         }
13671
13672         // Set to resolved
13673         mPrivateFlags2 |= PFLAG2_LAYOUT_DIRECTION_RESOLVED;
13674         return true;
13675     }
13676
13677     /**
13678      * Check if layout direction resolution can be done.
13679      *
13680      * @return true if layout direction resolution can be done otherwise return false.
13681      */
13682     public boolean canResolveLayoutDirection() {
13683         switch (getRawLayoutDirection()) {
13684             case LAYOUT_DIRECTION_INHERIT:
13685                 if (mParent != null) {
13686                     try {
13687                         return mParent.canResolveLayoutDirection();
13688                     } catch (AbstractMethodError e) {
13689                         Log.e(VIEW_LOG_TAG, mParent.getClass().getSimpleName() +
13690                                 " does not fully implement ViewParent", e);
13691                     }
13692                 }
13693                 return false;
13694
13695             default:
13696                 return true;
13697         }
13698     }
13699
13700     /**
13701      * Reset the resolved layout direction. Layout direction will be resolved during a call to
13702      * {@link #onMeasure(int, int)}.
13703      *
13704      * @hide
13705      */
13706     public void resetResolvedLayoutDirection() {
13707         // Reset the current resolved bits
13708         mPrivateFlags2 &= ~PFLAG2_LAYOUT_DIRECTION_RESOLVED_MASK;
13709     }
13710
13711     /**
13712      * @return true if the layout direction is inherited.
13713      *
13714      * @hide
13715      */
13716     public boolean isLayoutDirectionInherited() {
13717         return (getRawLayoutDirection() == LAYOUT_DIRECTION_INHERIT);
13718     }
13719
13720     /**
13721      * @return true if layout direction has been resolved.
13722      */
13723     public boolean isLayoutDirectionResolved() {
13724         return (mPrivateFlags2 & PFLAG2_LAYOUT_DIRECTION_RESOLVED) == PFLAG2_LAYOUT_DIRECTION_RESOLVED;
13725     }
13726
13727     /**
13728      * Return if padding has been resolved
13729      *
13730      * @hide
13731      */
13732     boolean isPaddingResolved() {
13733         return (mPrivateFlags2 & PFLAG2_PADDING_RESOLVED) == PFLAG2_PADDING_RESOLVED;
13734     }
13735
13736     /**
13737      * Resolves padding depending on layout direction, if applicable, and
13738      * recomputes internal padding values to adjust for scroll bars.
13739      *
13740      * @hide
13741      */
13742     public void resolvePadding() {
13743         final int resolvedLayoutDirection = getLayoutDirection();
13744
13745         if (!isRtlCompatibilityMode()) {
13746             // Post Jelly Bean MR1 case: we need to take the resolved layout direction into account.
13747             // If start / end padding are defined, they will be resolved (hence overriding) to
13748             // left / right or right / left depending on the resolved layout direction.
13749             // If start / end padding are not defined, use the left / right ones.
13750             if (mBackground != null && (!mLeftPaddingDefined || !mRightPaddingDefined)) {
13751                 Rect padding = sThreadLocal.get();
13752                 if (padding == null) {
13753                     padding = new Rect();
13754                     sThreadLocal.set(padding);
13755                 }
13756                 mBackground.getPadding(padding);
13757                 if (!mLeftPaddingDefined) {
13758                     mUserPaddingLeftInitial = padding.left;
13759                 }
13760                 if (!mRightPaddingDefined) {
13761                     mUserPaddingRightInitial = padding.right;
13762                 }
13763             }
13764             switch (resolvedLayoutDirection) {
13765                 case LAYOUT_DIRECTION_RTL:
13766                     if (mUserPaddingStart != UNDEFINED_PADDING) {
13767                         mUserPaddingRight = mUserPaddingStart;
13768                     } else {
13769                         mUserPaddingRight = mUserPaddingRightInitial;
13770                     }
13771                     if (mUserPaddingEnd != UNDEFINED_PADDING) {
13772                         mUserPaddingLeft = mUserPaddingEnd;
13773                     } else {
13774                         mUserPaddingLeft = mUserPaddingLeftInitial;
13775                     }
13776                     break;
13777                 case LAYOUT_DIRECTION_LTR:
13778                 default:
13779                     if (mUserPaddingStart != UNDEFINED_PADDING) {
13780                         mUserPaddingLeft = mUserPaddingStart;
13781                     } else {
13782                         mUserPaddingLeft = mUserPaddingLeftInitial;
13783                     }
13784                     if (mUserPaddingEnd != UNDEFINED_PADDING) {
13785                         mUserPaddingRight = mUserPaddingEnd;
13786                     } else {
13787                         mUserPaddingRight = mUserPaddingRightInitial;
13788                     }
13789             }
13790
13791             mUserPaddingBottom = (mUserPaddingBottom >= 0) ? mUserPaddingBottom : mPaddingBottom;
13792         }
13793
13794         internalSetPadding(mUserPaddingLeft, mPaddingTop, mUserPaddingRight, mUserPaddingBottom);
13795         onRtlPropertiesChanged(resolvedLayoutDirection);
13796
13797         mPrivateFlags2 |= PFLAG2_PADDING_RESOLVED;
13798     }
13799
13800     /**
13801      * Reset the resolved layout direction.
13802      *
13803      * @hide
13804      */
13805     public void resetResolvedPadding() {
13806         resetResolvedPaddingInternal();
13807     }
13808
13809     /**
13810      * Used when we only want to reset *this* view's padding and not trigger overrides
13811      * in ViewGroup that reset children too.
13812      */
13813     void resetResolvedPaddingInternal() {
13814         mPrivateFlags2 &= ~PFLAG2_PADDING_RESOLVED;
13815     }
13816
13817     /**
13818      * This is called when the view is detached from a window.  At this point it
13819      * no longer has a surface for drawing.
13820      *
13821      * @see #onAttachedToWindow()
13822      */
13823     @CallSuper
13824     protected void onDetachedFromWindow() {
13825     }
13826
13827     /**
13828      * This is a framework-internal mirror of onDetachedFromWindow() that's called
13829      * after onDetachedFromWindow().
13830      *
13831      * If you override this you *MUST* call super.onDetachedFromWindowInternal()!
13832      * The super method should be called at the end of the overridden method to ensure
13833      * subclasses are destroyed first
13834      *
13835      * @hide
13836      */
13837     @CallSuper
13838     protected void onDetachedFromWindowInternal() {
13839         mPrivateFlags &= ~PFLAG_CANCEL_NEXT_UP_EVENT;
13840         mPrivateFlags3 &= ~PFLAG3_IS_LAID_OUT;
13841
13842         removeUnsetPressCallback();
13843         removeLongPressCallback();
13844         removePerformClickCallback();
13845         removeSendViewScrolledAccessibilityEventCallback();
13846         stopNestedScroll();
13847
13848         // Anything that started animating right before detach should already
13849         // be in its final state when re-attached.
13850         jumpDrawablesToCurrentState();
13851
13852         destroyDrawingCache();
13853
13854         cleanupDraw();
13855         mCurrentAnimation = null;
13856     }
13857
13858     private void cleanupDraw() {
13859         resetDisplayList();
13860         if (mAttachInfo != null) {
13861             mAttachInfo.mViewRootImpl.cancelInvalidate(this);
13862         }
13863     }
13864
13865     void invalidateInheritedLayoutMode(int layoutModeOfRoot) {
13866     }
13867
13868     /**
13869      * @return The number of times this view has been attached to a window
13870      */
13871     protected int getWindowAttachCount() {
13872         return mWindowAttachCount;
13873     }
13874
13875     /**
13876      * Retrieve a unique token identifying the window this view is attached to.
13877      * @return Return the window's token for use in
13878      * {@link WindowManager.LayoutParams#token WindowManager.LayoutParams.token}.
13879      */
13880     public IBinder getWindowToken() {
13881         return mAttachInfo != null ? mAttachInfo.mWindowToken : null;
13882     }
13883
13884     /**
13885      * Retrieve the {@link WindowId} for the window this view is
13886      * currently attached to.
13887      */
13888     public WindowId getWindowId() {
13889         if (mAttachInfo == null) {
13890             return null;
13891         }
13892         if (mAttachInfo.mWindowId == null) {
13893             try {
13894                 mAttachInfo.mIWindowId = mAttachInfo.mSession.getWindowId(
13895                         mAttachInfo.mWindowToken);
13896                 mAttachInfo.mWindowId = new WindowId(
13897                         mAttachInfo.mIWindowId);
13898             } catch (RemoteException e) {
13899             }
13900         }
13901         return mAttachInfo.mWindowId;
13902     }
13903
13904     /**
13905      * Retrieve a unique token identifying the top-level "real" window of
13906      * the window that this view is attached to.  That is, this is like
13907      * {@link #getWindowToken}, except if the window this view in is a panel
13908      * window (attached to another containing window), then the token of
13909      * the containing window is returned instead.
13910      *
13911      * @return Returns the associated window token, either
13912      * {@link #getWindowToken()} or the containing window's token.
13913      */
13914     public IBinder getApplicationWindowToken() {
13915         AttachInfo ai = mAttachInfo;
13916         if (ai != null) {
13917             IBinder appWindowToken = ai.mPanelParentWindowToken;
13918             if (appWindowToken == null) {
13919                 appWindowToken = ai.mWindowToken;
13920             }
13921             return appWindowToken;
13922         }
13923         return null;
13924     }
13925
13926     /**
13927      * Gets the logical display to which the view's window has been attached.
13928      *
13929      * @return The logical display, or null if the view is not currently attached to a window.
13930      */
13931     public Display getDisplay() {
13932         return mAttachInfo != null ? mAttachInfo.mDisplay : null;
13933     }
13934
13935     /**
13936      * Retrieve private session object this view hierarchy is using to
13937      * communicate with the window manager.
13938      * @return the session object to communicate with the window manager
13939      */
13940     /*package*/ IWindowSession getWindowSession() {
13941         return mAttachInfo != null ? mAttachInfo.mSession : null;
13942     }
13943
13944     /**
13945      * @param info the {@link android.view.View.AttachInfo} to associated with
13946      *        this view
13947      */
13948     void dispatchAttachedToWindow(AttachInfo info, int visibility) {
13949         //System.out.println("Attached! " + this);
13950         mAttachInfo = info;
13951         if (mOverlay != null) {
13952             mOverlay.getOverlayView().dispatchAttachedToWindow(info, visibility);
13953         }
13954         mWindowAttachCount++;
13955         // We will need to evaluate the drawable state at least once.
13956         mPrivateFlags |= PFLAG_DRAWABLE_STATE_DIRTY;
13957         if (mFloatingTreeObserver != null) {
13958             info.mTreeObserver.merge(mFloatingTreeObserver);
13959             mFloatingTreeObserver = null;
13960         }
13961         if ((mPrivateFlags&PFLAG_SCROLL_CONTAINER) != 0) {
13962             mAttachInfo.mScrollContainers.add(this);
13963             mPrivateFlags |= PFLAG_SCROLL_CONTAINER_ADDED;
13964         }
13965         performCollectViewAttributes(mAttachInfo, visibility);
13966         onAttachedToWindow();
13967
13968         ListenerInfo li = mListenerInfo;
13969         final CopyOnWriteArrayList<OnAttachStateChangeListener> listeners =
13970                 li != null ? li.mOnAttachStateChangeListeners : null;
13971         if (listeners != null && listeners.size() > 0) {
13972             // NOTE: because of the use of CopyOnWriteArrayList, we *must* use an iterator to
13973             // perform the dispatching. The iterator is a safe guard against listeners that
13974             // could mutate the list by calling the various add/remove methods. This prevents
13975             // the array from being modified while we iterate it.
13976             for (OnAttachStateChangeListener listener : listeners) {
13977                 listener.onViewAttachedToWindow(this);
13978             }
13979         }
13980
13981         int vis = info.mWindowVisibility;
13982         if (vis != GONE) {
13983             onWindowVisibilityChanged(vis);
13984         }
13985         if ((mPrivateFlags&PFLAG_DRAWABLE_STATE_DIRTY) != 0) {
13986             // If nobody has evaluated the drawable state yet, then do it now.
13987             refreshDrawableState();
13988         }
13989         needGlobalAttributesUpdate(false);
13990     }
13991
13992     void dispatchDetachedFromWindow() {
13993         AttachInfo info = mAttachInfo;
13994         if (info != null) {
13995             int vis = info.mWindowVisibility;
13996             if (vis != GONE) {
13997                 onWindowVisibilityChanged(GONE);
13998             }
13999         }
14000
14001         onDetachedFromWindow();
14002         onDetachedFromWindowInternal();
14003
14004         ListenerInfo li = mListenerInfo;
14005         final CopyOnWriteArrayList<OnAttachStateChangeListener> listeners =
14006                 li != null ? li.mOnAttachStateChangeListeners : null;
14007         if (listeners != null && listeners.size() > 0) {
14008             // NOTE: because of the use of CopyOnWriteArrayList, we *must* use an iterator to
14009             // perform the dispatching. The iterator is a safe guard against listeners that
14010             // could mutate the list by calling the various add/remove methods. This prevents
14011             // the array from being modified while we iterate it.
14012             for (OnAttachStateChangeListener listener : listeners) {
14013                 listener.onViewDetachedFromWindow(this);
14014             }
14015         }
14016
14017         if ((mPrivateFlags & PFLAG_SCROLL_CONTAINER_ADDED) != 0) {
14018             mAttachInfo.mScrollContainers.remove(this);
14019             mPrivateFlags &= ~PFLAG_SCROLL_CONTAINER_ADDED;
14020         }
14021
14022         mAttachInfo = null;
14023         if (mOverlay != null) {
14024             mOverlay.getOverlayView().dispatchDetachedFromWindow();
14025         }
14026     }
14027
14028     /**
14029      * Cancel any deferred high-level input events that were previously posted to the event queue.
14030      *
14031      * <p>Many views post high-level events such as click handlers to the event queue
14032      * to run deferred in order to preserve a desired user experience - clearing visible
14033      * pressed states before executing, etc. This method will abort any events of this nature
14034      * that are currently in flight.</p>
14035      *
14036      * <p>Custom views that generate their own high-level deferred input events should override
14037      * {@link #onCancelPendingInputEvents()} and remove those pending events from the queue.</p>
14038      *
14039      * <p>This will also cancel pending input events for any child views.</p>
14040      *
14041      * <p>Note that this may not be sufficient as a debouncing strategy for clicks in all cases.
14042      * This will not impact newer events posted after this call that may occur as a result of
14043      * lower-level input events still waiting in the queue. If you are trying to prevent
14044      * double-submitted  events for the duration of some sort of asynchronous transaction
14045      * you should also take other steps to protect against unexpected double inputs e.g. calling
14046      * {@link #setEnabled(boolean) setEnabled(false)} and re-enabling the view when
14047      * the transaction completes, tracking already submitted transaction IDs, etc.</p>
14048      */
14049     public final void cancelPendingInputEvents() {
14050         dispatchCancelPendingInputEvents();
14051     }
14052
14053     /**
14054      * Called by {@link #cancelPendingInputEvents()} to cancel input events in flight.
14055      * Overridden by ViewGroup to dispatch. Package scoped to prevent app-side meddling.
14056      */
14057     void dispatchCancelPendingInputEvents() {
14058         mPrivateFlags3 &= ~PFLAG3_CALLED_SUPER;
14059         onCancelPendingInputEvents();
14060         if ((mPrivateFlags3 & PFLAG3_CALLED_SUPER) != PFLAG3_CALLED_SUPER) {
14061             throw new SuperNotCalledException("View " + getClass().getSimpleName() +
14062                     " did not call through to super.onCancelPendingInputEvents()");
14063         }
14064     }
14065
14066     /**
14067      * Called as the result of a call to {@link #cancelPendingInputEvents()} on this view or
14068      * a parent view.
14069      *
14070      * <p>This method is responsible for removing any pending high-level input events that were
14071      * posted to the event queue to run later. Custom view classes that post their own deferred
14072      * high-level events via {@link #post(Runnable)}, {@link #postDelayed(Runnable, long)} or
14073      * {@link android.os.Handler} should override this method, call
14074      * <code>super.onCancelPendingInputEvents()</code> and remove those callbacks as appropriate.
14075      * </p>
14076      */
14077     public void onCancelPendingInputEvents() {
14078         removePerformClickCallback();
14079         cancelLongPress();
14080         mPrivateFlags3 |= PFLAG3_CALLED_SUPER;
14081     }
14082
14083     /**
14084      * Store this view hierarchy's frozen state into the given container.
14085      *
14086      * @param container The SparseArray in which to save the view's state.
14087      *
14088      * @see #restoreHierarchyState(android.util.SparseArray)
14089      * @see #dispatchSaveInstanceState(android.util.SparseArray)
14090      * @see #onSaveInstanceState()
14091      */
14092     public void saveHierarchyState(SparseArray<Parcelable> container) {
14093         dispatchSaveInstanceState(container);
14094     }
14095
14096     /**
14097      * Called by {@link #saveHierarchyState(android.util.SparseArray)} to store the state for
14098      * this view and its children. May be overridden to modify how freezing happens to a
14099      * view's children; for example, some views may want to not store state for their children.
14100      *
14101      * @param container The SparseArray in which to save the view's state.
14102      *
14103      * @see #dispatchRestoreInstanceState(android.util.SparseArray)
14104      * @see #saveHierarchyState(android.util.SparseArray)
14105      * @see #onSaveInstanceState()
14106      */
14107     protected void dispatchSaveInstanceState(SparseArray<Parcelable> container) {
14108         if (mID != NO_ID && (mViewFlags & SAVE_DISABLED_MASK) == 0) {
14109             mPrivateFlags &= ~PFLAG_SAVE_STATE_CALLED;
14110             Parcelable state = onSaveInstanceState();
14111             if ((mPrivateFlags & PFLAG_SAVE_STATE_CALLED) == 0) {
14112                 throw new IllegalStateException(
14113                         "Derived class did not call super.onSaveInstanceState()");
14114             }
14115             if (state != null) {
14116                 // Log.i("View", "Freezing #" + Integer.toHexString(mID)
14117                 // + ": " + state);
14118                 container.put(mID, state);
14119             }
14120         }
14121     }
14122
14123     /**
14124      * Hook allowing a view to generate a representation of its internal state
14125      * that can later be used to create a new instance with that same state.
14126      * This state should only contain information that is not persistent or can
14127      * not be reconstructed later. For example, you will never store your
14128      * current position on screen because that will be computed again when a
14129      * new instance of the view is placed in its view hierarchy.
14130      * <p>
14131      * Some examples of things you may store here: the current cursor position
14132      * in a text view (but usually not the text itself since that is stored in a
14133      * content provider or other persistent storage), the currently selected
14134      * item in a list view.
14135      *
14136      * @return Returns a Parcelable object containing the view's current dynamic
14137      *         state, or null if there is nothing interesting to save. The
14138      *         default implementation returns null.
14139      * @see #onRestoreInstanceState(android.os.Parcelable)
14140      * @see #saveHierarchyState(android.util.SparseArray)
14141      * @see #dispatchSaveInstanceState(android.util.SparseArray)
14142      * @see #setSaveEnabled(boolean)
14143      */
14144     @CallSuper
14145     protected Parcelable onSaveInstanceState() {
14146         mPrivateFlags |= PFLAG_SAVE_STATE_CALLED;
14147         if (mStartActivityRequestWho != null) {
14148             BaseSavedState state = new BaseSavedState(AbsSavedState.EMPTY_STATE);
14149             state.mStartActivityRequestWhoSaved = mStartActivityRequestWho;
14150             return state;
14151         }
14152         return BaseSavedState.EMPTY_STATE;
14153     }
14154
14155     /**
14156      * Restore this view hierarchy's frozen state from the given container.
14157      *
14158      * @param container The SparseArray which holds previously frozen states.
14159      *
14160      * @see #saveHierarchyState(android.util.SparseArray)
14161      * @see #dispatchRestoreInstanceState(android.util.SparseArray)
14162      * @see #onRestoreInstanceState(android.os.Parcelable)
14163      */
14164     public void restoreHierarchyState(SparseArray<Parcelable> container) {
14165         dispatchRestoreInstanceState(container);
14166     }
14167
14168     /**
14169      * Called by {@link #restoreHierarchyState(android.util.SparseArray)} to retrieve the
14170      * state for this view and its children. May be overridden to modify how restoring
14171      * happens to a view's children; for example, some views may want to not store state
14172      * for their children.
14173      *
14174      * @param container The SparseArray which holds previously saved state.
14175      *
14176      * @see #dispatchSaveInstanceState(android.util.SparseArray)
14177      * @see #restoreHierarchyState(android.util.SparseArray)
14178      * @see #onRestoreInstanceState(android.os.Parcelable)
14179      */
14180     protected void dispatchRestoreInstanceState(SparseArray<Parcelable> container) {
14181         if (mID != NO_ID) {
14182             Parcelable state = container.get(mID);
14183             if (state != null) {
14184                 // Log.i("View", "Restoreing #" + Integer.toHexString(mID)
14185                 // + ": " + state);
14186                 mPrivateFlags &= ~PFLAG_SAVE_STATE_CALLED;
14187                 onRestoreInstanceState(state);
14188                 if ((mPrivateFlags & PFLAG_SAVE_STATE_CALLED) == 0) {
14189                     throw new IllegalStateException(
14190                             "Derived class did not call super.onRestoreInstanceState()");
14191                 }
14192             }
14193         }
14194     }
14195
14196     /**
14197      * Hook allowing a view to re-apply a representation of its internal state that had previously
14198      * been generated by {@link #onSaveInstanceState}. This function will never be called with a
14199      * null state.
14200      *
14201      * @param state The frozen state that had previously been returned by
14202      *        {@link #onSaveInstanceState}.
14203      *
14204      * @see #onSaveInstanceState()
14205      * @see #restoreHierarchyState(android.util.SparseArray)
14206      * @see #dispatchRestoreInstanceState(android.util.SparseArray)
14207      */
14208     @CallSuper
14209     protected void onRestoreInstanceState(Parcelable state) {
14210         mPrivateFlags |= PFLAG_SAVE_STATE_CALLED;
14211         if (state != null && !(state instanceof AbsSavedState)) {
14212             throw new IllegalArgumentException("Wrong state class, expecting View State but "
14213                     + "received " + state.getClass().toString() + " instead. This usually happens "
14214                     + "when two views of different type have the same id in the same hierarchy. "
14215                     + "This view's id is " + ViewDebug.resolveId(mContext, getId()) + ". Make sure "
14216                     + "other views do not use the same id.");
14217         }
14218         if (state != null && state instanceof BaseSavedState) {
14219             mStartActivityRequestWho = ((BaseSavedState) state).mStartActivityRequestWhoSaved;
14220         }
14221     }
14222
14223     /**
14224      * <p>Return the time at which the drawing of the view hierarchy started.</p>
14225      *
14226      * @return the drawing start time in milliseconds
14227      */
14228     public long getDrawingTime() {
14229         return mAttachInfo != null ? mAttachInfo.mDrawingTime : 0;
14230     }
14231
14232     /**
14233      * <p>Enables or disables the duplication of the parent's state into this view. When
14234      * duplication is enabled, this view gets its drawable state from its parent rather
14235      * than from its own internal properties.</p>
14236      *
14237      * <p>Note: in the current implementation, setting this property to true after the
14238      * view was added to a ViewGroup might have no effect at all. This property should
14239      * always be used from XML or set to true before adding this view to a ViewGroup.</p>
14240      *
14241      * <p>Note: if this view's parent addStateFromChildren property is enabled and this
14242      * property is enabled, an exception will be thrown.</p>
14243      *
14244      * <p>Note: if the child view uses and updates additional states which are unknown to the
14245      * parent, these states should not be affected by this method.</p>
14246      *
14247      * @param enabled True to enable duplication of the parent's drawable state, false
14248      *                to disable it.
14249      *
14250      * @see #getDrawableState()
14251      * @see #isDuplicateParentStateEnabled()
14252      */
14253     public void setDuplicateParentStateEnabled(boolean enabled) {
14254         setFlags(enabled ? DUPLICATE_PARENT_STATE : 0, DUPLICATE_PARENT_STATE);
14255     }
14256
14257     /**
14258      * <p>Indicates whether this duplicates its drawable state from its parent.</p>
14259      *
14260      * @return True if this view's drawable state is duplicated from the parent,
14261      *         false otherwise
14262      *
14263      * @see #getDrawableState()
14264      * @see #setDuplicateParentStateEnabled(boolean)
14265      */
14266     public boolean isDuplicateParentStateEnabled() {
14267         return (mViewFlags & DUPLICATE_PARENT_STATE) == DUPLICATE_PARENT_STATE;
14268     }
14269
14270     /**
14271      * <p>Specifies the type of layer backing this view. The layer can be
14272      * {@link #LAYER_TYPE_NONE}, {@link #LAYER_TYPE_SOFTWARE} or
14273      * {@link #LAYER_TYPE_HARDWARE}.</p>
14274      *
14275      * <p>A layer is associated with an optional {@link android.graphics.Paint}
14276      * instance that controls how the layer is composed on screen. The following
14277      * properties of the paint are taken into account when composing the layer:</p>
14278      * <ul>
14279      * <li>{@link android.graphics.Paint#getAlpha() Translucency (alpha)}</li>
14280      * <li>{@link android.graphics.Paint#getXfermode() Blending mode}</li>
14281      * <li>{@link android.graphics.Paint#getColorFilter() Color filter}</li>
14282      * </ul>
14283      *
14284      * <p>If this view has an alpha value set to < 1.0 by calling
14285      * {@link #setAlpha(float)}, the alpha value of the layer's paint is superseded
14286      * by this view's alpha value.</p>
14287      *
14288      * <p>Refer to the documentation of {@link #LAYER_TYPE_NONE},
14289      * {@link #LAYER_TYPE_SOFTWARE} and {@link #LAYER_TYPE_HARDWARE}
14290      * for more information on when and how to use layers.</p>
14291      *
14292      * @param layerType The type of layer to use with this view, must be one of
14293      *        {@link #LAYER_TYPE_NONE}, {@link #LAYER_TYPE_SOFTWARE} or
14294      *        {@link #LAYER_TYPE_HARDWARE}
14295      * @param paint The paint used to compose the layer. This argument is optional
14296      *        and can be null. It is ignored when the layer type is
14297      *        {@link #LAYER_TYPE_NONE}
14298      *
14299      * @see #getLayerType()
14300      * @see #LAYER_TYPE_NONE
14301      * @see #LAYER_TYPE_SOFTWARE
14302      * @see #LAYER_TYPE_HARDWARE
14303      * @see #setAlpha(float)
14304      *
14305      * @attr ref android.R.styleable#View_layerType
14306      */
14307     public void setLayerType(int layerType, Paint paint) {
14308         if (layerType < LAYER_TYPE_NONE || layerType > LAYER_TYPE_HARDWARE) {
14309             throw new IllegalArgumentException("Layer type can only be one of: LAYER_TYPE_NONE, "
14310                     + "LAYER_TYPE_SOFTWARE or LAYER_TYPE_HARDWARE");
14311         }
14312
14313         boolean typeChanged = mRenderNode.setLayerType(layerType);
14314
14315         if (!typeChanged) {
14316             setLayerPaint(paint);
14317             return;
14318         }
14319
14320         // Destroy any previous software drawing cache if needed
14321         if (mLayerType == LAYER_TYPE_SOFTWARE) {
14322             destroyDrawingCache();
14323         }
14324
14325         mLayerType = layerType;
14326         final boolean layerDisabled = (mLayerType == LAYER_TYPE_NONE);
14327         mLayerPaint = layerDisabled ? null : (paint == null ? new Paint() : paint);
14328         mRenderNode.setLayerPaint(mLayerPaint);
14329
14330         // draw() behaves differently if we are on a layer, so we need to
14331         // invalidate() here
14332         invalidateParentCaches();
14333         invalidate(true);
14334     }
14335
14336     /**
14337      * Updates the {@link Paint} object used with the current layer (used only if the current
14338      * layer type is not set to {@link #LAYER_TYPE_NONE}). Changed properties of the Paint
14339      * provided to {@link #setLayerType(int, android.graphics.Paint)} will be used the next time
14340      * the View is redrawn, but {@link #setLayerPaint(android.graphics.Paint)} must be called to
14341      * ensure that the view gets redrawn immediately.
14342      *
14343      * <p>A layer is associated with an optional {@link android.graphics.Paint}
14344      * instance that controls how the layer is composed on screen. The following
14345      * properties of the paint are taken into account when composing the layer:</p>
14346      * <ul>
14347      * <li>{@link android.graphics.Paint#getAlpha() Translucency (alpha)}</li>
14348      * <li>{@link android.graphics.Paint#getXfermode() Blending mode}</li>
14349      * <li>{@link android.graphics.Paint#getColorFilter() Color filter}</li>
14350      * </ul>
14351      *
14352      * <p>If this view has an alpha value set to < 1.0 by calling {@link #setAlpha(float)}, the
14353      * alpha value of the layer's paint is superseded by this view's alpha value.</p>
14354      *
14355      * @param paint The paint used to compose the layer. This argument is optional
14356      *        and can be null. It is ignored when the layer type is
14357      *        {@link #LAYER_TYPE_NONE}
14358      *
14359      * @see #setLayerType(int, android.graphics.Paint)
14360      */
14361     public void setLayerPaint(Paint paint) {
14362         int layerType = getLayerType();
14363         if (layerType != LAYER_TYPE_NONE) {
14364             mLayerPaint = paint == null ? new Paint() : paint;
14365             if (layerType == LAYER_TYPE_HARDWARE) {
14366                 if (mRenderNode.setLayerPaint(mLayerPaint)) {
14367                     invalidateViewProperty(false, false);
14368                 }
14369             } else {
14370                 invalidate();
14371             }
14372         }
14373     }
14374
14375     /**
14376      * Indicates whether this view has a static layer. A view with layer type
14377      * {@link #LAYER_TYPE_NONE} is a static layer. Other types of layers are
14378      * dynamic.
14379      */
14380     boolean hasStaticLayer() {
14381         return true;
14382     }
14383
14384     /**
14385      * Indicates what type of layer is currently associated with this view. By default
14386      * a view does not have a layer, and the layer type is {@link #LAYER_TYPE_NONE}.
14387      * Refer to the documentation of {@link #setLayerType(int, android.graphics.Paint)}
14388      * for more information on the different types of layers.
14389      *
14390      * @return {@link #LAYER_TYPE_NONE}, {@link #LAYER_TYPE_SOFTWARE} or
14391      *         {@link #LAYER_TYPE_HARDWARE}
14392      *
14393      * @see #setLayerType(int, android.graphics.Paint)
14394      * @see #buildLayer()
14395      * @see #LAYER_TYPE_NONE
14396      * @see #LAYER_TYPE_SOFTWARE
14397      * @see #LAYER_TYPE_HARDWARE
14398      */
14399     public int getLayerType() {
14400         return mLayerType;
14401     }
14402
14403     /**
14404      * Forces this view's layer to be created and this view to be rendered
14405      * into its layer. If this view's layer type is set to {@link #LAYER_TYPE_NONE},
14406      * invoking this method will have no effect.
14407      *
14408      * This method can for instance be used to render a view into its layer before
14409      * starting an animation. If this view is complex, rendering into the layer
14410      * before starting the animation will avoid skipping frames.
14411      *
14412      * @throws IllegalStateException If this view is not attached to a window
14413      *
14414      * @see #setLayerType(int, android.graphics.Paint)
14415      */
14416     public void buildLayer() {
14417         if (mLayerType == LAYER_TYPE_NONE) return;
14418
14419         final AttachInfo attachInfo = mAttachInfo;
14420         if (attachInfo == null) {
14421             throw new IllegalStateException("This view must be attached to a window first");
14422         }
14423
14424         if (getWidth() == 0 || getHeight() == 0) {
14425             return;
14426         }
14427
14428         switch (mLayerType) {
14429             case LAYER_TYPE_HARDWARE:
14430                 updateDisplayListIfDirty();
14431                 if (attachInfo.mHardwareRenderer != null && mRenderNode.isValid()) {
14432                     attachInfo.mHardwareRenderer.buildLayer(mRenderNode);
14433                 }
14434                 break;
14435             case LAYER_TYPE_SOFTWARE:
14436                 buildDrawingCache(true);
14437                 break;
14438         }
14439     }
14440
14441     /**
14442      * If this View draws with a HardwareLayer, returns it.
14443      * Otherwise returns null
14444      *
14445      * TODO: Only TextureView uses this, can we eliminate it?
14446      */
14447     HardwareLayer getHardwareLayer() {
14448         return null;
14449     }
14450
14451     /**
14452      * Destroys all hardware rendering resources. This method is invoked
14453      * when the system needs to reclaim resources. Upon execution of this
14454      * method, you should free any OpenGL resources created by the view.
14455      *
14456      * Note: you <strong>must</strong> call
14457      * <code>super.destroyHardwareResources()</code> when overriding
14458      * this method.
14459      *
14460      * @hide
14461      */
14462     @CallSuper
14463     protected void destroyHardwareResources() {
14464         // Although the Layer will be destroyed by RenderNode, we want to release
14465         // the staging display list, which is also a signal to RenderNode that it's
14466         // safe to free its copy of the display list as it knows that we will
14467         // push an updated DisplayList if we try to draw again
14468         resetDisplayList();
14469     }
14470
14471     /**
14472      * <p>Enables or disables the drawing cache. When the drawing cache is enabled, the next call
14473      * to {@link #getDrawingCache()} or {@link #buildDrawingCache()} will draw the view in a
14474      * bitmap. Calling {@link #draw(android.graphics.Canvas)} will not draw from the cache when
14475      * the cache is enabled. To benefit from the cache, you must request the drawing cache by
14476      * calling {@link #getDrawingCache()} and draw it on screen if the returned bitmap is not
14477      * null.</p>
14478      *
14479      * <p>Enabling the drawing cache is similar to
14480      * {@link #setLayerType(int, android.graphics.Paint) setting a layer} when hardware
14481      * acceleration is turned off. When hardware acceleration is turned on, enabling the
14482      * drawing cache has no effect on rendering because the system uses a different mechanism
14483      * for acceleration which ignores the flag. If you want to use a Bitmap for the view, even
14484      * when hardware acceleration is enabled, see {@link #setLayerType(int, android.graphics.Paint)}
14485      * for information on how to enable software and hardware layers.</p>
14486      *
14487      * <p>This API can be used to manually generate
14488      * a bitmap copy of this view, by setting the flag to <code>true</code> and calling
14489      * {@link #getDrawingCache()}.</p>
14490      *
14491      * @param enabled true to enable the drawing cache, false otherwise
14492      *
14493      * @see #isDrawingCacheEnabled()
14494      * @see #getDrawingCache()
14495      * @see #buildDrawingCache()
14496      * @see #setLayerType(int, android.graphics.Paint)
14497      */
14498     public void setDrawingCacheEnabled(boolean enabled) {
14499         mCachingFailed = false;
14500         setFlags(enabled ? DRAWING_CACHE_ENABLED : 0, DRAWING_CACHE_ENABLED);
14501     }
14502
14503     /**
14504      * <p>Indicates whether the drawing cache is enabled for this view.</p>
14505      *
14506      * @return true if the drawing cache is enabled
14507      *
14508      * @see #setDrawingCacheEnabled(boolean)
14509      * @see #getDrawingCache()
14510      */
14511     @ViewDebug.ExportedProperty(category = "drawing")
14512     public boolean isDrawingCacheEnabled() {
14513         return (mViewFlags & DRAWING_CACHE_ENABLED) == DRAWING_CACHE_ENABLED;
14514     }
14515
14516     /**
14517      * Debugging utility which recursively outputs the dirty state of a view and its
14518      * descendants.
14519      *
14520      * @hide
14521      */
14522     @SuppressWarnings({"UnusedDeclaration"})
14523     public void outputDirtyFlags(String indent, boolean clear, int clearMask) {
14524         Log.d("View", indent + this + "             DIRTY(" + (mPrivateFlags & View.PFLAG_DIRTY_MASK) +
14525                 ") DRAWN(" + (mPrivateFlags & PFLAG_DRAWN) + ")" + " CACHE_VALID(" +
14526                 (mPrivateFlags & View.PFLAG_DRAWING_CACHE_VALID) +
14527                 ") INVALIDATED(" + (mPrivateFlags & PFLAG_INVALIDATED) + ")");
14528         if (clear) {
14529             mPrivateFlags &= clearMask;
14530         }
14531         if (this instanceof ViewGroup) {
14532             ViewGroup parent = (ViewGroup) this;
14533             final int count = parent.getChildCount();
14534             for (int i = 0; i < count; i++) {
14535                 final View child = parent.getChildAt(i);
14536                 child.outputDirtyFlags(indent + "  ", clear, clearMask);
14537             }
14538         }
14539     }
14540
14541     /**
14542      * This method is used by ViewGroup to cause its children to restore or recreate their
14543      * display lists. It is called by getDisplayList() when the parent ViewGroup does not need
14544      * to recreate its own display list, which would happen if it went through the normal
14545      * draw/dispatchDraw mechanisms.
14546      *
14547      * @hide
14548      */
14549     protected void dispatchGetDisplayList() {}
14550
14551     /**
14552      * A view that is not attached or hardware accelerated cannot create a display list.
14553      * This method checks these conditions and returns the appropriate result.
14554      *
14555      * @return true if view has the ability to create a display list, false otherwise.
14556      *
14557      * @hide
14558      */
14559     public boolean canHaveDisplayList() {
14560         return !(mAttachInfo == null || mAttachInfo.mHardwareRenderer == null);
14561     }
14562
14563     private void updateDisplayListIfDirty() {
14564         final RenderNode renderNode = mRenderNode;
14565         if (!canHaveDisplayList()) {
14566             // can't populate RenderNode, don't try
14567             return;
14568         }
14569
14570         if ((mPrivateFlags & PFLAG_DRAWING_CACHE_VALID) == 0
14571                 || !renderNode.isValid()
14572                 || (mRecreateDisplayList)) {
14573             // Don't need to recreate the display list, just need to tell our
14574             // children to restore/recreate theirs
14575             if (renderNode.isValid()
14576                     && !mRecreateDisplayList) {
14577                 mPrivateFlags |= PFLAG_DRAWN | PFLAG_DRAWING_CACHE_VALID;
14578                 mPrivateFlags &= ~PFLAG_DIRTY_MASK;
14579                 dispatchGetDisplayList();
14580
14581                 return; // no work needed
14582             }
14583
14584             // If we got here, we're recreating it. Mark it as such to ensure that
14585             // we copy in child display lists into ours in drawChild()
14586             mRecreateDisplayList = true;
14587
14588             int width = mRight - mLeft;
14589             int height = mBottom - mTop;
14590             int layerType = getLayerType();
14591
14592             final DisplayListCanvas canvas = renderNode.start(width, height);
14593             canvas.setHighContrastText(mAttachInfo.mHighContrastText);
14594
14595             try {
14596                 final HardwareLayer layer = getHardwareLayer();
14597                 if (layer != null && layer.isValid()) {
14598                     canvas.drawHardwareLayer(layer, 0, 0, mLayerPaint);
14599                 } else if (layerType == LAYER_TYPE_SOFTWARE) {
14600                     buildDrawingCache(true);
14601                     Bitmap cache = getDrawingCache(true);
14602                     if (cache != null) {
14603                         canvas.drawBitmap(cache, 0, 0, mLayerPaint);
14604                     }
14605                 } else {
14606                     computeScroll();
14607
14608                     canvas.translate(-mScrollX, -mScrollY);
14609                     mPrivateFlags |= PFLAG_DRAWN | PFLAG_DRAWING_CACHE_VALID;
14610                     mPrivateFlags &= ~PFLAG_DIRTY_MASK;
14611
14612                     // Fast path for layouts with no backgrounds
14613                     if ((mPrivateFlags & PFLAG_SKIP_DRAW) == PFLAG_SKIP_DRAW) {
14614                         dispatchDraw(canvas);
14615                         if (mOverlay != null && !mOverlay.isEmpty()) {
14616                             mOverlay.getOverlayView().draw(canvas);
14617                         }
14618                     } else {
14619                         draw(canvas);
14620                     }
14621                 }
14622             } finally {
14623                 renderNode.end(canvas);
14624                 setDisplayListProperties(renderNode);
14625             }
14626         } else {
14627             mPrivateFlags |= PFLAG_DRAWN | PFLAG_DRAWING_CACHE_VALID;
14628             mPrivateFlags &= ~PFLAG_DIRTY_MASK;
14629         }
14630     }
14631
14632     /**
14633      * Returns a RenderNode with View draw content recorded, which can be
14634      * used to draw this view again without executing its draw method.
14635      *
14636      * @return A RenderNode ready to replay, or null if caching is not enabled.
14637      *
14638      * @hide
14639      */
14640     public RenderNode getDisplayList() {
14641         updateDisplayListIfDirty();
14642         return mRenderNode;
14643     }
14644
14645     private void resetDisplayList() {
14646         if (mRenderNode.isValid()) {
14647             mRenderNode.destroyDisplayListData();
14648         }
14649
14650         if (mBackgroundRenderNode != null && mBackgroundRenderNode.isValid()) {
14651             mBackgroundRenderNode.destroyDisplayListData();
14652         }
14653     }
14654
14655     /**
14656      * <p>Calling this method is equivalent to calling <code>getDrawingCache(false)</code>.</p>
14657      *
14658      * @return A non-scaled bitmap representing this view or null if cache is disabled.
14659      *
14660      * @see #getDrawingCache(boolean)
14661      */
14662     public Bitmap getDrawingCache() {
14663         return getDrawingCache(false);
14664     }
14665
14666     /**
14667      * <p>Returns the bitmap in which this view drawing is cached. The returned bitmap
14668      * is null when caching is disabled. If caching is enabled and the cache is not ready,
14669      * this method will create it. Calling {@link #draw(android.graphics.Canvas)} will not
14670      * draw from the cache when the cache is enabled. To benefit from the cache, you must
14671      * request the drawing cache by calling this method and draw it on screen if the
14672      * returned bitmap is not null.</p>
14673      *
14674      * <p>Note about auto scaling in compatibility mode: When auto scaling is not enabled,
14675      * this method will create a bitmap of the same size as this view. Because this bitmap
14676      * will be drawn scaled by the parent ViewGroup, the result on screen might show
14677      * scaling artifacts. To avoid such artifacts, you should call this method by setting
14678      * the auto scaling to true. Doing so, however, will generate a bitmap of a different
14679      * size than the view. This implies that your application must be able to handle this
14680      * size.</p>
14681      *
14682      * @param autoScale Indicates whether the generated bitmap should be scaled based on
14683      *        the current density of the screen when the application is in compatibility
14684      *        mode.
14685      *
14686      * @return A bitmap representing this view or null if cache is disabled.
14687      *
14688      * @see #setDrawingCacheEnabled(boolean)
14689      * @see #isDrawingCacheEnabled()
14690      * @see #buildDrawingCache(boolean)
14691      * @see #destroyDrawingCache()
14692      */
14693     public Bitmap getDrawingCache(boolean autoScale) {
14694         if ((mViewFlags & WILL_NOT_CACHE_DRAWING) == WILL_NOT_CACHE_DRAWING) {
14695             return null;
14696         }
14697         if ((mViewFlags & DRAWING_CACHE_ENABLED) == DRAWING_CACHE_ENABLED) {
14698             buildDrawingCache(autoScale);
14699         }
14700         return autoScale ? mDrawingCache : mUnscaledDrawingCache;
14701     }
14702
14703     /**
14704      * <p>Frees the resources used by the drawing cache. If you call
14705      * {@link #buildDrawingCache()} manually without calling
14706      * {@link #setDrawingCacheEnabled(boolean) setDrawingCacheEnabled(true)}, you
14707      * should cleanup the cache with this method afterwards.</p>
14708      *
14709      * @see #setDrawingCacheEnabled(boolean)
14710      * @see #buildDrawingCache()
14711      * @see #getDrawingCache()
14712      */
14713     public void destroyDrawingCache() {
14714         if (mDrawingCache != null) {
14715             mDrawingCache.recycle();
14716             mDrawingCache = null;
14717         }
14718         if (mUnscaledDrawingCache != null) {
14719             mUnscaledDrawingCache.recycle();
14720             mUnscaledDrawingCache = null;
14721         }
14722     }
14723
14724     /**
14725      * Setting a solid background color for the drawing cache's bitmaps will improve
14726      * performance and memory usage. Note, though that this should only be used if this
14727      * view will always be drawn on top of a solid color.
14728      *
14729      * @param color The background color to use for the drawing cache's bitmap
14730      *
14731      * @see #setDrawingCacheEnabled(boolean)
14732      * @see #buildDrawingCache()
14733      * @see #getDrawingCache()
14734      */
14735     public void setDrawingCacheBackgroundColor(@ColorInt int color) {
14736         if (color != mDrawingCacheBackgroundColor) {
14737             mDrawingCacheBackgroundColor = color;
14738             mPrivateFlags &= ~PFLAG_DRAWING_CACHE_VALID;
14739         }
14740     }
14741
14742     /**
14743      * @see #setDrawingCacheBackgroundColor(int)
14744      *
14745      * @return The background color to used for the drawing cache's bitmap
14746      */
14747     @ColorInt
14748     public int getDrawingCacheBackgroundColor() {
14749         return mDrawingCacheBackgroundColor;
14750     }
14751
14752     /**
14753      * <p>Calling this method is equivalent to calling <code>buildDrawingCache(false)</code>.</p>
14754      *
14755      * @see #buildDrawingCache(boolean)
14756      */
14757     public void buildDrawingCache() {
14758         buildDrawingCache(false);
14759     }
14760
14761     /**
14762      * <p>Forces the drawing cache to be built if the drawing cache is invalid.</p>
14763      *
14764      * <p>If you call {@link #buildDrawingCache()} manually without calling
14765      * {@link #setDrawingCacheEnabled(boolean) setDrawingCacheEnabled(true)}, you
14766      * should cleanup the cache by calling {@link #destroyDrawingCache()} afterwards.</p>
14767      *
14768      * <p>Note about auto scaling in compatibility mode: When auto scaling is not enabled,
14769      * this method will create a bitmap of the same size as this view. Because this bitmap
14770      * will be drawn scaled by the parent ViewGroup, the result on screen might show
14771      * scaling artifacts. To avoid such artifacts, you should call this method by setting
14772      * the auto scaling to true. Doing so, however, will generate a bitmap of a different
14773      * size than the view. This implies that your application must be able to handle this
14774      * size.</p>
14775      *
14776      * <p>You should avoid calling this method when hardware acceleration is enabled. If
14777      * you do not need the drawing cache bitmap, calling this method will increase memory
14778      * usage and cause the view to be rendered in software once, thus negatively impacting
14779      * performance.</p>
14780      *
14781      * @see #getDrawingCache()
14782      * @see #destroyDrawingCache()
14783      */
14784     public void buildDrawingCache(boolean autoScale) {
14785         if ((mPrivateFlags & PFLAG_DRAWING_CACHE_VALID) == 0 || (autoScale ?
14786                 mDrawingCache == null : mUnscaledDrawingCache == null)) {
14787             if (Trace.isTagEnabled(Trace.TRACE_TAG_VIEW)) {
14788                 Trace.traceBegin(Trace.TRACE_TAG_VIEW,
14789                         "buildDrawingCache/SW Layer for " + getClass().getSimpleName());
14790             }
14791             try {
14792                 buildDrawingCacheImpl(autoScale);
14793             } finally {
14794                 Trace.traceEnd(Trace.TRACE_TAG_VIEW);
14795             }
14796         }
14797     }
14798
14799     /**
14800      * private, internal implementation of buildDrawingCache, used to enable tracing
14801      */
14802     private void buildDrawingCacheImpl(boolean autoScale) {
14803         mCachingFailed = false;
14804
14805         int width = mRight - mLeft;
14806         int height = mBottom - mTop;
14807
14808         final AttachInfo attachInfo = mAttachInfo;
14809         final boolean scalingRequired = attachInfo != null && attachInfo.mScalingRequired;
14810
14811         if (autoScale && scalingRequired) {
14812             width = (int) ((width * attachInfo.mApplicationScale) + 0.5f);
14813             height = (int) ((height * attachInfo.mApplicationScale) + 0.5f);
14814         }
14815
14816         final int drawingCacheBackgroundColor = mDrawingCacheBackgroundColor;
14817         final boolean opaque = drawingCacheBackgroundColor != 0 || isOpaque();
14818         final boolean use32BitCache = attachInfo != null && attachInfo.mUse32BitDrawingCache;
14819
14820         final long projectedBitmapSize = width * height * (opaque && !use32BitCache ? 2 : 4);
14821         final long drawingCacheSize =
14822                 ViewConfiguration.get(mContext).getScaledMaximumDrawingCacheSize();
14823         if (width <= 0 || height <= 0 || projectedBitmapSize > drawingCacheSize) {
14824             if (width > 0 && height > 0) {
14825                 Log.w(VIEW_LOG_TAG, "View too large to fit into drawing cache, needs "
14826                         + projectedBitmapSize + " bytes, only "
14827                         + drawingCacheSize + " available");
14828             }
14829             destroyDrawingCache();
14830             mCachingFailed = true;
14831             return;
14832         }
14833
14834         boolean clear = true;
14835         Bitmap bitmap = autoScale ? mDrawingCache : mUnscaledDrawingCache;
14836
14837         if (bitmap == null || bitmap.getWidth() != width || bitmap.getHeight() != height) {
14838             Bitmap.Config quality;
14839             if (!opaque) {
14840                 // Never pick ARGB_4444 because it looks awful
14841                 // Keep the DRAWING_CACHE_QUALITY_LOW flag just in case
14842                 switch (mViewFlags & DRAWING_CACHE_QUALITY_MASK) {
14843                     case DRAWING_CACHE_QUALITY_AUTO:
14844                     case DRAWING_CACHE_QUALITY_LOW:
14845                     case DRAWING_CACHE_QUALITY_HIGH:
14846                     default:
14847                         quality = Bitmap.Config.ARGB_8888;
14848                         break;
14849                 }
14850             } else {
14851                 // Optimization for translucent windows
14852                 // If the window is translucent, use a 32 bits bitmap to benefit from memcpy()
14853                 quality = use32BitCache ? Bitmap.Config.ARGB_8888 : Bitmap.Config.RGB_565;
14854             }
14855
14856             // Try to cleanup memory
14857             if (bitmap != null) bitmap.recycle();
14858
14859             try {
14860                 bitmap = Bitmap.createBitmap(mResources.getDisplayMetrics(),
14861                         width, height, quality);
14862                 bitmap.setDensity(getResources().getDisplayMetrics().densityDpi);
14863                 if (autoScale) {
14864                     mDrawingCache = bitmap;
14865                 } else {
14866                     mUnscaledDrawingCache = bitmap;
14867                 }
14868                 if (opaque && use32BitCache) bitmap.setHasAlpha(false);
14869             } catch (OutOfMemoryError e) {
14870                 // If there is not enough memory to create the bitmap cache, just
14871                 // ignore the issue as bitmap caches are not required to draw the
14872                 // view hierarchy
14873                 if (autoScale) {
14874                     mDrawingCache = null;
14875                 } else {
14876                     mUnscaledDrawingCache = null;
14877                 }
14878                 mCachingFailed = true;
14879                 return;
14880             }
14881
14882             clear = drawingCacheBackgroundColor != 0;
14883         }
14884
14885         Canvas canvas;
14886         if (attachInfo != null) {
14887             canvas = attachInfo.mCanvas;
14888             if (canvas == null) {
14889                 canvas = new Canvas();
14890             }
14891             canvas.setBitmap(bitmap);
14892             // Temporarily clobber the cached Canvas in case one of our children
14893             // is also using a drawing cache. Without this, the children would
14894             // steal the canvas by attaching their own bitmap to it and bad, bad
14895             // thing would happen (invisible views, corrupted drawings, etc.)
14896             attachInfo.mCanvas = null;
14897         } else {
14898             // This case should hopefully never or seldom happen
14899             canvas = new Canvas(bitmap);
14900         }
14901
14902         if (clear) {
14903             bitmap.eraseColor(drawingCacheBackgroundColor);
14904         }
14905
14906         computeScroll();
14907         final int restoreCount = canvas.save();
14908
14909         if (autoScale && scalingRequired) {
14910             final float scale = attachInfo.mApplicationScale;
14911             canvas.scale(scale, scale);
14912         }
14913
14914         canvas.translate(-mScrollX, -mScrollY);
14915
14916         mPrivateFlags |= PFLAG_DRAWN;
14917         if (mAttachInfo == null || !mAttachInfo.mHardwareAccelerated ||
14918                 mLayerType != LAYER_TYPE_NONE) {
14919             mPrivateFlags |= PFLAG_DRAWING_CACHE_VALID;
14920         }
14921
14922         // Fast path for layouts with no backgrounds
14923         if ((mPrivateFlags & PFLAG_SKIP_DRAW) == PFLAG_SKIP_DRAW) {
14924             mPrivateFlags &= ~PFLAG_DIRTY_MASK;
14925             dispatchDraw(canvas);
14926             if (mOverlay != null && !mOverlay.isEmpty()) {
14927                 mOverlay.getOverlayView().draw(canvas);
14928             }
14929         } else {
14930             draw(canvas);
14931         }
14932
14933         canvas.restoreToCount(restoreCount);
14934         canvas.setBitmap(null);
14935
14936         if (attachInfo != null) {
14937             // Restore the cached Canvas for our siblings
14938             attachInfo.mCanvas = canvas;
14939         }
14940     }
14941
14942     /**
14943      * Create a snapshot of the view into a bitmap.  We should probably make
14944      * some form of this public, but should think about the API.
14945      */
14946     Bitmap createSnapshot(Bitmap.Config quality, int backgroundColor, boolean skipChildren) {
14947         int width = mRight - mLeft;
14948         int height = mBottom - mTop;
14949
14950         final AttachInfo attachInfo = mAttachInfo;
14951         final float scale = attachInfo != null ? attachInfo.mApplicationScale : 1.0f;
14952         width = (int) ((width * scale) + 0.5f);
14953         height = (int) ((height * scale) + 0.5f);
14954
14955         Bitmap bitmap = Bitmap.createBitmap(mResources.getDisplayMetrics(),
14956                 width > 0 ? width : 1, height > 0 ? height : 1, quality);
14957         if (bitmap == null) {
14958             throw new OutOfMemoryError();
14959         }
14960
14961         Resources resources = getResources();
14962         if (resources != null) {
14963             bitmap.setDensity(resources.getDisplayMetrics().densityDpi);
14964         }
14965
14966         Canvas canvas;
14967         if (attachInfo != null) {
14968             canvas = attachInfo.mCanvas;
14969             if (canvas == null) {
14970                 canvas = new Canvas();
14971             }
14972             canvas.setBitmap(bitmap);
14973             // Temporarily clobber the cached Canvas in case one of our children
14974             // is also using a drawing cache. Without this, the children would
14975             // steal the canvas by attaching their own bitmap to it and bad, bad
14976             // things would happen (invisible views, corrupted drawings, etc.)
14977             attachInfo.mCanvas = null;
14978         } else {
14979             // This case should hopefully never or seldom happen
14980             canvas = new Canvas(bitmap);
14981         }
14982
14983         if ((backgroundColor & 0xff000000) != 0) {
14984             bitmap.eraseColor(backgroundColor);
14985         }
14986
14987         computeScroll();
14988         final int restoreCount = canvas.save();
14989         canvas.scale(scale, scale);
14990         canvas.translate(-mScrollX, -mScrollY);
14991
14992         // Temporarily remove the dirty mask
14993         int flags = mPrivateFlags;
14994         mPrivateFlags &= ~PFLAG_DIRTY_MASK;
14995
14996         // Fast path for layouts with no backgrounds
14997         if ((mPrivateFlags & PFLAG_SKIP_DRAW) == PFLAG_SKIP_DRAW) {
14998             dispatchDraw(canvas);
14999             if (mOverlay != null && !mOverlay.isEmpty()) {
15000                 mOverlay.getOverlayView().draw(canvas);
15001             }
15002         } else {
15003             draw(canvas);
15004         }
15005
15006         mPrivateFlags = flags;
15007
15008         canvas.restoreToCount(restoreCount);
15009         canvas.setBitmap(null);
15010
15011         if (attachInfo != null) {
15012             // Restore the cached Canvas for our siblings
15013             attachInfo.mCanvas = canvas;
15014         }
15015
15016         return bitmap;
15017     }
15018
15019     /**
15020      * Indicates whether this View is currently in edit mode. A View is usually
15021      * in edit mode when displayed within a developer tool. For instance, if
15022      * this View is being drawn by a visual user interface builder, this method
15023      * should return true.
15024      *
15025      * Subclasses should check the return value of this method to provide
15026      * different behaviors if their normal behavior might interfere with the
15027      * host environment. For instance: the class spawns a thread in its
15028      * constructor, the drawing code relies on device-specific features, etc.
15029      *
15030      * This method is usually checked in the drawing code of custom widgets.
15031      *
15032      * @return True if this View is in edit mode, false otherwise.
15033      */
15034     public boolean isInEditMode() {
15035         return false;
15036     }
15037
15038     /**
15039      * If the View draws content inside its padding and enables fading edges,
15040      * it needs to support padding offsets. Padding offsets are added to the
15041      * fading edges to extend the length of the fade so that it covers pixels
15042      * drawn inside the padding.
15043      *
15044      * Subclasses of this class should override this method if they need
15045      * to draw content inside the padding.
15046      *
15047      * @return True if padding offset must be applied, false otherwise.
15048      *
15049      * @see #getLeftPaddingOffset()
15050      * @see #getRightPaddingOffset()
15051      * @see #getTopPaddingOffset()
15052      * @see #getBottomPaddingOffset()
15053      *
15054      * @since CURRENT
15055      */
15056     protected boolean isPaddingOffsetRequired() {
15057         return false;
15058     }
15059
15060     /**
15061      * Amount by which to extend the left fading region. Called only when
15062      * {@link #isPaddingOffsetRequired()} returns true.
15063      *
15064      * @return The left padding offset in pixels.
15065      *
15066      * @see #isPaddingOffsetRequired()
15067      *
15068      * @since CURRENT
15069      */
15070     protected int getLeftPaddingOffset() {
15071         return 0;
15072     }
15073
15074     /**
15075      * Amount by which to extend the right fading region. Called only when
15076      * {@link #isPaddingOffsetRequired()} returns true.
15077      *
15078      * @return The right padding offset in pixels.
15079      *
15080      * @see #isPaddingOffsetRequired()
15081      *
15082      * @since CURRENT
15083      */
15084     protected int getRightPaddingOffset() {
15085         return 0;
15086     }
15087
15088     /**
15089      * Amount by which to extend the top fading region. Called only when
15090      * {@link #isPaddingOffsetRequired()} returns true.
15091      *
15092      * @return The top padding offset in pixels.
15093      *
15094      * @see #isPaddingOffsetRequired()
15095      *
15096      * @since CURRENT
15097      */
15098     protected int getTopPaddingOffset() {
15099         return 0;
15100     }
15101
15102     /**
15103      * Amount by which to extend the bottom fading region. Called only when
15104      * {@link #isPaddingOffsetRequired()} returns true.
15105      *
15106      * @return The bottom padding offset in pixels.
15107      *
15108      * @see #isPaddingOffsetRequired()
15109      *
15110      * @since CURRENT
15111      */
15112     protected int getBottomPaddingOffset() {
15113         return 0;
15114     }
15115
15116     /**
15117      * @hide
15118      * @param offsetRequired
15119      */
15120     protected int getFadeTop(boolean offsetRequired) {
15121         int top = mPaddingTop;
15122         if (offsetRequired) top += getTopPaddingOffset();
15123         return top;
15124     }
15125
15126     /**
15127      * @hide
15128      * @param offsetRequired
15129      */
15130     protected int getFadeHeight(boolean offsetRequired) {
15131         int padding = mPaddingTop;
15132         if (offsetRequired) padding += getTopPaddingOffset();
15133         return mBottom - mTop - mPaddingBottom - padding;
15134     }
15135
15136     /**
15137      * <p>Indicates whether this view is attached to a hardware accelerated
15138      * window or not.</p>
15139      *
15140      * <p>Even if this method returns true, it does not mean that every call
15141      * to {@link #draw(android.graphics.Canvas)} will be made with an hardware
15142      * accelerated {@link android.graphics.Canvas}. For instance, if this view
15143      * is drawn onto an offscreen {@link android.graphics.Bitmap} and its
15144      * window is hardware accelerated,
15145      * {@link android.graphics.Canvas#isHardwareAccelerated()} will likely
15146      * return false, and this method will return true.</p>
15147      *
15148      * @return True if the view is attached to a window and the window is
15149      *         hardware accelerated; false in any other case.
15150      */
15151     @ViewDebug.ExportedProperty(category = "drawing")
15152     public boolean isHardwareAccelerated() {
15153         return mAttachInfo != null && mAttachInfo.mHardwareAccelerated;
15154     }
15155
15156     /**
15157      * Sets a rectangular area on this view to which the view will be clipped
15158      * when it is drawn. Setting the value to null will remove the clip bounds
15159      * and the view will draw normally, using its full bounds.
15160      *
15161      * @param clipBounds The rectangular area, in the local coordinates of
15162      * this view, to which future drawing operations will be clipped.
15163      */
15164     public void setClipBounds(Rect clipBounds) {
15165         if (clipBounds == mClipBounds
15166                 || (clipBounds != null && clipBounds.equals(mClipBounds))) {
15167             return;
15168         }
15169         if (clipBounds != null) {
15170             if (mClipBounds == null) {
15171                 mClipBounds = new Rect(clipBounds);
15172             } else {
15173                 mClipBounds.set(clipBounds);
15174             }
15175         } else {
15176             mClipBounds = null;
15177         }
15178         mRenderNode.setClipBounds(mClipBounds);
15179         invalidateViewProperty(false, false);
15180     }
15181
15182     /**
15183      * Returns a copy of the current {@link #setClipBounds(Rect) clipBounds}.
15184      *
15185      * @return A copy of the current clip bounds if clip bounds are set,
15186      * otherwise null.
15187      */
15188     public Rect getClipBounds() {
15189         return (mClipBounds != null) ? new Rect(mClipBounds) : null;
15190     }
15191
15192
15193     /**
15194      * Populates an output rectangle with the clip bounds of the view,
15195      * returning {@code true} if successful or {@code false} if the view's
15196      * clip bounds are {@code null}.
15197      *
15198      * @param outRect rectangle in which to place the clip bounds of the view
15199      * @return {@code true} if successful or {@code false} if the view's
15200      *         clip bounds are {@code null}
15201      */
15202     public boolean getClipBounds(Rect outRect) {
15203         if (mClipBounds != null) {
15204             outRect.set(mClipBounds);
15205             return true;
15206         }
15207         return false;
15208     }
15209
15210     /**
15211      * Utility function, called by draw(canvas, parent, drawingTime) to handle the less common
15212      * case of an active Animation being run on the view.
15213      */
15214     private boolean applyLegacyAnimation(ViewGroup parent, long drawingTime,
15215             Animation a, boolean scalingRequired) {
15216         Transformation invalidationTransform;
15217         final int flags = parent.mGroupFlags;
15218         final boolean initialized = a.isInitialized();
15219         if (!initialized) {
15220             a.initialize(mRight - mLeft, mBottom - mTop, parent.getWidth(), parent.getHeight());
15221             a.initializeInvalidateRegion(0, 0, mRight - mLeft, mBottom - mTop);
15222             if (mAttachInfo != null) a.setListenerHandler(mAttachInfo.mHandler);
15223             onAnimationStart();
15224         }
15225
15226         final Transformation t = parent.getChildTransformation();
15227         boolean more = a.getTransformation(drawingTime, t, 1f);
15228         if (scalingRequired && mAttachInfo.mApplicationScale != 1f) {
15229             if (parent.mInvalidationTransformation == null) {
15230                 parent.mInvalidationTransformation = new Transformation();
15231             }
15232             invalidationTransform = parent.mInvalidationTransformation;
15233             a.getTransformation(drawingTime, invalidationTransform, 1f);
15234         } else {
15235             invalidationTransform = t;
15236         }
15237
15238         if (more) {
15239             if (!a.willChangeBounds()) {
15240                 if ((flags & (ViewGroup.FLAG_OPTIMIZE_INVALIDATE | ViewGroup.FLAG_ANIMATION_DONE)) ==
15241                         ViewGroup.FLAG_OPTIMIZE_INVALIDATE) {
15242                     parent.mGroupFlags |= ViewGroup.FLAG_INVALIDATE_REQUIRED;
15243                 } else if ((flags & ViewGroup.FLAG_INVALIDATE_REQUIRED) == 0) {
15244                     // The child need to draw an animation, potentially offscreen, so
15245                     // make sure we do not cancel invalidate requests
15246                     parent.mPrivateFlags |= PFLAG_DRAW_ANIMATION;
15247                     parent.invalidate(mLeft, mTop, mRight, mBottom);
15248                 }
15249             } else {
15250                 if (parent.mInvalidateRegion == null) {
15251                     parent.mInvalidateRegion = new RectF();
15252                 }
15253                 final RectF region = parent.mInvalidateRegion;
15254                 a.getInvalidateRegion(0, 0, mRight - mLeft, mBottom - mTop, region,
15255                         invalidationTransform);
15256
15257                 // The child need to draw an animation, potentially offscreen, so
15258                 // make sure we do not cancel invalidate requests
15259                 parent.mPrivateFlags |= PFLAG_DRAW_ANIMATION;
15260
15261                 final int left = mLeft + (int) region.left;
15262                 final int top = mTop + (int) region.top;
15263                 parent.invalidate(left, top, left + (int) (region.width() + .5f),
15264                         top + (int) (region.height() + .5f));
15265             }
15266         }
15267         return more;
15268     }
15269
15270     /**
15271      * This method is called by getDisplayList() when a display list is recorded for a View.
15272      * It pushes any properties to the RenderNode that aren't managed by the RenderNode.
15273      */
15274     void setDisplayListProperties(RenderNode renderNode) {
15275         if (renderNode != null) {
15276             renderNode.setHasOverlappingRendering(hasOverlappingRendering());
15277             renderNode.setClipToBounds(mParent instanceof ViewGroup
15278                     && ((ViewGroup) mParent).getClipChildren());
15279
15280             float alpha = 1;
15281             if (mParent instanceof ViewGroup && (((ViewGroup) mParent).mGroupFlags &
15282                     ViewGroup.FLAG_SUPPORT_STATIC_TRANSFORMATIONS) != 0) {
15283                 ViewGroup parentVG = (ViewGroup) mParent;
15284                 final Transformation t = parentVG.getChildTransformation();
15285                 if (parentVG.getChildStaticTransformation(this, t)) {
15286                     final int transformType = t.getTransformationType();
15287                     if (transformType != Transformation.TYPE_IDENTITY) {
15288                         if ((transformType & Transformation.TYPE_ALPHA) != 0) {
15289                             alpha = t.getAlpha();
15290                         }
15291                         if ((transformType & Transformation.TYPE_MATRIX) != 0) {
15292                             renderNode.setStaticMatrix(t.getMatrix());
15293                         }
15294                     }
15295                 }
15296             }
15297             if (mTransformationInfo != null) {
15298                 alpha *= getFinalAlpha();
15299                 if (alpha < 1) {
15300                     final int multipliedAlpha = (int) (255 * alpha);
15301                     if (onSetAlpha(multipliedAlpha)) {
15302                         alpha = 1;
15303                     }
15304                 }
15305                 renderNode.setAlpha(alpha);
15306             } else if (alpha < 1) {
15307                 renderNode.setAlpha(alpha);
15308             }
15309         }
15310     }
15311
15312     /**
15313      * This method is called by ViewGroup.drawChild() to have each child view draw itself.
15314      *
15315      * This is where the View specializes rendering behavior based on layer type,
15316      * and hardware acceleration.
15317      */
15318     boolean draw(Canvas canvas, ViewGroup parent, long drawingTime) {
15319         final boolean hardwareAcceleratedCanvas = canvas.isHardwareAccelerated();
15320         /* If an attached view draws to a HW canvas, it may use its RenderNode + DisplayList.
15321          *
15322          * If a view is dettached, its DisplayList shouldn't exist. If the canvas isn't
15323          * HW accelerated, it can't handle drawing RenderNodes.
15324          */
15325         boolean drawingWithRenderNode = mAttachInfo != null
15326                 && mAttachInfo.mHardwareAccelerated
15327                 && hardwareAcceleratedCanvas;
15328
15329         boolean more = false;
15330         final boolean childHasIdentityMatrix = hasIdentityMatrix();
15331         final int parentFlags = parent.mGroupFlags;
15332
15333         if ((parentFlags & ViewGroup.FLAG_CLEAR_TRANSFORMATION) != 0) {
15334             parent.getChildTransformation().clear();
15335             parent.mGroupFlags &= ~ViewGroup.FLAG_CLEAR_TRANSFORMATION;
15336         }
15337
15338         Transformation transformToApply = null;
15339         boolean concatMatrix = false;
15340         final boolean scalingRequired = mAttachInfo != null && mAttachInfo.mScalingRequired;
15341         final Animation a = getAnimation();
15342         if (a != null) {
15343             more = applyLegacyAnimation(parent, drawingTime, a, scalingRequired);
15344             concatMatrix = a.willChangeTransformationMatrix();
15345             if (concatMatrix) {
15346                 mPrivateFlags3 |= PFLAG3_VIEW_IS_ANIMATING_TRANSFORM;
15347             }
15348             transformToApply = parent.getChildTransformation();
15349         } else {
15350             if ((mPrivateFlags3 & PFLAG3_VIEW_IS_ANIMATING_TRANSFORM) != 0) {
15351                 // No longer animating: clear out old animation matrix
15352                 mRenderNode.setAnimationMatrix(null);
15353                 mPrivateFlags3 &= ~PFLAG3_VIEW_IS_ANIMATING_TRANSFORM;
15354             }
15355             if (!drawingWithRenderNode
15356                     && (parentFlags & ViewGroup.FLAG_SUPPORT_STATIC_TRANSFORMATIONS) != 0) {
15357                 final Transformation t = parent.getChildTransformation();
15358                 final boolean hasTransform = parent.getChildStaticTransformation(this, t);
15359                 if (hasTransform) {
15360                     final int transformType = t.getTransformationType();
15361                     transformToApply = transformType != Transformation.TYPE_IDENTITY ? t : null;
15362                     concatMatrix = (transformType & Transformation.TYPE_MATRIX) != 0;
15363                 }
15364             }
15365         }
15366
15367         concatMatrix |= !childHasIdentityMatrix;
15368
15369         // Sets the flag as early as possible to allow draw() implementations
15370         // to call invalidate() successfully when doing animations
15371         mPrivateFlags |= PFLAG_DRAWN;
15372
15373         if (!concatMatrix &&
15374                 (parentFlags & (ViewGroup.FLAG_SUPPORT_STATIC_TRANSFORMATIONS |
15375                         ViewGroup.FLAG_CLIP_CHILDREN)) == ViewGroup.FLAG_CLIP_CHILDREN &&
15376                 canvas.quickReject(mLeft, mTop, mRight, mBottom, Canvas.EdgeType.BW) &&
15377                 (mPrivateFlags & PFLAG_DRAW_ANIMATION) == 0) {
15378             mPrivateFlags2 |= PFLAG2_VIEW_QUICK_REJECTED;
15379             return more;
15380         }
15381         mPrivateFlags2 &= ~PFLAG2_VIEW_QUICK_REJECTED;
15382
15383         if (hardwareAcceleratedCanvas) {
15384             // Clear INVALIDATED flag to allow invalidation to occur during rendering, but
15385             // retain the flag's value temporarily in the mRecreateDisplayList flag
15386             mRecreateDisplayList = (mPrivateFlags & PFLAG_INVALIDATED) != 0;
15387             mPrivateFlags &= ~PFLAG_INVALIDATED;
15388         }
15389
15390         RenderNode renderNode = null;
15391         Bitmap cache = null;
15392         int layerType = getLayerType(); // TODO: signify cache state with just 'cache' local
15393         if (layerType == LAYER_TYPE_SOFTWARE
15394                 || (!drawingWithRenderNode && layerType != LAYER_TYPE_NONE)) {
15395             // If not drawing with RenderNode, treat HW layers as SW
15396             layerType = LAYER_TYPE_SOFTWARE;
15397             buildDrawingCache(true);
15398             cache = getDrawingCache(true);
15399         }
15400
15401         if (drawingWithRenderNode) {
15402             // Delay getting the display list until animation-driven alpha values are
15403             // set up and possibly passed on to the view
15404             renderNode = getDisplayList();
15405             if (!renderNode.isValid()) {
15406                 // Uncommon, but possible. If a view is removed from the hierarchy during the call
15407                 // to getDisplayList(), the display list will be marked invalid and we should not
15408                 // try to use it again.
15409                 renderNode = null;
15410                 drawingWithRenderNode = false;
15411             }
15412         }
15413
15414         int sx = 0;
15415         int sy = 0;
15416         if (!drawingWithRenderNode) {
15417             computeScroll();
15418             sx = mScrollX;
15419             sy = mScrollY;
15420         }
15421
15422         final boolean drawingWithDrawingCache = cache != null && !drawingWithRenderNode;
15423         final boolean offsetForScroll = cache == null && !drawingWithRenderNode;
15424
15425         int restoreTo = -1;
15426         if (!drawingWithRenderNode || transformToApply != null) {
15427             restoreTo = canvas.save();
15428         }
15429         if (offsetForScroll) {
15430             canvas.translate(mLeft - sx, mTop - sy);
15431         } else {
15432             if (!drawingWithRenderNode) {
15433                 canvas.translate(mLeft, mTop);
15434             }
15435             if (scalingRequired) {
15436                 if (drawingWithRenderNode) {
15437                     // TODO: Might not need this if we put everything inside the DL
15438                     restoreTo = canvas.save();
15439                 }
15440                 // mAttachInfo cannot be null, otherwise scalingRequired == false
15441                 final float scale = 1.0f / mAttachInfo.mApplicationScale;
15442                 canvas.scale(scale, scale);
15443             }
15444         }
15445
15446         float alpha = drawingWithRenderNode ? 1 : (getAlpha() * getTransitionAlpha());
15447         if (transformToApply != null
15448                 || alpha < 1
15449                 || !hasIdentityMatrix()
15450                 || (mPrivateFlags3 & PFLAG3_VIEW_IS_ANIMATING_ALPHA) != 0) {
15451             if (transformToApply != null || !childHasIdentityMatrix) {
15452                 int transX = 0;
15453                 int transY = 0;
15454
15455                 if (offsetForScroll) {
15456                     transX = -sx;
15457                     transY = -sy;
15458                 }
15459
15460                 if (transformToApply != null) {
15461                     if (concatMatrix) {
15462                         if (drawingWithRenderNode) {
15463                             renderNode.setAnimationMatrix(transformToApply.getMatrix());
15464                         } else {
15465                             // Undo the scroll translation, apply the transformation matrix,
15466                             // then redo the scroll translate to get the correct result.
15467                             canvas.translate(-transX, -transY);
15468                             canvas.concat(transformToApply.getMatrix());
15469                             canvas.translate(transX, transY);
15470                         }
15471                         parent.mGroupFlags |= ViewGroup.FLAG_CLEAR_TRANSFORMATION;
15472                     }
15473
15474                     float transformAlpha = transformToApply.getAlpha();
15475                     if (transformAlpha < 1) {
15476                         alpha *= transformAlpha;
15477                         parent.mGroupFlags |= ViewGroup.FLAG_CLEAR_TRANSFORMATION;
15478                     }
15479                 }
15480
15481                 if (!childHasIdentityMatrix && !drawingWithRenderNode) {
15482                     canvas.translate(-transX, -transY);
15483                     canvas.concat(getMatrix());
15484                     canvas.translate(transX, transY);
15485                 }
15486             }
15487
15488             // Deal with alpha if it is or used to be <1
15489             if (alpha < 1 || (mPrivateFlags3 & PFLAG3_VIEW_IS_ANIMATING_ALPHA) != 0) {
15490                 if (alpha < 1) {
15491                     mPrivateFlags3 |= PFLAG3_VIEW_IS_ANIMATING_ALPHA;
15492                 } else {
15493                     mPrivateFlags3 &= ~PFLAG3_VIEW_IS_ANIMATING_ALPHA;
15494                 }
15495                 parent.mGroupFlags |= ViewGroup.FLAG_CLEAR_TRANSFORMATION;
15496                 if (!drawingWithDrawingCache) {
15497                     final int multipliedAlpha = (int) (255 * alpha);
15498                     if (!onSetAlpha(multipliedAlpha)) {
15499                         if (drawingWithRenderNode) {
15500                             renderNode.setAlpha(alpha * getAlpha() * getTransitionAlpha());
15501                         } else if (layerType == LAYER_TYPE_NONE) {
15502                             int layerFlags = Canvas.HAS_ALPHA_LAYER_SAVE_FLAG;
15503                             if ((parentFlags & ViewGroup.FLAG_CLIP_CHILDREN) != 0) {
15504                                 layerFlags |= Canvas.CLIP_TO_LAYER_SAVE_FLAG;
15505                             }
15506                             canvas.saveLayerAlpha(sx, sy, sx + getWidth(), sy + getHeight(),
15507                                     multipliedAlpha, layerFlags);
15508                         }
15509                     } else {
15510                         // Alpha is handled by the child directly, clobber the layer's alpha
15511                         mPrivateFlags |= PFLAG_ALPHA_SET;
15512                     }
15513                 }
15514             }
15515         } else if ((mPrivateFlags & PFLAG_ALPHA_SET) == PFLAG_ALPHA_SET) {
15516             onSetAlpha(255);
15517             mPrivateFlags &= ~PFLAG_ALPHA_SET;
15518         }
15519
15520         if (!drawingWithRenderNode) {
15521             // apply clips directly, since RenderNode won't do it for this draw
15522             if ((parentFlags & ViewGroup.FLAG_CLIP_CHILDREN) != 0 && cache == null) {
15523                 if (offsetForScroll) {
15524                     canvas.clipRect(sx, sy, sx + getWidth(), sy + getHeight());
15525                 } else {
15526                     if (!scalingRequired || cache == null) {
15527                         canvas.clipRect(0, 0, getWidth(), getHeight());
15528                     } else {
15529                         canvas.clipRect(0, 0, cache.getWidth(), cache.getHeight());
15530                     }
15531                 }
15532             }
15533
15534             if (mClipBounds != null) {
15535                 // clip bounds ignore scroll
15536                 canvas.clipRect(mClipBounds);
15537             }
15538         }
15539
15540         if (!drawingWithDrawingCache) {
15541             if (drawingWithRenderNode) {
15542                 mPrivateFlags &= ~PFLAG_DIRTY_MASK;
15543                 ((DisplayListCanvas) canvas).drawRenderNode(renderNode);
15544             } else {
15545                 // Fast path for layouts with no backgrounds
15546                 if ((mPrivateFlags & PFLAG_SKIP_DRAW) == PFLAG_SKIP_DRAW) {
15547                     mPrivateFlags &= ~PFLAG_DIRTY_MASK;
15548                     dispatchDraw(canvas);
15549                 } else {
15550                     draw(canvas);
15551                 }
15552             }
15553         } else if (cache != null) {
15554             mPrivateFlags &= ~PFLAG_DIRTY_MASK;
15555             Paint cachePaint;
15556             int restoreAlpha = 0;
15557
15558             if (layerType == LAYER_TYPE_NONE) {
15559                 cachePaint = parent.mCachePaint;
15560                 if (cachePaint == null) {
15561                     cachePaint = new Paint();
15562                     cachePaint.setDither(false);
15563                     parent.mCachePaint = cachePaint;
15564                 }
15565             } else {
15566                 cachePaint = mLayerPaint;
15567                 restoreAlpha = mLayerPaint.getAlpha();
15568             }
15569             cachePaint.setAlpha((int) (alpha * 255));
15570             canvas.drawBitmap(cache, 0.0f, 0.0f, cachePaint);
15571             cachePaint.setAlpha(restoreAlpha);
15572         }
15573
15574         if (restoreTo >= 0) {
15575             canvas.restoreToCount(restoreTo);
15576         }
15577
15578         if (a != null && !more) {
15579             if (!hardwareAcceleratedCanvas && !a.getFillAfter()) {
15580                 onSetAlpha(255);
15581             }
15582             parent.finishAnimatingView(this, a);
15583         }
15584
15585         if (more && hardwareAcceleratedCanvas) {
15586             if (a.hasAlpha() && (mPrivateFlags & PFLAG_ALPHA_SET) == PFLAG_ALPHA_SET) {
15587                 // alpha animations should cause the child to recreate its display list
15588                 invalidate(true);
15589             }
15590         }
15591
15592         mRecreateDisplayList = false;
15593
15594         return more;
15595     }
15596
15597     /**
15598      * Manually render this view (and all of its children) to the given Canvas.
15599      * The view must have already done a full layout before this function is
15600      * called.  When implementing a view, implement
15601      * {@link #onDraw(android.graphics.Canvas)} instead of overriding this method.
15602      * If you do need to override this method, call the superclass version.
15603      *
15604      * @param canvas The Canvas to which the View is rendered.
15605      */
15606     @CallSuper
15607     public void draw(Canvas canvas) {
15608         final int privateFlags = mPrivateFlags;
15609         final boolean dirtyOpaque = (privateFlags & PFLAG_DIRTY_MASK) == PFLAG_DIRTY_OPAQUE &&
15610                 (mAttachInfo == null || !mAttachInfo.mIgnoreDirtyState);
15611         mPrivateFlags = (privateFlags & ~PFLAG_DIRTY_MASK) | PFLAG_DRAWN;
15612
15613         /*
15614          * Draw traversal performs several drawing steps which must be executed
15615          * in the appropriate order:
15616          *
15617          *      1. Draw the background
15618          *      2. If necessary, save the canvas' layers to prepare for fading
15619          *      3. Draw view's content
15620          *      4. Draw children
15621          *      5. If necessary, draw the fading edges and restore layers
15622          *      6. Draw decorations (scrollbars for instance)
15623          */
15624
15625         // Step 1, draw the background, if needed
15626         int saveCount;
15627
15628         if (!dirtyOpaque) {
15629             drawBackground(canvas);
15630         }
15631
15632         // skip step 2 & 5 if possible (common case)
15633         final int viewFlags = mViewFlags;
15634         boolean horizontalEdges = (viewFlags & FADING_EDGE_HORIZONTAL) != 0;
15635         boolean verticalEdges = (viewFlags & FADING_EDGE_VERTICAL) != 0;
15636         if (!verticalEdges && !horizontalEdges) {
15637             // Step 3, draw the content
15638             if (!dirtyOpaque) onDraw(canvas);
15639
15640             // Step 4, draw the children
15641             dispatchDraw(canvas);
15642
15643             // Overlay is part of the content and draws beneath Foreground
15644             if (mOverlay != null && !mOverlay.isEmpty()) {
15645                 mOverlay.getOverlayView().dispatchDraw(canvas);
15646             }
15647
15648             // Step 6, draw decorations (foreground, scrollbars)
15649             onDrawForeground(canvas);
15650
15651             // we're done...
15652             return;
15653         }
15654
15655         /*
15656          * Here we do the full fledged routine...
15657          * (this is an uncommon case where speed matters less,
15658          * this is why we repeat some of the tests that have been
15659          * done above)
15660          */
15661
15662         boolean drawTop = false;
15663         boolean drawBottom = false;
15664         boolean drawLeft = false;
15665         boolean drawRight = false;
15666
15667         float topFadeStrength = 0.0f;
15668         float bottomFadeStrength = 0.0f;
15669         float leftFadeStrength = 0.0f;
15670         float rightFadeStrength = 0.0f;
15671
15672         // Step 2, save the canvas' layers
15673         int paddingLeft = mPaddingLeft;
15674
15675         final boolean offsetRequired = isPaddingOffsetRequired();
15676         if (offsetRequired) {
15677             paddingLeft += getLeftPaddingOffset();
15678         }
15679
15680         int left = mScrollX + paddingLeft;
15681         int right = left + mRight - mLeft - mPaddingRight - paddingLeft;
15682         int top = mScrollY + getFadeTop(offsetRequired);
15683         int bottom = top + getFadeHeight(offsetRequired);
15684
15685         if (offsetRequired) {
15686             right += getRightPaddingOffset();
15687             bottom += getBottomPaddingOffset();
15688         }
15689
15690         final ScrollabilityCache scrollabilityCache = mScrollCache;
15691         final float fadeHeight = scrollabilityCache.fadingEdgeLength;
15692         int length = (int) fadeHeight;
15693
15694         // clip the fade length if top and bottom fades overlap
15695         // overlapping fades produce odd-looking artifacts
15696         if (verticalEdges && (top + length > bottom - length)) {
15697             length = (bottom - top) / 2;
15698         }
15699
15700         // also clip horizontal fades if necessary
15701         if (horizontalEdges && (left + length > right - length)) {
15702             length = (right - left) / 2;
15703         }
15704
15705         if (verticalEdges) {
15706             topFadeStrength = Math.max(0.0f, Math.min(1.0f, getTopFadingEdgeStrength()));
15707             drawTop = topFadeStrength * fadeHeight > 1.0f;
15708             bottomFadeStrength = Math.max(0.0f, Math.min(1.0f, getBottomFadingEdgeStrength()));
15709             drawBottom = bottomFadeStrength * fadeHeight > 1.0f;
15710         }
15711
15712         if (horizontalEdges) {
15713             leftFadeStrength = Math.max(0.0f, Math.min(1.0f, getLeftFadingEdgeStrength()));
15714             drawLeft = leftFadeStrength * fadeHeight > 1.0f;
15715             rightFadeStrength = Math.max(0.0f, Math.min(1.0f, getRightFadingEdgeStrength()));
15716             drawRight = rightFadeStrength * fadeHeight > 1.0f;
15717         }
15718
15719         saveCount = canvas.getSaveCount();
15720
15721         int solidColor = getSolidColor();
15722         if (solidColor == 0) {
15723             final int flags = Canvas.HAS_ALPHA_LAYER_SAVE_FLAG;
15724
15725             if (drawTop) {
15726                 canvas.saveLayer(left, top, right, top + length, null, flags);
15727             }
15728
15729             if (drawBottom) {
15730                 canvas.saveLayer(left, bottom - length, right, bottom, null, flags);
15731             }
15732
15733             if (drawLeft) {
15734                 canvas.saveLayer(left, top, left + length, bottom, null, flags);
15735             }
15736
15737             if (drawRight) {
15738                 canvas.saveLayer(right - length, top, right, bottom, null, flags);
15739             }
15740         } else {
15741             scrollabilityCache.setFadeColor(solidColor);
15742         }
15743
15744         // Step 3, draw the content
15745         if (!dirtyOpaque) onDraw(canvas);
15746
15747         // Step 4, draw the children
15748         dispatchDraw(canvas);
15749
15750         // Step 5, draw the fade effect and restore layers
15751         final Paint p = scrollabilityCache.paint;
15752         final Matrix matrix = scrollabilityCache.matrix;
15753         final Shader fade = scrollabilityCache.shader;
15754
15755         if (drawTop) {
15756             matrix.setScale(1, fadeHeight * topFadeStrength);
15757             matrix.postTranslate(left, top);
15758             fade.setLocalMatrix(matrix);
15759             p.setShader(fade);
15760             canvas.drawRect(left, top, right, top + length, p);
15761         }
15762
15763         if (drawBottom) {
15764             matrix.setScale(1, fadeHeight * bottomFadeStrength);
15765             matrix.postRotate(180);
15766             matrix.postTranslate(left, bottom);
15767             fade.setLocalMatrix(matrix);
15768             p.setShader(fade);
15769             canvas.drawRect(left, bottom - length, right, bottom, p);
15770         }
15771
15772         if (drawLeft) {
15773             matrix.setScale(1, fadeHeight * leftFadeStrength);
15774             matrix.postRotate(-90);
15775             matrix.postTranslate(left, top);
15776             fade.setLocalMatrix(matrix);
15777             p.setShader(fade);
15778             canvas.drawRect(left, top, left + length, bottom, p);
15779         }
15780
15781         if (drawRight) {
15782             matrix.setScale(1, fadeHeight * rightFadeStrength);
15783             matrix.postRotate(90);
15784             matrix.postTranslate(right, top);
15785             fade.setLocalMatrix(matrix);
15786             p.setShader(fade);
15787             canvas.drawRect(right - length, top, right, bottom, p);
15788         }
15789
15790         canvas.restoreToCount(saveCount);
15791
15792         // Overlay is part of the content and draws beneath Foreground
15793         if (mOverlay != null && !mOverlay.isEmpty()) {
15794             mOverlay.getOverlayView().dispatchDraw(canvas);
15795         }
15796
15797         // Step 6, draw decorations (foreground, scrollbars)
15798         onDrawForeground(canvas);
15799     }
15800
15801     /**
15802      * Draws the background onto the specified canvas.
15803      *
15804      * @param canvas Canvas on which to draw the background
15805      */
15806     private void drawBackground(Canvas canvas) {
15807         final Drawable background = mBackground;
15808         if (background == null) {
15809             return;
15810         }
15811
15812         setBackgroundBounds();
15813
15814         // Attempt to use a display list if requested.
15815         if (canvas.isHardwareAccelerated() && mAttachInfo != null
15816                 && mAttachInfo.mHardwareRenderer != null) {
15817             mBackgroundRenderNode = getDrawableRenderNode(background, mBackgroundRenderNode);
15818
15819             final RenderNode renderNode = mBackgroundRenderNode;
15820             if (renderNode != null && renderNode.isValid()) {
15821                 setBackgroundRenderNodeProperties(renderNode);
15822                 ((DisplayListCanvas) canvas).drawRenderNode(renderNode);
15823                 return;
15824             }
15825         }
15826
15827         final int scrollX = mScrollX;
15828         final int scrollY = mScrollY;
15829         if ((scrollX | scrollY) == 0) {
15830             background.draw(canvas);
15831         } else {
15832             canvas.translate(scrollX, scrollY);
15833             background.draw(canvas);
15834             canvas.translate(-scrollX, -scrollY);
15835         }
15836     }
15837
15838     /**
15839      * Sets the correct background bounds and rebuilds the outline, if needed.
15840      * <p/>
15841      * This is called by LayoutLib.
15842      */
15843     void setBackgroundBounds() {
15844         if (mBackgroundSizeChanged && mBackground != null) {
15845             mBackground.setBounds(0, 0,  mRight - mLeft, mBottom - mTop);
15846             mBackgroundSizeChanged = false;
15847             rebuildOutline();
15848         }
15849     }
15850
15851     private void setBackgroundRenderNodeProperties(RenderNode renderNode) {
15852         renderNode.setTranslationX(mScrollX);
15853         renderNode.setTranslationY(mScrollY);
15854     }
15855
15856     /**
15857      * Creates a new display list or updates the existing display list for the
15858      * specified Drawable.
15859      *
15860      * @param drawable Drawable for which to create a display list
15861      * @param renderNode Existing RenderNode, or {@code null}
15862      * @return A valid display list for the specified drawable
15863      */
15864     private RenderNode getDrawableRenderNode(Drawable drawable, RenderNode renderNode) {
15865         if (renderNode == null) {
15866             renderNode = RenderNode.create(drawable.getClass().getName(), this);
15867         }
15868
15869         final Rect bounds = drawable.getBounds();
15870         final int width = bounds.width();
15871         final int height = bounds.height();
15872         final DisplayListCanvas canvas = renderNode.start(width, height);
15873
15874         // Reverse left/top translation done by drawable canvas, which will
15875         // instead be applied by rendernode's LTRB bounds below. This way, the
15876         // drawable's bounds match with its rendernode bounds and its content
15877         // will lie within those bounds in the rendernode tree.
15878         canvas.translate(-bounds.left, -bounds.top);
15879
15880         try {
15881             drawable.draw(canvas);
15882         } finally {
15883             renderNode.end(canvas);
15884         }
15885
15886         // Set up drawable properties that are view-independent.
15887         renderNode.setLeftTopRightBottom(bounds.left, bounds.top, bounds.right, bounds.bottom);
15888         renderNode.setProjectBackwards(drawable.isProjected());
15889         renderNode.setProjectionReceiver(true);
15890         renderNode.setClipToBounds(false);
15891         return renderNode;
15892     }
15893
15894     /**
15895      * Returns the overlay for this view, creating it if it does not yet exist.
15896      * Adding drawables to the overlay will cause them to be displayed whenever
15897      * the view itself is redrawn. Objects in the overlay should be actively
15898      * managed: remove them when they should not be displayed anymore. The
15899      * overlay will always have the same size as its host view.
15900      *
15901      * <p>Note: Overlays do not currently work correctly with {@link
15902      * SurfaceView} or {@link TextureView}; contents in overlays for these
15903      * types of views may not display correctly.</p>
15904      *
15905      * @return The ViewOverlay object for this view.
15906      * @see ViewOverlay
15907      */
15908     public ViewOverlay getOverlay() {
15909         if (mOverlay == null) {
15910             mOverlay = new ViewOverlay(mContext, this);
15911         }
15912         return mOverlay;
15913     }
15914
15915     /**
15916      * Override this if your view is known to always be drawn on top of a solid color background,
15917      * and needs to draw fading edges. Returning a non-zero color enables the view system to
15918      * optimize the drawing of the fading edges. If you do return a non-zero color, the alpha
15919      * should be set to 0xFF.
15920      *
15921      * @see #setVerticalFadingEdgeEnabled(boolean)
15922      * @see #setHorizontalFadingEdgeEnabled(boolean)
15923      *
15924      * @return The known solid color background for this view, or 0 if the color may vary
15925      */
15926     @ViewDebug.ExportedProperty(category = "drawing")
15927     @ColorInt
15928     public int getSolidColor() {
15929         return 0;
15930     }
15931
15932     /**
15933      * Build a human readable string representation of the specified view flags.
15934      *
15935      * @param flags the view flags to convert to a string
15936      * @return a String representing the supplied flags
15937      */
15938     private static String printFlags(int flags) {
15939         String output = "";
15940         int numFlags = 0;
15941         if ((flags & FOCUSABLE_MASK) == FOCUSABLE) {
15942             output += "TAKES_FOCUS";
15943             numFlags++;
15944         }
15945
15946         switch (flags & VISIBILITY_MASK) {
15947         case INVISIBLE:
15948             if (numFlags > 0) {
15949                 output += " ";
15950             }
15951             output += "INVISIBLE";
15952             // USELESS HERE numFlags++;
15953             break;
15954         case GONE:
15955             if (numFlags > 0) {
15956                 output += " ";
15957             }
15958             output += "GONE";
15959             // USELESS HERE numFlags++;
15960             break;
15961         default:
15962             break;
15963         }
15964         return output;
15965     }
15966
15967     /**
15968      * Build a human readable string representation of the specified private
15969      * view flags.
15970      *
15971      * @param privateFlags the private view flags to convert to a string
15972      * @return a String representing the supplied flags
15973      */
15974     private static String printPrivateFlags(int privateFlags) {
15975         String output = "";
15976         int numFlags = 0;
15977
15978         if ((privateFlags & PFLAG_WANTS_FOCUS) == PFLAG_WANTS_FOCUS) {
15979             output += "WANTS_FOCUS";
15980             numFlags++;
15981         }
15982
15983         if ((privateFlags & PFLAG_FOCUSED) == PFLAG_FOCUSED) {
15984             if (numFlags > 0) {
15985                 output += " ";
15986             }
15987             output += "FOCUSED";
15988             numFlags++;
15989         }
15990
15991         if ((privateFlags & PFLAG_SELECTED) == PFLAG_SELECTED) {
15992             if (numFlags > 0) {
15993                 output += " ";
15994             }
15995             output += "SELECTED";
15996             numFlags++;
15997         }
15998
15999         if ((privateFlags & PFLAG_IS_ROOT_NAMESPACE) == PFLAG_IS_ROOT_NAMESPACE) {
16000             if (numFlags > 0) {
16001                 output += " ";
16002             }
16003             output += "IS_ROOT_NAMESPACE";
16004             numFlags++;
16005         }
16006
16007         if ((privateFlags & PFLAG_HAS_BOUNDS) == PFLAG_HAS_BOUNDS) {
16008             if (numFlags > 0) {
16009                 output += " ";
16010             }
16011             output += "HAS_BOUNDS";
16012             numFlags++;
16013         }
16014
16015         if ((privateFlags & PFLAG_DRAWN) == PFLAG_DRAWN) {
16016             if (numFlags > 0) {
16017                 output += " ";
16018             }
16019             output += "DRAWN";
16020             // USELESS HERE numFlags++;
16021         }
16022         return output;
16023     }
16024
16025     /**
16026      * <p>Indicates whether or not this view's layout will be requested during
16027      * the next hierarchy layout pass.</p>
16028      *
16029      * @return true if the layout will be forced during next layout pass
16030      */
16031     public boolean isLayoutRequested() {
16032         return (mPrivateFlags & PFLAG_FORCE_LAYOUT) == PFLAG_FORCE_LAYOUT;
16033     }
16034
16035     /**
16036      * Return true if o is a ViewGroup that is laying out using optical bounds.
16037      * @hide
16038      */
16039     public static boolean isLayoutModeOptical(Object o) {
16040         return o instanceof ViewGroup && ((ViewGroup) o).isLayoutModeOptical();
16041     }
16042
16043     private boolean setOpticalFrame(int left, int top, int right, int bottom) {
16044         Insets parentInsets = mParent instanceof View ?
16045                 ((View) mParent).getOpticalInsets() : Insets.NONE;
16046         Insets childInsets = getOpticalInsets();
16047         return setFrame(
16048                 left   + parentInsets.left - childInsets.left,
16049                 top    + parentInsets.top  - childInsets.top,
16050                 right  + parentInsets.left + childInsets.right,
16051                 bottom + parentInsets.top  + childInsets.bottom);
16052     }
16053
16054     /**
16055      * Assign a size and position to a view and all of its
16056      * descendants
16057      *
16058      * <p>This is the second phase of the layout mechanism.
16059      * (The first is measuring). In this phase, each parent calls
16060      * layout on all of its children to position them.
16061      * This is typically done using the child measurements
16062      * that were stored in the measure pass().</p>
16063      *
16064      * <p>Derived classes should not override this method.
16065      * Derived classes with children should override
16066      * onLayout. In that method, they should
16067      * call layout on each of their children.</p>
16068      *
16069      * @param l Left position, relative to parent
16070      * @param t Top position, relative to parent
16071      * @param r Right position, relative to parent
16072      * @param b Bottom position, relative to parent
16073      */
16074     @SuppressWarnings({"unchecked"})
16075     public void layout(int l, int t, int r, int b) {
16076         if ((mPrivateFlags3 & PFLAG3_MEASURE_NEEDED_BEFORE_LAYOUT) != 0) {
16077             onMeasure(mOldWidthMeasureSpec, mOldHeightMeasureSpec);
16078             mPrivateFlags3 &= ~PFLAG3_MEASURE_NEEDED_BEFORE_LAYOUT;
16079         }
16080
16081         int oldL = mLeft;
16082         int oldT = mTop;
16083         int oldB = mBottom;
16084         int oldR = mRight;
16085
16086         boolean changed = isLayoutModeOptical(mParent) ?
16087                 setOpticalFrame(l, t, r, b) : setFrame(l, t, r, b);
16088
16089         if (changed || (mPrivateFlags & PFLAG_LAYOUT_REQUIRED) == PFLAG_LAYOUT_REQUIRED) {
16090             onLayout(changed, l, t, r, b);
16091             mPrivateFlags &= ~PFLAG_LAYOUT_REQUIRED;
16092
16093             ListenerInfo li = mListenerInfo;
16094             if (li != null && li.mOnLayoutChangeListeners != null) {
16095                 ArrayList<OnLayoutChangeListener> listenersCopy =
16096                         (ArrayList<OnLayoutChangeListener>)li.mOnLayoutChangeListeners.clone();
16097                 int numListeners = listenersCopy.size();
16098                 for (int i = 0; i < numListeners; ++i) {
16099                     listenersCopy.get(i).onLayoutChange(this, l, t, r, b, oldL, oldT, oldR, oldB);
16100                 }
16101             }
16102         }
16103
16104         mPrivateFlags &= ~PFLAG_FORCE_LAYOUT;
16105         mPrivateFlags3 |= PFLAG3_IS_LAID_OUT;
16106     }
16107
16108     /**
16109      * Called from layout when this view should
16110      * assign a size and position to each of its children.
16111      *
16112      * Derived classes with children should override
16113      * this method and call layout on each of
16114      * their children.
16115      * @param changed This is a new size or position for this view
16116      * @param left Left position, relative to parent
16117      * @param top Top position, relative to parent
16118      * @param right Right position, relative to parent
16119      * @param bottom Bottom position, relative to parent
16120      */
16121     protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
16122     }
16123
16124     /**
16125      * Assign a size and position to this view.
16126      *
16127      * This is called from layout.
16128      *
16129      * @param left Left position, relative to parent
16130      * @param top Top position, relative to parent
16131      * @param right Right position, relative to parent
16132      * @param bottom Bottom position, relative to parent
16133      * @return true if the new size and position are different than the
16134      *         previous ones
16135      * {@hide}
16136      */
16137     protected boolean setFrame(int left, int top, int right, int bottom) {
16138         boolean changed = false;
16139
16140         if (DBG) {
16141             Log.d("View", this + " View.setFrame(" + left + "," + top + ","
16142                     + right + "," + bottom + ")");
16143         }
16144
16145         if (mLeft != left || mRight != right || mTop != top || mBottom != bottom) {
16146             changed = true;
16147
16148             // Remember our drawn bit
16149             int drawn = mPrivateFlags & PFLAG_DRAWN;
16150
16151             int oldWidth = mRight - mLeft;
16152             int oldHeight = mBottom - mTop;
16153             int newWidth = right - left;
16154             int newHeight = bottom - top;
16155             boolean sizeChanged = (newWidth != oldWidth) || (newHeight != oldHeight);
16156
16157             // Invalidate our old position
16158             invalidate(sizeChanged);
16159
16160             mLeft = left;
16161             mTop = top;
16162             mRight = right;
16163             mBottom = bottom;
16164             mRenderNode.setLeftTopRightBottom(mLeft, mTop, mRight, mBottom);
16165
16166             mPrivateFlags |= PFLAG_HAS_BOUNDS;
16167
16168
16169             if (sizeChanged) {
16170                 sizeChange(newWidth, newHeight, oldWidth, oldHeight);
16171             }
16172
16173             if ((mViewFlags & VISIBILITY_MASK) == VISIBLE || mGhostView != null) {
16174                 // If we are visible, force the DRAWN bit to on so that
16175                 // this invalidate will go through (at least to our parent).
16176                 // This is because someone may have invalidated this view
16177                 // before this call to setFrame came in, thereby clearing
16178                 // the DRAWN bit.
16179                 mPrivateFlags |= PFLAG_DRAWN;
16180                 invalidate(sizeChanged);
16181                 // parent display list may need to be recreated based on a change in the bounds
16182                 // of any child
16183                 invalidateParentCaches();
16184             }
16185
16186             // Reset drawn bit to original value (invalidate turns it off)
16187             mPrivateFlags |= drawn;
16188
16189             mBackgroundSizeChanged = true;
16190             if (mForegroundInfo != null) {
16191                 mForegroundInfo.mBoundsChanged = true;
16192             }
16193
16194             notifySubtreeAccessibilityStateChangedIfNeeded();
16195         }
16196         return changed;
16197     }
16198
16199     /**
16200      * Same as setFrame, but public and hidden. For use in {@link android.transition.ChangeBounds}.
16201      * @hide
16202      */
16203     public void setLeftTopRightBottom(int left, int top, int right, int bottom) {
16204         setFrame(left, top, right, bottom);
16205     }
16206
16207     private void sizeChange(int newWidth, int newHeight, int oldWidth, int oldHeight) {
16208         onSizeChanged(newWidth, newHeight, oldWidth, oldHeight);
16209         if (mOverlay != null) {
16210             mOverlay.getOverlayView().setRight(newWidth);
16211             mOverlay.getOverlayView().setBottom(newHeight);
16212         }
16213         rebuildOutline();
16214     }
16215
16216     /**
16217      * Finalize inflating a view from XML.  This is called as the last phase
16218      * of inflation, after all child views have been added.
16219      *
16220      * <p>Even if the subclass overrides onFinishInflate, they should always be
16221      * sure to call the super method, so that we get called.
16222      */
16223     @CallSuper
16224     protected void onFinishInflate() {
16225     }
16226
16227     /**
16228      * Returns the resources associated with this view.
16229      *
16230      * @return Resources object.
16231      */
16232     public Resources getResources() {
16233         return mResources;
16234     }
16235
16236     /**
16237      * Invalidates the specified Drawable.
16238      *
16239      * @param drawable the drawable to invalidate
16240      */
16241     @Override
16242     public void invalidateDrawable(@NonNull Drawable drawable) {
16243         if (verifyDrawable(drawable)) {
16244             final Rect dirty = drawable.getDirtyBounds();
16245             final int scrollX = mScrollX;
16246             final int scrollY = mScrollY;
16247
16248             invalidate(dirty.left + scrollX, dirty.top + scrollY,
16249                     dirty.right + scrollX, dirty.bottom + scrollY);
16250             rebuildOutline();
16251         }
16252     }
16253
16254     /**
16255      * Schedules an action on a drawable to occur at a specified time.
16256      *
16257      * @param who the recipient of the action
16258      * @param what the action to run on the drawable
16259      * @param when the time at which the action must occur. Uses the
16260      *        {@link SystemClock#uptimeMillis} timebase.
16261      */
16262     @Override
16263     public void scheduleDrawable(Drawable who, Runnable what, long when) {
16264         if (verifyDrawable(who) && what != null) {
16265             final long delay = when - SystemClock.uptimeMillis();
16266             if (mAttachInfo != null) {
16267                 mAttachInfo.mViewRootImpl.mChoreographer.postCallbackDelayed(
16268                         Choreographer.CALLBACK_ANIMATION, what, who,
16269                         Choreographer.subtractFrameDelay(delay));
16270             } else {
16271                 ViewRootImpl.getRunQueue().postDelayed(what, delay);
16272             }
16273         }
16274     }
16275
16276     /**
16277      * Cancels a scheduled action on a drawable.
16278      *
16279      * @param who the recipient of the action
16280      * @param what the action to cancel
16281      */
16282     @Override
16283     public void unscheduleDrawable(Drawable who, Runnable what) {
16284         if (verifyDrawable(who) && what != null) {
16285             if (mAttachInfo != null) {
16286                 mAttachInfo.mViewRootImpl.mChoreographer.removeCallbacks(
16287                         Choreographer.CALLBACK_ANIMATION, what, who);
16288             }
16289             ViewRootImpl.getRunQueue().removeCallbacks(what);
16290         }
16291     }
16292
16293     /**
16294      * Unschedule any events associated with the given Drawable.  This can be
16295      * used when selecting a new Drawable into a view, so that the previous
16296      * one is completely unscheduled.
16297      *
16298      * @param who The Drawable to unschedule.
16299      *
16300      * @see #drawableStateChanged
16301      */
16302     public void unscheduleDrawable(Drawable who) {
16303         if (mAttachInfo != null && who != null) {
16304             mAttachInfo.mViewRootImpl.mChoreographer.removeCallbacks(
16305                     Choreographer.CALLBACK_ANIMATION, null, who);
16306         }
16307     }
16308
16309     /**
16310      * Resolve the Drawables depending on the layout direction. This is implicitly supposing
16311      * that the View directionality can and will be resolved before its Drawables.
16312      *
16313      * Will call {@link View#onResolveDrawables} when resolution is done.
16314      *
16315      * @hide
16316      */
16317     protected void resolveDrawables() {
16318         // Drawables resolution may need to happen before resolving the layout direction (which is
16319         // done only during the measure() call).
16320         // If the layout direction is not resolved yet, we cannot resolve the Drawables except in
16321         // one case: when the raw layout direction has not been defined as LAYOUT_DIRECTION_INHERIT.
16322         // So, if the raw layout direction is LAYOUT_DIRECTION_LTR or LAYOUT_DIRECTION_RTL or
16323         // LAYOUT_DIRECTION_LOCALE, we can "cheat" and we don't need to wait for the layout
16324         // direction to be resolved as its resolved value will be the same as its raw value.
16325         if (!isLayoutDirectionResolved() &&
16326                 getRawLayoutDirection() == View.LAYOUT_DIRECTION_INHERIT) {
16327             return;
16328         }
16329
16330         final int layoutDirection = isLayoutDirectionResolved() ?
16331                 getLayoutDirection() : getRawLayoutDirection();
16332
16333         if (mBackground != null) {
16334             mBackground.setLayoutDirection(layoutDirection);
16335         }
16336         if (mForegroundInfo != null && mForegroundInfo.mDrawable != null) {
16337             mForegroundInfo.mDrawable.setLayoutDirection(layoutDirection);
16338         }
16339         mPrivateFlags2 |= PFLAG2_DRAWABLE_RESOLVED;
16340         onResolveDrawables(layoutDirection);
16341     }
16342
16343     boolean areDrawablesResolved() {
16344         return (mPrivateFlags2 & PFLAG2_DRAWABLE_RESOLVED) == PFLAG2_DRAWABLE_RESOLVED;
16345     }
16346
16347     /**
16348      * Called when layout direction has been resolved.
16349      *
16350      * The default implementation does nothing.
16351      *
16352      * @param layoutDirection The resolved layout direction.
16353      *
16354      * @see #LAYOUT_DIRECTION_LTR
16355      * @see #LAYOUT_DIRECTION_RTL
16356      *
16357      * @hide
16358      */
16359     public void onResolveDrawables(@ResolvedLayoutDir int layoutDirection) {
16360     }
16361
16362     /**
16363      * @hide
16364      */
16365     protected void resetResolvedDrawables() {
16366         resetResolvedDrawablesInternal();
16367     }
16368
16369     void resetResolvedDrawablesInternal() {
16370         mPrivateFlags2 &= ~PFLAG2_DRAWABLE_RESOLVED;
16371     }
16372
16373     /**
16374      * If your view subclass is displaying its own Drawable objects, it should
16375      * override this function and return true for any Drawable it is
16376      * displaying.  This allows animations for those drawables to be
16377      * scheduled.
16378      *
16379      * <p>Be sure to call through to the super class when overriding this
16380      * function.
16381      *
16382      * @param who The Drawable to verify.  Return true if it is one you are
16383      *            displaying, else return the result of calling through to the
16384      *            super class.
16385      *
16386      * @return boolean If true than the Drawable is being displayed in the
16387      *         view; else false and it is not allowed to animate.
16388      *
16389      * @see #unscheduleDrawable(android.graphics.drawable.Drawable)
16390      * @see #drawableStateChanged()
16391      */
16392     @CallSuper
16393     protected boolean verifyDrawable(Drawable who) {
16394         return who == mBackground || (mScrollCache != null && mScrollCache.scrollBar == who)
16395                 || (mForegroundInfo != null && mForegroundInfo.mDrawable == who);
16396     }
16397
16398     /**
16399      * This function is called whenever the state of the view changes in such
16400      * a way that it impacts the state of drawables being shown.
16401      * <p>
16402      * If the View has a StateListAnimator, it will also be called to run necessary state
16403      * change animations.
16404      * <p>
16405      * Be sure to call through to the superclass when overriding this function.
16406      *
16407      * @see Drawable#setState(int[])
16408      */
16409     @CallSuper
16410     protected void drawableStateChanged() {
16411         final int[] state = getDrawableState();
16412
16413         final Drawable bg = mBackground;
16414         if (bg != null && bg.isStateful()) {
16415             bg.setState(state);
16416         }
16417
16418         final Drawable fg = mForegroundInfo != null ? mForegroundInfo.mDrawable : null;
16419         if (fg != null && fg.isStateful()) {
16420             fg.setState(state);
16421         }
16422
16423         if (mScrollCache != null) {
16424             final Drawable scrollBar = mScrollCache.scrollBar;
16425             if (scrollBar != null && scrollBar.isStateful()) {
16426                 scrollBar.setState(state);
16427             }
16428         }
16429
16430         if (mStateListAnimator != null) {
16431             mStateListAnimator.setState(state);
16432         }
16433     }
16434
16435     /**
16436      * This function is called whenever the view hotspot changes and needs to
16437      * be propagated to drawables or child views managed by the view.
16438      * <p>
16439      * Dispatching to child views is handled by
16440      * {@link #dispatchDrawableHotspotChanged(float, float)}.
16441      * <p>
16442      * Be sure to call through to the superclass when overriding this function.
16443      *
16444      * @param x hotspot x coordinate
16445      * @param y hotspot y coordinate
16446      */
16447     @CallSuper
16448     public void drawableHotspotChanged(float x, float y) {
16449         if (mBackground != null) {
16450             mBackground.setHotspot(x, y);
16451         }
16452         if (mForegroundInfo != null && mForegroundInfo.mDrawable != null) {
16453             mForegroundInfo.mDrawable.setHotspot(x, y);
16454         }
16455
16456         dispatchDrawableHotspotChanged(x, y);
16457     }
16458
16459     /**
16460      * Dispatches drawableHotspotChanged to all of this View's children.
16461      *
16462      * @param x hotspot x coordinate
16463      * @param y hotspot y coordinate
16464      * @see #drawableHotspotChanged(float, float)
16465      */
16466     public void dispatchDrawableHotspotChanged(float x, float y) {
16467     }
16468
16469     /**
16470      * Call this to force a view to update its drawable state. This will cause
16471      * drawableStateChanged to be called on this view. Views that are interested
16472      * in the new state should call getDrawableState.
16473      *
16474      * @see #drawableStateChanged
16475      * @see #getDrawableState
16476      */
16477     public void refreshDrawableState() {
16478         mPrivateFlags |= PFLAG_DRAWABLE_STATE_DIRTY;
16479         drawableStateChanged();
16480
16481         ViewParent parent = mParent;
16482         if (parent != null) {
16483             parent.childDrawableStateChanged(this);
16484         }
16485     }
16486
16487     /**
16488      * Return an array of resource IDs of the drawable states representing the
16489      * current state of the view.
16490      *
16491      * @return The current drawable state
16492      *
16493      * @see Drawable#setState(int[])
16494      * @see #drawableStateChanged()
16495      * @see #onCreateDrawableState(int)
16496      */
16497     public final int[] getDrawableState() {
16498         if ((mDrawableState != null) && ((mPrivateFlags & PFLAG_DRAWABLE_STATE_DIRTY) == 0)) {
16499             return mDrawableState;
16500         } else {
16501             mDrawableState = onCreateDrawableState(0);
16502             mPrivateFlags &= ~PFLAG_DRAWABLE_STATE_DIRTY;
16503             return mDrawableState;
16504         }
16505     }
16506
16507     /**
16508      * Generate the new {@link android.graphics.drawable.Drawable} state for
16509      * this view. This is called by the view
16510      * system when the cached Drawable state is determined to be invalid.  To
16511      * retrieve the current state, you should use {@link #getDrawableState}.
16512      *
16513      * @param extraSpace if non-zero, this is the number of extra entries you
16514      * would like in the returned array in which you can place your own
16515      * states.
16516      *
16517      * @return Returns an array holding the current {@link Drawable} state of
16518      * the view.
16519      *
16520      * @see #mergeDrawableStates(int[], int[])
16521      */
16522     protected int[] onCreateDrawableState(int extraSpace) {
16523         if ((mViewFlags & DUPLICATE_PARENT_STATE) == DUPLICATE_PARENT_STATE &&
16524                 mParent instanceof View) {
16525             return ((View) mParent).onCreateDrawableState(extraSpace);
16526         }
16527
16528         int[] drawableState;
16529
16530         int privateFlags = mPrivateFlags;
16531
16532         int viewStateIndex = 0;
16533         if ((privateFlags & PFLAG_PRESSED) != 0) viewStateIndex |= StateSet.VIEW_STATE_PRESSED;
16534         if ((mViewFlags & ENABLED_MASK) == ENABLED) viewStateIndex |= StateSet.VIEW_STATE_ENABLED;
16535         if (isFocused()) viewStateIndex |= StateSet.VIEW_STATE_FOCUSED;
16536         if ((privateFlags & PFLAG_SELECTED) != 0) viewStateIndex |= StateSet.VIEW_STATE_SELECTED;
16537         if (hasWindowFocus()) viewStateIndex |= StateSet.VIEW_STATE_WINDOW_FOCUSED;
16538         if ((privateFlags & PFLAG_ACTIVATED) != 0) viewStateIndex |= StateSet.VIEW_STATE_ACTIVATED;
16539         if (mAttachInfo != null && mAttachInfo.mHardwareAccelerationRequested &&
16540                 HardwareRenderer.isAvailable()) {
16541             // This is set if HW acceleration is requested, even if the current
16542             // process doesn't allow it.  This is just to allow app preview
16543             // windows to better match their app.
16544             viewStateIndex |= StateSet.VIEW_STATE_ACCELERATED;
16545         }
16546         if ((privateFlags & PFLAG_HOVERED) != 0) viewStateIndex |= StateSet.VIEW_STATE_HOVERED;
16547
16548         final int privateFlags2 = mPrivateFlags2;
16549         if ((privateFlags2 & PFLAG2_DRAG_CAN_ACCEPT) != 0) {
16550             viewStateIndex |= StateSet.VIEW_STATE_DRAG_CAN_ACCEPT;
16551         }
16552         if ((privateFlags2 & PFLAG2_DRAG_HOVERED) != 0) {
16553             viewStateIndex |= StateSet.VIEW_STATE_DRAG_HOVERED;
16554         }
16555
16556         drawableState = StateSet.get(viewStateIndex);
16557
16558         //noinspection ConstantIfStatement
16559         if (false) {
16560             Log.i("View", "drawableStateIndex=" + viewStateIndex);
16561             Log.i("View", toString()
16562                     + " pressed=" + ((privateFlags & PFLAG_PRESSED) != 0)
16563                     + " en=" + ((mViewFlags & ENABLED_MASK) == ENABLED)
16564                     + " fo=" + hasFocus()
16565                     + " sl=" + ((privateFlags & PFLAG_SELECTED) != 0)
16566                     + " wf=" + hasWindowFocus()
16567                     + ": " + Arrays.toString(drawableState));
16568         }
16569
16570         if (extraSpace == 0) {
16571             return drawableState;
16572         }
16573
16574         final int[] fullState;
16575         if (drawableState != null) {
16576             fullState = new int[drawableState.length + extraSpace];
16577             System.arraycopy(drawableState, 0, fullState, 0, drawableState.length);
16578         } else {
16579             fullState = new int[extraSpace];
16580         }
16581
16582         return fullState;
16583     }
16584
16585     /**
16586      * Merge your own state values in <var>additionalState</var> into the base
16587      * state values <var>baseState</var> that were returned by
16588      * {@link #onCreateDrawableState(int)}.
16589      *
16590      * @param baseState The base state values returned by
16591      * {@link #onCreateDrawableState(int)}, which will be modified to also hold your
16592      * own additional state values.
16593      *
16594      * @param additionalState The additional state values you would like
16595      * added to <var>baseState</var>; this array is not modified.
16596      *
16597      * @return As a convenience, the <var>baseState</var> array you originally
16598      * passed into the function is returned.
16599      *
16600      * @see #onCreateDrawableState(int)
16601      */
16602     protected static int[] mergeDrawableStates(int[] baseState, int[] additionalState) {
16603         final int N = baseState.length;
16604         int i = N - 1;
16605         while (i >= 0 && baseState[i] == 0) {
16606             i--;
16607         }
16608         System.arraycopy(additionalState, 0, baseState, i + 1, additionalState.length);
16609         return baseState;
16610     }
16611
16612     /**
16613      * Call {@link Drawable#jumpToCurrentState() Drawable.jumpToCurrentState()}
16614      * on all Drawable objects associated with this view.
16615      * <p>
16616      * Also calls {@link StateListAnimator#jumpToCurrentState()} if there is a StateListAnimator
16617      * attached to this view.
16618      */
16619     public void jumpDrawablesToCurrentState() {
16620         if (mBackground != null) {
16621             mBackground.jumpToCurrentState();
16622         }
16623         if (mStateListAnimator != null) {
16624             mStateListAnimator.jumpToCurrentState();
16625         }
16626         if (mForegroundInfo != null && mForegroundInfo.mDrawable != null) {
16627             mForegroundInfo.mDrawable.jumpToCurrentState();
16628         }
16629     }
16630
16631     /**
16632      * Sets the background color for this view.
16633      * @param color the color of the background
16634      */
16635     @RemotableViewMethod
16636     public void setBackgroundColor(@ColorInt int color) {
16637         if (mBackground instanceof ColorDrawable) {
16638             ((ColorDrawable) mBackground.mutate()).setColor(color);
16639             computeOpaqueFlags();
16640             mBackgroundResource = 0;
16641         } else {
16642             setBackground(new ColorDrawable(color));
16643         }
16644     }
16645
16646     /**
16647      * If the view has a ColorDrawable background, returns the color of that
16648      * drawable.
16649      *
16650      * @return The color of the ColorDrawable background, if set, otherwise 0.
16651      */
16652     @ColorInt
16653     public int getBackgroundColor() {
16654         if (mBackground instanceof ColorDrawable) {
16655             return ((ColorDrawable) mBackground).getColor();
16656         }
16657         return 0;
16658     }
16659
16660     /**
16661      * Set the background to a given resource. The resource should refer to
16662      * a Drawable object or 0 to remove the background.
16663      * @param resid The identifier of the resource.
16664      *
16665      * @attr ref android.R.styleable#View_background
16666      */
16667     @RemotableViewMethod
16668     public void setBackgroundResource(@DrawableRes int resid) {
16669         if (resid != 0 && resid == mBackgroundResource) {
16670             return;
16671         }
16672
16673         Drawable d = null;
16674         if (resid != 0) {
16675             d = mContext.getDrawable(resid);
16676         }
16677         setBackground(d);
16678
16679         mBackgroundResource = resid;
16680     }
16681
16682     /**
16683      * Set the background to a given Drawable, or remove the background. If the
16684      * background has padding, this View's padding is set to the background's
16685      * padding. However, when a background is removed, this View's padding isn't
16686      * touched. If setting the padding is desired, please use
16687      * {@link #setPadding(int, int, int, int)}.
16688      *
16689      * @param background The Drawable to use as the background, or null to remove the
16690      *        background
16691      */
16692     public void setBackground(Drawable background) {
16693         //noinspection deprecation
16694         setBackgroundDrawable(background);
16695     }
16696
16697     /**
16698      * @deprecated use {@link #setBackground(Drawable)} instead
16699      */
16700     @Deprecated
16701     public void setBackgroundDrawable(Drawable background) {
16702         computeOpaqueFlags();
16703
16704         if (background == mBackground) {
16705             return;
16706         }
16707
16708         boolean requestLayout = false;
16709
16710         mBackgroundResource = 0;
16711
16712         /*
16713          * Regardless of whether we're setting a new background or not, we want
16714          * to clear the previous drawable.
16715          */
16716         if (mBackground != null) {
16717             mBackground.setCallback(null);
16718             unscheduleDrawable(mBackground);
16719         }
16720
16721         if (background != null) {
16722             Rect padding = sThreadLocal.get();
16723             if (padding == null) {
16724                 padding = new Rect();
16725                 sThreadLocal.set(padding);
16726             }
16727             resetResolvedDrawablesInternal();
16728             background.setLayoutDirection(getLayoutDirection());
16729             if (background.getPadding(padding)) {
16730                 resetResolvedPaddingInternal();
16731                 switch (background.getLayoutDirection()) {
16732                     case LAYOUT_DIRECTION_RTL:
16733                         mUserPaddingLeftInitial = padding.right;
16734                         mUserPaddingRightInitial = padding.left;
16735                         internalSetPadding(padding.right, padding.top, padding.left, padding.bottom);
16736                         break;
16737                     case LAYOUT_DIRECTION_LTR:
16738                     default:
16739                         mUserPaddingLeftInitial = padding.left;
16740                         mUserPaddingRightInitial = padding.right;
16741                         internalSetPadding(padding.left, padding.top, padding.right, padding.bottom);
16742                 }
16743                 mLeftPaddingDefined = false;
16744                 mRightPaddingDefined = false;
16745             }
16746
16747             // Compare the minimum sizes of the old Drawable and the new.  If there isn't an old or
16748             // if it has a different minimum size, we should layout again
16749             if (mBackground == null
16750                     || mBackground.getMinimumHeight() != background.getMinimumHeight()
16751                     || mBackground.getMinimumWidth() != background.getMinimumWidth()) {
16752                 requestLayout = true;
16753             }
16754
16755             background.setCallback(this);
16756             if (background.isStateful()) {
16757                 background.setState(getDrawableState());
16758             }
16759             background.setVisible(getVisibility() == VISIBLE, false);
16760             mBackground = background;
16761
16762             applyBackgroundTint();
16763
16764             if ((mPrivateFlags & PFLAG_SKIP_DRAW) != 0) {
16765                 mPrivateFlags &= ~PFLAG_SKIP_DRAW;
16766                 mPrivateFlags |= PFLAG_ONLY_DRAWS_BACKGROUND;
16767                 requestLayout = true;
16768             }
16769         } else {
16770             /* Remove the background */
16771             mBackground = null;
16772
16773             if ((mPrivateFlags & PFLAG_ONLY_DRAWS_BACKGROUND) != 0) {
16774                 /*
16775                  * This view ONLY drew the background before and we're removing
16776                  * the background, so now it won't draw anything
16777                  * (hence we SKIP_DRAW)
16778                  */
16779                 mPrivateFlags &= ~PFLAG_ONLY_DRAWS_BACKGROUND;
16780                 mPrivateFlags |= PFLAG_SKIP_DRAW;
16781             }
16782
16783             /*
16784              * When the background is set, we try to apply its padding to this
16785              * View. When the background is removed, we don't touch this View's
16786              * padding. This is noted in the Javadocs. Hence, we don't need to
16787              * requestLayout(), the invalidate() below is sufficient.
16788              */
16789
16790             // The old background's minimum size could have affected this
16791             // View's layout, so let's requestLayout
16792             requestLayout = true;
16793         }
16794
16795         computeOpaqueFlags();
16796
16797         if (requestLayout) {
16798             requestLayout();
16799         }
16800
16801         mBackgroundSizeChanged = true;
16802         invalidate(true);
16803     }
16804
16805     /**
16806      * Gets the background drawable
16807      *
16808      * @return The drawable used as the background for this view, if any.
16809      *
16810      * @see #setBackground(Drawable)
16811      *
16812      * @attr ref android.R.styleable#View_background
16813      */
16814     public Drawable getBackground() {
16815         return mBackground;
16816     }
16817
16818     /**
16819      * Applies a tint to the background drawable. Does not modify the current tint
16820      * mode, which is {@link PorterDuff.Mode#SRC_IN} by default.
16821      * <p>
16822      * Subsequent calls to {@link #setBackground(Drawable)} will automatically
16823      * mutate the drawable and apply the specified tint and tint mode using
16824      * {@link Drawable#setTintList(ColorStateList)}.
16825      *
16826      * @param tint the tint to apply, may be {@code null} to clear tint
16827      *
16828      * @attr ref android.R.styleable#View_backgroundTint
16829      * @see #getBackgroundTintList()
16830      * @see Drawable#setTintList(ColorStateList)
16831      */
16832     public void setBackgroundTintList(@Nullable ColorStateList tint) {
16833         if (mBackgroundTint == null) {
16834             mBackgroundTint = new TintInfo();
16835         }
16836         mBackgroundTint.mTintList = tint;
16837         mBackgroundTint.mHasTintList = true;
16838
16839         applyBackgroundTint();
16840     }
16841
16842     /**
16843      * Return the tint applied to the background drawable, if specified.
16844      *
16845      * @return the tint applied to the background drawable
16846      * @attr ref android.R.styleable#View_backgroundTint
16847      * @see #setBackgroundTintList(ColorStateList)
16848      */
16849     @Nullable
16850     public ColorStateList getBackgroundTintList() {
16851         return mBackgroundTint != null ? mBackgroundTint.mTintList : null;
16852     }
16853
16854     /**
16855      * Specifies the blending mode used to apply the tint specified by
16856      * {@link #setBackgroundTintList(ColorStateList)}} to the background
16857      * drawable. The default mode is {@link PorterDuff.Mode#SRC_IN}.
16858      *
16859      * @param tintMode the blending mode used to apply the tint, may be
16860      *                 {@code null} to clear tint
16861      * @attr ref android.R.styleable#View_backgroundTintMode
16862      * @see #getBackgroundTintMode()
16863      * @see Drawable#setTintMode(PorterDuff.Mode)
16864      */
16865     public void setBackgroundTintMode(@Nullable PorterDuff.Mode tintMode) {
16866         if (mBackgroundTint == null) {
16867             mBackgroundTint = new TintInfo();
16868         }
16869         mBackgroundTint.mTintMode = tintMode;
16870         mBackgroundTint.mHasTintMode = true;
16871
16872         applyBackgroundTint();
16873     }
16874
16875     /**
16876      * Return the blending mode used to apply the tint to the background
16877      * drawable, if specified.
16878      *
16879      * @return the blending mode used to apply the tint to the background
16880      *         drawable
16881      * @attr ref android.R.styleable#View_backgroundTintMode
16882      * @see #setBackgroundTintMode(PorterDuff.Mode)
16883      */
16884     @Nullable
16885     public PorterDuff.Mode getBackgroundTintMode() {
16886         return mBackgroundTint != null ? mBackgroundTint.mTintMode : null;
16887     }
16888
16889     private void applyBackgroundTint() {
16890         if (mBackground != null && mBackgroundTint != null) {
16891             final TintInfo tintInfo = mBackgroundTint;
16892             if (tintInfo.mHasTintList || tintInfo.mHasTintMode) {
16893                 mBackground = mBackground.mutate();
16894
16895                 if (tintInfo.mHasTintList) {
16896                     mBackground.setTintList(tintInfo.mTintList);
16897                 }
16898
16899                 if (tintInfo.mHasTintMode) {
16900                     mBackground.setTintMode(tintInfo.mTintMode);
16901                 }
16902
16903                 // The drawable (or one of its children) may not have been
16904                 // stateful before applying the tint, so let's try again.
16905                 if (mBackground.isStateful()) {
16906                     mBackground.setState(getDrawableState());
16907                 }
16908             }
16909         }
16910     }
16911
16912     /**
16913      * Returns the drawable used as the foreground of this View. The
16914      * foreground drawable, if non-null, is always drawn on top of the view's content.
16915      *
16916      * @return a Drawable or null if no foreground was set
16917      *
16918      * @see #onDrawForeground(Canvas)
16919      */
16920     public Drawable getForeground() {
16921         return mForegroundInfo != null ? mForegroundInfo.mDrawable : null;
16922     }
16923
16924     /**
16925      * Supply a Drawable that is to be rendered on top of all of the content in the view.
16926      *
16927      * @param foreground the Drawable to be drawn on top of the children
16928      *
16929      * @attr ref android.R.styleable#View_foreground
16930      */
16931     public void setForeground(Drawable foreground) {
16932         if (mForegroundInfo == null) {
16933             if (foreground == null) {
16934                 // Nothing to do.
16935                 return;
16936             }
16937             mForegroundInfo = new ForegroundInfo();
16938         }
16939
16940         if (foreground == mForegroundInfo.mDrawable) {
16941             // Nothing to do
16942             return;
16943         }
16944
16945         if (mForegroundInfo.mDrawable != null) {
16946             mForegroundInfo.mDrawable.setCallback(null);
16947             unscheduleDrawable(mForegroundInfo.mDrawable);
16948         }
16949
16950         mForegroundInfo.mDrawable = foreground;
16951         mForegroundInfo.mBoundsChanged = true;
16952         if (foreground != null) {
16953             setWillNotDraw(false);
16954             foreground.setCallback(this);
16955             foreground.setLayoutDirection(getLayoutDirection());
16956             if (foreground.isStateful()) {
16957                 foreground.setState(getDrawableState());
16958             }
16959             applyForegroundTint();
16960         }
16961         requestLayout();
16962         invalidate();
16963     }
16964
16965     /**
16966      * Magic bit used to support features of framework-internal window decor implementation details.
16967      * This used to live exclusively in FrameLayout.
16968      *
16969      * @return true if the foreground should draw inside the padding region or false
16970      *         if it should draw inset by the view's padding
16971      * @hide internal use only; only used by FrameLayout and internal screen layouts.
16972      */
16973     public boolean isForegroundInsidePadding() {
16974         return mForegroundInfo != null ? mForegroundInfo.mInsidePadding : true;
16975     }
16976
16977     /**
16978      * Describes how the foreground is positioned.
16979      *
16980      * @return foreground gravity.
16981      *
16982      * @see #setForegroundGravity(int)
16983      *
16984      * @attr ref android.R.styleable#View_foregroundGravity
16985      */
16986     public int getForegroundGravity() {
16987         return mForegroundInfo != null ? mForegroundInfo.mGravity
16988                 : Gravity.START | Gravity.TOP;
16989     }
16990
16991     /**
16992      * Describes how the foreground is positioned. Defaults to START and TOP.
16993      *
16994      * @param gravity see {@link android.view.Gravity}
16995      *
16996      * @see #getForegroundGravity()
16997      *
16998      * @attr ref android.R.styleable#View_foregroundGravity
16999      */
17000     public void setForegroundGravity(int gravity) {
17001         if (mForegroundInfo == null) {
17002             mForegroundInfo = new ForegroundInfo();
17003         }
17004
17005         if (mForegroundInfo.mGravity != gravity) {
17006             if ((gravity & Gravity.RELATIVE_HORIZONTAL_GRAVITY_MASK) == 0) {
17007                 gravity |= Gravity.START;
17008             }
17009
17010             if ((gravity & Gravity.VERTICAL_GRAVITY_MASK) == 0) {
17011                 gravity |= Gravity.TOP;
17012             }
17013
17014             mForegroundInfo.mGravity = gravity;
17015             requestLayout();
17016         }
17017     }
17018
17019     /**
17020      * Applies a tint to the foreground drawable. Does not modify the current tint
17021      * mode, which is {@link PorterDuff.Mode#SRC_IN} by default.
17022      * <p>
17023      * Subsequent calls to {@link #setForeground(Drawable)} will automatically
17024      * mutate the drawable and apply the specified tint and tint mode using
17025      * {@link Drawable#setTintList(ColorStateList)}.
17026      *
17027      * @param tint the tint to apply, may be {@code null} to clear tint
17028      *
17029      * @attr ref android.R.styleable#View_foregroundTint
17030      * @see #getForegroundTintList()
17031      * @see Drawable#setTintList(ColorStateList)
17032      */
17033     public void setForegroundTintList(@Nullable ColorStateList tint) {
17034         if (mForegroundInfo == null) {
17035             mForegroundInfo = new ForegroundInfo();
17036         }
17037         if (mForegroundInfo.mTintInfo == null) {
17038             mForegroundInfo.mTintInfo = new TintInfo();
17039         }
17040         mForegroundInfo.mTintInfo.mTintList = tint;
17041         mForegroundInfo.mTintInfo.mHasTintList = true;
17042
17043         applyForegroundTint();
17044     }
17045
17046     /**
17047      * Return the tint applied to the foreground drawable, if specified.
17048      *
17049      * @return the tint applied to the foreground drawable
17050      * @attr ref android.R.styleable#View_foregroundTint
17051      * @see #setForegroundTintList(ColorStateList)
17052      */
17053     @Nullable
17054     public ColorStateList getForegroundTintList() {
17055         return mForegroundInfo != null && mForegroundInfo.mTintInfo != null
17056                 ? mForegroundInfo.mTintInfo.mTintList : null;
17057     }
17058
17059     /**
17060      * Specifies the blending mode used to apply the tint specified by
17061      * {@link #setForegroundTintList(ColorStateList)}} to the background
17062      * drawable. The default mode is {@link PorterDuff.Mode#SRC_IN}.
17063      *
17064      * @param tintMode the blending mode used to apply the tint, may be
17065      *                 {@code null} to clear tint
17066      * @attr ref android.R.styleable#View_foregroundTintMode
17067      * @see #getForegroundTintMode()
17068      * @see Drawable#setTintMode(PorterDuff.Mode)
17069      */
17070     public void setForegroundTintMode(@Nullable PorterDuff.Mode tintMode) {
17071         if (mBackgroundTint == null) {
17072             mBackgroundTint = new TintInfo();
17073         }
17074         mBackgroundTint.mTintMode = tintMode;
17075         mBackgroundTint.mHasTintMode = true;
17076
17077         applyBackgroundTint();
17078     }
17079
17080     /**
17081      * Return the blending mode used to apply the tint to the foreground
17082      * drawable, if specified.
17083      *
17084      * @return the blending mode used to apply the tint to the foreground
17085      *         drawable
17086      * @attr ref android.R.styleable#View_foregroundTintMode
17087      * @see #setBackgroundTintMode(PorterDuff.Mode)
17088      */
17089     @Nullable
17090     public PorterDuff.Mode getForegroundTintMode() {
17091         return mForegroundInfo != null && mForegroundInfo.mTintInfo != null
17092                 ? mForegroundInfo.mTintInfo.mTintMode : null;
17093     }
17094
17095     private void applyForegroundTint() {
17096         if (mForegroundInfo != null && mForegroundInfo.mDrawable != null
17097                 && mForegroundInfo.mTintInfo != null) {
17098             final TintInfo tintInfo = mForegroundInfo.mTintInfo;
17099             if (tintInfo.mHasTintList || tintInfo.mHasTintMode) {
17100                 mForegroundInfo.mDrawable = mForegroundInfo.mDrawable.mutate();
17101
17102                 if (tintInfo.mHasTintList) {
17103                     mForegroundInfo.mDrawable.setTintList(tintInfo.mTintList);
17104                 }
17105
17106                 if (tintInfo.mHasTintMode) {
17107                     mForegroundInfo.mDrawable.setTintMode(tintInfo.mTintMode);
17108                 }
17109
17110                 // The drawable (or one of its children) may not have been
17111                 // stateful before applying the tint, so let's try again.
17112                 if (mForegroundInfo.mDrawable.isStateful()) {
17113                     mForegroundInfo.mDrawable.setState(getDrawableState());
17114                 }
17115             }
17116         }
17117     }
17118
17119     /**
17120      * Draw any foreground content for this view.
17121      *
17122      * <p>Foreground content may consist of scroll bars, a {@link #setForeground foreground}
17123      * drawable or other view-specific decorations. The foreground is drawn on top of the
17124      * primary view content.</p>
17125      *
17126      * @param canvas canvas to draw into
17127      */
17128     public void onDrawForeground(Canvas canvas) {
17129         onDrawScrollBars(canvas);
17130
17131         final Drawable foreground = mForegroundInfo != null ? mForegroundInfo.mDrawable : null;
17132         if (foreground != null) {
17133             if (mForegroundInfo.mBoundsChanged) {
17134                 mForegroundInfo.mBoundsChanged = false;
17135                 final Rect selfBounds = mForegroundInfo.mSelfBounds;
17136                 final Rect overlayBounds = mForegroundInfo.mOverlayBounds;
17137
17138                 if (mForegroundInfo.mInsidePadding) {
17139                     selfBounds.set(0, 0, getWidth(), getHeight());
17140                 } else {
17141                     selfBounds.set(getPaddingLeft(), getPaddingTop(),
17142                             getWidth() - getPaddingRight(), getHeight() - getPaddingBottom());
17143                 }
17144
17145                 final int ld = getLayoutDirection();
17146                 Gravity.apply(mForegroundInfo.mGravity, foreground.getIntrinsicWidth(),
17147                         foreground.getIntrinsicHeight(), selfBounds, overlayBounds, ld);
17148                 foreground.setBounds(overlayBounds);
17149             }
17150
17151             foreground.draw(canvas);
17152         }
17153     }
17154
17155     /**
17156      * Sets the padding. The view may add on the space required to display
17157      * the scrollbars, depending on the style and visibility of the scrollbars.
17158      * So the values returned from {@link #getPaddingLeft}, {@link #getPaddingTop},
17159      * {@link #getPaddingRight} and {@link #getPaddingBottom} may be different
17160      * from the values set in this call.
17161      *
17162      * @attr ref android.R.styleable#View_padding
17163      * @attr ref android.R.styleable#View_paddingBottom
17164      * @attr ref android.R.styleable#View_paddingLeft
17165      * @attr ref android.R.styleable#View_paddingRight
17166      * @attr ref android.R.styleable#View_paddingTop
17167      * @param left the left padding in pixels
17168      * @param top the top padding in pixels
17169      * @param right the right padding in pixels
17170      * @param bottom the bottom padding in pixels
17171      */
17172     public void setPadding(int left, int top, int right, int bottom) {
17173         resetResolvedPaddingInternal();
17174
17175         mUserPaddingStart = UNDEFINED_PADDING;
17176         mUserPaddingEnd = UNDEFINED_PADDING;
17177
17178         mUserPaddingLeftInitial = left;
17179         mUserPaddingRightInitial = right;
17180
17181         mLeftPaddingDefined = true;
17182         mRightPaddingDefined = true;
17183
17184         internalSetPadding(left, top, right, bottom);
17185     }
17186
17187     /**
17188      * @hide
17189      */
17190     protected void internalSetPadding(int left, int top, int right, int bottom) {
17191         mUserPaddingLeft = left;
17192         mUserPaddingRight = right;
17193         mUserPaddingBottom = bottom;
17194
17195         final int viewFlags = mViewFlags;
17196         boolean changed = false;
17197
17198         // Common case is there are no scroll bars.
17199         if ((viewFlags & (SCROLLBARS_VERTICAL|SCROLLBARS_HORIZONTAL)) != 0) {
17200             if ((viewFlags & SCROLLBARS_VERTICAL) != 0) {
17201                 final int offset = (viewFlags & SCROLLBARS_INSET_MASK) == 0
17202                         ? 0 : getVerticalScrollbarWidth();
17203                 switch (mVerticalScrollbarPosition) {
17204                     case SCROLLBAR_POSITION_DEFAULT:
17205                         if (isLayoutRtl()) {
17206                             left += offset;
17207                         } else {
17208                             right += offset;
17209                         }
17210                         break;
17211                     case SCROLLBAR_POSITION_RIGHT:
17212                         right += offset;
17213                         break;
17214                     case SCROLLBAR_POSITION_LEFT:
17215                         left += offset;
17216                         break;
17217                 }
17218             }
17219             if ((viewFlags & SCROLLBARS_HORIZONTAL) != 0) {
17220                 bottom += (viewFlags & SCROLLBARS_INSET_MASK) == 0
17221                         ? 0 : getHorizontalScrollbarHeight();
17222             }
17223         }
17224
17225         if (mPaddingLeft != left) {
17226             changed = true;
17227             mPaddingLeft = left;
17228         }
17229         if (mPaddingTop != top) {
17230             changed = true;
17231             mPaddingTop = top;
17232         }
17233         if (mPaddingRight != right) {
17234             changed = true;
17235             mPaddingRight = right;
17236         }
17237         if (mPaddingBottom != bottom) {
17238             changed = true;
17239             mPaddingBottom = bottom;
17240         }
17241
17242         if (changed) {
17243             requestLayout();
17244             invalidateOutline();
17245         }
17246     }
17247
17248     /**
17249      * Sets the relative padding. The view may add on the space required to display
17250      * the scrollbars, depending on the style and visibility of the scrollbars.
17251      * So the values returned from {@link #getPaddingStart}, {@link #getPaddingTop},
17252      * {@link #getPaddingEnd} and {@link #getPaddingBottom} may be different
17253      * from the values set in this call.
17254      *
17255      * @attr ref android.R.styleable#View_padding
17256      * @attr ref android.R.styleable#View_paddingBottom
17257      * @attr ref android.R.styleable#View_paddingStart
17258      * @attr ref android.R.styleable#View_paddingEnd
17259      * @attr ref android.R.styleable#View_paddingTop
17260      * @param start the start padding in pixels
17261      * @param top the top padding in pixels
17262      * @param end the end padding in pixels
17263      * @param bottom the bottom padding in pixels
17264      */
17265     public void setPaddingRelative(int start, int top, int end, int bottom) {
17266         resetResolvedPaddingInternal();
17267
17268         mUserPaddingStart = start;
17269         mUserPaddingEnd = end;
17270         mLeftPaddingDefined = true;
17271         mRightPaddingDefined = true;
17272
17273         switch(getLayoutDirection()) {
17274             case LAYOUT_DIRECTION_RTL:
17275                 mUserPaddingLeftInitial = end;
17276                 mUserPaddingRightInitial = start;
17277                 internalSetPadding(end, top, start, bottom);
17278                 break;
17279             case LAYOUT_DIRECTION_LTR:
17280             default:
17281                 mUserPaddingLeftInitial = start;
17282                 mUserPaddingRightInitial = end;
17283                 internalSetPadding(start, top, end, bottom);
17284         }
17285     }
17286
17287     /**
17288      * Returns the top padding of this view.
17289      *
17290      * @return the top padding in pixels
17291      */
17292     public int getPaddingTop() {
17293         return mPaddingTop;
17294     }
17295
17296     /**
17297      * Returns the bottom padding of this view. If there are inset and enabled
17298      * scrollbars, this value may include the space required to display the
17299      * scrollbars as well.
17300      *
17301      * @return the bottom padding in pixels
17302      */
17303     public int getPaddingBottom() {
17304         return mPaddingBottom;
17305     }
17306
17307     /**
17308      * Returns the left padding of this view. If there are inset and enabled
17309      * scrollbars, this value may include the space required to display the
17310      * scrollbars as well.
17311      *
17312      * @return the left padding in pixels
17313      */
17314     public int getPaddingLeft() {
17315         if (!isPaddingResolved()) {
17316             resolvePadding();
17317         }
17318         return mPaddingLeft;
17319     }
17320
17321     /**
17322      * Returns the start padding of this view depending on its resolved layout direction.
17323      * If there are inset and enabled scrollbars, this value may include the space
17324      * required to display the scrollbars as well.
17325      *
17326      * @return the start padding in pixels
17327      */
17328     public int getPaddingStart() {
17329         if (!isPaddingResolved()) {
17330             resolvePadding();
17331         }
17332         return (getLayoutDirection() == LAYOUT_DIRECTION_RTL) ?
17333                 mPaddingRight : mPaddingLeft;
17334     }
17335
17336     /**
17337      * Returns the right padding of this view. If there are inset and enabled
17338      * scrollbars, this value may include the space required to display the
17339      * scrollbars as well.
17340      *
17341      * @return the right padding in pixels
17342      */
17343     public int getPaddingRight() {
17344         if (!isPaddingResolved()) {
17345             resolvePadding();
17346         }
17347         return mPaddingRight;
17348     }
17349
17350     /**
17351      * Returns the end padding of this view depending on its resolved layout direction.
17352      * If there are inset and enabled scrollbars, this value may include the space
17353      * required to display the scrollbars as well.
17354      *
17355      * @return the end padding in pixels
17356      */
17357     public int getPaddingEnd() {
17358         if (!isPaddingResolved()) {
17359             resolvePadding();
17360         }
17361         return (getLayoutDirection() == LAYOUT_DIRECTION_RTL) ?
17362                 mPaddingLeft : mPaddingRight;
17363     }
17364
17365     /**
17366      * Return if the padding has been set through relative values
17367      * {@link #setPaddingRelative(int, int, int, int)} or through
17368      * @attr ref android.R.styleable#View_paddingStart or
17369      * @attr ref android.R.styleable#View_paddingEnd
17370      *
17371      * @return true if the padding is relative or false if it is not.
17372      */
17373     public boolean isPaddingRelative() {
17374         return (mUserPaddingStart != UNDEFINED_PADDING || mUserPaddingEnd != UNDEFINED_PADDING);
17375     }
17376
17377     Insets computeOpticalInsets() {
17378         return (mBackground == null) ? Insets.NONE : mBackground.getOpticalInsets();
17379     }
17380
17381     /**
17382      * @hide
17383      */
17384     public void resetPaddingToInitialValues() {
17385         if (isRtlCompatibilityMode()) {
17386             mPaddingLeft = mUserPaddingLeftInitial;
17387             mPaddingRight = mUserPaddingRightInitial;
17388             return;
17389         }
17390         if (isLayoutRtl()) {
17391             mPaddingLeft = (mUserPaddingEnd >= 0) ? mUserPaddingEnd : mUserPaddingLeftInitial;
17392             mPaddingRight = (mUserPaddingStart >= 0) ? mUserPaddingStart : mUserPaddingRightInitial;
17393         } else {
17394             mPaddingLeft = (mUserPaddingStart >= 0) ? mUserPaddingStart : mUserPaddingLeftInitial;
17395             mPaddingRight = (mUserPaddingEnd >= 0) ? mUserPaddingEnd : mUserPaddingRightInitial;
17396         }
17397     }
17398
17399     /**
17400      * @hide
17401      */
17402     public Insets getOpticalInsets() {
17403         if (mLayoutInsets == null) {
17404             mLayoutInsets = computeOpticalInsets();
17405         }
17406         return mLayoutInsets;
17407     }
17408
17409     /**
17410      * Set this view's optical insets.
17411      *
17412      * <p>This method should be treated similarly to setMeasuredDimension and not as a general
17413      * property. Views that compute their own optical insets should call it as part of measurement.
17414      * This method does not request layout. If you are setting optical insets outside of
17415      * measure/layout itself you will want to call requestLayout() yourself.
17416      * </p>
17417      * @hide
17418      */
17419     public void setOpticalInsets(Insets insets) {
17420         mLayoutInsets = insets;
17421     }
17422
17423     /**
17424      * Changes the selection state of this view. A view can be selected or not.
17425      * Note that selection is not the same as focus. Views are typically
17426      * selected in the context of an AdapterView like ListView or GridView;
17427      * the selected view is the view that is highlighted.
17428      *
17429      * @param selected true if the view must be selected, false otherwise
17430      */
17431     public void setSelected(boolean selected) {
17432         //noinspection DoubleNegation
17433         if (((mPrivateFlags & PFLAG_SELECTED) != 0) != selected) {
17434             mPrivateFlags = (mPrivateFlags & ~PFLAG_SELECTED) | (selected ? PFLAG_SELECTED : 0);
17435             if (!selected) resetPressedState();
17436             invalidate(true);
17437             refreshDrawableState();
17438             dispatchSetSelected(selected);
17439             if (selected) {
17440                 sendAccessibilityEvent(AccessibilityEvent.TYPE_VIEW_SELECTED);
17441             } else {
17442                 notifyViewAccessibilityStateChangedIfNeeded(
17443                         AccessibilityEvent.CONTENT_CHANGE_TYPE_UNDEFINED);
17444             }
17445         }
17446     }
17447
17448     /**
17449      * Dispatch setSelected to all of this View's children.
17450      *
17451      * @see #setSelected(boolean)
17452      *
17453      * @param selected The new selected state
17454      */
17455     protected void dispatchSetSelected(boolean selected) {
17456     }
17457
17458     /**
17459      * Indicates the selection state of this view.
17460      *
17461      * @return true if the view is selected, false otherwise
17462      */
17463     @ViewDebug.ExportedProperty
17464     public boolean isSelected() {
17465         return (mPrivateFlags & PFLAG_SELECTED) != 0;
17466     }
17467
17468     /**
17469      * Changes the activated state of this view. A view can be activated or not.
17470      * Note that activation is not the same as selection.  Selection is
17471      * a transient property, representing the view (hierarchy) the user is
17472      * currently interacting with.  Activation is a longer-term state that the
17473      * user can move views in and out of.  For example, in a list view with
17474      * single or multiple selection enabled, the views in the current selection
17475      * set are activated.  (Um, yeah, we are deeply sorry about the terminology
17476      * here.)  The activated state is propagated down to children of the view it
17477      * is set on.
17478      *
17479      * @param activated true if the view must be activated, false otherwise
17480      */
17481     public void setActivated(boolean activated) {
17482         //noinspection DoubleNegation
17483         if (((mPrivateFlags & PFLAG_ACTIVATED) != 0) != activated) {
17484             mPrivateFlags = (mPrivateFlags & ~PFLAG_ACTIVATED) | (activated ? PFLAG_ACTIVATED : 0);
17485             invalidate(true);
17486             refreshDrawableState();
17487             dispatchSetActivated(activated);
17488         }
17489     }
17490
17491     /**
17492      * Dispatch setActivated to all of this View's children.
17493      *
17494      * @see #setActivated(boolean)
17495      *
17496      * @param activated The new activated state
17497      */
17498     protected void dispatchSetActivated(boolean activated) {
17499     }
17500
17501     /**
17502      * Indicates the activation state of this view.
17503      *
17504      * @return true if the view is activated, false otherwise
17505      */
17506     @ViewDebug.ExportedProperty
17507     public boolean isActivated() {
17508         return (mPrivateFlags & PFLAG_ACTIVATED) != 0;
17509     }
17510
17511     /**
17512      * Returns the ViewTreeObserver for this view's hierarchy. The view tree
17513      * observer can be used to get notifications when global events, like
17514      * layout, happen.
17515      *
17516      * The returned ViewTreeObserver observer is not guaranteed to remain
17517      * valid for the lifetime of this View. If the caller of this method keeps
17518      * a long-lived reference to ViewTreeObserver, it should always check for
17519      * the return value of {@link ViewTreeObserver#isAlive()}.
17520      *
17521      * @return The ViewTreeObserver for this view's hierarchy.
17522      */
17523     public ViewTreeObserver getViewTreeObserver() {
17524         if (mAttachInfo != null) {
17525             return mAttachInfo.mTreeObserver;
17526         }
17527         if (mFloatingTreeObserver == null) {
17528             mFloatingTreeObserver = new ViewTreeObserver();
17529         }
17530         return mFloatingTreeObserver;
17531     }
17532
17533     /**
17534      * <p>Finds the topmost view in the current view hierarchy.</p>
17535      *
17536      * @return the topmost view containing this view
17537      */
17538     public View getRootView() {
17539         if (mAttachInfo != null) {
17540             final View v = mAttachInfo.mRootView;
17541             if (v != null) {
17542                 return v;
17543             }
17544         }
17545
17546         View parent = this;
17547
17548         while (parent.mParent != null && parent.mParent instanceof View) {
17549             parent = (View) parent.mParent;
17550         }
17551
17552         return parent;
17553     }
17554
17555     /**
17556      * Transforms a motion event from view-local coordinates to on-screen
17557      * coordinates.
17558      *
17559      * @param ev the view-local motion event
17560      * @return false if the transformation could not be applied
17561      * @hide
17562      */
17563     public boolean toGlobalMotionEvent(MotionEvent ev) {
17564         final AttachInfo info = mAttachInfo;
17565         if (info == null) {
17566             return false;
17567         }
17568
17569         final Matrix m = info.mTmpMatrix;
17570         m.set(Matrix.IDENTITY_MATRIX);
17571         transformMatrixToGlobal(m);
17572         ev.transform(m);
17573         return true;
17574     }
17575
17576     /**
17577      * Transforms a motion event from on-screen coordinates to view-local
17578      * coordinates.
17579      *
17580      * @param ev the on-screen motion event
17581      * @return false if the transformation could not be applied
17582      * @hide
17583      */
17584     public boolean toLocalMotionEvent(MotionEvent ev) {
17585         final AttachInfo info = mAttachInfo;
17586         if (info == null) {
17587             return false;
17588         }
17589
17590         final Matrix m = info.mTmpMatrix;
17591         m.set(Matrix.IDENTITY_MATRIX);
17592         transformMatrixToLocal(m);
17593         ev.transform(m);
17594         return true;
17595     }
17596
17597     /**
17598      * Modifies the input matrix such that it maps view-local coordinates to
17599      * on-screen coordinates.
17600      *
17601      * @param m input matrix to modify
17602      * @hide
17603      */
17604     public void transformMatrixToGlobal(Matrix m) {
17605         final ViewParent parent = mParent;
17606         if (parent instanceof View) {
17607             final View vp = (View) parent;
17608             vp.transformMatrixToGlobal(m);
17609             m.preTranslate(-vp.mScrollX, -vp.mScrollY);
17610         } else if (parent instanceof ViewRootImpl) {
17611             final ViewRootImpl vr = (ViewRootImpl) parent;
17612             vr.transformMatrixToGlobal(m);
17613             m.preTranslate(0, -vr.mCurScrollY);
17614         }
17615
17616         m.preTranslate(mLeft, mTop);
17617
17618         if (!hasIdentityMatrix()) {
17619             m.preConcat(getMatrix());
17620         }
17621     }
17622
17623     /**
17624      * Modifies the input matrix such that it maps on-screen coordinates to
17625      * view-local coordinates.
17626      *
17627      * @param m input matrix to modify
17628      * @hide
17629      */
17630     public void transformMatrixToLocal(Matrix m) {
17631         final ViewParent parent = mParent;
17632         if (parent instanceof View) {
17633             final View vp = (View) parent;
17634             vp.transformMatrixToLocal(m);
17635             m.postTranslate(vp.mScrollX, vp.mScrollY);
17636         } else if (parent instanceof ViewRootImpl) {
17637             final ViewRootImpl vr = (ViewRootImpl) parent;
17638             vr.transformMatrixToLocal(m);
17639             m.postTranslate(0, vr.mCurScrollY);
17640         }
17641
17642         m.postTranslate(-mLeft, -mTop);
17643
17644         if (!hasIdentityMatrix()) {
17645             m.postConcat(getInverseMatrix());
17646         }
17647     }
17648
17649     /**
17650      * @hide
17651      */
17652     @ViewDebug.ExportedProperty(category = "layout", indexMapping = {
17653             @ViewDebug.IntToString(from = 0, to = "x"),
17654             @ViewDebug.IntToString(from = 1, to = "y")
17655     })
17656     public int[] getLocationOnScreen() {
17657         int[] location = new int[2];
17658         getLocationOnScreen(location);
17659         return location;
17660     }
17661
17662     /**
17663      * <p>Computes the coordinates of this view on the screen. The argument
17664      * must be an array of two integers. After the method returns, the array
17665      * contains the x and y location in that order.</p>
17666      *
17667      * @param location an array of two integers in which to hold the coordinates
17668      */
17669     public void getLocationOnScreen(@Size(2) int[] location) {
17670         getLocationInWindow(location);
17671
17672         final AttachInfo info = mAttachInfo;
17673         if (info != null) {
17674             location[0] += info.mWindowLeft;
17675             location[1] += info.mWindowTop;
17676         }
17677     }
17678
17679     /**
17680      * <p>Computes the coordinates of this view in its window. The argument
17681      * must be an array of two integers. After the method returns, the array
17682      * contains the x and y location in that order.</p>
17683      *
17684      * @param location an array of two integers in which to hold the coordinates
17685      */
17686     public void getLocationInWindow(@Size(2) int[] location) {
17687         if (location == null || location.length < 2) {
17688             throw new IllegalArgumentException("location must be an array of two integers");
17689         }
17690
17691         if (mAttachInfo == null) {
17692             // When the view is not attached to a window, this method does not make sense
17693             location[0] = location[1] = 0;
17694             return;
17695         }
17696
17697         float[] position = mAttachInfo.mTmpTransformLocation;
17698         position[0] = position[1] = 0.0f;
17699
17700         if (!hasIdentityMatrix()) {
17701             getMatrix().mapPoints(position);
17702         }
17703
17704         position[0] += mLeft;
17705         position[1] += mTop;
17706
17707         ViewParent viewParent = mParent;
17708         while (viewParent instanceof View) {
17709             final View view = (View) viewParent;
17710
17711             position[0] -= view.mScrollX;
17712             position[1] -= view.mScrollY;
17713
17714             if (!view.hasIdentityMatrix()) {
17715                 view.getMatrix().mapPoints(position);
17716             }
17717
17718             position[0] += view.mLeft;
17719             position[1] += view.mTop;
17720
17721             viewParent = view.mParent;
17722          }
17723
17724         if (viewParent instanceof ViewRootImpl) {
17725             // *cough*
17726             final ViewRootImpl vr = (ViewRootImpl) viewParent;
17727             position[1] -= vr.mCurScrollY;
17728         }
17729
17730         location[0] = (int) (position[0] + 0.5f);
17731         location[1] = (int) (position[1] + 0.5f);
17732     }
17733
17734     /**
17735      * {@hide}
17736      * @param id the id of the view to be found
17737      * @return the view of the specified id, null if cannot be found
17738      */
17739     protected View findViewTraversal(@IdRes int id) {
17740         if (id == mID) {
17741             return this;
17742         }
17743         return null;
17744     }
17745
17746     /**
17747      * {@hide}
17748      * @param tag the tag of the view to be found
17749      * @return the view of specified tag, null if cannot be found
17750      */
17751     protected View findViewWithTagTraversal(Object tag) {
17752         if (tag != null && tag.equals(mTag)) {
17753             return this;
17754         }
17755         return null;
17756     }
17757
17758     /**
17759      * {@hide}
17760      * @param predicate The predicate to evaluate.
17761      * @param childToSkip If not null, ignores this child during the recursive traversal.
17762      * @return The first view that matches the predicate or null.
17763      */
17764     protected View findViewByPredicateTraversal(Predicate<View> predicate, View childToSkip) {
17765         if (predicate.apply(this)) {
17766             return this;
17767         }
17768         return null;
17769     }
17770
17771     /**
17772      * Look for a child view with the given id.  If this view has the given
17773      * id, return this view.
17774      *
17775      * @param id The id to search for.
17776      * @return The view that has the given id in the hierarchy or null
17777      */
17778     @Nullable
17779     public final View findViewById(@IdRes int id) {
17780         if (id < 0) {
17781             return null;
17782         }
17783         return findViewTraversal(id);
17784     }
17785
17786     /**
17787      * Finds a view by its unuque and stable accessibility id.
17788      *
17789      * @param accessibilityId The searched accessibility id.
17790      * @return The found view.
17791      */
17792     final View findViewByAccessibilityId(int accessibilityId) {
17793         if (accessibilityId < 0) {
17794             return null;
17795         }
17796         return findViewByAccessibilityIdTraversal(accessibilityId);
17797     }
17798
17799     /**
17800      * Performs the traversal to find a view by its unuque and stable accessibility id.
17801      *
17802      * <strong>Note:</strong>This method does not stop at the root namespace
17803      * boundary since the user can touch the screen at an arbitrary location
17804      * potentially crossing the root namespace bounday which will send an
17805      * accessibility event to accessibility services and they should be able
17806      * to obtain the event source. Also accessibility ids are guaranteed to be
17807      * unique in the window.
17808      *
17809      * @param accessibilityId The accessibility id.
17810      * @return The found view.
17811      *
17812      * @hide
17813      */
17814     public View findViewByAccessibilityIdTraversal(int accessibilityId) {
17815         if (getAccessibilityViewId() == accessibilityId) {
17816             return this;
17817         }
17818         return null;
17819     }
17820
17821     /**
17822      * Look for a child view with the given tag.  If this view has the given
17823      * tag, return this view.
17824      *
17825      * @param tag The tag to search for, using "tag.equals(getTag())".
17826      * @return The View that has the given tag in the hierarchy or null
17827      */
17828     public final View findViewWithTag(Object tag) {
17829         if (tag == null) {
17830             return null;
17831         }
17832         return findViewWithTagTraversal(tag);
17833     }
17834
17835     /**
17836      * {@hide}
17837      * Look for a child view that matches the specified predicate.
17838      * If this view matches the predicate, return this view.
17839      *
17840      * @param predicate The predicate to evaluate.
17841      * @return The first view that matches the predicate or null.
17842      */
17843     public final View findViewByPredicate(Predicate<View> predicate) {
17844         return findViewByPredicateTraversal(predicate, null);
17845     }
17846
17847     /**
17848      * {@hide}
17849      * Look for a child view that matches the specified predicate,
17850      * starting with the specified view and its descendents and then
17851      * recusively searching the ancestors and siblings of that view
17852      * until this view is reached.
17853      *
17854      * This method is useful in cases where the predicate does not match
17855      * a single unique view (perhaps multiple views use the same id)
17856      * and we are trying to find the view that is "closest" in scope to the
17857      * starting view.
17858      *
17859      * @param start The view to start from.
17860      * @param predicate The predicate to evaluate.
17861      * @return The first view that matches the predicate or null.
17862      */
17863     public final View findViewByPredicateInsideOut(View start, Predicate<View> predicate) {
17864         View childToSkip = null;
17865         for (;;) {
17866             View view = start.findViewByPredicateTraversal(predicate, childToSkip);
17867             if (view != null || start == this) {
17868                 return view;
17869             }
17870
17871             ViewParent parent = start.getParent();
17872             if (parent == null || !(parent instanceof View)) {
17873                 return null;
17874             }
17875
17876             childToSkip = start;
17877             start = (View) parent;
17878         }
17879     }
17880
17881     /**
17882      * Sets the identifier for this view. The identifier does not have to be
17883      * unique in this view's hierarchy. The identifier should be a positive
17884      * number.
17885      *
17886      * @see #NO_ID
17887      * @see #getId()
17888      * @see #findViewById(int)
17889      *
17890      * @param id a number used to identify the view
17891      *
17892      * @attr ref android.R.styleable#View_id
17893      */
17894     public void setId(@IdRes int id) {
17895         mID = id;
17896         if (mID == View.NO_ID && mLabelForId != View.NO_ID) {
17897             mID = generateViewId();
17898         }
17899     }
17900
17901     /**
17902      * {@hide}
17903      *
17904      * @param isRoot true if the view belongs to the root namespace, false
17905      *        otherwise
17906      */
17907     public void setIsRootNamespace(boolean isRoot) {
17908         if (isRoot) {
17909             mPrivateFlags |= PFLAG_IS_ROOT_NAMESPACE;
17910         } else {
17911             mPrivateFlags &= ~PFLAG_IS_ROOT_NAMESPACE;
17912         }
17913     }
17914
17915     /**
17916      * {@hide}
17917      *
17918      * @return true if the view belongs to the root namespace, false otherwise
17919      */
17920     public boolean isRootNamespace() {
17921         return (mPrivateFlags&PFLAG_IS_ROOT_NAMESPACE) != 0;
17922     }
17923
17924     /**
17925      * Returns this view's identifier.
17926      *
17927      * @return a positive integer used to identify the view or {@link #NO_ID}
17928      *         if the view has no ID
17929      *
17930      * @see #setId(int)
17931      * @see #findViewById(int)
17932      * @attr ref android.R.styleable#View_id
17933      */
17934     @IdRes
17935     @ViewDebug.CapturedViewProperty
17936     public int getId() {
17937         return mID;
17938     }
17939
17940     /**
17941      * Returns this view's tag.
17942      *
17943      * @return the Object stored in this view as a tag, or {@code null} if not
17944      *         set
17945      *
17946      * @see #setTag(Object)
17947      * @see #getTag(int)
17948      */
17949     @ViewDebug.ExportedProperty
17950     public Object getTag() {
17951         return mTag;
17952     }
17953
17954     /**
17955      * Sets the tag associated with this view. A tag can be used to mark
17956      * a view in its hierarchy and does not have to be unique within the
17957      * hierarchy. Tags can also be used to store data within a view without
17958      * resorting to another data structure.
17959      *
17960      * @param tag an Object to tag the view with
17961      *
17962      * @see #getTag()
17963      * @see #setTag(int, Object)
17964      */
17965     public void setTag(final Object tag) {
17966         mTag = tag;
17967     }
17968
17969     /**
17970      * Returns the tag associated with this view and the specified key.
17971      *
17972      * @param key The key identifying the tag
17973      *
17974      * @return the Object stored in this view as a tag, or {@code null} if not
17975      *         set
17976      *
17977      * @see #setTag(int, Object)
17978      * @see #getTag()
17979      */
17980     public Object getTag(int key) {
17981         if (mKeyedTags != null) return mKeyedTags.get(key);
17982         return null;
17983     }
17984
17985     /**
17986      * Sets a tag associated with this view and a key. A tag can be used
17987      * to mark a view in its hierarchy and does not have to be unique within
17988      * the hierarchy. Tags can also be used to store data within a view
17989      * without resorting to another data structure.
17990      *
17991      * The specified key should be an id declared in the resources of the
17992      * application to ensure it is unique (see the <a
17993      * href="{@docRoot}guide/topics/resources/more-resources.html#Id">ID resource type</a>).
17994      * Keys identified as belonging to
17995      * the Android framework or not associated with any package will cause
17996      * an {@link IllegalArgumentException} to be thrown.
17997      *
17998      * @param key The key identifying the tag
17999      * @param tag An Object to tag the view with
18000      *
18001      * @throws IllegalArgumentException If they specified key is not valid
18002      *
18003      * @see #setTag(Object)
18004      * @see #getTag(int)
18005      */
18006     public void setTag(int key, final Object tag) {
18007         // If the package id is 0x00 or 0x01, it's either an undefined package
18008         // or a framework id
18009         if ((key >>> 24) < 2) {
18010             throw new IllegalArgumentException("The key must be an application-specific "
18011                     + "resource id.");
18012         }
18013
18014         setKeyedTag(key, tag);
18015     }
18016
18017     /**
18018      * Variation of {@link #setTag(int, Object)} that enforces the key to be a
18019      * framework id.
18020      *
18021      * @hide
18022      */
18023     public void setTagInternal(int key, Object tag) {
18024         if ((key >>> 24) != 0x1) {
18025             throw new IllegalArgumentException("The key must be a framework-specific "
18026                     + "resource id.");
18027         }
18028
18029         setKeyedTag(key, tag);
18030     }
18031
18032     private void setKeyedTag(int key, Object tag) {
18033         if (mKeyedTags == null) {
18034             mKeyedTags = new SparseArray<Object>(2);
18035         }
18036
18037         mKeyedTags.put(key, tag);
18038     }
18039
18040     /**
18041      * Prints information about this view in the log output, with the tag
18042      * {@link #VIEW_LOG_TAG}.
18043      *
18044      * @hide
18045      */
18046     public void debug() {
18047         debug(0);
18048     }
18049
18050     /**
18051      * Prints information about this view in the log output, with the tag
18052      * {@link #VIEW_LOG_TAG}. Each line in the output is preceded with an
18053      * indentation defined by the <code>depth</code>.
18054      *
18055      * @param depth the indentation level
18056      *
18057      * @hide
18058      */
18059     protected void debug(int depth) {
18060         String output = debugIndent(depth - 1);
18061
18062         output += "+ " + this;
18063         int id = getId();
18064         if (id != -1) {
18065             output += " (id=" + id + ")";
18066         }
18067         Object tag = getTag();
18068         if (tag != null) {
18069             output += " (tag=" + tag + ")";
18070         }
18071         Log.d(VIEW_LOG_TAG, output);
18072
18073         if ((mPrivateFlags & PFLAG_FOCUSED) != 0) {
18074             output = debugIndent(depth) + " FOCUSED";
18075             Log.d(VIEW_LOG_TAG, output);
18076         }
18077
18078         output = debugIndent(depth);
18079         output += "frame={" + mLeft + ", " + mTop + ", " + mRight
18080                 + ", " + mBottom + "} scroll={" + mScrollX + ", " + mScrollY
18081                 + "} ";
18082         Log.d(VIEW_LOG_TAG, output);
18083
18084         if (mPaddingLeft != 0 || mPaddingTop != 0 || mPaddingRight != 0
18085                 || mPaddingBottom != 0) {
18086             output = debugIndent(depth);
18087             output += "padding={" + mPaddingLeft + ", " + mPaddingTop
18088                     + ", " + mPaddingRight + ", " + mPaddingBottom + "}";
18089             Log.d(VIEW_LOG_TAG, output);
18090         }
18091
18092         output = debugIndent(depth);
18093         output += "mMeasureWidth=" + mMeasuredWidth +
18094                 " mMeasureHeight=" + mMeasuredHeight;
18095         Log.d(VIEW_LOG_TAG, output);
18096
18097         output = debugIndent(depth);
18098         if (mLayoutParams == null) {
18099             output += "BAD! no layout params";
18100         } else {
18101             output = mLayoutParams.debug(output);
18102         }
18103         Log.d(VIEW_LOG_TAG, output);
18104
18105         output = debugIndent(depth);
18106         output += "flags={";
18107         output += View.printFlags(mViewFlags);
18108         output += "}";
18109         Log.d(VIEW_LOG_TAG, output);
18110
18111         output = debugIndent(depth);
18112         output += "privateFlags={";
18113         output += View.printPrivateFlags(mPrivateFlags);
18114         output += "}";
18115         Log.d(VIEW_LOG_TAG, output);
18116     }
18117
18118     /**
18119      * Creates a string of whitespaces used for indentation.
18120      *
18121      * @param depth the indentation level
18122      * @return a String containing (depth * 2 + 3) * 2 white spaces
18123      *
18124      * @hide
18125      */
18126     protected static String debugIndent(int depth) {
18127         StringBuilder spaces = new StringBuilder((depth * 2 + 3) * 2);
18128         for (int i = 0; i < (depth * 2) + 3; i++) {
18129             spaces.append(' ').append(' ');
18130         }
18131         return spaces.toString();
18132     }
18133
18134     /**
18135      * <p>Return the offset of the widget's text baseline from the widget's top
18136      * boundary. If this widget does not support baseline alignment, this
18137      * method returns -1. </p>
18138      *
18139      * @return the offset of the baseline within the widget's bounds or -1
18140      *         if baseline alignment is not supported
18141      */
18142     @ViewDebug.ExportedProperty(category = "layout")
18143     public int getBaseline() {
18144         return -1;
18145     }
18146
18147     /**
18148      * Returns whether the view hierarchy is currently undergoing a layout pass. This
18149      * information is useful to avoid situations such as calling {@link #requestLayout()} during
18150      * a layout pass.
18151      *
18152      * @return whether the view hierarchy is currently undergoing a layout pass
18153      */
18154     public boolean isInLayout() {
18155         ViewRootImpl viewRoot = getViewRootImpl();
18156         return (viewRoot != null && viewRoot.isInLayout());
18157     }
18158
18159     /**
18160      * Call this when something has changed which has invalidated the
18161      * layout of this view. This will schedule a layout pass of the view
18162      * tree. This should not be called while the view hierarchy is currently in a layout
18163      * pass ({@link #isInLayout()}. If layout is happening, the request may be honored at the
18164      * end of the current layout pass (and then layout will run again) or after the current
18165      * frame is drawn and the next layout occurs.
18166      *
18167      * <p>Subclasses which override this method should call the superclass method to
18168      * handle possible request-during-layout errors correctly.</p>
18169      */
18170     @CallSuper
18171     public void requestLayout() {
18172         if (mMeasureCache != null) mMeasureCache.clear();
18173
18174         if (mAttachInfo != null && mAttachInfo.mViewRequestingLayout == null) {
18175             // Only trigger request-during-layout logic if this is the view requesting it,
18176             // not the views in its parent hierarchy
18177             ViewRootImpl viewRoot = getViewRootImpl();
18178             if (viewRoot != null && viewRoot.isInLayout()) {
18179                 if (!viewRoot.requestLayoutDuringLayout(this)) {
18180                     return;
18181                 }
18182             }
18183             mAttachInfo.mViewRequestingLayout = this;
18184         }
18185
18186         mPrivateFlags |= PFLAG_FORCE_LAYOUT;
18187         mPrivateFlags |= PFLAG_INVALIDATED;
18188
18189         if (mParent != null && !mParent.isLayoutRequested()) {
18190             mParent.requestLayout();
18191         }
18192         if (mAttachInfo != null && mAttachInfo.mViewRequestingLayout == this) {
18193             mAttachInfo.mViewRequestingLayout = null;
18194         }
18195     }
18196
18197     /**
18198      * Forces this view to be laid out during the next layout pass.
18199      * This method does not call requestLayout() or forceLayout()
18200      * on the parent.
18201      */
18202     public void forceLayout() {
18203         if (mMeasureCache != null) mMeasureCache.clear();
18204
18205         mPrivateFlags |= PFLAG_FORCE_LAYOUT;
18206         mPrivateFlags |= PFLAG_INVALIDATED;
18207     }
18208
18209     /**
18210      * <p>
18211      * This is called to find out how big a view should be. The parent
18212      * supplies constraint information in the width and height parameters.
18213      * </p>
18214      *
18215      * <p>
18216      * The actual measurement work of a view is performed in
18217      * {@link #onMeasure(int, int)}, called by this method. Therefore, only
18218      * {@link #onMeasure(int, int)} can and must be overridden by subclasses.
18219      * </p>
18220      *
18221      *
18222      * @param widthMeasureSpec Horizontal space requirements as imposed by the
18223      *        parent
18224      * @param heightMeasureSpec Vertical space requirements as imposed by the
18225      *        parent
18226      *
18227      * @see #onMeasure(int, int)
18228      */
18229     public final void measure(int widthMeasureSpec, int heightMeasureSpec) {
18230         boolean optical = isLayoutModeOptical(this);
18231         if (optical != isLayoutModeOptical(mParent)) {
18232             Insets insets = getOpticalInsets();
18233             int oWidth  = insets.left + insets.right;
18234             int oHeight = insets.top  + insets.bottom;
18235             widthMeasureSpec  = MeasureSpec.adjust(widthMeasureSpec,  optical ? -oWidth  : oWidth);
18236             heightMeasureSpec = MeasureSpec.adjust(heightMeasureSpec, optical ? -oHeight : oHeight);
18237         }
18238
18239         // Suppress sign extension for the low bytes
18240         long key = (long) widthMeasureSpec << 32 | (long) heightMeasureSpec & 0xffffffffL;
18241         if (mMeasureCache == null) mMeasureCache = new LongSparseLongArray(2);
18242
18243         final boolean forceLayout = (mPrivateFlags & PFLAG_FORCE_LAYOUT) == PFLAG_FORCE_LAYOUT;
18244         final boolean isExactly = MeasureSpec.getMode(widthMeasureSpec) == MeasureSpec.EXACTLY &&
18245                 MeasureSpec.getMode(heightMeasureSpec) == MeasureSpec.EXACTLY;
18246         final boolean matchingSize = isExactly &&
18247                 getMeasuredWidth() == MeasureSpec.getSize(widthMeasureSpec) &&
18248                 getMeasuredHeight() == MeasureSpec.getSize(heightMeasureSpec);
18249         if (forceLayout || !matchingSize &&
18250                 (widthMeasureSpec != mOldWidthMeasureSpec ||
18251                         heightMeasureSpec != mOldHeightMeasureSpec)) {
18252
18253             // first clears the measured dimension flag
18254             mPrivateFlags &= ~PFLAG_MEASURED_DIMENSION_SET;
18255
18256             resolveRtlPropertiesIfNeeded();
18257
18258             int cacheIndex = forceLayout ? -1 : mMeasureCache.indexOfKey(key);
18259             if (cacheIndex < 0 || sIgnoreMeasureCache) {
18260                 // measure ourselves, this should set the measured dimension flag back
18261                 onMeasure(widthMeasureSpec, heightMeasureSpec);
18262                 mPrivateFlags3 &= ~PFLAG3_MEASURE_NEEDED_BEFORE_LAYOUT;
18263             } else {
18264                 long value = mMeasureCache.valueAt(cacheIndex);
18265                 // Casting a long to int drops the high 32 bits, no mask needed
18266                 setMeasuredDimensionRaw((int) (value >> 32), (int) value);
18267                 mPrivateFlags3 |= PFLAG3_MEASURE_NEEDED_BEFORE_LAYOUT;
18268             }
18269
18270             // flag not set, setMeasuredDimension() was not invoked, we raise
18271             // an exception to warn the developer
18272             if ((mPrivateFlags & PFLAG_MEASURED_DIMENSION_SET) != PFLAG_MEASURED_DIMENSION_SET) {
18273                 throw new IllegalStateException("View with id " + getId() + ": "
18274                         + getClass().getName() + "#onMeasure() did not set the"
18275                         + " measured dimension by calling"
18276                         + " setMeasuredDimension()");
18277             }
18278
18279             mPrivateFlags |= PFLAG_LAYOUT_REQUIRED;
18280         }
18281
18282         mOldWidthMeasureSpec = widthMeasureSpec;
18283         mOldHeightMeasureSpec = heightMeasureSpec;
18284
18285         mMeasureCache.put(key, ((long) mMeasuredWidth) << 32 |
18286                 (long) mMeasuredHeight & 0xffffffffL); // suppress sign extension
18287     }
18288
18289     /**
18290      * <p>
18291      * Measure the view and its content to determine the measured width and the
18292      * measured height. This method is invoked by {@link #measure(int, int)} and
18293      * should be overridden by subclasses to provide accurate and efficient
18294      * measurement of their contents.
18295      * </p>
18296      *
18297      * <p>
18298      * <strong>CONTRACT:</strong> When overriding this method, you
18299      * <em>must</em> call {@link #setMeasuredDimension(int, int)} to store the
18300      * measured width and height of this view. Failure to do so will trigger an
18301      * <code>IllegalStateException</code>, thrown by
18302      * {@link #measure(int, int)}. Calling the superclass'
18303      * {@link #onMeasure(int, int)} is a valid use.
18304      * </p>
18305      *
18306      * <p>
18307      * The base class implementation of measure defaults to the background size,
18308      * unless a larger size is allowed by the MeasureSpec. Subclasses should
18309      * override {@link #onMeasure(int, int)} to provide better measurements of
18310      * their content.
18311      * </p>
18312      *
18313      * <p>
18314      * If this method is overridden, it is the subclass's responsibility to make
18315      * sure the measured height and width are at least the view's minimum height
18316      * and width ({@link #getSuggestedMinimumHeight()} and
18317      * {@link #getSuggestedMinimumWidth()}).
18318      * </p>
18319      *
18320      * @param widthMeasureSpec horizontal space requirements as imposed by the parent.
18321      *                         The requirements are encoded with
18322      *                         {@link android.view.View.MeasureSpec}.
18323      * @param heightMeasureSpec vertical space requirements as imposed by the parent.
18324      *                         The requirements are encoded with
18325      *                         {@link android.view.View.MeasureSpec}.
18326      *
18327      * @see #getMeasuredWidth()
18328      * @see #getMeasuredHeight()
18329      * @see #setMeasuredDimension(int, int)
18330      * @see #getSuggestedMinimumHeight()
18331      * @see #getSuggestedMinimumWidth()
18332      * @see android.view.View.MeasureSpec#getMode(int)
18333      * @see android.view.View.MeasureSpec#getSize(int)
18334      */
18335     protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
18336         setMeasuredDimension(getDefaultSize(getSuggestedMinimumWidth(), widthMeasureSpec),
18337                 getDefaultSize(getSuggestedMinimumHeight(), heightMeasureSpec));
18338     }
18339
18340     /**
18341      * <p>This method must be called by {@link #onMeasure(int, int)} to store the
18342      * measured width and measured height. Failing to do so will trigger an
18343      * exception at measurement time.</p>
18344      *
18345      * @param measuredWidth The measured width of this view.  May be a complex
18346      * bit mask as defined by {@link #MEASURED_SIZE_MASK} and
18347      * {@link #MEASURED_STATE_TOO_SMALL}.
18348      * @param measuredHeight The measured height of this view.  May be a complex
18349      * bit mask as defined by {@link #MEASURED_SIZE_MASK} and
18350      * {@link #MEASURED_STATE_TOO_SMALL}.
18351      */
18352     protected final void setMeasuredDimension(int measuredWidth, int measuredHeight) {
18353         boolean optical = isLayoutModeOptical(this);
18354         if (optical != isLayoutModeOptical(mParent)) {
18355             Insets insets = getOpticalInsets();
18356             int opticalWidth  = insets.left + insets.right;
18357             int opticalHeight = insets.top  + insets.bottom;
18358
18359             measuredWidth  += optical ? opticalWidth  : -opticalWidth;
18360             measuredHeight += optical ? opticalHeight : -opticalHeight;
18361         }
18362         setMeasuredDimensionRaw(measuredWidth, measuredHeight);
18363     }
18364
18365     /**
18366      * Sets the measured dimension without extra processing for things like optical bounds.
18367      * Useful for reapplying consistent values that have already been cooked with adjustments
18368      * for optical bounds, etc. such as those from the measurement cache.
18369      *
18370      * @param measuredWidth The measured width of this view.  May be a complex
18371      * bit mask as defined by {@link #MEASURED_SIZE_MASK} and
18372      * {@link #MEASURED_STATE_TOO_SMALL}.
18373      * @param measuredHeight The measured height of this view.  May be a complex
18374      * bit mask as defined by {@link #MEASURED_SIZE_MASK} and
18375      * {@link #MEASURED_STATE_TOO_SMALL}.
18376      */
18377     private void setMeasuredDimensionRaw(int measuredWidth, int measuredHeight) {
18378         mMeasuredWidth = measuredWidth;
18379         mMeasuredHeight = measuredHeight;
18380
18381         mPrivateFlags |= PFLAG_MEASURED_DIMENSION_SET;
18382     }
18383
18384     /**
18385      * Merge two states as returned by {@link #getMeasuredState()}.
18386      * @param curState The current state as returned from a view or the result
18387      * of combining multiple views.
18388      * @param newState The new view state to combine.
18389      * @return Returns a new integer reflecting the combination of the two
18390      * states.
18391      */
18392     public static int combineMeasuredStates(int curState, int newState) {
18393         return curState | newState;
18394     }
18395
18396     /**
18397      * Version of {@link #resolveSizeAndState(int, int, int)}
18398      * returning only the {@link #MEASURED_SIZE_MASK} bits of the result.
18399      */
18400     public static int resolveSize(int size, int measureSpec) {
18401         return resolveSizeAndState(size, measureSpec, 0) & MEASURED_SIZE_MASK;
18402     }
18403
18404     /**
18405      * Utility to reconcile a desired size and state, with constraints imposed
18406      * by a MeasureSpec. Will take the desired size, unless a different size
18407      * is imposed by the constraints. The returned value is a compound integer,
18408      * with the resolved size in the {@link #MEASURED_SIZE_MASK} bits and
18409      * optionally the bit {@link #MEASURED_STATE_TOO_SMALL} set if the
18410      * resulting size is smaller than the size the view wants to be.
18411      *
18412      * @param size How big the view wants to be.
18413      * @param measureSpec Constraints imposed by the parent.
18414      * @param childMeasuredState Size information bit mask for the view's
18415      *                           children.
18416      * @return Size information bit mask as defined by
18417      *         {@link #MEASURED_SIZE_MASK} and
18418      *         {@link #MEASURED_STATE_TOO_SMALL}.
18419      */
18420     public static int resolveSizeAndState(int size, int measureSpec, int childMeasuredState) {
18421         final int specMode = MeasureSpec.getMode(measureSpec);
18422         final int specSize = MeasureSpec.getSize(measureSpec);
18423         final int result;
18424         switch (specMode) {
18425             case MeasureSpec.AT_MOST:
18426                 if (specSize < size) {
18427                     result = specSize | MEASURED_STATE_TOO_SMALL;
18428                 } else {
18429                     result = size;
18430                 }
18431                 break;
18432             case MeasureSpec.EXACTLY:
18433                 result = specSize;
18434                 break;
18435             case MeasureSpec.UNSPECIFIED:
18436             default:
18437                 result = size;
18438         }
18439         return result | (childMeasuredState & MEASURED_STATE_MASK);
18440     }
18441
18442     /**
18443      * Utility to return a default size. Uses the supplied size if the
18444      * MeasureSpec imposed no constraints. Will get larger if allowed
18445      * by the MeasureSpec.
18446      *
18447      * @param size Default size for this view
18448      * @param measureSpec Constraints imposed by the parent
18449      * @return The size this view should be.
18450      */
18451     public static int getDefaultSize(int size, int measureSpec) {
18452         int result = size;
18453         int specMode = MeasureSpec.getMode(measureSpec);
18454         int specSize = MeasureSpec.getSize(measureSpec);
18455
18456         switch (specMode) {
18457         case MeasureSpec.UNSPECIFIED:
18458             result = size;
18459             break;
18460         case MeasureSpec.AT_MOST:
18461         case MeasureSpec.EXACTLY:
18462             result = specSize;
18463             break;
18464         }
18465         return result;
18466     }
18467
18468     /**
18469      * Returns the suggested minimum height that the view should use. This
18470      * returns the maximum of the view's minimum height
18471      * and the background's minimum height
18472      * ({@link android.graphics.drawable.Drawable#getMinimumHeight()}).
18473      * <p>
18474      * When being used in {@link #onMeasure(int, int)}, the caller should still
18475      * ensure the returned height is within the requirements of the parent.
18476      *
18477      * @return The suggested minimum height of the view.
18478      */
18479     protected int getSuggestedMinimumHeight() {
18480         return (mBackground == null) ? mMinHeight : max(mMinHeight, mBackground.getMinimumHeight());
18481
18482     }
18483
18484     /**
18485      * Returns the suggested minimum width that the view should use. This
18486      * returns the maximum of the view's minimum width)
18487      * and the background's minimum width
18488      *  ({@link android.graphics.drawable.Drawable#getMinimumWidth()}).
18489      * <p>
18490      * When being used in {@link #onMeasure(int, int)}, the caller should still
18491      * ensure the returned width is within the requirements of the parent.
18492      *
18493      * @return The suggested minimum width of the view.
18494      */
18495     protected int getSuggestedMinimumWidth() {
18496         return (mBackground == null) ? mMinWidth : max(mMinWidth, mBackground.getMinimumWidth());
18497     }
18498
18499     /**
18500      * Returns the minimum height of the view.
18501      *
18502      * @return the minimum height the view will try to be.
18503      *
18504      * @see #setMinimumHeight(int)
18505      *
18506      * @attr ref android.R.styleable#View_minHeight
18507      */
18508     public int getMinimumHeight() {
18509         return mMinHeight;
18510     }
18511
18512     /**
18513      * Sets the minimum height of the view. It is not guaranteed the view will
18514      * be able to achieve this minimum height (for example, if its parent layout
18515      * constrains it with less available height).
18516      *
18517      * @param minHeight The minimum height the view will try to be.
18518      *
18519      * @see #getMinimumHeight()
18520      *
18521      * @attr ref android.R.styleable#View_minHeight
18522      */
18523     public void setMinimumHeight(int minHeight) {
18524         mMinHeight = minHeight;
18525         requestLayout();
18526     }
18527
18528     /**
18529      * Returns the minimum width of the view.
18530      *
18531      * @return the minimum width the view will try to be.
18532      *
18533      * @see #setMinimumWidth(int)
18534      *
18535      * @attr ref android.R.styleable#View_minWidth
18536      */
18537     public int getMinimumWidth() {
18538         return mMinWidth;
18539     }
18540
18541     /**
18542      * Sets the minimum width of the view. It is not guaranteed the view will
18543      * be able to achieve this minimum width (for example, if its parent layout
18544      * constrains it with less available width).
18545      *
18546      * @param minWidth The minimum width the view will try to be.
18547      *
18548      * @see #getMinimumWidth()
18549      *
18550      * @attr ref android.R.styleable#View_minWidth
18551      */
18552     public void setMinimumWidth(int minWidth) {
18553         mMinWidth = minWidth;
18554         requestLayout();
18555
18556     }
18557
18558     /**
18559      * Get the animation currently associated with this view.
18560      *
18561      * @return The animation that is currently playing or
18562      *         scheduled to play for this view.
18563      */
18564     public Animation getAnimation() {
18565         return mCurrentAnimation;
18566     }
18567
18568     /**
18569      * Start the specified animation now.
18570      *
18571      * @param animation the animation to start now
18572      */
18573     public void startAnimation(Animation animation) {
18574         animation.setStartTime(Animation.START_ON_FIRST_FRAME);
18575         setAnimation(animation);
18576         invalidateParentCaches();
18577         invalidate(true);
18578     }
18579
18580     /**
18581      * Cancels any animations for this view.
18582      */
18583     public void clearAnimation() {
18584         if (mCurrentAnimation != null) {
18585             mCurrentAnimation.detach();
18586         }
18587         mCurrentAnimation = null;
18588         invalidateParentIfNeeded();
18589     }
18590
18591     /**
18592      * Sets the next animation to play for this view.
18593      * If you want the animation to play immediately, use
18594      * {@link #startAnimation(android.view.animation.Animation)} instead.
18595      * This method provides allows fine-grained
18596      * control over the start time and invalidation, but you
18597      * must make sure that 1) the animation has a start time set, and
18598      * 2) the view's parent (which controls animations on its children)
18599      * will be invalidated when the animation is supposed to
18600      * start.
18601      *
18602      * @param animation The next animation, or null.
18603      */
18604     public void setAnimation(Animation animation) {
18605         mCurrentAnimation = animation;
18606
18607         if (animation != null) {
18608             // If the screen is off assume the animation start time is now instead of
18609             // the next frame we draw. Keeping the START_ON_FIRST_FRAME start time
18610             // would cause the animation to start when the screen turns back on
18611             if (mAttachInfo != null && mAttachInfo.mDisplayState == Display.STATE_OFF
18612                     && animation.getStartTime() == Animation.START_ON_FIRST_FRAME) {
18613                 animation.setStartTime(AnimationUtils.currentAnimationTimeMillis());
18614             }
18615             animation.reset();
18616         }
18617     }
18618
18619     /**
18620      * Invoked by a parent ViewGroup to notify the start of the animation
18621      * currently associated with this view. If you override this method,
18622      * always call super.onAnimationStart();
18623      *
18624      * @see #setAnimation(android.view.animation.Animation)
18625      * @see #getAnimation()
18626      */
18627     @CallSuper
18628     protected void onAnimationStart() {
18629         mPrivateFlags |= PFLAG_ANIMATION_STARTED;
18630     }
18631
18632     /**
18633      * Invoked by a parent ViewGroup to notify the end of the animation
18634      * currently associated with this view. If you override this method,
18635      * always call super.onAnimationEnd();
18636      *
18637      * @see #setAnimation(android.view.animation.Animation)
18638      * @see #getAnimation()
18639      */
18640     @CallSuper
18641     protected void onAnimationEnd() {
18642         mPrivateFlags &= ~PFLAG_ANIMATION_STARTED;
18643     }
18644
18645     /**
18646      * Invoked if there is a Transform that involves alpha. Subclass that can
18647      * draw themselves with the specified alpha should return true, and then
18648      * respect that alpha when their onDraw() is called. If this returns false
18649      * then the view may be redirected to draw into an offscreen buffer to
18650      * fulfill the request, which will look fine, but may be slower than if the
18651      * subclass handles it internally. The default implementation returns false.
18652      *
18653      * @param alpha The alpha (0..255) to apply to the view's drawing
18654      * @return true if the view can draw with the specified alpha.
18655      */
18656     protected boolean onSetAlpha(int alpha) {
18657         return false;
18658     }
18659
18660     /**
18661      * This is used by the RootView to perform an optimization when
18662      * the view hierarchy contains one or several SurfaceView.
18663      * SurfaceView is always considered transparent, but its children are not,
18664      * therefore all View objects remove themselves from the global transparent
18665      * region (passed as a parameter to this function).
18666      *
18667      * @param region The transparent region for this ViewAncestor (window).
18668      *
18669      * @return Returns true if the effective visibility of the view at this
18670      * point is opaque, regardless of the transparent region; returns false
18671      * if it is possible for underlying windows to be seen behind the view.
18672      *
18673      * {@hide}
18674      */
18675     public boolean gatherTransparentRegion(Region region) {
18676         final AttachInfo attachInfo = mAttachInfo;
18677         if (region != null && attachInfo != null) {
18678             final int pflags = mPrivateFlags;
18679             if ((pflags & PFLAG_SKIP_DRAW) == 0) {
18680                 // The SKIP_DRAW flag IS NOT set, so this view draws. We need to
18681                 // remove it from the transparent region.
18682                 final int[] location = attachInfo.mTransparentLocation;
18683                 getLocationInWindow(location);
18684                 region.op(location[0], location[1], location[0] + mRight - mLeft,
18685                         location[1] + mBottom - mTop, Region.Op.DIFFERENCE);
18686             } else if ((pflags & PFLAG_ONLY_DRAWS_BACKGROUND) != 0 && mBackground != null &&
18687                     mBackground.getOpacity() != PixelFormat.TRANSPARENT) {
18688                 // The ONLY_DRAWS_BACKGROUND flag IS set and the background drawable
18689                 // exists, so we remove the background drawable's non-transparent
18690                 // parts from this transparent region.
18691                 applyDrawableToTransparentRegion(mBackground, region);
18692             }
18693             final Drawable foreground = mForegroundInfo != null ? mForegroundInfo.mDrawable : null;
18694             if (foreground != null) {
18695                 applyDrawableToTransparentRegion(mForegroundInfo.mDrawable, region);
18696             }
18697         }
18698         return true;
18699     }
18700
18701     /**
18702      * Play a sound effect for this view.
18703      *
18704      * <p>The framework will play sound effects for some built in actions, such as
18705      * clicking, but you may wish to play these effects in your widget,
18706      * for instance, for internal navigation.
18707      *
18708      * <p>The sound effect will only be played if sound effects are enabled by the user, and
18709      * {@link #isSoundEffectsEnabled()} is true.
18710      *
18711      * @param soundConstant One of the constants defined in {@link SoundEffectConstants}
18712      */
18713     public void playSoundEffect(int soundConstant) {
18714         if (mAttachInfo == null || mAttachInfo.mRootCallbacks == null || !isSoundEffectsEnabled()) {
18715             return;
18716         }
18717         mAttachInfo.mRootCallbacks.playSoundEffect(soundConstant);
18718     }
18719
18720     /**
18721      * BZZZTT!!1!
18722      *
18723      * <p>Provide haptic feedback to the user for this view.
18724      *
18725      * <p>The framework will provide haptic feedback for some built in actions,
18726      * such as long presses, but you may wish to provide feedback for your
18727      * own widget.
18728      *
18729      * <p>The feedback will only be performed if
18730      * {@link #isHapticFeedbackEnabled()} is true.
18731      *
18732      * @param feedbackConstant One of the constants defined in
18733      * {@link HapticFeedbackConstants}
18734      */
18735     public boolean performHapticFeedback(int feedbackConstant) {
18736         return performHapticFeedback(feedbackConstant, 0);
18737     }
18738
18739     /**
18740      * BZZZTT!!1!
18741      *
18742      * <p>Like {@link #performHapticFeedback(int)}, with additional options.
18743      *
18744      * @param feedbackConstant One of the constants defined in
18745      * {@link HapticFeedbackConstants}
18746      * @param flags Additional flags as per {@link HapticFeedbackConstants}.
18747      */
18748     public boolean performHapticFeedback(int feedbackConstant, int flags) {
18749         if (mAttachInfo == null) {
18750             return false;
18751         }
18752         //noinspection SimplifiableIfStatement
18753         if ((flags & HapticFeedbackConstants.FLAG_IGNORE_VIEW_SETTING) == 0
18754                 && !isHapticFeedbackEnabled()) {
18755             return false;
18756         }
18757         return mAttachInfo.mRootCallbacks.performHapticFeedback(feedbackConstant,
18758                 (flags & HapticFeedbackConstants.FLAG_IGNORE_GLOBAL_SETTING) != 0);
18759     }
18760
18761     /**
18762      * Request that the visibility of the status bar or other screen/window
18763      * decorations be changed.
18764      *
18765      * <p>This method is used to put the over device UI into temporary modes
18766      * where the user's attention is focused more on the application content,
18767      * by dimming or hiding surrounding system affordances.  This is typically
18768      * used in conjunction with {@link Window#FEATURE_ACTION_BAR_OVERLAY
18769      * Window.FEATURE_ACTION_BAR_OVERLAY}, allowing the applications content
18770      * to be placed behind the action bar (and with these flags other system
18771      * affordances) so that smooth transitions between hiding and showing them
18772      * can be done.
18773      *
18774      * <p>Two representative examples of the use of system UI visibility is
18775      * implementing a content browsing application (like a magazine reader)
18776      * and a video playing application.
18777      *
18778      * <p>The first code shows a typical implementation of a View in a content
18779      * browsing application.  In this implementation, the application goes
18780      * into a content-oriented mode by hiding the status bar and action bar,
18781      * and putting the navigation elements into lights out mode.  The user can
18782      * then interact with content while in this mode.  Such an application should
18783      * provide an easy way for the user to toggle out of the mode (such as to
18784      * check information in the status bar or access notifications).  In the
18785      * implementation here, this is done simply by tapping on the content.
18786      *
18787      * {@sample development/samples/ApiDemos/src/com/example/android/apis/view/ContentBrowserActivity.java
18788      *      content}
18789      *
18790      * <p>This second code sample shows a typical implementation of a View
18791      * in a video playing application.  In this situation, while the video is
18792      * playing the application would like to go into a complete full-screen mode,
18793      * to use as much of the display as possible for the video.  When in this state
18794      * the user can not interact with the application; the system intercepts
18795      * touching on the screen to pop the UI out of full screen mode.  See
18796      * {@link #fitSystemWindows(Rect)} for a sample layout that goes with this code.
18797      *
18798      * {@sample development/samples/ApiDemos/src/com/example/android/apis/view/VideoPlayerActivity.java
18799      *      content}
18800      *
18801      * @param visibility  Bitwise-or of flags {@link #SYSTEM_UI_FLAG_LOW_PROFILE},
18802      * {@link #SYSTEM_UI_FLAG_HIDE_NAVIGATION}, {@link #SYSTEM_UI_FLAG_FULLSCREEN},
18803      * {@link #SYSTEM_UI_FLAG_LAYOUT_STABLE}, {@link #SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION},
18804      * {@link #SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN}, {@link #SYSTEM_UI_FLAG_IMMERSIVE},
18805      * and {@link #SYSTEM_UI_FLAG_IMMERSIVE_STICKY}.
18806      */
18807     public void setSystemUiVisibility(int visibility) {
18808         if (visibility != mSystemUiVisibility) {
18809             mSystemUiVisibility = visibility;
18810             if (mParent != null && mAttachInfo != null && !mAttachInfo.mRecomputeGlobalAttributes) {
18811                 mParent.recomputeViewAttributes(this);
18812             }
18813         }
18814     }
18815
18816     /**
18817      * Returns the last {@link #setSystemUiVisibility(int)} that this view has requested.
18818      * @return  Bitwise-or of flags {@link #SYSTEM_UI_FLAG_LOW_PROFILE},
18819      * {@link #SYSTEM_UI_FLAG_HIDE_NAVIGATION}, {@link #SYSTEM_UI_FLAG_FULLSCREEN},
18820      * {@link #SYSTEM_UI_FLAG_LAYOUT_STABLE}, {@link #SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION},
18821      * {@link #SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN}, {@link #SYSTEM_UI_FLAG_IMMERSIVE},
18822      * and {@link #SYSTEM_UI_FLAG_IMMERSIVE_STICKY}.
18823      */
18824     public int getSystemUiVisibility() {
18825         return mSystemUiVisibility;
18826     }
18827
18828     /**
18829      * Returns the current system UI visibility that is currently set for
18830      * the entire window.  This is the combination of the
18831      * {@link #setSystemUiVisibility(int)} values supplied by all of the
18832      * views in the window.
18833      */
18834     public int getWindowSystemUiVisibility() {
18835         return mAttachInfo != null ? mAttachInfo.mSystemUiVisibility : 0;
18836     }
18837
18838     /**
18839      * Override to find out when the window's requested system UI visibility
18840      * has changed, that is the value returned by {@link #getWindowSystemUiVisibility()}.
18841      * This is different from the callbacks received through
18842      * {@link #setOnSystemUiVisibilityChangeListener(OnSystemUiVisibilityChangeListener)}
18843      * in that this is only telling you about the local request of the window,
18844      * not the actual values applied by the system.
18845      */
18846     public void onWindowSystemUiVisibilityChanged(int visible) {
18847     }
18848
18849     /**
18850      * Dispatch callbacks to {@link #onWindowSystemUiVisibilityChanged(int)} down
18851      * the view hierarchy.
18852      */
18853     public void dispatchWindowSystemUiVisiblityChanged(int visible) {
18854         onWindowSystemUiVisibilityChanged(visible);
18855     }
18856
18857     /**
18858      * Set a listener to receive callbacks when the visibility of the system bar changes.
18859      * @param l  The {@link OnSystemUiVisibilityChangeListener} to receive callbacks.
18860      */
18861     public void setOnSystemUiVisibilityChangeListener(OnSystemUiVisibilityChangeListener l) {
18862         getListenerInfo().mOnSystemUiVisibilityChangeListener = l;
18863         if (mParent != null && mAttachInfo != null && !mAttachInfo.mRecomputeGlobalAttributes) {
18864             mParent.recomputeViewAttributes(this);
18865         }
18866     }
18867
18868     /**
18869      * Dispatch callbacks to {@link #setOnSystemUiVisibilityChangeListener} down
18870      * the view hierarchy.
18871      */
18872     public void dispatchSystemUiVisibilityChanged(int visibility) {
18873         ListenerInfo li = mListenerInfo;
18874         if (li != null && li.mOnSystemUiVisibilityChangeListener != null) {
18875             li.mOnSystemUiVisibilityChangeListener.onSystemUiVisibilityChange(
18876                     visibility & PUBLIC_STATUS_BAR_VISIBILITY_MASK);
18877         }
18878     }
18879
18880     boolean updateLocalSystemUiVisibility(int localValue, int localChanges) {
18881         int val = (mSystemUiVisibility&~localChanges) | (localValue&localChanges);
18882         if (val != mSystemUiVisibility) {
18883             setSystemUiVisibility(val);
18884             return true;
18885         }
18886         return false;
18887     }
18888
18889     /** @hide */
18890     public void setDisabledSystemUiVisibility(int flags) {
18891         if (mAttachInfo != null) {
18892             if (mAttachInfo.mDisabledSystemUiVisibility != flags) {
18893                 mAttachInfo.mDisabledSystemUiVisibility = flags;
18894                 if (mParent != null) {
18895                     mParent.recomputeViewAttributes(this);
18896                 }
18897             }
18898         }
18899     }
18900
18901     /**
18902      * Creates an image that the system displays during the drag and drop
18903      * operation. This is called a &quot;drag shadow&quot;. The default implementation
18904      * for a DragShadowBuilder based on a View returns an image that has exactly the same
18905      * appearance as the given View. The default also positions the center of the drag shadow
18906      * directly under the touch point. If no View is provided (the constructor with no parameters
18907      * is used), and {@link #onProvideShadowMetrics(Point,Point) onProvideShadowMetrics()} and
18908      * {@link #onDrawShadow(Canvas) onDrawShadow()} are not overridden, then the
18909      * default is an invisible drag shadow.
18910      * <p>
18911      * You are not required to use the View you provide to the constructor as the basis of the
18912      * drag shadow. The {@link #onDrawShadow(Canvas) onDrawShadow()} method allows you to draw
18913      * anything you want as the drag shadow.
18914      * </p>
18915      * <p>
18916      *  You pass a DragShadowBuilder object to the system when you start the drag. The system
18917      *  calls {@link #onProvideShadowMetrics(Point,Point) onProvideShadowMetrics()} to get the
18918      *  size and position of the drag shadow. It uses this data to construct a
18919      *  {@link android.graphics.Canvas} object, then it calls {@link #onDrawShadow(Canvas) onDrawShadow()}
18920      *  so that your application can draw the shadow image in the Canvas.
18921      * </p>
18922      *
18923      * <div class="special reference">
18924      * <h3>Developer Guides</h3>
18925      * <p>For a guide to implementing drag and drop features, read the
18926      * <a href="{@docRoot}guide/topics/ui/drag-drop.html">Drag and Drop</a> developer guide.</p>
18927      * </div>
18928      */
18929     public static class DragShadowBuilder {
18930         private final WeakReference<View> mView;
18931
18932         /**
18933          * Constructs a shadow image builder based on a View. By default, the resulting drag
18934          * shadow will have the same appearance and dimensions as the View, with the touch point
18935          * over the center of the View.
18936          * @param view A View. Any View in scope can be used.
18937          */
18938         public DragShadowBuilder(View view) {
18939             mView = new WeakReference<View>(view);
18940         }
18941
18942         /**
18943          * Construct a shadow builder object with no associated View.  This
18944          * constructor variant is only useful when the {@link #onProvideShadowMetrics(Point, Point)}
18945          * and {@link #onDrawShadow(Canvas)} methods are also overridden in order
18946          * to supply the drag shadow's dimensions and appearance without
18947          * reference to any View object. If they are not overridden, then the result is an
18948          * invisible drag shadow.
18949          */
18950         public DragShadowBuilder() {
18951             mView = new WeakReference<View>(null);
18952         }
18953
18954         /**
18955          * Returns the View object that had been passed to the
18956          * {@link #View.DragShadowBuilder(View)}
18957          * constructor.  If that View parameter was {@code null} or if the
18958          * {@link #View.DragShadowBuilder()}
18959          * constructor was used to instantiate the builder object, this method will return
18960          * null.
18961          *
18962          * @return The View object associate with this builder object.
18963          */
18964         @SuppressWarnings({"JavadocReference"})
18965         final public View getView() {
18966             return mView.get();
18967         }
18968
18969         /**
18970          * Provides the metrics for the shadow image. These include the dimensions of
18971          * the shadow image, and the point within that shadow that should
18972          * be centered under the touch location while dragging.
18973          * <p>
18974          * The default implementation sets the dimensions of the shadow to be the
18975          * same as the dimensions of the View itself and centers the shadow under
18976          * the touch point.
18977          * </p>
18978          *
18979          * @param shadowSize A {@link android.graphics.Point} containing the width and height
18980          * of the shadow image. Your application must set {@link android.graphics.Point#x} to the
18981          * desired width and must set {@link android.graphics.Point#y} to the desired height of the
18982          * image.
18983          *
18984          * @param shadowTouchPoint A {@link android.graphics.Point} for the position within the
18985          * shadow image that should be underneath the touch point during the drag and drop
18986          * operation. Your application must set {@link android.graphics.Point#x} to the
18987          * X coordinate and {@link android.graphics.Point#y} to the Y coordinate of this position.
18988          */
18989         public void onProvideShadowMetrics(Point shadowSize, Point shadowTouchPoint) {
18990             final View view = mView.get();
18991             if (view != null) {
18992                 shadowSize.set(view.getWidth(), view.getHeight());
18993                 shadowTouchPoint.set(shadowSize.x / 2, shadowSize.y / 2);
18994             } else {
18995                 Log.e(View.VIEW_LOG_TAG, "Asked for drag thumb metrics but no view");
18996             }
18997         }
18998
18999         /**
19000          * Draws the shadow image. The system creates the {@link android.graphics.Canvas} object
19001          * based on the dimensions it received from the
19002          * {@link #onProvideShadowMetrics(Point, Point)} callback.
19003          *
19004          * @param canvas A {@link android.graphics.Canvas} object in which to draw the shadow image.
19005          */
19006         public void onDrawShadow(Canvas canvas) {
19007             final View view = mView.get();
19008             if (view != null) {
19009                 view.draw(canvas);
19010             } else {
19011                 Log.e(View.VIEW_LOG_TAG, "Asked to draw drag shadow but no view");
19012             }
19013         }
19014     }
19015
19016     /**
19017      * Starts a drag and drop operation. When your application calls this method, it passes a
19018      * {@link android.view.View.DragShadowBuilder} object to the system. The
19019      * system calls this object's {@link DragShadowBuilder#onProvideShadowMetrics(Point, Point)}
19020      * to get metrics for the drag shadow, and then calls the object's
19021      * {@link DragShadowBuilder#onDrawShadow(Canvas)} to draw the drag shadow itself.
19022      * <p>
19023      *  Once the system has the drag shadow, it begins the drag and drop operation by sending
19024      *  drag events to all the View objects in your application that are currently visible. It does
19025      *  this either by calling the View object's drag listener (an implementation of
19026      *  {@link android.view.View.OnDragListener#onDrag(View,DragEvent) onDrag()} or by calling the
19027      *  View object's {@link android.view.View#onDragEvent(DragEvent) onDragEvent()} method.
19028      *  Both are passed a {@link android.view.DragEvent} object that has a
19029      *  {@link android.view.DragEvent#getAction()} value of
19030      *  {@link android.view.DragEvent#ACTION_DRAG_STARTED}.
19031      * </p>
19032      * <p>
19033      * Your application can invoke startDrag() on any attached View object. The View object does not
19034      * need to be the one used in {@link android.view.View.DragShadowBuilder}, nor does it need to
19035      * be related to the View the user selected for dragging.
19036      * </p>
19037      * @param data A {@link android.content.ClipData} object pointing to the data to be
19038      * transferred by the drag and drop operation.
19039      * @param shadowBuilder A {@link android.view.View.DragShadowBuilder} object for building the
19040      * drag shadow.
19041      * @param myLocalState An {@link java.lang.Object} containing local data about the drag and
19042      * drop operation. This Object is put into every DragEvent object sent by the system during the
19043      * current drag.
19044      * <p>
19045      * myLocalState is a lightweight mechanism for the sending information from the dragged View
19046      * to the target Views. For example, it can contain flags that differentiate between a
19047      * a copy operation and a move operation.
19048      * </p>
19049      * @param flags Flags that control the drag and drop operation. No flags are currently defined,
19050      * so the parameter should be set to 0.
19051      * @return {@code true} if the method completes successfully, or
19052      * {@code false} if it fails anywhere. Returning {@code false} means the system was unable to
19053      * do a drag, and so no drag operation is in progress.
19054      */
19055     public final boolean startDrag(ClipData data, DragShadowBuilder shadowBuilder,
19056             Object myLocalState, int flags) {
19057         if (ViewDebug.DEBUG_DRAG) {
19058             Log.d(VIEW_LOG_TAG, "startDrag: data=" + data + " flags=" + flags);
19059         }
19060         boolean okay = false;
19061
19062         Point shadowSize = new Point();
19063         Point shadowTouchPoint = new Point();
19064         shadowBuilder.onProvideShadowMetrics(shadowSize, shadowTouchPoint);
19065
19066         if ((shadowSize.x < 0) || (shadowSize.y < 0) ||
19067                 (shadowTouchPoint.x < 0) || (shadowTouchPoint.y < 0)) {
19068             throw new IllegalStateException("Drag shadow dimensions must not be negative");
19069         }
19070
19071         if (ViewDebug.DEBUG_DRAG) {
19072             Log.d(VIEW_LOG_TAG, "drag shadow: width=" + shadowSize.x + " height=" + shadowSize.y
19073                     + " shadowX=" + shadowTouchPoint.x + " shadowY=" + shadowTouchPoint.y);
19074         }
19075         Surface surface = new Surface();
19076         try {
19077             IBinder token = mAttachInfo.mSession.prepareDrag(mAttachInfo.mWindow,
19078                     flags, shadowSize.x, shadowSize.y, surface);
19079             if (ViewDebug.DEBUG_DRAG) Log.d(VIEW_LOG_TAG, "prepareDrag returned token=" + token
19080                     + " surface=" + surface);
19081             if (token != null) {
19082                 Canvas canvas = surface.lockCanvas(null);
19083                 try {
19084                     canvas.drawColor(0, PorterDuff.Mode.CLEAR);
19085                     shadowBuilder.onDrawShadow(canvas);
19086                 } finally {
19087                     surface.unlockCanvasAndPost(canvas);
19088                 }
19089
19090                 final ViewRootImpl root = getViewRootImpl();
19091
19092                 // Cache the local state object for delivery with DragEvents
19093                 root.setLocalDragState(myLocalState);
19094
19095                 // repurpose 'shadowSize' for the last touch point
19096                 root.getLastTouchPoint(shadowSize);
19097
19098                 okay = mAttachInfo.mSession.performDrag(mAttachInfo.mWindow, token,
19099                         shadowSize.x, shadowSize.y,
19100                         shadowTouchPoint.x, shadowTouchPoint.y, data);
19101                 if (ViewDebug.DEBUG_DRAG) Log.d(VIEW_LOG_TAG, "performDrag returned " + okay);
19102
19103                 // Off and running!  Release our local surface instance; the drag
19104                 // shadow surface is now managed by the system process.
19105                 surface.release();
19106             }
19107         } catch (Exception e) {
19108             Log.e(VIEW_LOG_TAG, "Unable to initiate drag", e);
19109             surface.destroy();
19110         }
19111
19112         return okay;
19113     }
19114
19115     /**
19116      * Handles drag events sent by the system following a call to
19117      * {@link android.view.View#startDrag(ClipData,DragShadowBuilder,Object,int) startDrag()}.
19118      *<p>
19119      * When the system calls this method, it passes a
19120      * {@link android.view.DragEvent} object. A call to
19121      * {@link android.view.DragEvent#getAction()} returns one of the action type constants defined
19122      * in DragEvent. The method uses these to determine what is happening in the drag and drop
19123      * operation.
19124      * @param event The {@link android.view.DragEvent} sent by the system.
19125      * The {@link android.view.DragEvent#getAction()} method returns an action type constant defined
19126      * in DragEvent, indicating the type of drag event represented by this object.
19127      * @return {@code true} if the method was successful, otherwise {@code false}.
19128      * <p>
19129      *  The method should return {@code true} in response to an action type of
19130      *  {@link android.view.DragEvent#ACTION_DRAG_STARTED} to receive drag events for the current
19131      *  operation.
19132      * </p>
19133      * <p>
19134      *  The method should also return {@code true} in response to an action type of
19135      *  {@link android.view.DragEvent#ACTION_DROP} if it consumed the drop, or
19136      *  {@code false} if it didn't.
19137      * </p>
19138      */
19139     public boolean onDragEvent(DragEvent event) {
19140         return false;
19141     }
19142
19143     /**
19144      * Detects if this View is enabled and has a drag event listener.
19145      * If both are true, then it calls the drag event listener with the
19146      * {@link android.view.DragEvent} it received. If the drag event listener returns
19147      * {@code true}, then dispatchDragEvent() returns {@code true}.
19148      * <p>
19149      * For all other cases, the method calls the
19150      * {@link android.view.View#onDragEvent(DragEvent) onDragEvent()} drag event handler
19151      * method and returns its result.
19152      * </p>
19153      * <p>
19154      * This ensures that a drag event is always consumed, even if the View does not have a drag
19155      * event listener. However, if the View has a listener and the listener returns true, then
19156      * onDragEvent() is not called.
19157      * </p>
19158      */
19159     public boolean dispatchDragEvent(DragEvent event) {
19160         ListenerInfo li = mListenerInfo;
19161         //noinspection SimplifiableIfStatement
19162         if (li != null && li.mOnDragListener != null && (mViewFlags & ENABLED_MASK) == ENABLED
19163                 && li.mOnDragListener.onDrag(this, event)) {
19164             return true;
19165         }
19166         return onDragEvent(event);
19167     }
19168
19169     boolean canAcceptDrag() {
19170         return (mPrivateFlags2 & PFLAG2_DRAG_CAN_ACCEPT) != 0;
19171     }
19172
19173     /**
19174      * This needs to be a better API (NOT ON VIEW) before it is exposed.  If
19175      * it is ever exposed at all.
19176      * @hide
19177      */
19178     public void onCloseSystemDialogs(String reason) {
19179     }
19180
19181     /**
19182      * Given a Drawable whose bounds have been set to draw into this view,
19183      * update a Region being computed for
19184      * {@link #gatherTransparentRegion(android.graphics.Region)} so
19185      * that any non-transparent parts of the Drawable are removed from the
19186      * given transparent region.
19187      *
19188      * @param dr The Drawable whose transparency is to be applied to the region.
19189      * @param region A Region holding the current transparency information,
19190      * where any parts of the region that are set are considered to be
19191      * transparent.  On return, this region will be modified to have the
19192      * transparency information reduced by the corresponding parts of the
19193      * Drawable that are not transparent.
19194      * {@hide}
19195      */
19196     public void applyDrawableToTransparentRegion(Drawable dr, Region region) {
19197         if (DBG) {
19198             Log.i("View", "Getting transparent region for: " + this);
19199         }
19200         final Region r = dr.getTransparentRegion();
19201         final Rect db = dr.getBounds();
19202         final AttachInfo attachInfo = mAttachInfo;
19203         if (r != null && attachInfo != null) {
19204             final int w = getRight()-getLeft();
19205             final int h = getBottom()-getTop();
19206             if (db.left > 0) {
19207                 //Log.i("VIEW", "Drawable left " + db.left + " > view 0");
19208                 r.op(0, 0, db.left, h, Region.Op.UNION);
19209             }
19210             if (db.right < w) {
19211                 //Log.i("VIEW", "Drawable right " + db.right + " < view " + w);
19212                 r.op(db.right, 0, w, h, Region.Op.UNION);
19213             }
19214             if (db.top > 0) {
19215                 //Log.i("VIEW", "Drawable top " + db.top + " > view 0");
19216                 r.op(0, 0, w, db.top, Region.Op.UNION);
19217             }
19218             if (db.bottom < h) {
19219                 //Log.i("VIEW", "Drawable bottom " + db.bottom + " < view " + h);
19220                 r.op(0, db.bottom, w, h, Region.Op.UNION);
19221             }
19222             final int[] location = attachInfo.mTransparentLocation;
19223             getLocationInWindow(location);
19224             r.translate(location[0], location[1]);
19225             region.op(r, Region.Op.INTERSECT);
19226         } else {
19227             region.op(db, Region.Op.DIFFERENCE);
19228         }
19229     }
19230
19231     private void checkForLongClick(int delayOffset) {
19232         if ((mViewFlags & LONG_CLICKABLE) == LONG_CLICKABLE) {
19233             mHasPerformedLongPress = false;
19234
19235             if (mPendingCheckForLongPress == null) {
19236                 mPendingCheckForLongPress = new CheckForLongPress();
19237             }
19238             mPendingCheckForLongPress.rememberWindowAttachCount();
19239             postDelayed(mPendingCheckForLongPress,
19240                     ViewConfiguration.getLongPressTimeout() - delayOffset);
19241         }
19242     }
19243
19244     /**
19245      * Inflate a view from an XML resource.  This convenience method wraps the {@link
19246      * LayoutInflater} class, which provides a full range of options for view inflation.
19247      *
19248      * @param context The Context object for your activity or application.
19249      * @param resource The resource ID to inflate
19250      * @param root A view group that will be the parent.  Used to properly inflate the
19251      * layout_* parameters.
19252      * @see LayoutInflater
19253      */
19254     public static View inflate(Context context, @LayoutRes int resource, ViewGroup root) {
19255         LayoutInflater factory = LayoutInflater.from(context);
19256         return factory.inflate(resource, root);
19257     }
19258
19259     /**
19260      * Scroll the view with standard behavior for scrolling beyond the normal
19261      * content boundaries. Views that call this method should override
19262      * {@link #onOverScrolled(int, int, boolean, boolean)} to respond to the
19263      * results of an over-scroll operation.
19264      *
19265      * Views can use this method to handle any touch or fling-based scrolling.
19266      *
19267      * @param deltaX Change in X in pixels
19268      * @param deltaY Change in Y in pixels
19269      * @param scrollX Current X scroll value in pixels before applying deltaX
19270      * @param scrollY Current Y scroll value in pixels before applying deltaY
19271      * @param scrollRangeX Maximum content scroll range along the X axis
19272      * @param scrollRangeY Maximum content scroll range along the Y axis
19273      * @param maxOverScrollX Number of pixels to overscroll by in either direction
19274      *          along the X axis.
19275      * @param maxOverScrollY Number of pixels to overscroll by in either direction
19276      *          along the Y axis.
19277      * @param isTouchEvent true if this scroll operation is the result of a touch event.
19278      * @return true if scrolling was clamped to an over-scroll boundary along either
19279      *          axis, false otherwise.
19280      */
19281     @SuppressWarnings({"UnusedParameters"})
19282     protected boolean overScrollBy(int deltaX, int deltaY,
19283             int scrollX, int scrollY,
19284             int scrollRangeX, int scrollRangeY,
19285             int maxOverScrollX, int maxOverScrollY,
19286             boolean isTouchEvent) {
19287         final int overScrollMode = mOverScrollMode;
19288         final boolean canScrollHorizontal =
19289                 computeHorizontalScrollRange() > computeHorizontalScrollExtent();
19290         final boolean canScrollVertical =
19291                 computeVerticalScrollRange() > computeVerticalScrollExtent();
19292         final boolean overScrollHorizontal = overScrollMode == OVER_SCROLL_ALWAYS ||
19293                 (overScrollMode == OVER_SCROLL_IF_CONTENT_SCROLLS && canScrollHorizontal);
19294         final boolean overScrollVertical = overScrollMode == OVER_SCROLL_ALWAYS ||
19295                 (overScrollMode == OVER_SCROLL_IF_CONTENT_SCROLLS && canScrollVertical);
19296
19297         int newScrollX = scrollX + deltaX;
19298         if (!overScrollHorizontal) {
19299             maxOverScrollX = 0;
19300         }
19301
19302         int newScrollY = scrollY + deltaY;
19303         if (!overScrollVertical) {
19304             maxOverScrollY = 0;
19305         }
19306
19307         // Clamp values if at the limits and record
19308         final int left = -maxOverScrollX;
19309         final int right = maxOverScrollX + scrollRangeX;
19310         final int top = -maxOverScrollY;
19311         final int bottom = maxOverScrollY + scrollRangeY;
19312
19313         boolean clampedX = false;
19314         if (newScrollX > right) {
19315             newScrollX = right;
19316             clampedX = true;
19317         } else if (newScrollX < left) {
19318             newScrollX = left;
19319             clampedX = true;
19320         }
19321
19322         boolean clampedY = false;
19323         if (newScrollY > bottom) {
19324             newScrollY = bottom;
19325             clampedY = true;
19326         } else if (newScrollY < top) {
19327             newScrollY = top;
19328             clampedY = true;
19329         }
19330
19331         onOverScrolled(newScrollX, newScrollY, clampedX, clampedY);
19332
19333         return clampedX || clampedY;
19334     }
19335
19336     /**
19337      * Called by {@link #overScrollBy(int, int, int, int, int, int, int, int, boolean)} to
19338      * respond to the results of an over-scroll operation.
19339      *
19340      * @param scrollX New X scroll value in pixels
19341      * @param scrollY New Y scroll value in pixels
19342      * @param clampedX True if scrollX was clamped to an over-scroll boundary
19343      * @param clampedY True if scrollY was clamped to an over-scroll boundary
19344      */
19345     protected void onOverScrolled(int scrollX, int scrollY,
19346             boolean clampedX, boolean clampedY) {
19347         // Intentionally empty.
19348     }
19349
19350     /**
19351      * Returns the over-scroll mode for this view. The result will be
19352      * one of {@link #OVER_SCROLL_ALWAYS} (default), {@link #OVER_SCROLL_IF_CONTENT_SCROLLS}
19353      * (allow over-scrolling only if the view content is larger than the container),
19354      * or {@link #OVER_SCROLL_NEVER}.
19355      *
19356      * @return This view's over-scroll mode.
19357      */
19358     public int getOverScrollMode() {
19359         return mOverScrollMode;
19360     }
19361
19362     /**
19363      * Set the over-scroll mode for this view. Valid over-scroll modes are
19364      * {@link #OVER_SCROLL_ALWAYS} (default), {@link #OVER_SCROLL_IF_CONTENT_SCROLLS}
19365      * (allow over-scrolling only if the view content is larger than the container),
19366      * or {@link #OVER_SCROLL_NEVER}.
19367      *
19368      * Setting the over-scroll mode of a view will have an effect only if the
19369      * view is capable of scrolling.
19370      *
19371      * @param overScrollMode The new over-scroll mode for this view.
19372      */
19373     public void setOverScrollMode(int overScrollMode) {
19374         if (overScrollMode != OVER_SCROLL_ALWAYS &&
19375                 overScrollMode != OVER_SCROLL_IF_CONTENT_SCROLLS &&
19376                 overScrollMode != OVER_SCROLL_NEVER) {
19377             throw new IllegalArgumentException("Invalid overscroll mode " + overScrollMode);
19378         }
19379         mOverScrollMode = overScrollMode;
19380     }
19381
19382     /**
19383      * Enable or disable nested scrolling for this view.
19384      *
19385      * <p>If this property is set to true the view will be permitted to initiate nested
19386      * scrolling operations with a compatible parent view in the current hierarchy. If this
19387      * view does not implement nested scrolling this will have no effect. Disabling nested scrolling
19388      * while a nested scroll is in progress has the effect of {@link #stopNestedScroll() stopping}
19389      * the nested scroll.</p>
19390      *
19391      * @param enabled true to enable nested scrolling, false to disable
19392      *
19393      * @see #isNestedScrollingEnabled()
19394      */
19395     public void setNestedScrollingEnabled(boolean enabled) {
19396         if (enabled) {
19397             mPrivateFlags3 |= PFLAG3_NESTED_SCROLLING_ENABLED;
19398         } else {
19399             stopNestedScroll();
19400             mPrivateFlags3 &= ~PFLAG3_NESTED_SCROLLING_ENABLED;
19401         }
19402     }
19403
19404     /**
19405      * Returns true if nested scrolling is enabled for this view.
19406      *
19407      * <p>If nested scrolling is enabled and this View class implementation supports it,
19408      * this view will act as a nested scrolling child view when applicable, forwarding data
19409      * about the scroll operation in progress to a compatible and cooperating nested scrolling
19410      * parent.</p>
19411      *
19412      * @return true if nested scrolling is enabled
19413      *
19414      * @see #setNestedScrollingEnabled(boolean)
19415      */
19416     public boolean isNestedScrollingEnabled() {
19417         return (mPrivateFlags3 & PFLAG3_NESTED_SCROLLING_ENABLED) ==
19418                 PFLAG3_NESTED_SCROLLING_ENABLED;
19419     }
19420
19421     /**
19422      * Begin a nestable scroll operation along the given axes.
19423      *
19424      * <p>A view starting a nested scroll promises to abide by the following contract:</p>
19425      *
19426      * <p>The view will call startNestedScroll upon initiating a scroll operation. In the case
19427      * of a touch scroll this corresponds to the initial {@link MotionEvent#ACTION_DOWN}.
19428      * In the case of touch scrolling the nested scroll will be terminated automatically in
19429      * the same manner as {@link ViewParent#requestDisallowInterceptTouchEvent(boolean)}.
19430      * In the event of programmatic scrolling the caller must explicitly call
19431      * {@link #stopNestedScroll()} to indicate the end of the nested scroll.</p>
19432      *
19433      * <p>If <code>startNestedScroll</code> returns true, a cooperative parent was found.
19434      * If it returns false the caller may ignore the rest of this contract until the next scroll.
19435      * Calling startNestedScroll while a nested scroll is already in progress will return true.</p>
19436      *
19437      * <p>At each incremental step of the scroll the caller should invoke
19438      * {@link #dispatchNestedPreScroll(int, int, int[], int[]) dispatchNestedPreScroll}
19439      * once it has calculated the requested scrolling delta. If it returns true the nested scrolling
19440      * parent at least partially consumed the scroll and the caller should adjust the amount it
19441      * scrolls by.</p>
19442      *
19443      * <p>After applying the remainder of the scroll delta the caller should invoke
19444      * {@link #dispatchNestedScroll(int, int, int, int, int[]) dispatchNestedScroll}, passing
19445      * both the delta consumed and the delta unconsumed. A nested scrolling parent may treat
19446      * these values differently. See {@link ViewParent#onNestedScroll(View, int, int, int, int)}.
19447      * </p>
19448      *
19449      * @param axes Flags consisting of a combination of {@link #SCROLL_AXIS_HORIZONTAL} and/or
19450      *             {@link #SCROLL_AXIS_VERTICAL}.
19451      * @return true if a cooperative parent was found and nested scrolling has been enabled for
19452      *         the current gesture.
19453      *
19454      * @see #stopNestedScroll()
19455      * @see #dispatchNestedPreScroll(int, int, int[], int[])
19456      * @see #dispatchNestedScroll(int, int, int, int, int[])
19457      */
19458     public boolean startNestedScroll(int axes) {
19459         if (hasNestedScrollingParent()) {
19460             // Already in progress
19461             return true;
19462         }
19463         if (isNestedScrollingEnabled()) {
19464             ViewParent p = getParent();
19465             View child = this;
19466             while (p != null) {
19467                 try {
19468                     if (p.onStartNestedScroll(child, this, axes)) {
19469                         mNestedScrollingParent = p;
19470                         p.onNestedScrollAccepted(child, this, axes);
19471                         return true;
19472                     }
19473                 } catch (AbstractMethodError e) {
19474                     Log.e(VIEW_LOG_TAG, "ViewParent " + p + " does not implement interface " +
19475                             "method onStartNestedScroll", e);
19476                     // Allow the search upward to continue
19477                 }
19478                 if (p instanceof View) {
19479                     child = (View) p;
19480                 }
19481                 p = p.getParent();
19482             }
19483         }
19484         return false;
19485     }
19486
19487     /**
19488      * Stop a nested scroll in progress.
19489      *
19490      * <p>Calling this method when a nested scroll is not currently in progress is harmless.</p>
19491      *
19492      * @see #startNestedScroll(int)
19493      */
19494     public void stopNestedScroll() {
19495         if (mNestedScrollingParent != null) {
19496             mNestedScrollingParent.onStopNestedScroll(this);
19497             mNestedScrollingParent = null;
19498         }
19499     }
19500
19501     /**
19502      * Returns true if this view has a nested scrolling parent.
19503      *
19504      * <p>The presence of a nested scrolling parent indicates that this view has initiated
19505      * a nested scroll and it was accepted by an ancestor view further up the view hierarchy.</p>
19506      *
19507      * @return whether this view has a nested scrolling parent
19508      */
19509     public boolean hasNestedScrollingParent() {
19510         return mNestedScrollingParent != null;
19511     }
19512
19513     /**
19514      * Dispatch one step of a nested scroll in progress.
19515      *
19516      * <p>Implementations of views that support nested scrolling should call this to report
19517      * info about a scroll in progress to the current nested scrolling parent. If a nested scroll
19518      * is not currently in progress or nested scrolling is not
19519      * {@link #isNestedScrollingEnabled() enabled} for this view this method does nothing.</p>
19520      *
19521      * <p>Compatible View implementations should also call
19522      * {@link #dispatchNestedPreScroll(int, int, int[], int[]) dispatchNestedPreScroll} before
19523      * consuming a component of the scroll event themselves.</p>
19524      *
19525      * @param dxConsumed Horizontal distance in pixels consumed by this view during this scroll step
19526      * @param dyConsumed Vertical distance in pixels consumed by this view during this scroll step
19527      * @param dxUnconsumed Horizontal scroll distance in pixels not consumed by this view
19528      * @param dyUnconsumed Horizontal scroll distance in pixels not consumed by this view
19529      * @param offsetInWindow Optional. If not null, on return this will contain the offset
19530      *                       in local view coordinates of this view from before this operation
19531      *                       to after it completes. View implementations may use this to adjust
19532      *                       expected input coordinate tracking.
19533      * @return true if the event was dispatched, false if it could not be dispatched.
19534      * @see #dispatchNestedPreScroll(int, int, int[], int[])
19535      */
19536     public boolean dispatchNestedScroll(int dxConsumed, int dyConsumed,
19537             int dxUnconsumed, int dyUnconsumed, @Nullable @Size(2) int[] offsetInWindow) {
19538         if (isNestedScrollingEnabled() && mNestedScrollingParent != null) {
19539             if (dxConsumed != 0 || dyConsumed != 0 || dxUnconsumed != 0 || dyUnconsumed != 0) {
19540                 int startX = 0;
19541                 int startY = 0;
19542                 if (offsetInWindow != null) {
19543                     getLocationInWindow(offsetInWindow);
19544                     startX = offsetInWindow[0];
19545                     startY = offsetInWindow[1];
19546                 }
19547
19548                 mNestedScrollingParent.onNestedScroll(this, dxConsumed, dyConsumed,
19549                         dxUnconsumed, dyUnconsumed);
19550
19551                 if (offsetInWindow != null) {
19552                     getLocationInWindow(offsetInWindow);
19553                     offsetInWindow[0] -= startX;
19554                     offsetInWindow[1] -= startY;
19555                 }
19556                 return true;
19557             } else if (offsetInWindow != null) {
19558                 // No motion, no dispatch. Keep offsetInWindow up to date.
19559                 offsetInWindow[0] = 0;
19560                 offsetInWindow[1] = 0;
19561             }
19562         }
19563         return false;
19564     }
19565
19566     /**
19567      * Dispatch one step of a nested scroll in progress before this view consumes any portion of it.
19568      *
19569      * <p>Nested pre-scroll events are to nested scroll events what touch intercept is to touch.
19570      * <code>dispatchNestedPreScroll</code> offers an opportunity for the parent view in a nested
19571      * scrolling operation to consume some or all of the scroll operation before the child view
19572      * consumes it.</p>
19573      *
19574      * @param dx Horizontal scroll distance in pixels
19575      * @param dy Vertical scroll distance in pixels
19576      * @param consumed Output. If not null, consumed[0] will contain the consumed component of dx
19577      *                 and consumed[1] the consumed dy.
19578      * @param offsetInWindow Optional. If not null, on return this will contain the offset
19579      *                       in local view coordinates of this view from before this operation
19580      *                       to after it completes. View implementations may use this to adjust
19581      *                       expected input coordinate tracking.
19582      * @return true if the parent consumed some or all of the scroll delta
19583      * @see #dispatchNestedScroll(int, int, int, int, int[])
19584      */
19585     public boolean dispatchNestedPreScroll(int dx, int dy,
19586             @Nullable @Size(2) int[] consumed, @Nullable @Size(2) int[] offsetInWindow) {
19587         if (isNestedScrollingEnabled() && mNestedScrollingParent != null) {
19588             if (dx != 0 || dy != 0) {
19589                 int startX = 0;
19590                 int startY = 0;
19591                 if (offsetInWindow != null) {
19592                     getLocationInWindow(offsetInWindow);
19593                     startX = offsetInWindow[0];
19594                     startY = offsetInWindow[1];
19595                 }
19596
19597                 if (consumed == null) {
19598                     if (mTempNestedScrollConsumed == null) {
19599                         mTempNestedScrollConsumed = new int[2];
19600                     }
19601                     consumed = mTempNestedScrollConsumed;
19602                 }
19603                 consumed[0] = 0;
19604                 consumed[1] = 0;
19605                 mNestedScrollingParent.onNestedPreScroll(this, dx, dy, consumed);
19606
19607                 if (offsetInWindow != null) {
19608                     getLocationInWindow(offsetInWindow);
19609                     offsetInWindow[0] -= startX;
19610                     offsetInWindow[1] -= startY;
19611                 }
19612                 return consumed[0] != 0 || consumed[1] != 0;
19613             } else if (offsetInWindow != null) {
19614                 offsetInWindow[0] = 0;
19615                 offsetInWindow[1] = 0;
19616             }
19617         }
19618         return false;
19619     }
19620
19621     /**
19622      * Dispatch a fling to a nested scrolling parent.
19623      *
19624      * <p>This method should be used to indicate that a nested scrolling child has detected
19625      * suitable conditions for a fling. Generally this means that a touch scroll has ended with a
19626      * {@link VelocityTracker velocity} in the direction of scrolling that meets or exceeds
19627      * the {@link ViewConfiguration#getScaledMinimumFlingVelocity() minimum fling velocity}
19628      * along a scrollable axis.</p>
19629      *
19630      * <p>If a nested scrolling child view would normally fling but it is at the edge of
19631      * its own content, it can use this method to delegate the fling to its nested scrolling
19632      * parent instead. The parent may optionally consume the fling or observe a child fling.</p>
19633      *
19634      * @param velocityX Horizontal fling velocity in pixels per second
19635      * @param velocityY Vertical fling velocity in pixels per second
19636      * @param consumed true if the child consumed the fling, false otherwise
19637      * @return true if the nested scrolling parent consumed or otherwise reacted to the fling
19638      */
19639     public boolean dispatchNestedFling(float velocityX, float velocityY, boolean consumed) {
19640         if (isNestedScrollingEnabled() && mNestedScrollingParent != null) {
19641             return mNestedScrollingParent.onNestedFling(this, velocityX, velocityY, consumed);
19642         }
19643         return false;
19644     }
19645
19646     /**
19647      * Dispatch a fling to a nested scrolling parent before it is processed by this view.
19648      *
19649      * <p>Nested pre-fling events are to nested fling events what touch intercept is to touch
19650      * and what nested pre-scroll is to nested scroll. <code>dispatchNestedPreFling</code>
19651      * offsets an opportunity for the parent view in a nested fling to fully consume the fling
19652      * before the child view consumes it. If this method returns <code>true</code>, a nested
19653      * parent view consumed the fling and this view should not scroll as a result.</p>
19654      *
19655      * <p>For a better user experience, only one view in a nested scrolling chain should consume
19656      * the fling at a time. If a parent view consumed the fling this method will return false.
19657      * Custom view implementations should account for this in two ways:</p>
19658      *
19659      * <ul>
19660      *     <li>If a custom view is paged and needs to settle to a fixed page-point, do not
19661      *     call <code>dispatchNestedPreFling</code>; consume the fling and settle to a valid
19662      *     position regardless.</li>
19663      *     <li>If a nested parent does consume the fling, this view should not scroll at all,
19664      *     even to settle back to a valid idle position.</li>
19665      * </ul>
19666      *
19667      * <p>Views should also not offer fling velocities to nested parent views along an axis
19668      * where scrolling is not currently supported; a {@link android.widget.ScrollView ScrollView}
19669      * should not offer a horizontal fling velocity to its parents since scrolling along that
19670      * axis is not permitted and carrying velocity along that motion does not make sense.</p>
19671      *
19672      * @param velocityX Horizontal fling velocity in pixels per second
19673      * @param velocityY Vertical fling velocity in pixels per second
19674      * @return true if a nested scrolling parent consumed the fling
19675      */
19676     public boolean dispatchNestedPreFling(float velocityX, float velocityY) {
19677         if (isNestedScrollingEnabled() && mNestedScrollingParent != null) {
19678             return mNestedScrollingParent.onNestedPreFling(this, velocityX, velocityY);
19679         }
19680         return false;
19681     }
19682
19683     /**
19684      * Gets a scale factor that determines the distance the view should scroll
19685      * vertically in response to {@link MotionEvent#ACTION_SCROLL}.
19686      * @return The vertical scroll scale factor.
19687      * @hide
19688      */
19689     protected float getVerticalScrollFactor() {
19690         if (mVerticalScrollFactor == 0) {
19691             TypedValue outValue = new TypedValue();
19692             if (!mContext.getTheme().resolveAttribute(
19693                     com.android.internal.R.attr.listPreferredItemHeight, outValue, true)) {
19694                 throw new IllegalStateException(
19695                         "Expected theme to define listPreferredItemHeight.");
19696             }
19697             mVerticalScrollFactor = outValue.getDimension(
19698                     mContext.getResources().getDisplayMetrics());
19699         }
19700         return mVerticalScrollFactor;
19701     }
19702
19703     /**
19704      * Gets a scale factor that determines the distance the view should scroll
19705      * horizontally in response to {@link MotionEvent#ACTION_SCROLL}.
19706      * @return The horizontal scroll scale factor.
19707      * @hide
19708      */
19709     protected float getHorizontalScrollFactor() {
19710         // TODO: Should use something else.
19711         return getVerticalScrollFactor();
19712     }
19713
19714     /**
19715      * Return the value specifying the text direction or policy that was set with
19716      * {@link #setTextDirection(int)}.
19717      *
19718      * @return the defined text direction. It can be one of:
19719      *
19720      * {@link #TEXT_DIRECTION_INHERIT},
19721      * {@link #TEXT_DIRECTION_FIRST_STRONG},
19722      * {@link #TEXT_DIRECTION_ANY_RTL},
19723      * {@link #TEXT_DIRECTION_LTR},
19724      * {@link #TEXT_DIRECTION_RTL},
19725      * {@link #TEXT_DIRECTION_LOCALE},
19726      * {@link #TEXT_DIRECTION_FIRST_STRONG_LTR},
19727      * {@link #TEXT_DIRECTION_FIRST_STRONG_RTL}
19728      *
19729      * @attr ref android.R.styleable#View_textDirection
19730      *
19731      * @hide
19732      */
19733     @ViewDebug.ExportedProperty(category = "text", mapping = {
19734             @ViewDebug.IntToString(from = TEXT_DIRECTION_INHERIT, to = "INHERIT"),
19735             @ViewDebug.IntToString(from = TEXT_DIRECTION_FIRST_STRONG, to = "FIRST_STRONG"),
19736             @ViewDebug.IntToString(from = TEXT_DIRECTION_ANY_RTL, to = "ANY_RTL"),
19737             @ViewDebug.IntToString(from = TEXT_DIRECTION_LTR, to = "LTR"),
19738             @ViewDebug.IntToString(from = TEXT_DIRECTION_RTL, to = "RTL"),
19739             @ViewDebug.IntToString(from = TEXT_DIRECTION_LOCALE, to = "LOCALE"),
19740             @ViewDebug.IntToString(from = TEXT_DIRECTION_FIRST_STRONG_LTR, to = "FIRST_STRONG_LTR"),
19741             @ViewDebug.IntToString(from = TEXT_DIRECTION_FIRST_STRONG_RTL, to = "FIRST_STRONG_RTL")
19742     })
19743     public int getRawTextDirection() {
19744         return (mPrivateFlags2 & PFLAG2_TEXT_DIRECTION_MASK) >> PFLAG2_TEXT_DIRECTION_MASK_SHIFT;
19745     }
19746
19747     /**
19748      * Set the text direction.
19749      *
19750      * @param textDirection the direction to set. Should be one of:
19751      *
19752      * {@link #TEXT_DIRECTION_INHERIT},
19753      * {@link #TEXT_DIRECTION_FIRST_STRONG},
19754      * {@link #TEXT_DIRECTION_ANY_RTL},
19755      * {@link #TEXT_DIRECTION_LTR},
19756      * {@link #TEXT_DIRECTION_RTL},
19757      * {@link #TEXT_DIRECTION_LOCALE}
19758      * {@link #TEXT_DIRECTION_FIRST_STRONG_LTR},
19759      * {@link #TEXT_DIRECTION_FIRST_STRONG_RTL},
19760      *
19761      * Resolution will be done if the value is set to TEXT_DIRECTION_INHERIT. The resolution
19762      * proceeds up the parent chain of the view to get the value. If there is no parent, then it will
19763      * return the default {@link #TEXT_DIRECTION_FIRST_STRONG}.
19764      *
19765      * @attr ref android.R.styleable#View_textDirection
19766      */
19767     public void setTextDirection(int textDirection) {
19768         if (getRawTextDirection() != textDirection) {
19769             // Reset the current text direction and the resolved one
19770             mPrivateFlags2 &= ~PFLAG2_TEXT_DIRECTION_MASK;
19771             resetResolvedTextDirection();
19772             // Set the new text direction
19773             mPrivateFlags2 |= ((textDirection << PFLAG2_TEXT_DIRECTION_MASK_SHIFT) & PFLAG2_TEXT_DIRECTION_MASK);
19774             // Do resolution
19775             resolveTextDirection();
19776             // Notify change
19777             onRtlPropertiesChanged(getLayoutDirection());
19778             // Refresh
19779             requestLayout();
19780             invalidate(true);
19781         }
19782     }
19783
19784     /**
19785      * Return the resolved text direction.
19786      *
19787      * @return the resolved text direction. Returns one of:
19788      *
19789      * {@link #TEXT_DIRECTION_FIRST_STRONG},
19790      * {@link #TEXT_DIRECTION_ANY_RTL},
19791      * {@link #TEXT_DIRECTION_LTR},
19792      * {@link #TEXT_DIRECTION_RTL},
19793      * {@link #TEXT_DIRECTION_LOCALE},
19794      * {@link #TEXT_DIRECTION_FIRST_STRONG_LTR},
19795      * {@link #TEXT_DIRECTION_FIRST_STRONG_RTL}
19796      *
19797      * @attr ref android.R.styleable#View_textDirection
19798      */
19799     @ViewDebug.ExportedProperty(category = "text", mapping = {
19800             @ViewDebug.IntToString(from = TEXT_DIRECTION_INHERIT, to = "INHERIT"),
19801             @ViewDebug.IntToString(from = TEXT_DIRECTION_FIRST_STRONG, to = "FIRST_STRONG"),
19802             @ViewDebug.IntToString(from = TEXT_DIRECTION_ANY_RTL, to = "ANY_RTL"),
19803             @ViewDebug.IntToString(from = TEXT_DIRECTION_LTR, to = "LTR"),
19804             @ViewDebug.IntToString(from = TEXT_DIRECTION_RTL, to = "RTL"),
19805             @ViewDebug.IntToString(from = TEXT_DIRECTION_LOCALE, to = "LOCALE"),
19806             @ViewDebug.IntToString(from = TEXT_DIRECTION_FIRST_STRONG_LTR, to = "FIRST_STRONG_LTR"),
19807             @ViewDebug.IntToString(from = TEXT_DIRECTION_FIRST_STRONG_RTL, to = "FIRST_STRONG_RTL")
19808     })
19809     public int getTextDirection() {
19810         return (mPrivateFlags2 & PFLAG2_TEXT_DIRECTION_RESOLVED_MASK) >> PFLAG2_TEXT_DIRECTION_RESOLVED_MASK_SHIFT;
19811     }
19812
19813     /**
19814      * Resolve the text direction.
19815      *
19816      * @return true if resolution has been done, false otherwise.
19817      *
19818      * @hide
19819      */
19820     public boolean resolveTextDirection() {
19821         // Reset any previous text direction resolution
19822         mPrivateFlags2 &= ~(PFLAG2_TEXT_DIRECTION_RESOLVED | PFLAG2_TEXT_DIRECTION_RESOLVED_MASK);
19823
19824         if (hasRtlSupport()) {
19825             // Set resolved text direction flag depending on text direction flag
19826             final int textDirection = getRawTextDirection();
19827             switch(textDirection) {
19828                 case TEXT_DIRECTION_INHERIT:
19829                     if (!canResolveTextDirection()) {
19830                         // We cannot do the resolution if there is no parent, so use the default one
19831                         mPrivateFlags2 |= PFLAG2_TEXT_DIRECTION_RESOLVED_DEFAULT;
19832                         // Resolution will need to happen again later
19833                         return false;
19834                     }
19835
19836                     // Parent has not yet resolved, so we still return the default
19837                     try {
19838                         if (!mParent.isTextDirectionResolved()) {
19839                             mPrivateFlags2 |= PFLAG2_TEXT_DIRECTION_RESOLVED_DEFAULT;
19840                             // Resolution will need to happen again later
19841                             return false;
19842                         }
19843                     } catch (AbstractMethodError e) {
19844                         Log.e(VIEW_LOG_TAG, mParent.getClass().getSimpleName() +
19845                                 " does not fully implement ViewParent", e);
19846                         mPrivateFlags2 |= PFLAG2_TEXT_DIRECTION_RESOLVED |
19847                                 PFLAG2_TEXT_DIRECTION_RESOLVED_DEFAULT;
19848                         return true;
19849                     }
19850
19851                     // Set current resolved direction to the same value as the parent's one
19852                     int parentResolvedDirection;
19853                     try {
19854                         parentResolvedDirection = mParent.getTextDirection();
19855                     } catch (AbstractMethodError e) {
19856                         Log.e(VIEW_LOG_TAG, mParent.getClass().getSimpleName() +
19857                                 " does not fully implement ViewParent", e);
19858                         parentResolvedDirection = TEXT_DIRECTION_LTR;
19859                     }
19860                     switch (parentResolvedDirection) {
19861                         case TEXT_DIRECTION_FIRST_STRONG:
19862                         case TEXT_DIRECTION_ANY_RTL:
19863                         case TEXT_DIRECTION_LTR:
19864                         case TEXT_DIRECTION_RTL:
19865                         case TEXT_DIRECTION_LOCALE:
19866                         case TEXT_DIRECTION_FIRST_STRONG_LTR:
19867                         case TEXT_DIRECTION_FIRST_STRONG_RTL:
19868                             mPrivateFlags2 |=
19869                                     (parentResolvedDirection << PFLAG2_TEXT_DIRECTION_RESOLVED_MASK_SHIFT);
19870                             break;
19871                         default:
19872                             // Default resolved direction is "first strong" heuristic
19873                             mPrivateFlags2 |= PFLAG2_TEXT_DIRECTION_RESOLVED_DEFAULT;
19874                     }
19875                     break;
19876                 case TEXT_DIRECTION_FIRST_STRONG:
19877                 case TEXT_DIRECTION_ANY_RTL:
19878                 case TEXT_DIRECTION_LTR:
19879                 case TEXT_DIRECTION_RTL:
19880                 case TEXT_DIRECTION_LOCALE:
19881                 case TEXT_DIRECTION_FIRST_STRONG_LTR:
19882                 case TEXT_DIRECTION_FIRST_STRONG_RTL:
19883                     // Resolved direction is the same as text direction
19884                     mPrivateFlags2 |= (textDirection << PFLAG2_TEXT_DIRECTION_RESOLVED_MASK_SHIFT);
19885                     break;
19886                 default:
19887                     // Default resolved direction is "first strong" heuristic
19888                     mPrivateFlags2 |= PFLAG2_TEXT_DIRECTION_RESOLVED_DEFAULT;
19889             }
19890         } else {
19891             // Default resolved direction is "first strong" heuristic
19892             mPrivateFlags2 |= PFLAG2_TEXT_DIRECTION_RESOLVED_DEFAULT;
19893         }
19894
19895         // Set to resolved
19896         mPrivateFlags2 |= PFLAG2_TEXT_DIRECTION_RESOLVED;
19897         return true;
19898     }
19899
19900     /**
19901      * Check if text direction resolution can be done.
19902      *
19903      * @return true if text direction resolution can be done otherwise return false.
19904      */
19905     public boolean canResolveTextDirection() {
19906         switch (getRawTextDirection()) {
19907             case TEXT_DIRECTION_INHERIT:
19908                 if (mParent != null) {
19909                     try {
19910                         return mParent.canResolveTextDirection();
19911                     } catch (AbstractMethodError e) {
19912                         Log.e(VIEW_LOG_TAG, mParent.getClass().getSimpleName() +
19913                                 " does not fully implement ViewParent", e);
19914                     }
19915                 }
19916                 return false;
19917
19918             default:
19919                 return true;
19920         }
19921     }
19922
19923     /**
19924      * Reset resolved text direction. Text direction will be resolved during a call to
19925      * {@link #onMeasure(int, int)}.
19926      *
19927      * @hide
19928      */
19929     public void resetResolvedTextDirection() {
19930         // Reset any previous text direction resolution
19931         mPrivateFlags2 &= ~(PFLAG2_TEXT_DIRECTION_RESOLVED | PFLAG2_TEXT_DIRECTION_RESOLVED_MASK);
19932         // Set to default value
19933         mPrivateFlags2 |= PFLAG2_TEXT_DIRECTION_RESOLVED_DEFAULT;
19934     }
19935
19936     /**
19937      * @return true if text direction is inherited.
19938      *
19939      * @hide
19940      */
19941     public boolean isTextDirectionInherited() {
19942         return (getRawTextDirection() == TEXT_DIRECTION_INHERIT);
19943     }
19944
19945     /**
19946      * @return true if text direction is resolved.
19947      */
19948     public boolean isTextDirectionResolved() {
19949         return (mPrivateFlags2 & PFLAG2_TEXT_DIRECTION_RESOLVED) == PFLAG2_TEXT_DIRECTION_RESOLVED;
19950     }
19951
19952     /**
19953      * Return the value specifying the text alignment or policy that was set with
19954      * {@link #setTextAlignment(int)}.
19955      *
19956      * @return the defined text alignment. It can be one of:
19957      *
19958      * {@link #TEXT_ALIGNMENT_INHERIT},
19959      * {@link #TEXT_ALIGNMENT_GRAVITY},
19960      * {@link #TEXT_ALIGNMENT_CENTER},
19961      * {@link #TEXT_ALIGNMENT_TEXT_START},
19962      * {@link #TEXT_ALIGNMENT_TEXT_END},
19963      * {@link #TEXT_ALIGNMENT_VIEW_START},
19964      * {@link #TEXT_ALIGNMENT_VIEW_END}
19965      *
19966      * @attr ref android.R.styleable#View_textAlignment
19967      *
19968      * @hide
19969      */
19970     @ViewDebug.ExportedProperty(category = "text", mapping = {
19971             @ViewDebug.IntToString(from = TEXT_ALIGNMENT_INHERIT, to = "INHERIT"),
19972             @ViewDebug.IntToString(from = TEXT_ALIGNMENT_GRAVITY, to = "GRAVITY"),
19973             @ViewDebug.IntToString(from = TEXT_ALIGNMENT_TEXT_START, to = "TEXT_START"),
19974             @ViewDebug.IntToString(from = TEXT_ALIGNMENT_TEXT_END, to = "TEXT_END"),
19975             @ViewDebug.IntToString(from = TEXT_ALIGNMENT_CENTER, to = "CENTER"),
19976             @ViewDebug.IntToString(from = TEXT_ALIGNMENT_VIEW_START, to = "VIEW_START"),
19977             @ViewDebug.IntToString(from = TEXT_ALIGNMENT_VIEW_END, to = "VIEW_END")
19978     })
19979     @TextAlignment
19980     public int getRawTextAlignment() {
19981         return (mPrivateFlags2 & PFLAG2_TEXT_ALIGNMENT_MASK) >> PFLAG2_TEXT_ALIGNMENT_MASK_SHIFT;
19982     }
19983
19984     /**
19985      * Set the text alignment.
19986      *
19987      * @param textAlignment The text alignment to set. Should be one of
19988      *
19989      * {@link #TEXT_ALIGNMENT_INHERIT},
19990      * {@link #TEXT_ALIGNMENT_GRAVITY},
19991      * {@link #TEXT_ALIGNMENT_CENTER},
19992      * {@link #TEXT_ALIGNMENT_TEXT_START},
19993      * {@link #TEXT_ALIGNMENT_TEXT_END},
19994      * {@link #TEXT_ALIGNMENT_VIEW_START},
19995      * {@link #TEXT_ALIGNMENT_VIEW_END}
19996      *
19997      * Resolution will be done if the value is set to TEXT_ALIGNMENT_INHERIT. The resolution
19998      * proceeds up the parent chain of the view to get the value. If there is no parent, then it
19999      * will return the default {@link #TEXT_ALIGNMENT_GRAVITY}.
20000      *
20001      * @attr ref android.R.styleable#View_textAlignment
20002      */
20003     public void setTextAlignment(@TextAlignment int textAlignment) {
20004         if (textAlignment != getRawTextAlignment()) {
20005             // Reset the current and resolved text alignment
20006             mPrivateFlags2 &= ~PFLAG2_TEXT_ALIGNMENT_MASK;
20007             resetResolvedTextAlignment();
20008             // Set the new text alignment
20009             mPrivateFlags2 |=
20010                     ((textAlignment << PFLAG2_TEXT_ALIGNMENT_MASK_SHIFT) & PFLAG2_TEXT_ALIGNMENT_MASK);
20011             // Do resolution
20012             resolveTextAlignment();
20013             // Notify change
20014             onRtlPropertiesChanged(getLayoutDirection());
20015             // Refresh
20016             requestLayout();
20017             invalidate(true);
20018         }
20019     }
20020
20021     /**
20022      * Return the resolved text alignment.
20023      *
20024      * @return the resolved text alignment. Returns one of:
20025      *
20026      * {@link #TEXT_ALIGNMENT_GRAVITY},
20027      * {@link #TEXT_ALIGNMENT_CENTER},
20028      * {@link #TEXT_ALIGNMENT_TEXT_START},
20029      * {@link #TEXT_ALIGNMENT_TEXT_END},
20030      * {@link #TEXT_ALIGNMENT_VIEW_START},
20031      * {@link #TEXT_ALIGNMENT_VIEW_END}
20032      *
20033      * @attr ref android.R.styleable#View_textAlignment
20034      */
20035     @ViewDebug.ExportedProperty(category = "text", mapping = {
20036             @ViewDebug.IntToString(from = TEXT_ALIGNMENT_INHERIT, to = "INHERIT"),
20037             @ViewDebug.IntToString(from = TEXT_ALIGNMENT_GRAVITY, to = "GRAVITY"),
20038             @ViewDebug.IntToString(from = TEXT_ALIGNMENT_TEXT_START, to = "TEXT_START"),
20039             @ViewDebug.IntToString(from = TEXT_ALIGNMENT_TEXT_END, to = "TEXT_END"),
20040             @ViewDebug.IntToString(from = TEXT_ALIGNMENT_CENTER, to = "CENTER"),
20041             @ViewDebug.IntToString(from = TEXT_ALIGNMENT_VIEW_START, to = "VIEW_START"),
20042             @ViewDebug.IntToString(from = TEXT_ALIGNMENT_VIEW_END, to = "VIEW_END")
20043     })
20044     @TextAlignment
20045     public int getTextAlignment() {
20046         return (mPrivateFlags2 & PFLAG2_TEXT_ALIGNMENT_RESOLVED_MASK) >>
20047                 PFLAG2_TEXT_ALIGNMENT_RESOLVED_MASK_SHIFT;
20048     }
20049
20050     /**
20051      * Resolve the text alignment.
20052      *
20053      * @return true if resolution has been done, false otherwise.
20054      *
20055      * @hide
20056      */
20057     public boolean resolveTextAlignment() {
20058         // Reset any previous text alignment resolution
20059         mPrivateFlags2 &= ~(PFLAG2_TEXT_ALIGNMENT_RESOLVED | PFLAG2_TEXT_ALIGNMENT_RESOLVED_MASK);
20060
20061         if (hasRtlSupport()) {
20062             // Set resolved text alignment flag depending on text alignment flag
20063             final int textAlignment = getRawTextAlignment();
20064             switch (textAlignment) {
20065                 case TEXT_ALIGNMENT_INHERIT:
20066                     // Check if we can resolve the text alignment
20067                     if (!canResolveTextAlignment()) {
20068                         // We cannot do the resolution if there is no parent so use the default
20069                         mPrivateFlags2 |= PFLAG2_TEXT_ALIGNMENT_RESOLVED_DEFAULT;
20070                         // Resolution will need to happen again later
20071                         return false;
20072                     }
20073
20074                     // Parent has not yet resolved, so we still return the default
20075                     try {
20076                         if (!mParent.isTextAlignmentResolved()) {
20077                             mPrivateFlags2 |= PFLAG2_TEXT_ALIGNMENT_RESOLVED_DEFAULT;
20078                             // Resolution will need to happen again later
20079                             return false;
20080                         }
20081                     } catch (AbstractMethodError e) {
20082                         Log.e(VIEW_LOG_TAG, mParent.getClass().getSimpleName() +
20083                                 " does not fully implement ViewParent", e);
20084                         mPrivateFlags2 |= PFLAG2_TEXT_ALIGNMENT_RESOLVED |
20085                                 PFLAG2_TEXT_ALIGNMENT_RESOLVED_DEFAULT;
20086                         return true;
20087                     }
20088
20089                     int parentResolvedTextAlignment;
20090                     try {
20091                         parentResolvedTextAlignment = mParent.getTextAlignment();
20092                     } catch (AbstractMethodError e) {
20093                         Log.e(VIEW_LOG_TAG, mParent.getClass().getSimpleName() +
20094                                 " does not fully implement ViewParent", e);
20095                         parentResolvedTextAlignment = TEXT_ALIGNMENT_GRAVITY;
20096                     }
20097                     switch (parentResolvedTextAlignment) {
20098                         case TEXT_ALIGNMENT_GRAVITY:
20099                         case TEXT_ALIGNMENT_TEXT_START:
20100                         case TEXT_ALIGNMENT_TEXT_END:
20101                         case TEXT_ALIGNMENT_CENTER:
20102                         case TEXT_ALIGNMENT_VIEW_START:
20103                         case TEXT_ALIGNMENT_VIEW_END:
20104                             // Resolved text alignment is the same as the parent resolved
20105                             // text alignment
20106                             mPrivateFlags2 |=
20107                                     (parentResolvedTextAlignment << PFLAG2_TEXT_ALIGNMENT_RESOLVED_MASK_SHIFT);
20108                             break;
20109                         default:
20110                             // Use default resolved text alignment
20111                             mPrivateFlags2 |= PFLAG2_TEXT_ALIGNMENT_RESOLVED_DEFAULT;
20112                     }
20113                     break;
20114                 case TEXT_ALIGNMENT_GRAVITY:
20115                 case TEXT_ALIGNMENT_TEXT_START:
20116                 case TEXT_ALIGNMENT_TEXT_END:
20117                 case TEXT_ALIGNMENT_CENTER:
20118                 case TEXT_ALIGNMENT_VIEW_START:
20119                 case TEXT_ALIGNMENT_VIEW_END:
20120                     // Resolved text alignment is the same as text alignment
20121                     mPrivateFlags2 |= (textAlignment << PFLAG2_TEXT_ALIGNMENT_RESOLVED_MASK_SHIFT);
20122                     break;
20123                 default:
20124                     // Use default resolved text alignment
20125                     mPrivateFlags2 |= PFLAG2_TEXT_ALIGNMENT_RESOLVED_DEFAULT;
20126             }
20127         } else {
20128             // Use default resolved text alignment
20129             mPrivateFlags2 |= PFLAG2_TEXT_ALIGNMENT_RESOLVED_DEFAULT;
20130         }
20131
20132         // Set the resolved
20133         mPrivateFlags2 |= PFLAG2_TEXT_ALIGNMENT_RESOLVED;
20134         return true;
20135     }
20136
20137     /**
20138      * Check if text alignment resolution can be done.
20139      *
20140      * @return true if text alignment resolution can be done otherwise return false.
20141      */
20142     public boolean canResolveTextAlignment() {
20143         switch (getRawTextAlignment()) {
20144             case TEXT_DIRECTION_INHERIT:
20145                 if (mParent != null) {
20146                     try {
20147                         return mParent.canResolveTextAlignment();
20148                     } catch (AbstractMethodError e) {
20149                         Log.e(VIEW_LOG_TAG, mParent.getClass().getSimpleName() +
20150                                 " does not fully implement ViewParent", e);
20151                     }
20152                 }
20153                 return false;
20154
20155             default:
20156                 return true;
20157         }
20158     }
20159
20160     /**
20161      * Reset resolved text alignment. Text alignment will be resolved during a call to
20162      * {@link #onMeasure(int, int)}.
20163      *
20164      * @hide
20165      */
20166     public void resetResolvedTextAlignment() {
20167         // Reset any previous text alignment resolution
20168         mPrivateFlags2 &= ~(PFLAG2_TEXT_ALIGNMENT_RESOLVED | PFLAG2_TEXT_ALIGNMENT_RESOLVED_MASK);
20169         // Set to default
20170         mPrivateFlags2 |= PFLAG2_TEXT_ALIGNMENT_RESOLVED_DEFAULT;
20171     }
20172
20173     /**
20174      * @return true if text alignment is inherited.
20175      *
20176      * @hide
20177      */
20178     public boolean isTextAlignmentInherited() {
20179         return (getRawTextAlignment() == TEXT_ALIGNMENT_INHERIT);
20180     }
20181
20182     /**
20183      * @return true if text alignment is resolved.
20184      */
20185     public boolean isTextAlignmentResolved() {
20186         return (mPrivateFlags2 & PFLAG2_TEXT_ALIGNMENT_RESOLVED) == PFLAG2_TEXT_ALIGNMENT_RESOLVED;
20187     }
20188
20189     /**
20190      * Generate a value suitable for use in {@link #setId(int)}.
20191      * This value will not collide with ID values generated at build time by aapt for R.id.
20192      *
20193      * @return a generated ID value
20194      */
20195     public static int generateViewId() {
20196         for (;;) {
20197             final int result = sNextGeneratedId.get();
20198             // aapt-generated IDs have the high byte nonzero; clamp to the range under that.
20199             int newValue = result + 1;
20200             if (newValue > 0x00FFFFFF) newValue = 1; // Roll over to 1, not 0.
20201             if (sNextGeneratedId.compareAndSet(result, newValue)) {
20202                 return result;
20203             }
20204         }
20205     }
20206
20207     /**
20208      * Gets the Views in the hierarchy affected by entering and exiting Activity Scene transitions.
20209      * @param transitioningViews This View will be added to transitioningViews if it is VISIBLE and
20210      *                           a normal View or a ViewGroup with
20211      *                           {@link android.view.ViewGroup#isTransitionGroup()} true.
20212      * @hide
20213      */
20214     public void captureTransitioningViews(List<View> transitioningViews) {
20215         if (getVisibility() == View.VISIBLE) {
20216             transitioningViews.add(this);
20217         }
20218     }
20219
20220     /**
20221      * Adds all Views that have {@link #getTransitionName()} non-null to namedElements.
20222      * @param namedElements Will contain all Views in the hierarchy having a transitionName.
20223      * @hide
20224      */
20225     public void findNamedViews(Map<String, View> namedElements) {
20226         if (getVisibility() == VISIBLE || mGhostView != null) {
20227             String transitionName = getTransitionName();
20228             if (transitionName != null) {
20229                 namedElements.put(transitionName, this);
20230             }
20231         }
20232     }
20233
20234     //
20235     // Properties
20236     //
20237     /**
20238      * A Property wrapper around the <code>alpha</code> functionality handled by the
20239      * {@link View#setAlpha(float)} and {@link View#getAlpha()} methods.
20240      */
20241     public static final Property<View, Float> ALPHA = new FloatProperty<View>("alpha") {
20242         @Override
20243         public void setValue(View object, float value) {
20244             object.setAlpha(value);
20245         }
20246
20247         @Override
20248         public Float get(View object) {
20249             return object.getAlpha();
20250         }
20251     };
20252
20253     /**
20254      * A Property wrapper around the <code>translationX</code> functionality handled by the
20255      * {@link View#setTranslationX(float)} and {@link View#getTranslationX()} methods.
20256      */
20257     public static final Property<View, Float> TRANSLATION_X = new FloatProperty<View>("translationX") {
20258         @Override
20259         public void setValue(View object, float value) {
20260             object.setTranslationX(value);
20261         }
20262
20263                 @Override
20264         public Float get(View object) {
20265             return object.getTranslationX();
20266         }
20267     };
20268
20269     /**
20270      * A Property wrapper around the <code>translationY</code> functionality handled by the
20271      * {@link View#setTranslationY(float)} and {@link View#getTranslationY()} methods.
20272      */
20273     public static final Property<View, Float> TRANSLATION_Y = new FloatProperty<View>("translationY") {
20274         @Override
20275         public void setValue(View object, float value) {
20276             object.setTranslationY(value);
20277         }
20278
20279         @Override
20280         public Float get(View object) {
20281             return object.getTranslationY();
20282         }
20283     };
20284
20285     /**
20286      * A Property wrapper around the <code>translationZ</code> functionality handled by the
20287      * {@link View#setTranslationZ(float)} and {@link View#getTranslationZ()} methods.
20288      */
20289     public static final Property<View, Float> TRANSLATION_Z = new FloatProperty<View>("translationZ") {
20290         @Override
20291         public void setValue(View object, float value) {
20292             object.setTranslationZ(value);
20293         }
20294
20295         @Override
20296         public Float get(View object) {
20297             return object.getTranslationZ();
20298         }
20299     };
20300
20301     /**
20302      * A Property wrapper around the <code>x</code> functionality handled by the
20303      * {@link View#setX(float)} and {@link View#getX()} methods.
20304      */
20305     public static final Property<View, Float> X = new FloatProperty<View>("x") {
20306         @Override
20307         public void setValue(View object, float value) {
20308             object.setX(value);
20309         }
20310
20311         @Override
20312         public Float get(View object) {
20313             return object.getX();
20314         }
20315     };
20316
20317     /**
20318      * A Property wrapper around the <code>y</code> functionality handled by the
20319      * {@link View#setY(float)} and {@link View#getY()} methods.
20320      */
20321     public static final Property<View, Float> Y = new FloatProperty<View>("y") {
20322         @Override
20323         public void setValue(View object, float value) {
20324             object.setY(value);
20325         }
20326
20327         @Override
20328         public Float get(View object) {
20329             return object.getY();
20330         }
20331     };
20332
20333     /**
20334      * A Property wrapper around the <code>z</code> functionality handled by the
20335      * {@link View#setZ(float)} and {@link View#getZ()} methods.
20336      */
20337     public static final Property<View, Float> Z = new FloatProperty<View>("z") {
20338         @Override
20339         public void setValue(View object, float value) {
20340             object.setZ(value);
20341         }
20342
20343         @Override
20344         public Float get(View object) {
20345             return object.getZ();
20346         }
20347     };
20348
20349     /**
20350      * A Property wrapper around the <code>rotation</code> functionality handled by the
20351      * {@link View#setRotation(float)} and {@link View#getRotation()} methods.
20352      */
20353     public static final Property<View, Float> ROTATION = new FloatProperty<View>("rotation") {
20354         @Override
20355         public void setValue(View object, float value) {
20356             object.setRotation(value);
20357         }
20358
20359         @Override
20360         public Float get(View object) {
20361             return object.getRotation();
20362         }
20363     };
20364
20365     /**
20366      * A Property wrapper around the <code>rotationX</code> functionality handled by the
20367      * {@link View#setRotationX(float)} and {@link View#getRotationX()} methods.
20368      */
20369     public static final Property<View, Float> ROTATION_X = new FloatProperty<View>("rotationX") {
20370         @Override
20371         public void setValue(View object, float value) {
20372             object.setRotationX(value);
20373         }
20374
20375         @Override
20376         public Float get(View object) {
20377             return object.getRotationX();
20378         }
20379     };
20380
20381     /**
20382      * A Property wrapper around the <code>rotationY</code> functionality handled by the
20383      * {@link View#setRotationY(float)} and {@link View#getRotationY()} methods.
20384      */
20385     public static final Property<View, Float> ROTATION_Y = new FloatProperty<View>("rotationY") {
20386         @Override
20387         public void setValue(View object, float value) {
20388             object.setRotationY(value);
20389         }
20390
20391         @Override
20392         public Float get(View object) {
20393             return object.getRotationY();
20394         }
20395     };
20396
20397     /**
20398      * A Property wrapper around the <code>scaleX</code> functionality handled by the
20399      * {@link View#setScaleX(float)} and {@link View#getScaleX()} methods.
20400      */
20401     public static final Property<View, Float> SCALE_X = new FloatProperty<View>("scaleX") {
20402         @Override
20403         public void setValue(View object, float value) {
20404             object.setScaleX(value);
20405         }
20406
20407         @Override
20408         public Float get(View object) {
20409             return object.getScaleX();
20410         }
20411     };
20412
20413     /**
20414      * A Property wrapper around the <code>scaleY</code> functionality handled by the
20415      * {@link View#setScaleY(float)} and {@link View#getScaleY()} methods.
20416      */
20417     public static final Property<View, Float> SCALE_Y = new FloatProperty<View>("scaleY") {
20418         @Override
20419         public void setValue(View object, float value) {
20420             object.setScaleY(value);
20421         }
20422
20423         @Override
20424         public Float get(View object) {
20425             return object.getScaleY();
20426         }
20427     };
20428
20429     /**
20430      * A MeasureSpec encapsulates the layout requirements passed from parent to child.
20431      * Each MeasureSpec represents a requirement for either the width or the height.
20432      * A MeasureSpec is comprised of a size and a mode. There are three possible
20433      * modes:
20434      * <dl>
20435      * <dt>UNSPECIFIED</dt>
20436      * <dd>
20437      * The parent has not imposed any constraint on the child. It can be whatever size
20438      * it wants.
20439      * </dd>
20440      *
20441      * <dt>EXACTLY</dt>
20442      * <dd>
20443      * The parent has determined an exact size for the child. The child is going to be
20444      * given those bounds regardless of how big it wants to be.
20445      * </dd>
20446      *
20447      * <dt>AT_MOST</dt>
20448      * <dd>
20449      * The child can be as large as it wants up to the specified size.
20450      * </dd>
20451      * </dl>
20452      *
20453      * MeasureSpecs are implemented as ints to reduce object allocation. This class
20454      * is provided to pack and unpack the &lt;size, mode&gt; tuple into the int.
20455      */
20456     public static class MeasureSpec {
20457         private static final int MODE_SHIFT = 30;
20458         private static final int MODE_MASK  = 0x3 << MODE_SHIFT;
20459
20460         /**
20461          * Measure specification mode: The parent has not imposed any constraint
20462          * on the child. It can be whatever size it wants.
20463          */
20464         public static final int UNSPECIFIED = 0 << MODE_SHIFT;
20465
20466         /**
20467          * Measure specification mode: The parent has determined an exact size
20468          * for the child. The child is going to be given those bounds regardless
20469          * of how big it wants to be.
20470          */
20471         public static final int EXACTLY     = 1 << MODE_SHIFT;
20472
20473         /**
20474          * Measure specification mode: The child can be as large as it wants up
20475          * to the specified size.
20476          */
20477         public static final int AT_MOST     = 2 << MODE_SHIFT;
20478
20479         /**
20480          * Creates a measure specification based on the supplied size and mode.
20481          *
20482          * The mode must always be one of the following:
20483          * <ul>
20484          *  <li>{@link android.view.View.MeasureSpec#UNSPECIFIED}</li>
20485          *  <li>{@link android.view.View.MeasureSpec#EXACTLY}</li>
20486          *  <li>{@link android.view.View.MeasureSpec#AT_MOST}</li>
20487          * </ul>
20488          *
20489          * <p><strong>Note:</strong> On API level 17 and lower, makeMeasureSpec's
20490          * implementation was such that the order of arguments did not matter
20491          * and overflow in either value could impact the resulting MeasureSpec.
20492          * {@link android.widget.RelativeLayout} was affected by this bug.
20493          * Apps targeting API levels greater than 17 will get the fixed, more strict
20494          * behavior.</p>
20495          *
20496          * @param size the size of the measure specification
20497          * @param mode the mode of the measure specification
20498          * @return the measure specification based on size and mode
20499          */
20500         public static int makeMeasureSpec(int size, int mode) {
20501             if (sUseBrokenMakeMeasureSpec) {
20502                 return size + mode;
20503             } else {
20504                 return (size & ~MODE_MASK) | (mode & MODE_MASK);
20505             }
20506         }
20507
20508         /**
20509          * Extracts the mode from the supplied measure specification.
20510          *
20511          * @param measureSpec the measure specification to extract the mode from
20512          * @return {@link android.view.View.MeasureSpec#UNSPECIFIED},
20513          *         {@link android.view.View.MeasureSpec#AT_MOST} or
20514          *         {@link android.view.View.MeasureSpec#EXACTLY}
20515          */
20516         public static int getMode(int measureSpec) {
20517             return (measureSpec & MODE_MASK);
20518         }
20519
20520         /**
20521          * Extracts the size from the supplied measure specification.
20522          *
20523          * @param measureSpec the measure specification to extract the size from
20524          * @return the size in pixels defined in the supplied measure specification
20525          */
20526         public static int getSize(int measureSpec) {
20527             return (measureSpec & ~MODE_MASK);
20528         }
20529
20530         static int adjust(int measureSpec, int delta) {
20531             final int mode = getMode(measureSpec);
20532             int size = getSize(measureSpec);
20533             if (mode == UNSPECIFIED) {
20534                 // No need to adjust size for UNSPECIFIED mode.
20535                 return makeMeasureSpec(size, UNSPECIFIED);
20536             }
20537             size += delta;
20538             if (size < 0) {
20539                 Log.e(VIEW_LOG_TAG, "MeasureSpec.adjust: new size would be negative! (" + size +
20540                         ") spec: " + toString(measureSpec) + " delta: " + delta);
20541                 size = 0;
20542             }
20543             return makeMeasureSpec(size, mode);
20544         }
20545
20546         /**
20547          * Returns a String representation of the specified measure
20548          * specification.
20549          *
20550          * @param measureSpec the measure specification to convert to a String
20551          * @return a String with the following format: "MeasureSpec: MODE SIZE"
20552          */
20553         public static String toString(int measureSpec) {
20554             int mode = getMode(measureSpec);
20555             int size = getSize(measureSpec);
20556
20557             StringBuilder sb = new StringBuilder("MeasureSpec: ");
20558
20559             if (mode == UNSPECIFIED)
20560                 sb.append("UNSPECIFIED ");
20561             else if (mode == EXACTLY)
20562                 sb.append("EXACTLY ");
20563             else if (mode == AT_MOST)
20564                 sb.append("AT_MOST ");
20565             else
20566                 sb.append(mode).append(" ");
20567
20568             sb.append(size);
20569             return sb.toString();
20570         }
20571     }
20572
20573     private final class CheckForLongPress implements Runnable {
20574         private int mOriginalWindowAttachCount;
20575
20576         @Override
20577         public void run() {
20578             if (isPressed() && (mParent != null)
20579                     && mOriginalWindowAttachCount == mWindowAttachCount) {
20580                 if (performLongClick()) {
20581                     mHasPerformedLongPress = true;
20582                 }
20583             }
20584         }
20585
20586         public void rememberWindowAttachCount() {
20587             mOriginalWindowAttachCount = mWindowAttachCount;
20588         }
20589     }
20590
20591     private final class CheckForTap implements Runnable {
20592         public float x;
20593         public float y;
20594
20595         @Override
20596         public void run() {
20597             mPrivateFlags &= ~PFLAG_PREPRESSED;
20598             setPressed(true, x, y);
20599             checkForLongClick(ViewConfiguration.getTapTimeout());
20600         }
20601     }
20602
20603     private final class PerformClick implements Runnable {
20604         @Override
20605         public void run() {
20606             performClick();
20607         }
20608     }
20609
20610     /** @hide */
20611     public void hackTurnOffWindowResizeAnim(boolean off) {
20612         mAttachInfo.mTurnOffWindowResizeAnim = off;
20613     }
20614
20615     /**
20616      * This method returns a ViewPropertyAnimator object, which can be used to animate
20617      * specific properties on this View.
20618      *
20619      * @return ViewPropertyAnimator The ViewPropertyAnimator associated with this View.
20620      */
20621     public ViewPropertyAnimator animate() {
20622         if (mAnimator == null) {
20623             mAnimator = new ViewPropertyAnimator(this);
20624         }
20625         return mAnimator;
20626     }
20627
20628     /**
20629      * Sets the name of the View to be used to identify Views in Transitions.
20630      * Names should be unique in the View hierarchy.
20631      *
20632      * @param transitionName The name of the View to uniquely identify it for Transitions.
20633      */
20634     public final void setTransitionName(String transitionName) {
20635         mTransitionName = transitionName;
20636     }
20637
20638     /**
20639      * Returns the name of the View to be used to identify Views in Transitions.
20640      * Names should be unique in the View hierarchy.
20641      *
20642      * <p>This returns null if the View has not been given a name.</p>
20643      *
20644      * @return The name used of the View to be used to identify Views in Transitions or null
20645      * if no name has been given.
20646      */
20647     @ViewDebug.ExportedProperty
20648     public String getTransitionName() {
20649         return mTransitionName;
20650     }
20651
20652     /**
20653      * Interface definition for a callback to be invoked when a hardware key event is
20654      * dispatched to this view. The callback will be invoked before the key event is
20655      * given to the view. This is only useful for hardware keyboards; a software input
20656      * method has no obligation to trigger this listener.
20657      */
20658     public interface OnKeyListener {
20659         /**
20660          * Called when a hardware key is dispatched to a view. This allows listeners to
20661          * get a chance to respond before the target view.
20662          * <p>Key presses in software keyboards will generally NOT trigger this method,
20663          * although some may elect to do so in some situations. Do not assume a
20664          * software input method has to be key-based; even if it is, it may use key presses
20665          * in a different way than you expect, so there is no way to reliably catch soft
20666          * input key presses.
20667          *
20668          * @param v The view the key has been dispatched to.
20669          * @param keyCode The code for the physical key that was pressed
20670          * @param event The KeyEvent object containing full information about
20671          *        the event.
20672          * @return True if the listener has consumed the event, false otherwise.
20673          */
20674         boolean onKey(View v, int keyCode, KeyEvent event);
20675     }
20676
20677     /**
20678      * Interface definition for a callback to be invoked when a touch event is
20679      * dispatched to this view. The callback will be invoked before the touch
20680      * event is given to the view.
20681      */
20682     public interface OnTouchListener {
20683         /**
20684          * Called when a touch event is dispatched to a view. This allows listeners to
20685          * get a chance to respond before the target view.
20686          *
20687          * @param v The view the touch event has been dispatched to.
20688          * @param event The MotionEvent object containing full information about
20689          *        the event.
20690          * @return True if the listener has consumed the event, false otherwise.
20691          */
20692         boolean onTouch(View v, MotionEvent event);
20693     }
20694
20695     /**
20696      * Interface definition for a callback to be invoked when a hover event is
20697      * dispatched to this view. The callback will be invoked before the hover
20698      * event is given to the view.
20699      */
20700     public interface OnHoverListener {
20701         /**
20702          * Called when a hover event is dispatched to a view. This allows listeners to
20703          * get a chance to respond before the target view.
20704          *
20705          * @param v The view the hover event has been dispatched to.
20706          * @param event The MotionEvent object containing full information about
20707          *        the event.
20708          * @return True if the listener has consumed the event, false otherwise.
20709          */
20710         boolean onHover(View v, MotionEvent event);
20711     }
20712
20713     /**
20714      * Interface definition for a callback to be invoked when a generic motion event is
20715      * dispatched to this view. The callback will be invoked before the generic motion
20716      * event is given to the view.
20717      */
20718     public interface OnGenericMotionListener {
20719         /**
20720          * Called when a generic motion event is dispatched to a view. This allows listeners to
20721          * get a chance to respond before the target view.
20722          *
20723          * @param v The view the generic motion event has been dispatched to.
20724          * @param event The MotionEvent object containing full information about
20725          *        the event.
20726          * @return True if the listener has consumed the event, false otherwise.
20727          */
20728         boolean onGenericMotion(View v, MotionEvent event);
20729     }
20730
20731     /**
20732      * Interface definition for a callback to be invoked when a view has been clicked and held.
20733      */
20734     public interface OnLongClickListener {
20735         /**
20736          * Called when a view has been clicked and held.
20737          *
20738          * @param v The view that was clicked and held.
20739          *
20740          * @return true if the callback consumed the long click, false otherwise.
20741          */
20742         boolean onLongClick(View v);
20743     }
20744
20745     /**
20746      * Interface definition for a callback to be invoked when a drag is being dispatched
20747      * to this view.  The callback will be invoked before the hosting view's own
20748      * onDrag(event) method.  If the listener wants to fall back to the hosting view's
20749      * onDrag(event) behavior, it should return 'false' from this callback.
20750      *
20751      * <div class="special reference">
20752      * <h3>Developer Guides</h3>
20753      * <p>For a guide to implementing drag and drop features, read the
20754      * <a href="{@docRoot}guide/topics/ui/drag-drop.html">Drag and Drop</a> developer guide.</p>
20755      * </div>
20756      */
20757     public interface OnDragListener {
20758         /**
20759          * Called when a drag event is dispatched to a view. This allows listeners
20760          * to get a chance to override base View behavior.
20761          *
20762          * @param v The View that received the drag event.
20763          * @param event The {@link android.view.DragEvent} object for the drag event.
20764          * @return {@code true} if the drag event was handled successfully, or {@code false}
20765          * if the drag event was not handled. Note that {@code false} will trigger the View
20766          * to call its {@link #onDragEvent(DragEvent) onDragEvent()} handler.
20767          */
20768         boolean onDrag(View v, DragEvent event);
20769     }
20770
20771     /**
20772      * Interface definition for a callback to be invoked when the focus state of
20773      * a view changed.
20774      */
20775     public interface OnFocusChangeListener {
20776         /**
20777          * Called when the focus state of a view has changed.
20778          *
20779          * @param v The view whose state has changed.
20780          * @param hasFocus The new focus state of v.
20781          */
20782         void onFocusChange(View v, boolean hasFocus);
20783     }
20784
20785     /**
20786      * Interface definition for a callback to be invoked when a view is clicked.
20787      */
20788     public interface OnClickListener {
20789         /**
20790          * Called when a view has been clicked.
20791          *
20792          * @param v The view that was clicked.
20793          */
20794         void onClick(View v);
20795     }
20796
20797     /**
20798      * Interface definition for a callback to be invoked when the context menu
20799      * for this view is being built.
20800      */
20801     public interface OnCreateContextMenuListener {
20802         /**
20803          * Called when the context menu for this view is being built. It is not
20804          * safe to hold onto the menu after this method returns.
20805          *
20806          * @param menu The context menu that is being built
20807          * @param v The view for which the context menu is being built
20808          * @param menuInfo Extra information about the item for which the
20809          *            context menu should be shown. This information will vary
20810          *            depending on the class of v.
20811          */
20812         void onCreateContextMenu(ContextMenu menu, View v, ContextMenuInfo menuInfo);
20813     }
20814
20815     /**
20816      * Interface definition for a callback to be invoked when the status bar changes
20817      * visibility.  This reports <strong>global</strong> changes to the system UI
20818      * state, not what the application is requesting.
20819      *
20820      * @see View#setOnSystemUiVisibilityChangeListener(android.view.View.OnSystemUiVisibilityChangeListener)
20821      */
20822     public interface OnSystemUiVisibilityChangeListener {
20823         /**
20824          * Called when the status bar changes visibility because of a call to
20825          * {@link View#setSystemUiVisibility(int)}.
20826          *
20827          * @param visibility  Bitwise-or of flags {@link #SYSTEM_UI_FLAG_LOW_PROFILE},
20828          * {@link #SYSTEM_UI_FLAG_HIDE_NAVIGATION}, and {@link #SYSTEM_UI_FLAG_FULLSCREEN}.
20829          * This tells you the <strong>global</strong> state of these UI visibility
20830          * flags, not what your app is currently applying.
20831          */
20832         public void onSystemUiVisibilityChange(int visibility);
20833     }
20834
20835     /**
20836      * Interface definition for a callback to be invoked when this view is attached
20837      * or detached from its window.
20838      */
20839     public interface OnAttachStateChangeListener {
20840         /**
20841          * Called when the view is attached to a window.
20842          * @param v The view that was attached
20843          */
20844         public void onViewAttachedToWindow(View v);
20845         /**
20846          * Called when the view is detached from a window.
20847          * @param v The view that was detached
20848          */
20849         public void onViewDetachedFromWindow(View v);
20850     }
20851
20852     /**
20853      * Listener for applying window insets on a view in a custom way.
20854      *
20855      * <p>Apps may choose to implement this interface if they want to apply custom policy
20856      * to the way that window insets are treated for a view. If an OnApplyWindowInsetsListener
20857      * is set, its
20858      * {@link OnApplyWindowInsetsListener#onApplyWindowInsets(View, WindowInsets) onApplyWindowInsets}
20859      * method will be called instead of the View's own
20860      * {@link #onApplyWindowInsets(WindowInsets) onApplyWindowInsets} method. The listener
20861      * may optionally call the parameter View's <code>onApplyWindowInsets</code> method to apply
20862      * the View's normal behavior as part of its own.</p>
20863      */
20864     public interface OnApplyWindowInsetsListener {
20865         /**
20866          * When {@link View#setOnApplyWindowInsetsListener(View.OnApplyWindowInsetsListener) set}
20867          * on a View, this listener method will be called instead of the view's own
20868          * {@link View#onApplyWindowInsets(WindowInsets) onApplyWindowInsets} method.
20869          *
20870          * @param v The view applying window insets
20871          * @param insets The insets to apply
20872          * @return The insets supplied, minus any insets that were consumed
20873          */
20874         public WindowInsets onApplyWindowInsets(View v, WindowInsets insets);
20875     }
20876
20877     private final class UnsetPressedState implements Runnable {
20878         @Override
20879         public void run() {
20880             setPressed(false);
20881         }
20882     }
20883
20884     /**
20885      * Base class for derived classes that want to save and restore their own
20886      * state in {@link android.view.View#onSaveInstanceState()}.
20887      */
20888     public static class BaseSavedState extends AbsSavedState {
20889         String mStartActivityRequestWhoSaved;
20890
20891         /**
20892          * Constructor used when reading from a parcel. Reads the state of the superclass.
20893          *
20894          * @param source
20895          */
20896         public BaseSavedState(Parcel source) {
20897             super(source);
20898             mStartActivityRequestWhoSaved = source.readString();
20899         }
20900
20901         /**
20902          * Constructor called by derived classes when creating their SavedState objects
20903          *
20904          * @param superState The state of the superclass of this view
20905          */
20906         public BaseSavedState(Parcelable superState) {
20907             super(superState);
20908         }
20909
20910         @Override
20911         public void writeToParcel(Parcel out, int flags) {
20912             super.writeToParcel(out, flags);
20913             out.writeString(mStartActivityRequestWhoSaved);
20914         }
20915
20916         public static final Parcelable.Creator<BaseSavedState> CREATOR =
20917                 new Parcelable.Creator<BaseSavedState>() {
20918             public BaseSavedState createFromParcel(Parcel in) {
20919                 return new BaseSavedState(in);
20920             }
20921
20922             public BaseSavedState[] newArray(int size) {
20923                 return new BaseSavedState[size];
20924             }
20925         };
20926     }
20927
20928     /**
20929      * A set of information given to a view when it is attached to its parent
20930      * window.
20931      */
20932     final static class AttachInfo {
20933         interface Callbacks {
20934             void playSoundEffect(int effectId);
20935             boolean performHapticFeedback(int effectId, boolean always);
20936         }
20937
20938         /**
20939          * InvalidateInfo is used to post invalidate(int, int, int, int) messages
20940          * to a Handler. This class contains the target (View) to invalidate and
20941          * the coordinates of the dirty rectangle.
20942          *
20943          * For performance purposes, this class also implements a pool of up to
20944          * POOL_LIMIT objects that get reused. This reduces memory allocations
20945          * whenever possible.
20946          */
20947         static class InvalidateInfo {
20948             private static final int POOL_LIMIT = 10;
20949
20950             private static final SynchronizedPool<InvalidateInfo> sPool =
20951                     new SynchronizedPool<InvalidateInfo>(POOL_LIMIT);
20952
20953             View target;
20954
20955             int left;
20956             int top;
20957             int right;
20958             int bottom;
20959
20960             public static InvalidateInfo obtain() {
20961                 InvalidateInfo instance = sPool.acquire();
20962                 return (instance != null) ? instance : new InvalidateInfo();
20963             }
20964
20965             public void recycle() {
20966                 target = null;
20967                 sPool.release(this);
20968             }
20969         }
20970
20971         final IWindowSession mSession;
20972
20973         final IWindow mWindow;
20974
20975         final IBinder mWindowToken;
20976
20977         final Display mDisplay;
20978
20979         final Callbacks mRootCallbacks;
20980
20981         IWindowId mIWindowId;
20982         WindowId mWindowId;
20983
20984         /**
20985          * The top view of the hierarchy.
20986          */
20987         View mRootView;
20988
20989         IBinder mPanelParentWindowToken;
20990
20991         boolean mHardwareAccelerated;
20992         boolean mHardwareAccelerationRequested;
20993         HardwareRenderer mHardwareRenderer;
20994         List<RenderNode> mPendingAnimatingRenderNodes;
20995
20996         /**
20997          * The state of the display to which the window is attached, as reported
20998          * by {@link Display#getState()}.  Note that the display state constants
20999          * declared by {@link Display} do not exactly line up with the screen state
21000          * constants declared by {@link View} (there are more display states than
21001          * screen states).
21002          */
21003         int mDisplayState = Display.STATE_UNKNOWN;
21004
21005         /**
21006          * Scale factor used by the compatibility mode
21007          */
21008         float mApplicationScale;
21009
21010         /**
21011          * Indicates whether the application is in compatibility mode
21012          */
21013         boolean mScalingRequired;
21014
21015         /**
21016          * If set, ViewRootImpl doesn't use its lame animation for when the window resizes.
21017          */
21018         boolean mTurnOffWindowResizeAnim;
21019
21020         /**
21021          * Left position of this view's window
21022          */
21023         int mWindowLeft;
21024
21025         /**
21026          * Top position of this view's window
21027          */
21028         int mWindowTop;
21029
21030         /**
21031          * Indicates whether views need to use 32-bit drawing caches
21032          */
21033         boolean mUse32BitDrawingCache;
21034
21035         /**
21036          * For windows that are full-screen but using insets to layout inside
21037          * of the screen areas, these are the current insets to appear inside
21038          * the overscan area of the display.
21039          */
21040         final Rect mOverscanInsets = new Rect();
21041
21042         /**
21043          * For windows that are full-screen but using insets to layout inside
21044          * of the screen decorations, these are the current insets for the
21045          * content of the window.
21046          */
21047         final Rect mContentInsets = new Rect();
21048
21049         /**
21050          * For windows that are full-screen but using insets to layout inside
21051          * of the screen decorations, these are the current insets for the
21052          * actual visible parts of the window.
21053          */
21054         final Rect mVisibleInsets = new Rect();
21055
21056         /**
21057          * For windows that are full-screen but using insets to layout inside
21058          * of the screen decorations, these are the current insets for the
21059          * stable system windows.
21060          */
21061         final Rect mStableInsets = new Rect();
21062
21063         /**
21064          * The internal insets given by this window.  This value is
21065          * supplied by the client (through
21066          * {@link ViewTreeObserver.OnComputeInternalInsetsListener}) and will
21067          * be given to the window manager when changed to be used in laying
21068          * out windows behind it.
21069          */
21070         final ViewTreeObserver.InternalInsetsInfo mGivenInternalInsets
21071                 = new ViewTreeObserver.InternalInsetsInfo();
21072
21073         /**
21074          * Set to true when mGivenInternalInsets is non-empty.
21075          */
21076         boolean mHasNonEmptyGivenInternalInsets;
21077
21078         /**
21079          * All views in the window's hierarchy that serve as scroll containers,
21080          * used to determine if the window can be resized or must be panned
21081          * to adjust for a soft input area.
21082          */
21083         final ArrayList<View> mScrollContainers = new ArrayList<View>();
21084
21085         final KeyEvent.DispatcherState mKeyDispatchState
21086                 = new KeyEvent.DispatcherState();
21087
21088         /**
21089          * Indicates whether the view's window currently has the focus.
21090          */
21091         boolean mHasWindowFocus;
21092
21093         /**
21094          * The current visibility of the window.
21095          */
21096         int mWindowVisibility;
21097
21098         /**
21099          * Indicates the time at which drawing started to occur.
21100          */
21101         long mDrawingTime;
21102
21103         /**
21104          * Indicates whether or not ignoring the DIRTY_MASK flags.
21105          */
21106         boolean mIgnoreDirtyState;
21107
21108         /**
21109          * This flag tracks when the mIgnoreDirtyState flag is set during draw(),
21110          * to avoid clearing that flag prematurely.
21111          */
21112         boolean mSetIgnoreDirtyState = false;
21113
21114         /**
21115          * Indicates whether the view's window is currently in touch mode.
21116          */
21117         boolean mInTouchMode;
21118
21119         /**
21120          * Indicates whether the view has requested unbuffered input dispatching for the current
21121          * event stream.
21122          */
21123         boolean mUnbufferedDispatchRequested;
21124
21125         /**
21126          * Indicates that ViewAncestor should trigger a global layout change
21127          * the next time it performs a traversal
21128          */
21129         boolean mRecomputeGlobalAttributes;
21130
21131         /**
21132          * Always report new attributes at next traversal.
21133          */
21134         boolean mForceReportNewAttributes;
21135
21136         /**
21137          * Set during a traveral if any views want to keep the screen on.
21138          */
21139         boolean mKeepScreenOn;
21140
21141         /**
21142          * Bitwise-or of all of the values that views have passed to setSystemUiVisibility().
21143          */
21144         int mSystemUiVisibility;
21145
21146         /**
21147          * Hack to force certain system UI visibility flags to be cleared.
21148          */
21149         int mDisabledSystemUiVisibility;
21150
21151         /**
21152          * Last global system UI visibility reported by the window manager.
21153          */
21154         int mGlobalSystemUiVisibility;
21155
21156         /**
21157          * True if a view in this hierarchy has an OnSystemUiVisibilityChangeListener
21158          * attached.
21159          */
21160         boolean mHasSystemUiListeners;
21161
21162         /**
21163          * Set if the window has requested to extend into the overscan region
21164          * via WindowManager.LayoutParams.FLAG_LAYOUT_IN_OVERSCAN.
21165          */
21166         boolean mOverscanRequested;
21167
21168         /**
21169          * Set if the visibility of any views has changed.
21170          */
21171         boolean mViewVisibilityChanged;
21172
21173         /**
21174          * Set to true if a view has been scrolled.
21175          */
21176         boolean mViewScrollChanged;
21177
21178         /**
21179          * Set to true if high contrast mode enabled
21180          */
21181         boolean mHighContrastText;
21182
21183         /**
21184          * Global to the view hierarchy used as a temporary for dealing with
21185          * x/y points in the transparent region computations.
21186          */
21187         final int[] mTransparentLocation = new int[2];
21188
21189         /**
21190          * Global to the view hierarchy used as a temporary for dealing with
21191          * x/y points in the ViewGroup.invalidateChild implementation.
21192          */
21193         final int[] mInvalidateChildLocation = new int[2];
21194
21195         /**
21196          * Global to the view hierarchy used as a temporary for dealng with
21197          * computing absolute on-screen location.
21198          */
21199         final int[] mTmpLocation = new int[2];
21200
21201         /**
21202          * Global to the view hierarchy used as a temporary for dealing with
21203          * x/y location when view is transformed.
21204          */
21205         final float[] mTmpTransformLocation = new float[2];
21206
21207         /**
21208          * The view tree observer used to dispatch global events like
21209          * layout, pre-draw, touch mode change, etc.
21210          */
21211         final ViewTreeObserver mTreeObserver = new ViewTreeObserver();
21212
21213         /**
21214          * A Canvas used by the view hierarchy to perform bitmap caching.
21215          */
21216         Canvas mCanvas;
21217
21218         /**
21219          * The view root impl.
21220          */
21221         final ViewRootImpl mViewRootImpl;
21222
21223         /**
21224          * A Handler supplied by a view's {@link android.view.ViewRootImpl}. This
21225          * handler can be used to pump events in the UI events queue.
21226          */
21227         final Handler mHandler;
21228
21229         /**
21230          * Temporary for use in computing invalidate rectangles while
21231          * calling up the hierarchy.
21232          */
21233         final Rect mTmpInvalRect = new Rect();
21234
21235         /**
21236          * Temporary for use in computing hit areas with transformed views
21237          */
21238         final RectF mTmpTransformRect = new RectF();
21239
21240         /**
21241          * Temporary for use in computing hit areas with transformed views
21242          */
21243         final RectF mTmpTransformRect1 = new RectF();
21244
21245         /**
21246          * Temporary list of rectanges.
21247          */
21248         final List<RectF> mTmpRectList = new ArrayList<>();
21249
21250         /**
21251          * Temporary for use in transforming invalidation rect
21252          */
21253         final Matrix mTmpMatrix = new Matrix();
21254
21255         /**
21256          * Temporary for use in transforming invalidation rect
21257          */
21258         final Transformation mTmpTransformation = new Transformation();
21259
21260         /**
21261          * Temporary for use in querying outlines from OutlineProviders
21262          */
21263         final Outline mTmpOutline = new Outline();
21264
21265         /**
21266          * Temporary list for use in collecting focusable descendents of a view.
21267          */
21268         final ArrayList<View> mTempArrayList = new ArrayList<View>(24);
21269
21270         /**
21271          * The id of the window for accessibility purposes.
21272          */
21273         int mAccessibilityWindowId = AccessibilityNodeInfo.UNDEFINED_ITEM_ID;
21274
21275         /**
21276          * Flags related to accessibility processing.
21277          *
21278          * @see AccessibilityNodeInfo#FLAG_INCLUDE_NOT_IMPORTANT_VIEWS
21279          * @see AccessibilityNodeInfo#FLAG_REPORT_VIEW_IDS
21280          */
21281         int mAccessibilityFetchFlags;
21282
21283         /**
21284          * The drawable for highlighting accessibility focus.
21285          */
21286         Drawable mAccessibilityFocusDrawable;
21287
21288         /**
21289          * Show where the margins, bounds and layout bounds are for each view.
21290          */
21291         boolean mDebugLayout = SystemProperties.getBoolean(DEBUG_LAYOUT_PROPERTY, false);
21292
21293         /**
21294          * Point used to compute visible regions.
21295          */
21296         final Point mPoint = new Point();
21297
21298         /**
21299          * Used to track which View originated a requestLayout() call, used when
21300          * requestLayout() is called during layout.
21301          */
21302         View mViewRequestingLayout;
21303
21304         /**
21305          * Creates a new set of attachment information with the specified
21306          * events handler and thread.
21307          *
21308          * @param handler the events handler the view must use
21309          */
21310         AttachInfo(IWindowSession session, IWindow window, Display display,
21311                 ViewRootImpl viewRootImpl, Handler handler, Callbacks effectPlayer) {
21312             mSession = session;
21313             mWindow = window;
21314             mWindowToken = window.asBinder();
21315             mDisplay = display;
21316             mViewRootImpl = viewRootImpl;
21317             mHandler = handler;
21318             mRootCallbacks = effectPlayer;
21319         }
21320     }
21321
21322     /**
21323      * <p>ScrollabilityCache holds various fields used by a View when scrolling
21324      * is supported. This avoids keeping too many unused fields in most
21325      * instances of View.</p>
21326      */
21327     private static class ScrollabilityCache implements Runnable {
21328
21329         /**
21330          * Scrollbars are not visible
21331          */
21332         public static final int OFF = 0;
21333
21334         /**
21335          * Scrollbars are visible
21336          */
21337         public static final int ON = 1;
21338
21339         /**
21340          * Scrollbars are fading away
21341          */
21342         public static final int FADING = 2;
21343
21344         public boolean fadeScrollBars;
21345
21346         public int fadingEdgeLength;
21347         public int scrollBarDefaultDelayBeforeFade;
21348         public int scrollBarFadeDuration;
21349
21350         public int scrollBarSize;
21351         public ScrollBarDrawable scrollBar;
21352         public float[] interpolatorValues;
21353         public View host;
21354
21355         public final Paint paint;
21356         public final Matrix matrix;
21357         public Shader shader;
21358
21359         public final Interpolator scrollBarInterpolator = new Interpolator(1, 2);
21360
21361         private static final float[] OPAQUE = { 255 };
21362         private static final float[] TRANSPARENT = { 0.0f };
21363
21364         /**
21365          * When fading should start. This time moves into the future every time
21366          * a new scroll happens. Measured based on SystemClock.uptimeMillis()
21367          */
21368         public long fadeStartTime;
21369
21370
21371         /**
21372          * The current state of the scrollbars: ON, OFF, or FADING
21373          */
21374         public int state = OFF;
21375
21376         private int mLastColor;
21377
21378         public ScrollabilityCache(ViewConfiguration configuration, View host) {
21379             fadingEdgeLength = configuration.getScaledFadingEdgeLength();
21380             scrollBarSize = configuration.getScaledScrollBarSize();
21381             scrollBarDefaultDelayBeforeFade = ViewConfiguration.getScrollDefaultDelay();
21382             scrollBarFadeDuration = ViewConfiguration.getScrollBarFadeDuration();
21383
21384             paint = new Paint();
21385             matrix = new Matrix();
21386             // use use a height of 1, and then wack the matrix each time we
21387             // actually use it.
21388             shader = new LinearGradient(0, 0, 0, 1, 0xFF000000, 0, Shader.TileMode.CLAMP);
21389             paint.setShader(shader);
21390             paint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.DST_OUT));
21391
21392             this.host = host;
21393         }
21394
21395         public void setFadeColor(int color) {
21396             if (color != mLastColor) {
21397                 mLastColor = color;
21398
21399                 if (color != 0) {
21400                     shader = new LinearGradient(0, 0, 0, 1, color | 0xFF000000,
21401                             color & 0x00FFFFFF, Shader.TileMode.CLAMP);
21402                     paint.setShader(shader);
21403                     // Restore the default transfer mode (src_over)
21404                     paint.setXfermode(null);
21405                 } else {
21406                     shader = new LinearGradient(0, 0, 0, 1, 0xFF000000, 0, Shader.TileMode.CLAMP);
21407                     paint.setShader(shader);
21408                     paint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.DST_OUT));
21409                 }
21410             }
21411         }
21412
21413         public void run() {
21414             long now = AnimationUtils.currentAnimationTimeMillis();
21415             if (now >= fadeStartTime) {
21416
21417                 // the animation fades the scrollbars out by changing
21418                 // the opacity (alpha) from fully opaque to fully
21419                 // transparent
21420                 int nextFrame = (int) now;
21421                 int framesCount = 0;
21422
21423                 Interpolator interpolator = scrollBarInterpolator;
21424
21425                 // Start opaque
21426                 interpolator.setKeyFrame(framesCount++, nextFrame, OPAQUE);
21427
21428                 // End transparent
21429                 nextFrame += scrollBarFadeDuration;
21430                 interpolator.setKeyFrame(framesCount, nextFrame, TRANSPARENT);
21431
21432                 state = FADING;
21433
21434                 // Kick off the fade animation
21435                 host.invalidate(true);
21436             }
21437         }
21438     }
21439
21440     /**
21441      * Resuable callback for sending
21442      * {@link AccessibilityEvent#TYPE_VIEW_SCROLLED} accessibility event.
21443      */
21444     private class SendViewScrolledAccessibilityEvent implements Runnable {
21445         public volatile boolean mIsPending;
21446
21447         public void run() {
21448             sendAccessibilityEvent(AccessibilityEvent.TYPE_VIEW_SCROLLED);
21449             mIsPending = false;
21450         }
21451     }
21452
21453     /**
21454      * <p>
21455      * This class represents a delegate that can be registered in a {@link View}
21456      * to enhance accessibility support via composition rather via inheritance.
21457      * It is specifically targeted to widget developers that extend basic View
21458      * classes i.e. classes in package android.view, that would like their
21459      * applications to be backwards compatible.
21460      * </p>
21461      * <div class="special reference">
21462      * <h3>Developer Guides</h3>
21463      * <p>For more information about making applications accessible, read the
21464      * <a href="{@docRoot}guide/topics/ui/accessibility/index.html">Accessibility</a>
21465      * developer guide.</p>
21466      * </div>
21467      * <p>
21468      * A scenario in which a developer would like to use an accessibility delegate
21469      * is overriding a method introduced in a later API version then the minimal API
21470      * version supported by the application. For example, the method
21471      * {@link View#onInitializeAccessibilityNodeInfo(AccessibilityNodeInfo)} is not available
21472      * in API version 4 when the accessibility APIs were first introduced. If a
21473      * developer would like his application to run on API version 4 devices (assuming
21474      * all other APIs used by the application are version 4 or lower) and take advantage
21475      * of this method, instead of overriding the method which would break the application's
21476      * backwards compatibility, he can override the corresponding method in this
21477      * delegate and register the delegate in the target View if the API version of
21478      * the system is high enough i.e. the API version is same or higher to the API
21479      * version that introduced
21480      * {@link View#onInitializeAccessibilityNodeInfo(AccessibilityNodeInfo)}.
21481      * </p>
21482      * <p>
21483      * Here is an example implementation:
21484      * </p>
21485      * <code><pre><p>
21486      * if (Build.VERSION.SDK_INT >= 14) {
21487      *     // If the API version is equal of higher than the version in
21488      *     // which onInitializeAccessibilityNodeInfo was introduced we
21489      *     // register a delegate with a customized implementation.
21490      *     View view = findViewById(R.id.view_id);
21491      *     view.setAccessibilityDelegate(new AccessibilityDelegate() {
21492      *         public void onInitializeAccessibilityNodeInfo(View host,
21493      *                 AccessibilityNodeInfo info) {
21494      *             // Let the default implementation populate the info.
21495      *             super.onInitializeAccessibilityNodeInfo(host, info);
21496      *             // Set some other information.
21497      *             info.setEnabled(host.isEnabled());
21498      *         }
21499      *     });
21500      * }
21501      * </code></pre></p>
21502      * <p>
21503      * This delegate contains methods that correspond to the accessibility methods
21504      * in View. If a delegate has been specified the implementation in View hands
21505      * off handling to the corresponding method in this delegate. The default
21506      * implementation the delegate methods behaves exactly as the corresponding
21507      * method in View for the case of no accessibility delegate been set. Hence,
21508      * to customize the behavior of a View method, clients can override only the
21509      * corresponding delegate method without altering the behavior of the rest
21510      * accessibility related methods of the host view.
21511      * </p>
21512      */
21513     public static class AccessibilityDelegate {
21514
21515         /**
21516          * Sends an accessibility event of the given type. If accessibility is not
21517          * enabled this method has no effect.
21518          * <p>
21519          * The default implementation behaves as {@link View#sendAccessibilityEvent(int)
21520          *  View#sendAccessibilityEvent(int)} for the case of no accessibility delegate
21521          * been set.
21522          * </p>
21523          *
21524          * @param host The View hosting the delegate.
21525          * @param eventType The type of the event to send.
21526          *
21527          * @see View#sendAccessibilityEvent(int) View#sendAccessibilityEvent(int)
21528          */
21529         public void sendAccessibilityEvent(View host, int eventType) {
21530             host.sendAccessibilityEventInternal(eventType);
21531         }
21532
21533         /**
21534          * Performs the specified accessibility action on the view. For
21535          * possible accessibility actions look at {@link AccessibilityNodeInfo}.
21536          * <p>
21537          * The default implementation behaves as
21538          * {@link View#performAccessibilityAction(int, Bundle)
21539          *  View#performAccessibilityAction(int, Bundle)} for the case of
21540          *  no accessibility delegate been set.
21541          * </p>
21542          *
21543          * @param action The action to perform.
21544          * @return Whether the action was performed.
21545          *
21546          * @see View#performAccessibilityAction(int, Bundle)
21547          *      View#performAccessibilityAction(int, Bundle)
21548          */
21549         public boolean performAccessibilityAction(View host, int action, Bundle args) {
21550             return host.performAccessibilityActionInternal(action, args);
21551         }
21552
21553         /**
21554          * Sends an accessibility event. This method behaves exactly as
21555          * {@link #sendAccessibilityEvent(View, int)} but takes as an argument an
21556          * empty {@link AccessibilityEvent} and does not perform a check whether
21557          * accessibility is enabled.
21558          * <p>
21559          * The default implementation behaves as
21560          * {@link View#sendAccessibilityEventUnchecked(AccessibilityEvent)
21561          *  View#sendAccessibilityEventUnchecked(AccessibilityEvent)} for
21562          * the case of no accessibility delegate been set.
21563          * </p>
21564          *
21565          * @param host The View hosting the delegate.
21566          * @param event The event to send.
21567          *
21568          * @see View#sendAccessibilityEventUnchecked(AccessibilityEvent)
21569          *      View#sendAccessibilityEventUnchecked(AccessibilityEvent)
21570          */
21571         public void sendAccessibilityEventUnchecked(View host, AccessibilityEvent event) {
21572             host.sendAccessibilityEventUncheckedInternal(event);
21573         }
21574
21575         /**
21576          * Dispatches an {@link AccessibilityEvent} to the host {@link View} first and then
21577          * to its children for adding their text content to the event.
21578          * <p>
21579          * The default implementation behaves as
21580          * {@link View#dispatchPopulateAccessibilityEvent(AccessibilityEvent)
21581          *  View#dispatchPopulateAccessibilityEvent(AccessibilityEvent)} for
21582          * the case of no accessibility delegate been set.
21583          * </p>
21584          *
21585          * @param host The View hosting the delegate.
21586          * @param event The event.
21587          * @return True if the event population was completed.
21588          *
21589          * @see View#dispatchPopulateAccessibilityEvent(AccessibilityEvent)
21590          *      View#dispatchPopulateAccessibilityEvent(AccessibilityEvent)
21591          */
21592         public boolean dispatchPopulateAccessibilityEvent(View host, AccessibilityEvent event) {
21593             return host.dispatchPopulateAccessibilityEventInternal(event);
21594         }
21595
21596         /**
21597          * Gives a chance to the host View to populate the accessibility event with its
21598          * text content.
21599          * <p>
21600          * The default implementation behaves as
21601          * {@link View#onPopulateAccessibilityEvent(AccessibilityEvent)
21602          *  View#onPopulateAccessibilityEvent(AccessibilityEvent)} for
21603          * the case of no accessibility delegate been set.
21604          * </p>
21605          *
21606          * @param host The View hosting the delegate.
21607          * @param event The accessibility event which to populate.
21608          *
21609          * @see View#onPopulateAccessibilityEvent(AccessibilityEvent)
21610          *      View#onPopulateAccessibilityEvent(AccessibilityEvent)
21611          */
21612         public void onPopulateAccessibilityEvent(View host, AccessibilityEvent event) {
21613             host.onPopulateAccessibilityEventInternal(event);
21614         }
21615
21616         /**
21617          * Initializes an {@link AccessibilityEvent} with information about the
21618          * the host View which is the event source.
21619          * <p>
21620          * The default implementation behaves as
21621          * {@link View#onInitializeAccessibilityEvent(AccessibilityEvent)
21622          *  View#onInitializeAccessibilityEvent(AccessibilityEvent)} for
21623          * the case of no accessibility delegate been set.
21624          * </p>
21625          *
21626          * @param host The View hosting the delegate.
21627          * @param event The event to initialize.
21628          *
21629          * @see View#onInitializeAccessibilityEvent(AccessibilityEvent)
21630          *      View#onInitializeAccessibilityEvent(AccessibilityEvent)
21631          */
21632         public void onInitializeAccessibilityEvent(View host, AccessibilityEvent event) {
21633             host.onInitializeAccessibilityEventInternal(event);
21634         }
21635
21636         /**
21637          * Initializes an {@link AccessibilityNodeInfo} with information about the host view.
21638          * <p>
21639          * The default implementation behaves as
21640          * {@link View#onInitializeAccessibilityNodeInfo(AccessibilityNodeInfo)
21641          *  View#onInitializeAccessibilityNodeInfo(AccessibilityNodeInfo)} for
21642          * the case of no accessibility delegate been set.
21643          * </p>
21644          *
21645          * @param host The View hosting the delegate.
21646          * @param info The instance to initialize.
21647          *
21648          * @see View#onInitializeAccessibilityNodeInfo(AccessibilityNodeInfo)
21649          *      View#onInitializeAccessibilityNodeInfo(AccessibilityNodeInfo)
21650          */
21651         public void onInitializeAccessibilityNodeInfo(View host, AccessibilityNodeInfo info) {
21652             host.onInitializeAccessibilityNodeInfoInternal(info);
21653         }
21654
21655         /**
21656          * Called when a child of the host View has requested sending an
21657          * {@link AccessibilityEvent} and gives an opportunity to the parent (the host)
21658          * to augment the event.
21659          * <p>
21660          * The default implementation behaves as
21661          * {@link ViewGroup#onRequestSendAccessibilityEvent(View, AccessibilityEvent)
21662          *  ViewGroup#onRequestSendAccessibilityEvent(View, AccessibilityEvent)} for
21663          * the case of no accessibility delegate been set.
21664          * </p>
21665          *
21666          * @param host The View hosting the delegate.
21667          * @param child The child which requests sending the event.
21668          * @param event The event to be sent.
21669          * @return True if the event should be sent
21670          *
21671          * @see ViewGroup#onRequestSendAccessibilityEvent(View, AccessibilityEvent)
21672          *      ViewGroup#onRequestSendAccessibilityEvent(View, AccessibilityEvent)
21673          */
21674         public boolean onRequestSendAccessibilityEvent(ViewGroup host, View child,
21675                 AccessibilityEvent event) {
21676             return host.onRequestSendAccessibilityEventInternal(child, event);
21677         }
21678
21679         /**
21680          * Gets the provider for managing a virtual view hierarchy rooted at this View
21681          * and reported to {@link android.accessibilityservice.AccessibilityService}s
21682          * that explore the window content.
21683          * <p>
21684          * The default implementation behaves as
21685          * {@link View#getAccessibilityNodeProvider() View#getAccessibilityNodeProvider()} for
21686          * the case of no accessibility delegate been set.
21687          * </p>
21688          *
21689          * @return The provider.
21690          *
21691          * @see AccessibilityNodeProvider
21692          */
21693         public AccessibilityNodeProvider getAccessibilityNodeProvider(View host) {
21694             return null;
21695         }
21696
21697         /**
21698          * Returns an {@link AccessibilityNodeInfo} representing the host view from the
21699          * point of view of an {@link android.accessibilityservice.AccessibilityService}.
21700          * This method is responsible for obtaining an accessibility node info from a
21701          * pool of reusable instances and calling
21702          * {@link #onInitializeAccessibilityNodeInfo(AccessibilityNodeInfo)} on the host
21703          * view to initialize the former.
21704          * <p>
21705          * <strong>Note:</strong> The client is responsible for recycling the obtained
21706          * instance by calling {@link AccessibilityNodeInfo#recycle()} to minimize object
21707          * creation.
21708          * </p>
21709          * <p>
21710          * The default implementation behaves as
21711          * {@link View#createAccessibilityNodeInfo() View#createAccessibilityNodeInfo()} for
21712          * the case of no accessibility delegate been set.
21713          * </p>
21714          * @return A populated {@link AccessibilityNodeInfo}.
21715          *
21716          * @see AccessibilityNodeInfo
21717          *
21718          * @hide
21719          */
21720         public AccessibilityNodeInfo createAccessibilityNodeInfo(View host) {
21721             return host.createAccessibilityNodeInfoInternal();
21722         }
21723     }
21724
21725     private class MatchIdPredicate implements Predicate<View> {
21726         public int mId;
21727
21728         @Override
21729         public boolean apply(View view) {
21730             return (view.mID == mId);
21731         }
21732     }
21733
21734     private class MatchLabelForPredicate implements Predicate<View> {
21735         private int mLabeledId;
21736
21737         @Override
21738         public boolean apply(View view) {
21739             return (view.mLabelForId == mLabeledId);
21740         }
21741     }
21742
21743     private class SendViewStateChangedAccessibilityEvent implements Runnable {
21744         private int mChangeTypes = 0;
21745         private boolean mPosted;
21746         private boolean mPostedWithDelay;
21747         private long mLastEventTimeMillis;
21748
21749         @Override
21750         public void run() {
21751             mPosted = false;
21752             mPostedWithDelay = false;
21753             mLastEventTimeMillis = SystemClock.uptimeMillis();
21754             if (AccessibilityManager.getInstance(mContext).isEnabled()) {
21755                 final AccessibilityEvent event = AccessibilityEvent.obtain();
21756                 event.setEventType(AccessibilityEvent.TYPE_WINDOW_CONTENT_CHANGED);
21757                 event.setContentChangeTypes(mChangeTypes);
21758                 sendAccessibilityEventUnchecked(event);
21759             }
21760             mChangeTypes = 0;
21761         }
21762
21763         public void runOrPost(int changeType) {
21764             mChangeTypes |= changeType;
21765
21766             // If this is a live region or the child of a live region, collect
21767             // all events from this frame and send them on the next frame.
21768             if (inLiveRegion()) {
21769                 // If we're already posted with a delay, remove that.
21770                 if (mPostedWithDelay) {
21771                     removeCallbacks(this);
21772                     mPostedWithDelay = false;
21773                 }
21774                 // Only post if we're not already posted.
21775                 if (!mPosted) {
21776                     post(this);
21777                     mPosted = true;
21778                 }
21779                 return;
21780             }
21781
21782             if (mPosted) {
21783                 return;
21784             }
21785
21786             final long timeSinceLastMillis = SystemClock.uptimeMillis() - mLastEventTimeMillis;
21787             final long minEventIntevalMillis =
21788                     ViewConfiguration.getSendRecurringAccessibilityEventsInterval();
21789             if (timeSinceLastMillis >= minEventIntevalMillis) {
21790                 removeCallbacks(this);
21791                 run();
21792             } else {
21793                 postDelayed(this, minEventIntevalMillis - timeSinceLastMillis);
21794                 mPostedWithDelay = true;
21795             }
21796         }
21797     }
21798
21799     private boolean inLiveRegion() {
21800         if (getAccessibilityLiveRegion() != View.ACCESSIBILITY_LIVE_REGION_NONE) {
21801             return true;
21802         }
21803
21804         ViewParent parent = getParent();
21805         while (parent instanceof View) {
21806             if (((View) parent).getAccessibilityLiveRegion()
21807                     != View.ACCESSIBILITY_LIVE_REGION_NONE) {
21808                 return true;
21809             }
21810             parent = parent.getParent();
21811         }
21812
21813         return false;
21814     }
21815
21816     /**
21817      * Dump all private flags in readable format, useful for documentation and
21818      * sanity checking.
21819      */
21820     private static void dumpFlags() {
21821         final HashMap<String, String> found = Maps.newHashMap();
21822         try {
21823             for (Field field : View.class.getDeclaredFields()) {
21824                 final int modifiers = field.getModifiers();
21825                 if (Modifier.isStatic(modifiers) && Modifier.isFinal(modifiers)) {
21826                     if (field.getType().equals(int.class)) {
21827                         final int value = field.getInt(null);
21828                         dumpFlag(found, field.getName(), value);
21829                     } else if (field.getType().equals(int[].class)) {
21830                         final int[] values = (int[]) field.get(null);
21831                         for (int i = 0; i < values.length; i++) {
21832                             dumpFlag(found, field.getName() + "[" + i + "]", values[i]);
21833                         }
21834                     }
21835                 }
21836             }
21837         } catch (IllegalAccessException e) {
21838             throw new RuntimeException(e);
21839         }
21840
21841         final ArrayList<String> keys = Lists.newArrayList();
21842         keys.addAll(found.keySet());
21843         Collections.sort(keys);
21844         for (String key : keys) {
21845             Log.d(VIEW_LOG_TAG, found.get(key));
21846         }
21847     }
21848
21849     private static void dumpFlag(HashMap<String, String> found, String name, int value) {
21850         // Sort flags by prefix, then by bits, always keeping unique keys
21851         final String bits = String.format("%32s", Integer.toBinaryString(value)).replace('0', ' ');
21852         final int prefix = name.indexOf('_');
21853         final String key = (prefix > 0 ? name.substring(0, prefix) : name) + bits + name;
21854         final String output = bits + " " + name;
21855         found.put(key, output);
21856     }
21857 }