OSDN Git Service

Merge "Fixing issue where Recents would not work if the time is changed. (Bug 1799503...
[android-x86/frameworks-base.git] / core / java / android / view / View.java
1 /*
2  * Copyright (C) 2006 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16
17 package android.view;
18
19 import android.animation.AnimatorInflater;
20 import android.animation.StateListAnimator;
21 import android.annotation.IntDef;
22 import android.annotation.NonNull;
23 import android.annotation.Nullable;
24 import android.content.ClipData;
25 import android.content.Context;
26 import android.content.res.ColorStateList;
27 import android.content.res.Configuration;
28 import android.content.res.Resources;
29 import android.content.res.TypedArray;
30 import android.graphics.Bitmap;
31 import android.graphics.Canvas;
32 import android.graphics.Insets;
33 import android.graphics.Interpolator;
34 import android.graphics.LinearGradient;
35 import android.graphics.Matrix;
36 import android.graphics.Outline;
37 import android.graphics.Paint;
38 import android.graphics.Path;
39 import android.graphics.PathMeasure;
40 import android.graphics.PixelFormat;
41 import android.graphics.Point;
42 import android.graphics.PorterDuff;
43 import android.graphics.PorterDuffXfermode;
44 import android.graphics.Rect;
45 import android.graphics.RectF;
46 import android.graphics.Region;
47 import android.graphics.Shader;
48 import android.graphics.drawable.ColorDrawable;
49 import android.graphics.drawable.Drawable;
50 import android.hardware.display.DisplayManagerGlobal;
51 import android.os.Bundle;
52 import android.os.Handler;
53 import android.os.IBinder;
54 import android.os.Parcel;
55 import android.os.Parcelable;
56 import android.os.RemoteException;
57 import android.os.SystemClock;
58 import android.os.SystemProperties;
59 import android.text.TextUtils;
60 import android.util.AttributeSet;
61 import android.util.FloatProperty;
62 import android.util.LayoutDirection;
63 import android.util.Log;
64 import android.util.LongSparseLongArray;
65 import android.util.Pools.SynchronizedPool;
66 import android.util.Property;
67 import android.util.SparseArray;
68 import android.util.SuperNotCalledException;
69 import android.util.TypedValue;
70 import android.view.ContextMenu.ContextMenuInfo;
71 import android.view.AccessibilityIterators.TextSegmentIterator;
72 import android.view.AccessibilityIterators.CharacterTextSegmentIterator;
73 import android.view.AccessibilityIterators.WordTextSegmentIterator;
74 import android.view.AccessibilityIterators.ParagraphTextSegmentIterator;
75 import android.view.accessibility.AccessibilityEvent;
76 import android.view.accessibility.AccessibilityEventSource;
77 import android.view.accessibility.AccessibilityManager;
78 import android.view.accessibility.AccessibilityNodeInfo;
79 import android.view.accessibility.AccessibilityNodeProvider;
80 import android.view.animation.Animation;
81 import android.view.animation.AnimationUtils;
82 import android.view.animation.Transformation;
83 import android.view.inputmethod.EditorInfo;
84 import android.view.inputmethod.InputConnection;
85 import android.view.inputmethod.InputMethodManager;
86 import android.widget.ScrollBarDrawable;
87
88 import static android.os.Build.VERSION_CODES.*;
89 import static java.lang.Math.max;
90
91 import com.android.internal.R;
92 import com.android.internal.util.Predicate;
93 import com.android.internal.view.menu.MenuBuilder;
94 import com.google.android.collect.Lists;
95 import com.google.android.collect.Maps;
96
97 import java.lang.annotation.Retention;
98 import java.lang.annotation.RetentionPolicy;
99 import java.lang.ref.WeakReference;
100 import java.lang.reflect.Field;
101 import java.lang.reflect.InvocationTargetException;
102 import java.lang.reflect.Method;
103 import java.lang.reflect.Modifier;
104 import java.util.ArrayList;
105 import java.util.Arrays;
106 import java.util.Collections;
107 import java.util.HashMap;
108 import java.util.List;
109 import java.util.Locale;
110 import java.util.Map;
111 import java.util.concurrent.CopyOnWriteArrayList;
112 import java.util.concurrent.atomic.AtomicInteger;
113
114 /**
115  * <p>
116  * This class represents the basic building block for user interface components. A View
117  * occupies a rectangular area on the screen and is responsible for drawing and
118  * event handling. View is the base class for <em>widgets</em>, which are
119  * used to create interactive UI components (buttons, text fields, etc.). The
120  * {@link android.view.ViewGroup} subclass is the base class for <em>layouts</em>, which
121  * are invisible containers that hold other Views (or other ViewGroups) and define
122  * their layout properties.
123  * </p>
124  *
125  * <div class="special reference">
126  * <h3>Developer Guides</h3>
127  * <p>For information about using this class to develop your application's user interface,
128  * read the <a href="{@docRoot}guide/topics/ui/index.html">User Interface</a> developer guide.
129  * </div>
130  *
131  * <a name="Using"></a>
132  * <h3>Using Views</h3>
133  * <p>
134  * All of the views in a window are arranged in a single tree. You can add views
135  * either from code or by specifying a tree of views in one or more XML layout
136  * files. There are many specialized subclasses of views that act as controls or
137  * are capable of displaying text, images, or other content.
138  * </p>
139  * <p>
140  * Once you have created a tree of views, there are typically a few types of
141  * common operations you may wish to perform:
142  * <ul>
143  * <li><strong>Set properties:</strong> for example setting the text of a
144  * {@link android.widget.TextView}. The available properties and the methods
145  * that set them will vary among the different subclasses of views. Note that
146  * properties that are known at build time can be set in the XML layout
147  * files.</li>
148  * <li><strong>Set focus:</strong> The framework will handled moving focus in
149  * response to user input. To force focus to a specific view, call
150  * {@link #requestFocus}.</li>
151  * <li><strong>Set up listeners:</strong> Views allow clients to set listeners
152  * that will be notified when something interesting happens to the view. For
153  * example, all views will let you set a listener to be notified when the view
154  * gains or loses focus. You can register such a listener using
155  * {@link #setOnFocusChangeListener(android.view.View.OnFocusChangeListener)}.
156  * Other view subclasses offer more specialized listeners. For example, a Button
157  * exposes a listener to notify clients when the button is clicked.</li>
158  * <li><strong>Set visibility:</strong> You can hide or show views using
159  * {@link #setVisibility(int)}.</li>
160  * </ul>
161  * </p>
162  * <p><em>
163  * Note: The Android framework is responsible for measuring, laying out and
164  * drawing views. You should not call methods that perform these actions on
165  * views yourself unless you are actually implementing a
166  * {@link android.view.ViewGroup}.
167  * </em></p>
168  *
169  * <a name="Lifecycle"></a>
170  * <h3>Implementing a Custom View</h3>
171  *
172  * <p>
173  * To implement a custom view, you will usually begin by providing overrides for
174  * some of the standard methods that the framework calls on all views. You do
175  * not need to override all of these methods. In fact, you can start by just
176  * overriding {@link #onDraw(android.graphics.Canvas)}.
177  * <table border="2" width="85%" align="center" cellpadding="5">
178  *     <thead>
179  *         <tr><th>Category</th> <th>Methods</th> <th>Description</th></tr>
180  *     </thead>
181  *
182  *     <tbody>
183  *     <tr>
184  *         <td rowspan="2">Creation</td>
185  *         <td>Constructors</td>
186  *         <td>There is a form of the constructor that are called when the view
187  *         is created from code and a form that is called when the view is
188  *         inflated from a layout file. The second form should parse and apply
189  *         any attributes defined in the layout file.
190  *         </td>
191  *     </tr>
192  *     <tr>
193  *         <td><code>{@link #onFinishInflate()}</code></td>
194  *         <td>Called after a view and all of its children has been inflated
195  *         from XML.</td>
196  *     </tr>
197  *
198  *     <tr>
199  *         <td rowspan="3">Layout</td>
200  *         <td><code>{@link #onMeasure(int, int)}</code></td>
201  *         <td>Called to determine the size requirements for this view and all
202  *         of its children.
203  *         </td>
204  *     </tr>
205  *     <tr>
206  *         <td><code>{@link #onLayout(boolean, int, int, int, int)}</code></td>
207  *         <td>Called when this view should assign a size and position to all
208  *         of its children.
209  *         </td>
210  *     </tr>
211  *     <tr>
212  *         <td><code>{@link #onSizeChanged(int, int, int, int)}</code></td>
213  *         <td>Called when the size of this view has changed.
214  *         </td>
215  *     </tr>
216  *
217  *     <tr>
218  *         <td>Drawing</td>
219  *         <td><code>{@link #onDraw(android.graphics.Canvas)}</code></td>
220  *         <td>Called when the view should render its content.
221  *         </td>
222  *     </tr>
223  *
224  *     <tr>
225  *         <td rowspan="4">Event processing</td>
226  *         <td><code>{@link #onKeyDown(int, KeyEvent)}</code></td>
227  *         <td>Called when a new hardware key event occurs.
228  *         </td>
229  *     </tr>
230  *     <tr>
231  *         <td><code>{@link #onKeyUp(int, KeyEvent)}</code></td>
232  *         <td>Called when a hardware key up event occurs.
233  *         </td>
234  *     </tr>
235  *     <tr>
236  *         <td><code>{@link #onTrackballEvent(MotionEvent)}</code></td>
237  *         <td>Called when a trackball motion event occurs.
238  *         </td>
239  *     </tr>
240  *     <tr>
241  *         <td><code>{@link #onTouchEvent(MotionEvent)}</code></td>
242  *         <td>Called when a touch screen motion event occurs.
243  *         </td>
244  *     </tr>
245  *
246  *     <tr>
247  *         <td rowspan="2">Focus</td>
248  *         <td><code>{@link #onFocusChanged(boolean, int, android.graphics.Rect)}</code></td>
249  *         <td>Called when the view gains or loses focus.
250  *         </td>
251  *     </tr>
252  *
253  *     <tr>
254  *         <td><code>{@link #onWindowFocusChanged(boolean)}</code></td>
255  *         <td>Called when the window containing the view gains or loses focus.
256  *         </td>
257  *     </tr>
258  *
259  *     <tr>
260  *         <td rowspan="3">Attaching</td>
261  *         <td><code>{@link #onAttachedToWindow()}</code></td>
262  *         <td>Called when the view is attached to a window.
263  *         </td>
264  *     </tr>
265  *
266  *     <tr>
267  *         <td><code>{@link #onDetachedFromWindow}</code></td>
268  *         <td>Called when the view is detached from its window.
269  *         </td>
270  *     </tr>
271  *
272  *     <tr>
273  *         <td><code>{@link #onWindowVisibilityChanged(int)}</code></td>
274  *         <td>Called when the visibility of the window containing the view
275  *         has changed.
276  *         </td>
277  *     </tr>
278  *     </tbody>
279  *
280  * </table>
281  * </p>
282  *
283  * <a name="IDs"></a>
284  * <h3>IDs</h3>
285  * Views may have an integer id associated with them. These ids are typically
286  * assigned in the layout XML files, and are used to find specific views within
287  * the view tree. A common pattern is to:
288  * <ul>
289  * <li>Define a Button in the layout file and assign it a unique ID.
290  * <pre>
291  * &lt;Button
292  *     android:id="@+id/my_button"
293  *     android:layout_width="wrap_content"
294  *     android:layout_height="wrap_content"
295  *     android:text="@string/my_button_text"/&gt;
296  * </pre></li>
297  * <li>From the onCreate method of an Activity, find the Button
298  * <pre class="prettyprint">
299  *      Button myButton = (Button) findViewById(R.id.my_button);
300  * </pre></li>
301  * </ul>
302  * <p>
303  * View IDs need not be unique throughout the tree, but it is good practice to
304  * ensure that they are at least unique within the part of the tree you are
305  * searching.
306  * </p>
307  *
308  * <a name="Position"></a>
309  * <h3>Position</h3>
310  * <p>
311  * The geometry of a view is that of a rectangle. A view has a location,
312  * expressed as a pair of <em>left</em> and <em>top</em> coordinates, and
313  * two dimensions, expressed as a width and a height. The unit for location
314  * and dimensions is the pixel.
315  * </p>
316  *
317  * <p>
318  * It is possible to retrieve the location of a view by invoking the methods
319  * {@link #getLeft()} and {@link #getTop()}. The former returns the left, or X,
320  * coordinate of the rectangle representing the view. The latter returns the
321  * top, or Y, coordinate of the rectangle representing the view. These methods
322  * both return the location of the view relative to its parent. For instance,
323  * when getLeft() returns 20, that means the view is located 20 pixels to the
324  * right of the left edge of its direct parent.
325  * </p>
326  *
327  * <p>
328  * In addition, several convenience methods are offered to avoid unnecessary
329  * computations, namely {@link #getRight()} and {@link #getBottom()}.
330  * These methods return the coordinates of the right and bottom edges of the
331  * rectangle representing the view. For instance, calling {@link #getRight()}
332  * is similar to the following computation: <code>getLeft() + getWidth()</code>
333  * (see <a href="#SizePaddingMargins">Size</a> for more information about the width.)
334  * </p>
335  *
336  * <a name="SizePaddingMargins"></a>
337  * <h3>Size, padding and margins</h3>
338  * <p>
339  * The size of a view is expressed with a width and a height. A view actually
340  * possess two pairs of width and height values.
341  * </p>
342  *
343  * <p>
344  * The first pair is known as <em>measured width</em> and
345  * <em>measured height</em>. These dimensions define how big a view wants to be
346  * within its parent (see <a href="#Layout">Layout</a> for more details.) The
347  * measured dimensions can be obtained by calling {@link #getMeasuredWidth()}
348  * and {@link #getMeasuredHeight()}.
349  * </p>
350  *
351  * <p>
352  * The second pair is simply known as <em>width</em> and <em>height</em>, or
353  * sometimes <em>drawing width</em> and <em>drawing height</em>. These
354  * dimensions define the actual size of the view on screen, at drawing time and
355  * after layout. These values may, but do not have to, be different from the
356  * measured width and height. The width and height can be obtained by calling
357  * {@link #getWidth()} and {@link #getHeight()}.
358  * </p>
359  *
360  * <p>
361  * To measure its dimensions, a view takes into account its padding. The padding
362  * is expressed in pixels for the left, top, right and bottom parts of the view.
363  * Padding can be used to offset the content of the view by a specific amount of
364  * pixels. For instance, a left padding of 2 will push the view's content by
365  * 2 pixels to the right of the left edge. Padding can be set using the
366  * {@link #setPadding(int, int, int, int)} or {@link #setPaddingRelative(int, int, int, int)}
367  * method and queried by calling {@link #getPaddingLeft()}, {@link #getPaddingTop()},
368  * {@link #getPaddingRight()}, {@link #getPaddingBottom()}, {@link #getPaddingStart()},
369  * {@link #getPaddingEnd()}.
370  * </p>
371  *
372  * <p>
373  * Even though a view can define a padding, it does not provide any support for
374  * margins. However, view groups provide such a support. Refer to
375  * {@link android.view.ViewGroup} and
376  * {@link android.view.ViewGroup.MarginLayoutParams} for further information.
377  * </p>
378  *
379  * <a name="Layout"></a>
380  * <h3>Layout</h3>
381  * <p>
382  * Layout is a two pass process: a measure pass and a layout pass. The measuring
383  * pass is implemented in {@link #measure(int, int)} and is a top-down traversal
384  * of the view tree. Each view pushes dimension specifications down the tree
385  * during the recursion. At the end of the measure pass, every view has stored
386  * its measurements. The second pass happens in
387  * {@link #layout(int,int,int,int)} and is also top-down. During
388  * this pass each parent is responsible for positioning all of its children
389  * using the sizes computed in the measure pass.
390  * </p>
391  *
392  * <p>
393  * When a view's measure() method returns, its {@link #getMeasuredWidth()} and
394  * {@link #getMeasuredHeight()} values must be set, along with those for all of
395  * that view's descendants. A view's measured width and measured height values
396  * must respect the constraints imposed by the view's parents. This guarantees
397  * that at the end of the measure pass, all parents accept all of their
398  * children's measurements. A parent view may call measure() more than once on
399  * its children. For example, the parent may measure each child once with
400  * unspecified dimensions to find out how big they want to be, then call
401  * measure() on them again with actual numbers if the sum of all the children's
402  * unconstrained sizes is too big or too small.
403  * </p>
404  *
405  * <p>
406  * The measure pass uses two classes to communicate dimensions. The
407  * {@link MeasureSpec} class is used by views to tell their parents how they
408  * want to be measured and positioned. The base LayoutParams class just
409  * describes how big the view wants to be for both width and height. For each
410  * dimension, it can specify one of:
411  * <ul>
412  * <li> an exact number
413  * <li>MATCH_PARENT, which means the view wants to be as big as its parent
414  * (minus padding)
415  * <li> WRAP_CONTENT, which means that the view wants to be just big enough to
416  * enclose its content (plus padding).
417  * </ul>
418  * There are subclasses of LayoutParams for different subclasses of ViewGroup.
419  * For example, AbsoluteLayout has its own subclass of LayoutParams which adds
420  * an X and Y value.
421  * </p>
422  *
423  * <p>
424  * MeasureSpecs are used to push requirements down the tree from parent to
425  * child. A MeasureSpec can be in one of three modes:
426  * <ul>
427  * <li>UNSPECIFIED: This is used by a parent to determine the desired dimension
428  * of a child view. For example, a LinearLayout may call measure() on its child
429  * with the height set to UNSPECIFIED and a width of EXACTLY 240 to find out how
430  * tall the child view wants to be given a width of 240 pixels.
431  * <li>EXACTLY: This is used by the parent to impose an exact size on the
432  * child. The child must use this size, and guarantee that all of its
433  * descendants will fit within this size.
434  * <li>AT_MOST: This is used by the parent to impose a maximum size on the
435  * child. The child must guarantee that it and all of its descendants will fit
436  * within this size.
437  * </ul>
438  * </p>
439  *
440  * <p>
441  * To intiate a layout, call {@link #requestLayout}. This method is typically
442  * called by a view on itself when it believes that is can no longer fit within
443  * its current bounds.
444  * </p>
445  *
446  * <a name="Drawing"></a>
447  * <h3>Drawing</h3>
448  * <p>
449  * Drawing is handled by walking the tree and recording the drawing commands of
450  * any View that needs to update. After this, the drawing commands of the
451  * entire tree are issued to screen, clipped to the newly damaged area.
452  * </p>
453  *
454  * <p>
455  * The tree is largely recorded and drawn in order, with parents drawn before
456  * (i.e., behind) their children, with siblings drawn in the order they appear
457  * in the tree. If you set a background drawable for a View, then the View will
458  * draw it before calling back to its <code>onDraw()</code> method. The child
459  * drawing order can be overridden with
460  * {@link ViewGroup#setChildrenDrawingOrderEnabled(boolean) custom child drawing order}
461  * in a ViewGroup, and with {@link #setZ(float)} custom Z values} set on Views.
462  * </p>
463  *
464  * <p>
465  * To force a view to draw, call {@link #invalidate()}.
466  * </p>
467  *
468  * <a name="EventHandlingThreading"></a>
469  * <h3>Event Handling and Threading</h3>
470  * <p>
471  * The basic cycle of a view is as follows:
472  * <ol>
473  * <li>An event comes in and is dispatched to the appropriate view. The view
474  * handles the event and notifies any listeners.</li>
475  * <li>If in the course of processing the event, the view's bounds may need
476  * to be changed, the view will call {@link #requestLayout()}.</li>
477  * <li>Similarly, if in the course of processing the event the view's appearance
478  * may need to be changed, the view will call {@link #invalidate()}.</li>
479  * <li>If either {@link #requestLayout()} or {@link #invalidate()} were called,
480  * the framework will take care of measuring, laying out, and drawing the tree
481  * as appropriate.</li>
482  * </ol>
483  * </p>
484  *
485  * <p><em>Note: The entire view tree is single threaded. You must always be on
486  * the UI thread when calling any method on any view.</em>
487  * If you are doing work on other threads and want to update the state of a view
488  * from that thread, you should use a {@link Handler}.
489  * </p>
490  *
491  * <a name="FocusHandling"></a>
492  * <h3>Focus Handling</h3>
493  * <p>
494  * The framework will handle routine focus movement in response to user input.
495  * This includes changing the focus as views are removed or hidden, or as new
496  * views become available. Views indicate their willingness to take focus
497  * through the {@link #isFocusable} method. To change whether a view can take
498  * focus, call {@link #setFocusable(boolean)}.  When in touch mode (see notes below)
499  * views indicate whether they still would like focus via {@link #isFocusableInTouchMode}
500  * and can change this via {@link #setFocusableInTouchMode(boolean)}.
501  * </p>
502  * <p>
503  * Focus movement is based on an algorithm which finds the nearest neighbor in a
504  * given direction. In rare cases, the default algorithm may not match the
505  * intended behavior of the developer. In these situations, you can provide
506  * explicit overrides by using these XML attributes in the layout file:
507  * <pre>
508  * nextFocusDown
509  * nextFocusLeft
510  * nextFocusRight
511  * nextFocusUp
512  * </pre>
513  * </p>
514  *
515  *
516  * <p>
517  * To get a particular view to take focus, call {@link #requestFocus()}.
518  * </p>
519  *
520  * <a name="TouchMode"></a>
521  * <h3>Touch Mode</h3>
522  * <p>
523  * When a user is navigating a user interface via directional keys such as a D-pad, it is
524  * necessary to give focus to actionable items such as buttons so the user can see
525  * what will take input.  If the device has touch capabilities, however, and the user
526  * begins interacting with the interface by touching it, it is no longer necessary to
527  * always highlight, or give focus to, a particular view.  This motivates a mode
528  * for interaction named 'touch mode'.
529  * </p>
530  * <p>
531  * For a touch capable device, once the user touches the screen, the device
532  * will enter touch mode.  From this point onward, only views for which
533  * {@link #isFocusableInTouchMode} is true will be focusable, such as text editing widgets.
534  * Other views that are touchable, like buttons, will not take focus when touched; they will
535  * only fire the on click listeners.
536  * </p>
537  * <p>
538  * Any time a user hits a directional key, such as a D-pad direction, the view device will
539  * exit touch mode, and find a view to take focus, so that the user may resume interacting
540  * with the user interface without touching the screen again.
541  * </p>
542  * <p>
543  * The touch mode state is maintained across {@link android.app.Activity}s.  Call
544  * {@link #isInTouchMode} to see whether the device is currently in touch mode.
545  * </p>
546  *
547  * <a name="Scrolling"></a>
548  * <h3>Scrolling</h3>
549  * <p>
550  * The framework provides basic support for views that wish to internally
551  * scroll their content. This includes keeping track of the X and Y scroll
552  * offset as well as mechanisms for drawing scrollbars. See
553  * {@link #scrollBy(int, int)}, {@link #scrollTo(int, int)}, and
554  * {@link #awakenScrollBars()} for more details.
555  * </p>
556  *
557  * <a name="Tags"></a>
558  * <h3>Tags</h3>
559  * <p>
560  * Unlike IDs, tags are not used to identify views. Tags are essentially an
561  * extra piece of information that can be associated with a view. They are most
562  * often used as a convenience to store data related to views in the views
563  * themselves rather than by putting them in a separate structure.
564  * </p>
565  *
566  * <a name="Properties"></a>
567  * <h3>Properties</h3>
568  * <p>
569  * The View class exposes an {@link #ALPHA} property, as well as several transform-related
570  * properties, such as {@link #TRANSLATION_X} and {@link #TRANSLATION_Y}. These properties are
571  * available both in the {@link Property} form as well as in similarly-named setter/getter
572  * methods (such as {@link #setAlpha(float)} for {@link #ALPHA}). These properties can
573  * be used to set persistent state associated with these rendering-related properties on the view.
574  * The properties and methods can also be used in conjunction with
575  * {@link android.animation.Animator Animator}-based animations, described more in the
576  * <a href="#Animation">Animation</a> section.
577  * </p>
578  *
579  * <a name="Animation"></a>
580  * <h3>Animation</h3>
581  * <p>
582  * Starting with Android 3.0, the preferred way of animating views is to use the
583  * {@link android.animation} package APIs. These {@link android.animation.Animator Animator}-based
584  * classes change actual properties of the View object, such as {@link #setAlpha(float) alpha} and
585  * {@link #setTranslationX(float) translationX}. This behavior is contrasted to that of the pre-3.0
586  * {@link android.view.animation.Animation Animation}-based classes, which instead animate only
587  * how the view is drawn on the display. In particular, the {@link ViewPropertyAnimator} class
588  * makes animating these View properties particularly easy and efficient.
589  * </p>
590  * <p>
591  * Alternatively, you can use the pre-3.0 animation classes to animate how Views are rendered.
592  * You can attach an {@link Animation} object to a view using
593  * {@link #setAnimation(Animation)} or
594  * {@link #startAnimation(Animation)}. The animation can alter the scale,
595  * rotation, translation and alpha of a view over time. If the animation is
596  * attached to a view that has children, the animation will affect the entire
597  * subtree rooted by that node. When an animation is started, the framework will
598  * take care of redrawing the appropriate views until the animation completes.
599  * </p>
600  *
601  * <a name="Security"></a>
602  * <h3>Security</h3>
603  * <p>
604  * Sometimes it is essential that an application be able to verify that an action
605  * is being performed with the full knowledge and consent of the user, such as
606  * granting a permission request, making a purchase or clicking on an advertisement.
607  * Unfortunately, a malicious application could try to spoof the user into
608  * performing these actions, unaware, by concealing the intended purpose of the view.
609  * As a remedy, the framework offers a touch filtering mechanism that can be used to
610  * improve the security of views that provide access to sensitive functionality.
611  * </p><p>
612  * To enable touch filtering, call {@link #setFilterTouchesWhenObscured(boolean)} or set the
613  * android:filterTouchesWhenObscured layout attribute to true.  When enabled, the framework
614  * will discard touches that are received whenever the view's window is obscured by
615  * another visible window.  As a result, the view will not receive touches whenever a
616  * toast, dialog or other window appears above the view's window.
617  * </p><p>
618  * For more fine-grained control over security, consider overriding the
619  * {@link #onFilterTouchEventForSecurity(MotionEvent)} method to implement your own
620  * security policy. See also {@link MotionEvent#FLAG_WINDOW_IS_OBSCURED}.
621  * </p>
622  *
623  * @attr ref android.R.styleable#View_alpha
624  * @attr ref android.R.styleable#View_background
625  * @attr ref android.R.styleable#View_clickable
626  * @attr ref android.R.styleable#View_contentDescription
627  * @attr ref android.R.styleable#View_drawingCacheQuality
628  * @attr ref android.R.styleable#View_duplicateParentState
629  * @attr ref android.R.styleable#View_id
630  * @attr ref android.R.styleable#View_requiresFadingEdge
631  * @attr ref android.R.styleable#View_fadeScrollbars
632  * @attr ref android.R.styleable#View_fadingEdgeLength
633  * @attr ref android.R.styleable#View_filterTouchesWhenObscured
634  * @attr ref android.R.styleable#View_fitsSystemWindows
635  * @attr ref android.R.styleable#View_isScrollContainer
636  * @attr ref android.R.styleable#View_focusable
637  * @attr ref android.R.styleable#View_focusableInTouchMode
638  * @attr ref android.R.styleable#View_hapticFeedbackEnabled
639  * @attr ref android.R.styleable#View_keepScreenOn
640  * @attr ref android.R.styleable#View_layerType
641  * @attr ref android.R.styleable#View_layoutDirection
642  * @attr ref android.R.styleable#View_longClickable
643  * @attr ref android.R.styleable#View_minHeight
644  * @attr ref android.R.styleable#View_minWidth
645  * @attr ref android.R.styleable#View_nextFocusDown
646  * @attr ref android.R.styleable#View_nextFocusLeft
647  * @attr ref android.R.styleable#View_nextFocusRight
648  * @attr ref android.R.styleable#View_nextFocusUp
649  * @attr ref android.R.styleable#View_onClick
650  * @attr ref android.R.styleable#View_padding
651  * @attr ref android.R.styleable#View_paddingBottom
652  * @attr ref android.R.styleable#View_paddingLeft
653  * @attr ref android.R.styleable#View_paddingRight
654  * @attr ref android.R.styleable#View_paddingTop
655  * @attr ref android.R.styleable#View_paddingStart
656  * @attr ref android.R.styleable#View_paddingEnd
657  * @attr ref android.R.styleable#View_saveEnabled
658  * @attr ref android.R.styleable#View_rotation
659  * @attr ref android.R.styleable#View_rotationX
660  * @attr ref android.R.styleable#View_rotationY
661  * @attr ref android.R.styleable#View_scaleX
662  * @attr ref android.R.styleable#View_scaleY
663  * @attr ref android.R.styleable#View_scrollX
664  * @attr ref android.R.styleable#View_scrollY
665  * @attr ref android.R.styleable#View_scrollbarSize
666  * @attr ref android.R.styleable#View_scrollbarStyle
667  * @attr ref android.R.styleable#View_scrollbars
668  * @attr ref android.R.styleable#View_scrollbarDefaultDelayBeforeFade
669  * @attr ref android.R.styleable#View_scrollbarFadeDuration
670  * @attr ref android.R.styleable#View_scrollbarTrackHorizontal
671  * @attr ref android.R.styleable#View_scrollbarThumbHorizontal
672  * @attr ref android.R.styleable#View_scrollbarThumbVertical
673  * @attr ref android.R.styleable#View_scrollbarTrackVertical
674  * @attr ref android.R.styleable#View_scrollbarAlwaysDrawHorizontalTrack
675  * @attr ref android.R.styleable#View_scrollbarAlwaysDrawVerticalTrack
676  * @attr ref android.R.styleable#View_stateListAnimator
677  * @attr ref android.R.styleable#View_transitionName
678  * @attr ref android.R.styleable#View_soundEffectsEnabled
679  * @attr ref android.R.styleable#View_tag
680  * @attr ref android.R.styleable#View_textAlignment
681  * @attr ref android.R.styleable#View_textDirection
682  * @attr ref android.R.styleable#View_transformPivotX
683  * @attr ref android.R.styleable#View_transformPivotY
684  * @attr ref android.R.styleable#View_translationX
685  * @attr ref android.R.styleable#View_translationY
686  * @attr ref android.R.styleable#View_translationZ
687  * @attr ref android.R.styleable#View_visibility
688  *
689  * @see android.view.ViewGroup
690  */
691 public class View implements Drawable.Callback, KeyEvent.Callback,
692         AccessibilityEventSource {
693     private static final boolean DBG = false;
694
695     /**
696      * The logging tag used by this class with android.util.Log.
697      */
698     protected static final String VIEW_LOG_TAG = "View";
699
700     /**
701      * When set to true, apps will draw debugging information about their layouts.
702      *
703      * @hide
704      */
705     public static final String DEBUG_LAYOUT_PROPERTY = "debug.layout";
706
707     /**
708      * When set to true, this view will save its attribute data.
709      *
710      * @hide
711      */
712     public static boolean mDebugViewAttributes = false;
713
714     /**
715      * Used to mark a View that has no ID.
716      */
717     public static final int NO_ID = -1;
718
719     /**
720      * Signals that compatibility booleans have been initialized according to
721      * target SDK versions.
722      */
723     private static boolean sCompatibilityDone = false;
724
725     /**
726      * Use the old (broken) way of building MeasureSpecs.
727      */
728     private static boolean sUseBrokenMakeMeasureSpec = false;
729
730     /**
731      * Ignore any optimizations using the measure cache.
732      */
733     private static boolean sIgnoreMeasureCache = false;
734
735     /**
736      * This view does not want keystrokes. Use with TAKES_FOCUS_MASK when
737      * calling setFlags.
738      */
739     private static final int NOT_FOCUSABLE = 0x00000000;
740
741     /**
742      * This view wants keystrokes. Use with TAKES_FOCUS_MASK when calling
743      * setFlags.
744      */
745     private static final int FOCUSABLE = 0x00000001;
746
747     /**
748      * Mask for use with setFlags indicating bits used for focus.
749      */
750     private static final int FOCUSABLE_MASK = 0x00000001;
751
752     /**
753      * This view will adjust its padding to fit sytem windows (e.g. status bar)
754      */
755     private static final int FITS_SYSTEM_WINDOWS = 0x00000002;
756
757     /** @hide */
758     @IntDef({VISIBLE, INVISIBLE, GONE})
759     @Retention(RetentionPolicy.SOURCE)
760     public @interface Visibility {}
761
762     /**
763      * This view is visible.
764      * Use with {@link #setVisibility} and <a href="#attr_android:visibility">{@code
765      * android:visibility}.
766      */
767     public static final int VISIBLE = 0x00000000;
768
769     /**
770      * This view is invisible, but it still takes up space for layout purposes.
771      * Use with {@link #setVisibility} and <a href="#attr_android:visibility">{@code
772      * android:visibility}.
773      */
774     public static final int INVISIBLE = 0x00000004;
775
776     /**
777      * This view is invisible, and it doesn't take any space for layout
778      * purposes. Use with {@link #setVisibility} and <a href="#attr_android:visibility">{@code
779      * android:visibility}.
780      */
781     public static final int GONE = 0x00000008;
782
783     /**
784      * Mask for use with setFlags indicating bits used for visibility.
785      * {@hide}
786      */
787     static final int VISIBILITY_MASK = 0x0000000C;
788
789     private static final int[] VISIBILITY_FLAGS = {VISIBLE, INVISIBLE, GONE};
790
791     /**
792      * This view is enabled. Interpretation varies by subclass.
793      * Use with ENABLED_MASK when calling setFlags.
794      * {@hide}
795      */
796     static final int ENABLED = 0x00000000;
797
798     /**
799      * This view is disabled. Interpretation varies by subclass.
800      * Use with ENABLED_MASK when calling setFlags.
801      * {@hide}
802      */
803     static final int DISABLED = 0x00000020;
804
805    /**
806     * Mask for use with setFlags indicating bits used for indicating whether
807     * this view is enabled
808     * {@hide}
809     */
810     static final int ENABLED_MASK = 0x00000020;
811
812     /**
813      * This view won't draw. {@link #onDraw(android.graphics.Canvas)} won't be
814      * called and further optimizations will be performed. It is okay to have
815      * this flag set and a background. Use with DRAW_MASK when calling setFlags.
816      * {@hide}
817      */
818     static final int WILL_NOT_DRAW = 0x00000080;
819
820     /**
821      * Mask for use with setFlags indicating bits used for indicating whether
822      * this view is will draw
823      * {@hide}
824      */
825     static final int DRAW_MASK = 0x00000080;
826
827     /**
828      * <p>This view doesn't show scrollbars.</p>
829      * {@hide}
830      */
831     static final int SCROLLBARS_NONE = 0x00000000;
832
833     /**
834      * <p>This view shows horizontal scrollbars.</p>
835      * {@hide}
836      */
837     static final int SCROLLBARS_HORIZONTAL = 0x00000100;
838
839     /**
840      * <p>This view shows vertical scrollbars.</p>
841      * {@hide}
842      */
843     static final int SCROLLBARS_VERTICAL = 0x00000200;
844
845     /**
846      * <p>Mask for use with setFlags indicating bits used for indicating which
847      * scrollbars are enabled.</p>
848      * {@hide}
849      */
850     static final int SCROLLBARS_MASK = 0x00000300;
851
852     /**
853      * Indicates that the view should filter touches when its window is obscured.
854      * Refer to the class comments for more information about this security feature.
855      * {@hide}
856      */
857     static final int FILTER_TOUCHES_WHEN_OBSCURED = 0x00000400;
858
859     /**
860      * Set for framework elements that use FITS_SYSTEM_WINDOWS, to indicate
861      * that they are optional and should be skipped if the window has
862      * requested system UI flags that ignore those insets for layout.
863      */
864     static final int OPTIONAL_FITS_SYSTEM_WINDOWS = 0x00000800;
865
866     /**
867      * <p>This view doesn't show fading edges.</p>
868      * {@hide}
869      */
870     static final int FADING_EDGE_NONE = 0x00000000;
871
872     /**
873      * <p>This view shows horizontal fading edges.</p>
874      * {@hide}
875      */
876     static final int FADING_EDGE_HORIZONTAL = 0x00001000;
877
878     /**
879      * <p>This view shows vertical fading edges.</p>
880      * {@hide}
881      */
882     static final int FADING_EDGE_VERTICAL = 0x00002000;
883
884     /**
885      * <p>Mask for use with setFlags indicating bits used for indicating which
886      * fading edges are enabled.</p>
887      * {@hide}
888      */
889     static final int FADING_EDGE_MASK = 0x00003000;
890
891     /**
892      * <p>Indicates this view can be clicked. When clickable, a View reacts
893      * to clicks by notifying the OnClickListener.<p>
894      * {@hide}
895      */
896     static final int CLICKABLE = 0x00004000;
897
898     /**
899      * <p>Indicates this view is caching its drawing into a bitmap.</p>
900      * {@hide}
901      */
902     static final int DRAWING_CACHE_ENABLED = 0x00008000;
903
904     /**
905      * <p>Indicates that no icicle should be saved for this view.<p>
906      * {@hide}
907      */
908     static final int SAVE_DISABLED = 0x000010000;
909
910     /**
911      * <p>Mask for use with setFlags indicating bits used for the saveEnabled
912      * property.</p>
913      * {@hide}
914      */
915     static final int SAVE_DISABLED_MASK = 0x000010000;
916
917     /**
918      * <p>Indicates that no drawing cache should ever be created for this view.<p>
919      * {@hide}
920      */
921     static final int WILL_NOT_CACHE_DRAWING = 0x000020000;
922
923     /**
924      * <p>Indicates this view can take / keep focus when int touch mode.</p>
925      * {@hide}
926      */
927     static final int FOCUSABLE_IN_TOUCH_MODE = 0x00040000;
928
929     /** @hide */
930     @Retention(RetentionPolicy.SOURCE)
931     @IntDef({DRAWING_CACHE_QUALITY_LOW, DRAWING_CACHE_QUALITY_HIGH, DRAWING_CACHE_QUALITY_AUTO})
932     public @interface DrawingCacheQuality {}
933
934     /**
935      * <p>Enables low quality mode for the drawing cache.</p>
936      */
937     public static final int DRAWING_CACHE_QUALITY_LOW = 0x00080000;
938
939     /**
940      * <p>Enables high quality mode for the drawing cache.</p>
941      */
942     public static final int DRAWING_CACHE_QUALITY_HIGH = 0x00100000;
943
944     /**
945      * <p>Enables automatic quality mode for the drawing cache.</p>
946      */
947     public static final int DRAWING_CACHE_QUALITY_AUTO = 0x00000000;
948
949     private static final int[] DRAWING_CACHE_QUALITY_FLAGS = {
950             DRAWING_CACHE_QUALITY_AUTO, DRAWING_CACHE_QUALITY_LOW, DRAWING_CACHE_QUALITY_HIGH
951     };
952
953     /**
954      * <p>Mask for use with setFlags indicating bits used for the cache
955      * quality property.</p>
956      * {@hide}
957      */
958     static final int DRAWING_CACHE_QUALITY_MASK = 0x00180000;
959
960     /**
961      * <p>
962      * Indicates this view can be long clicked. When long clickable, a View
963      * reacts to long clicks by notifying the OnLongClickListener or showing a
964      * context menu.
965      * </p>
966      * {@hide}
967      */
968     static final int LONG_CLICKABLE = 0x00200000;
969
970     /**
971      * <p>Indicates that this view gets its drawable states from its direct parent
972      * and ignores its original internal states.</p>
973      *
974      * @hide
975      */
976     static final int DUPLICATE_PARENT_STATE = 0x00400000;
977
978     /** @hide */
979     @IntDef({
980         SCROLLBARS_INSIDE_OVERLAY,
981         SCROLLBARS_INSIDE_INSET,
982         SCROLLBARS_OUTSIDE_OVERLAY,
983         SCROLLBARS_OUTSIDE_INSET
984     })
985     @Retention(RetentionPolicy.SOURCE)
986     public @interface ScrollBarStyle {}
987
988     /**
989      * The scrollbar style to display the scrollbars inside the content area,
990      * without increasing the padding. The scrollbars will be overlaid with
991      * translucency on the view's content.
992      */
993     public static final int SCROLLBARS_INSIDE_OVERLAY = 0;
994
995     /**
996      * The scrollbar style to display the scrollbars inside the padded area,
997      * increasing the padding of the view. The scrollbars will not overlap the
998      * content area of the view.
999      */
1000     public static final int SCROLLBARS_INSIDE_INSET = 0x01000000;
1001
1002     /**
1003      * The scrollbar style to display the scrollbars at the edge of the view,
1004      * without increasing the padding. The scrollbars will be overlaid with
1005      * translucency.
1006      */
1007     public static final int SCROLLBARS_OUTSIDE_OVERLAY = 0x02000000;
1008
1009     /**
1010      * The scrollbar style to display the scrollbars at the edge of the view,
1011      * increasing the padding of the view. The scrollbars will only overlap the
1012      * background, if any.
1013      */
1014     public static final int SCROLLBARS_OUTSIDE_INSET = 0x03000000;
1015
1016     /**
1017      * Mask to check if the scrollbar style is overlay or inset.
1018      * {@hide}
1019      */
1020     static final int SCROLLBARS_INSET_MASK = 0x01000000;
1021
1022     /**
1023      * Mask to check if the scrollbar style is inside or outside.
1024      * {@hide}
1025      */
1026     static final int SCROLLBARS_OUTSIDE_MASK = 0x02000000;
1027
1028     /**
1029      * Mask for scrollbar style.
1030      * {@hide}
1031      */
1032     static final int SCROLLBARS_STYLE_MASK = 0x03000000;
1033
1034     /**
1035      * View flag indicating that the screen should remain on while the
1036      * window containing this view is visible to the user.  This effectively
1037      * takes care of automatically setting the WindowManager's
1038      * {@link WindowManager.LayoutParams#FLAG_KEEP_SCREEN_ON}.
1039      */
1040     public static final int KEEP_SCREEN_ON = 0x04000000;
1041
1042     /**
1043      * View flag indicating whether this view should have sound effects enabled
1044      * for events such as clicking and touching.
1045      */
1046     public static final int SOUND_EFFECTS_ENABLED = 0x08000000;
1047
1048     /**
1049      * View flag indicating whether this view should have haptic feedback
1050      * enabled for events such as long presses.
1051      */
1052     public static final int HAPTIC_FEEDBACK_ENABLED = 0x10000000;
1053
1054     /**
1055      * <p>Indicates that the view hierarchy should stop saving state when
1056      * it reaches this view.  If state saving is initiated immediately at
1057      * the view, it will be allowed.
1058      * {@hide}
1059      */
1060     static final int PARENT_SAVE_DISABLED = 0x20000000;
1061
1062     /**
1063      * <p>Mask for use with setFlags indicating bits used for PARENT_SAVE_DISABLED.</p>
1064      * {@hide}
1065      */
1066     static final int PARENT_SAVE_DISABLED_MASK = 0x20000000;
1067
1068     /** @hide */
1069     @IntDef(flag = true,
1070             value = {
1071                 FOCUSABLES_ALL,
1072                 FOCUSABLES_TOUCH_MODE
1073             })
1074     @Retention(RetentionPolicy.SOURCE)
1075     public @interface FocusableMode {}
1076
1077     /**
1078      * View flag indicating whether {@link #addFocusables(ArrayList, int, int)}
1079      * should add all focusable Views regardless if they are focusable in touch mode.
1080      */
1081     public static final int FOCUSABLES_ALL = 0x00000000;
1082
1083     /**
1084      * View flag indicating whether {@link #addFocusables(ArrayList, int, int)}
1085      * should add only Views focusable in touch mode.
1086      */
1087     public static final int FOCUSABLES_TOUCH_MODE = 0x00000001;
1088
1089     /** @hide */
1090     @IntDef({
1091             FOCUS_BACKWARD,
1092             FOCUS_FORWARD,
1093             FOCUS_LEFT,
1094             FOCUS_UP,
1095             FOCUS_RIGHT,
1096             FOCUS_DOWN
1097     })
1098     @Retention(RetentionPolicy.SOURCE)
1099     public @interface FocusDirection {}
1100
1101     /** @hide */
1102     @IntDef({
1103             FOCUS_LEFT,
1104             FOCUS_UP,
1105             FOCUS_RIGHT,
1106             FOCUS_DOWN
1107     })
1108     @Retention(RetentionPolicy.SOURCE)
1109     public @interface FocusRealDirection {} // Like @FocusDirection, but without forward/backward
1110
1111     /**
1112      * Use with {@link #focusSearch(int)}. Move focus to the previous selectable
1113      * item.
1114      */
1115     public static final int FOCUS_BACKWARD = 0x00000001;
1116
1117     /**
1118      * Use with {@link #focusSearch(int)}. Move focus to the next selectable
1119      * item.
1120      */
1121     public static final int FOCUS_FORWARD = 0x00000002;
1122
1123     /**
1124      * Use with {@link #focusSearch(int)}. Move focus to the left.
1125      */
1126     public static final int FOCUS_LEFT = 0x00000011;
1127
1128     /**
1129      * Use with {@link #focusSearch(int)}. Move focus up.
1130      */
1131     public static final int FOCUS_UP = 0x00000021;
1132
1133     /**
1134      * Use with {@link #focusSearch(int)}. Move focus to the right.
1135      */
1136     public static final int FOCUS_RIGHT = 0x00000042;
1137
1138     /**
1139      * Use with {@link #focusSearch(int)}. Move focus down.
1140      */
1141     public static final int FOCUS_DOWN = 0x00000082;
1142
1143     /**
1144      * Bits of {@link #getMeasuredWidthAndState()} and
1145      * {@link #getMeasuredWidthAndState()} that provide the actual measured size.
1146      */
1147     public static final int MEASURED_SIZE_MASK = 0x00ffffff;
1148
1149     /**
1150      * Bits of {@link #getMeasuredWidthAndState()} and
1151      * {@link #getMeasuredWidthAndState()} that provide the additional state bits.
1152      */
1153     public static final int MEASURED_STATE_MASK = 0xff000000;
1154
1155     /**
1156      * Bit shift of {@link #MEASURED_STATE_MASK} to get to the height bits
1157      * for functions that combine both width and height into a single int,
1158      * such as {@link #getMeasuredState()} and the childState argument of
1159      * {@link #resolveSizeAndState(int, int, int)}.
1160      */
1161     public static final int MEASURED_HEIGHT_STATE_SHIFT = 16;
1162
1163     /**
1164      * Bit of {@link #getMeasuredWidthAndState()} and
1165      * {@link #getMeasuredWidthAndState()} that indicates the measured size
1166      * is smaller that the space the view would like to have.
1167      */
1168     public static final int MEASURED_STATE_TOO_SMALL = 0x01000000;
1169
1170     /**
1171      * Base View state sets
1172      */
1173     // Singles
1174     /**
1175      * Indicates the view has no states set. States are used with
1176      * {@link android.graphics.drawable.Drawable} to change the drawing of the
1177      * view depending on its state.
1178      *
1179      * @see android.graphics.drawable.Drawable
1180      * @see #getDrawableState()
1181      */
1182     protected static final int[] EMPTY_STATE_SET;
1183     /**
1184      * Indicates the view is enabled. States are used with
1185      * {@link android.graphics.drawable.Drawable} to change the drawing of the
1186      * view depending on its state.
1187      *
1188      * @see android.graphics.drawable.Drawable
1189      * @see #getDrawableState()
1190      */
1191     protected static final int[] ENABLED_STATE_SET;
1192     /**
1193      * Indicates the view is focused. States are used with
1194      * {@link android.graphics.drawable.Drawable} to change the drawing of the
1195      * view depending on its state.
1196      *
1197      * @see android.graphics.drawable.Drawable
1198      * @see #getDrawableState()
1199      */
1200     protected static final int[] FOCUSED_STATE_SET;
1201     /**
1202      * Indicates the view is selected. States are used with
1203      * {@link android.graphics.drawable.Drawable} to change the drawing of the
1204      * view depending on its state.
1205      *
1206      * @see android.graphics.drawable.Drawable
1207      * @see #getDrawableState()
1208      */
1209     protected static final int[] SELECTED_STATE_SET;
1210     /**
1211      * Indicates the view is pressed. States are used with
1212      * {@link android.graphics.drawable.Drawable} to change the drawing of the
1213      * view depending on its state.
1214      *
1215      * @see android.graphics.drawable.Drawable
1216      * @see #getDrawableState()
1217      */
1218     protected static final int[] PRESSED_STATE_SET;
1219     /**
1220      * Indicates the view's window has focus. States are used with
1221      * {@link android.graphics.drawable.Drawable} to change the drawing of the
1222      * view depending on its state.
1223      *
1224      * @see android.graphics.drawable.Drawable
1225      * @see #getDrawableState()
1226      */
1227     protected static final int[] WINDOW_FOCUSED_STATE_SET;
1228     // Doubles
1229     /**
1230      * Indicates the view is enabled and has the focus.
1231      *
1232      * @see #ENABLED_STATE_SET
1233      * @see #FOCUSED_STATE_SET
1234      */
1235     protected static final int[] ENABLED_FOCUSED_STATE_SET;
1236     /**
1237      * Indicates the view is enabled and selected.
1238      *
1239      * @see #ENABLED_STATE_SET
1240      * @see #SELECTED_STATE_SET
1241      */
1242     protected static final int[] ENABLED_SELECTED_STATE_SET;
1243     /**
1244      * Indicates the view is enabled and that its window has focus.
1245      *
1246      * @see #ENABLED_STATE_SET
1247      * @see #WINDOW_FOCUSED_STATE_SET
1248      */
1249     protected static final int[] ENABLED_WINDOW_FOCUSED_STATE_SET;
1250     /**
1251      * Indicates the view is focused and selected.
1252      *
1253      * @see #FOCUSED_STATE_SET
1254      * @see #SELECTED_STATE_SET
1255      */
1256     protected static final int[] FOCUSED_SELECTED_STATE_SET;
1257     /**
1258      * Indicates the view has the focus and that its window has the focus.
1259      *
1260      * @see #FOCUSED_STATE_SET
1261      * @see #WINDOW_FOCUSED_STATE_SET
1262      */
1263     protected static final int[] FOCUSED_WINDOW_FOCUSED_STATE_SET;
1264     /**
1265      * Indicates the view is selected and that its window has the focus.
1266      *
1267      * @see #SELECTED_STATE_SET
1268      * @see #WINDOW_FOCUSED_STATE_SET
1269      */
1270     protected static final int[] SELECTED_WINDOW_FOCUSED_STATE_SET;
1271     // Triples
1272     /**
1273      * Indicates the view is enabled, focused and selected.
1274      *
1275      * @see #ENABLED_STATE_SET
1276      * @see #FOCUSED_STATE_SET
1277      * @see #SELECTED_STATE_SET
1278      */
1279     protected static final int[] ENABLED_FOCUSED_SELECTED_STATE_SET;
1280     /**
1281      * Indicates the view is enabled, focused and its window has the focus.
1282      *
1283      * @see #ENABLED_STATE_SET
1284      * @see #FOCUSED_STATE_SET
1285      * @see #WINDOW_FOCUSED_STATE_SET
1286      */
1287     protected static final int[] ENABLED_FOCUSED_WINDOW_FOCUSED_STATE_SET;
1288     /**
1289      * Indicates the view is enabled, selected and its window has the focus.
1290      *
1291      * @see #ENABLED_STATE_SET
1292      * @see #SELECTED_STATE_SET
1293      * @see #WINDOW_FOCUSED_STATE_SET
1294      */
1295     protected static final int[] ENABLED_SELECTED_WINDOW_FOCUSED_STATE_SET;
1296     /**
1297      * Indicates the view is focused, selected and its window has the focus.
1298      *
1299      * @see #FOCUSED_STATE_SET
1300      * @see #SELECTED_STATE_SET
1301      * @see #WINDOW_FOCUSED_STATE_SET
1302      */
1303     protected static final int[] FOCUSED_SELECTED_WINDOW_FOCUSED_STATE_SET;
1304     /**
1305      * Indicates the view is enabled, focused, selected and its window
1306      * has the focus.
1307      *
1308      * @see #ENABLED_STATE_SET
1309      * @see #FOCUSED_STATE_SET
1310      * @see #SELECTED_STATE_SET
1311      * @see #WINDOW_FOCUSED_STATE_SET
1312      */
1313     protected static final int[] ENABLED_FOCUSED_SELECTED_WINDOW_FOCUSED_STATE_SET;
1314     /**
1315      * Indicates the view is pressed and its window has the focus.
1316      *
1317      * @see #PRESSED_STATE_SET
1318      * @see #WINDOW_FOCUSED_STATE_SET
1319      */
1320     protected static final int[] PRESSED_WINDOW_FOCUSED_STATE_SET;
1321     /**
1322      * Indicates the view is pressed and selected.
1323      *
1324      * @see #PRESSED_STATE_SET
1325      * @see #SELECTED_STATE_SET
1326      */
1327     protected static final int[] PRESSED_SELECTED_STATE_SET;
1328     /**
1329      * Indicates the view is pressed, selected and its window has the focus.
1330      *
1331      * @see #PRESSED_STATE_SET
1332      * @see #SELECTED_STATE_SET
1333      * @see #WINDOW_FOCUSED_STATE_SET
1334      */
1335     protected static final int[] PRESSED_SELECTED_WINDOW_FOCUSED_STATE_SET;
1336     /**
1337      * Indicates the view is pressed and focused.
1338      *
1339      * @see #PRESSED_STATE_SET
1340      * @see #FOCUSED_STATE_SET
1341      */
1342     protected static final int[] PRESSED_FOCUSED_STATE_SET;
1343     /**
1344      * Indicates the view is pressed, focused and its window has the focus.
1345      *
1346      * @see #PRESSED_STATE_SET
1347      * @see #FOCUSED_STATE_SET
1348      * @see #WINDOW_FOCUSED_STATE_SET
1349      */
1350     protected static final int[] PRESSED_FOCUSED_WINDOW_FOCUSED_STATE_SET;
1351     /**
1352      * Indicates the view is pressed, focused and selected.
1353      *
1354      * @see #PRESSED_STATE_SET
1355      * @see #SELECTED_STATE_SET
1356      * @see #FOCUSED_STATE_SET
1357      */
1358     protected static final int[] PRESSED_FOCUSED_SELECTED_STATE_SET;
1359     /**
1360      * Indicates the view is pressed, focused, selected and its window has the focus.
1361      *
1362      * @see #PRESSED_STATE_SET
1363      * @see #FOCUSED_STATE_SET
1364      * @see #SELECTED_STATE_SET
1365      * @see #WINDOW_FOCUSED_STATE_SET
1366      */
1367     protected static final int[] PRESSED_FOCUSED_SELECTED_WINDOW_FOCUSED_STATE_SET;
1368     /**
1369      * Indicates the view is pressed and enabled.
1370      *
1371      * @see #PRESSED_STATE_SET
1372      * @see #ENABLED_STATE_SET
1373      */
1374     protected static final int[] PRESSED_ENABLED_STATE_SET;
1375     /**
1376      * Indicates the view is pressed, enabled and its window has the focus.
1377      *
1378      * @see #PRESSED_STATE_SET
1379      * @see #ENABLED_STATE_SET
1380      * @see #WINDOW_FOCUSED_STATE_SET
1381      */
1382     protected static final int[] PRESSED_ENABLED_WINDOW_FOCUSED_STATE_SET;
1383     /**
1384      * Indicates the view is pressed, enabled and selected.
1385      *
1386      * @see #PRESSED_STATE_SET
1387      * @see #ENABLED_STATE_SET
1388      * @see #SELECTED_STATE_SET
1389      */
1390     protected static final int[] PRESSED_ENABLED_SELECTED_STATE_SET;
1391     /**
1392      * Indicates the view is pressed, enabled, selected and its window has the
1393      * focus.
1394      *
1395      * @see #PRESSED_STATE_SET
1396      * @see #ENABLED_STATE_SET
1397      * @see #SELECTED_STATE_SET
1398      * @see #WINDOW_FOCUSED_STATE_SET
1399      */
1400     protected static final int[] PRESSED_ENABLED_SELECTED_WINDOW_FOCUSED_STATE_SET;
1401     /**
1402      * Indicates the view is pressed, enabled and focused.
1403      *
1404      * @see #PRESSED_STATE_SET
1405      * @see #ENABLED_STATE_SET
1406      * @see #FOCUSED_STATE_SET
1407      */
1408     protected static final int[] PRESSED_ENABLED_FOCUSED_STATE_SET;
1409     /**
1410      * Indicates the view is pressed, enabled, focused and its window has the
1411      * focus.
1412      *
1413      * @see #PRESSED_STATE_SET
1414      * @see #ENABLED_STATE_SET
1415      * @see #FOCUSED_STATE_SET
1416      * @see #WINDOW_FOCUSED_STATE_SET
1417      */
1418     protected static final int[] PRESSED_ENABLED_FOCUSED_WINDOW_FOCUSED_STATE_SET;
1419     /**
1420      * Indicates the view is pressed, enabled, focused and selected.
1421      *
1422      * @see #PRESSED_STATE_SET
1423      * @see #ENABLED_STATE_SET
1424      * @see #SELECTED_STATE_SET
1425      * @see #FOCUSED_STATE_SET
1426      */
1427     protected static final int[] PRESSED_ENABLED_FOCUSED_SELECTED_STATE_SET;
1428     /**
1429      * Indicates the view is pressed, enabled, focused, selected and its window
1430      * has the focus.
1431      *
1432      * @see #PRESSED_STATE_SET
1433      * @see #ENABLED_STATE_SET
1434      * @see #SELECTED_STATE_SET
1435      * @see #FOCUSED_STATE_SET
1436      * @see #WINDOW_FOCUSED_STATE_SET
1437      */
1438     protected static final int[] PRESSED_ENABLED_FOCUSED_SELECTED_WINDOW_FOCUSED_STATE_SET;
1439
1440     /**
1441      * The order here is very important to {@link #getDrawableState()}
1442      */
1443     private static final int[][] VIEW_STATE_SETS;
1444
1445     static final int VIEW_STATE_WINDOW_FOCUSED = 1;
1446     static final int VIEW_STATE_SELECTED = 1 << 1;
1447     static final int VIEW_STATE_FOCUSED = 1 << 2;
1448     static final int VIEW_STATE_ENABLED = 1 << 3;
1449     static final int VIEW_STATE_PRESSED = 1 << 4;
1450     static final int VIEW_STATE_ACTIVATED = 1 << 5;
1451     static final int VIEW_STATE_ACCELERATED = 1 << 6;
1452     static final int VIEW_STATE_HOVERED = 1 << 7;
1453     static final int VIEW_STATE_DRAG_CAN_ACCEPT = 1 << 8;
1454     static final int VIEW_STATE_DRAG_HOVERED = 1 << 9;
1455
1456     static final int[] VIEW_STATE_IDS = new int[] {
1457         R.attr.state_window_focused,    VIEW_STATE_WINDOW_FOCUSED,
1458         R.attr.state_selected,          VIEW_STATE_SELECTED,
1459         R.attr.state_focused,           VIEW_STATE_FOCUSED,
1460         R.attr.state_enabled,           VIEW_STATE_ENABLED,
1461         R.attr.state_pressed,           VIEW_STATE_PRESSED,
1462         R.attr.state_activated,         VIEW_STATE_ACTIVATED,
1463         R.attr.state_accelerated,       VIEW_STATE_ACCELERATED,
1464         R.attr.state_hovered,           VIEW_STATE_HOVERED,
1465         R.attr.state_drag_can_accept,   VIEW_STATE_DRAG_CAN_ACCEPT,
1466         R.attr.state_drag_hovered,      VIEW_STATE_DRAG_HOVERED
1467     };
1468
1469     static {
1470         if ((VIEW_STATE_IDS.length/2) != R.styleable.ViewDrawableStates.length) {
1471             throw new IllegalStateException(
1472                     "VIEW_STATE_IDs array length does not match ViewDrawableStates style array");
1473         }
1474         int[] orderedIds = new int[VIEW_STATE_IDS.length];
1475         for (int i = 0; i < R.styleable.ViewDrawableStates.length; i++) {
1476             int viewState = R.styleable.ViewDrawableStates[i];
1477             for (int j = 0; j<VIEW_STATE_IDS.length; j += 2) {
1478                 if (VIEW_STATE_IDS[j] == viewState) {
1479                     orderedIds[i * 2] = viewState;
1480                     orderedIds[i * 2 + 1] = VIEW_STATE_IDS[j + 1];
1481                 }
1482             }
1483         }
1484         final int NUM_BITS = VIEW_STATE_IDS.length / 2;
1485         VIEW_STATE_SETS = new int[1 << NUM_BITS][];
1486         for (int i = 0; i < VIEW_STATE_SETS.length; i++) {
1487             int numBits = Integer.bitCount(i);
1488             int[] set = new int[numBits];
1489             int pos = 0;
1490             for (int j = 0; j < orderedIds.length; j += 2) {
1491                 if ((i & orderedIds[j+1]) != 0) {
1492                     set[pos++] = orderedIds[j];
1493                 }
1494             }
1495             VIEW_STATE_SETS[i] = set;
1496         }
1497
1498         EMPTY_STATE_SET = VIEW_STATE_SETS[0];
1499         WINDOW_FOCUSED_STATE_SET = VIEW_STATE_SETS[VIEW_STATE_WINDOW_FOCUSED];
1500         SELECTED_STATE_SET = VIEW_STATE_SETS[VIEW_STATE_SELECTED];
1501         SELECTED_WINDOW_FOCUSED_STATE_SET = VIEW_STATE_SETS[
1502                 VIEW_STATE_WINDOW_FOCUSED | VIEW_STATE_SELECTED];
1503         FOCUSED_STATE_SET = VIEW_STATE_SETS[VIEW_STATE_FOCUSED];
1504         FOCUSED_WINDOW_FOCUSED_STATE_SET = VIEW_STATE_SETS[
1505                 VIEW_STATE_WINDOW_FOCUSED | VIEW_STATE_FOCUSED];
1506         FOCUSED_SELECTED_STATE_SET = VIEW_STATE_SETS[
1507                 VIEW_STATE_SELECTED | VIEW_STATE_FOCUSED];
1508         FOCUSED_SELECTED_WINDOW_FOCUSED_STATE_SET = VIEW_STATE_SETS[
1509                 VIEW_STATE_WINDOW_FOCUSED | VIEW_STATE_SELECTED
1510                 | VIEW_STATE_FOCUSED];
1511         ENABLED_STATE_SET = VIEW_STATE_SETS[VIEW_STATE_ENABLED];
1512         ENABLED_WINDOW_FOCUSED_STATE_SET = VIEW_STATE_SETS[
1513                 VIEW_STATE_WINDOW_FOCUSED | VIEW_STATE_ENABLED];
1514         ENABLED_SELECTED_STATE_SET = VIEW_STATE_SETS[
1515                 VIEW_STATE_SELECTED | VIEW_STATE_ENABLED];
1516         ENABLED_SELECTED_WINDOW_FOCUSED_STATE_SET = VIEW_STATE_SETS[
1517                 VIEW_STATE_WINDOW_FOCUSED | VIEW_STATE_SELECTED
1518                 | VIEW_STATE_ENABLED];
1519         ENABLED_FOCUSED_STATE_SET = VIEW_STATE_SETS[
1520                 VIEW_STATE_FOCUSED | VIEW_STATE_ENABLED];
1521         ENABLED_FOCUSED_WINDOW_FOCUSED_STATE_SET = VIEW_STATE_SETS[
1522                 VIEW_STATE_WINDOW_FOCUSED | VIEW_STATE_FOCUSED
1523                 | VIEW_STATE_ENABLED];
1524         ENABLED_FOCUSED_SELECTED_STATE_SET = VIEW_STATE_SETS[
1525                 VIEW_STATE_SELECTED | VIEW_STATE_FOCUSED
1526                 | VIEW_STATE_ENABLED];
1527         ENABLED_FOCUSED_SELECTED_WINDOW_FOCUSED_STATE_SET = VIEW_STATE_SETS[
1528                 VIEW_STATE_WINDOW_FOCUSED | VIEW_STATE_SELECTED
1529                 | VIEW_STATE_FOCUSED| VIEW_STATE_ENABLED];
1530
1531         PRESSED_STATE_SET = VIEW_STATE_SETS[VIEW_STATE_PRESSED];
1532         PRESSED_WINDOW_FOCUSED_STATE_SET = VIEW_STATE_SETS[
1533                 VIEW_STATE_WINDOW_FOCUSED | VIEW_STATE_PRESSED];
1534         PRESSED_SELECTED_STATE_SET = VIEW_STATE_SETS[
1535                 VIEW_STATE_SELECTED | VIEW_STATE_PRESSED];
1536         PRESSED_SELECTED_WINDOW_FOCUSED_STATE_SET = VIEW_STATE_SETS[
1537                 VIEW_STATE_WINDOW_FOCUSED | VIEW_STATE_SELECTED
1538                 | VIEW_STATE_PRESSED];
1539         PRESSED_FOCUSED_STATE_SET = VIEW_STATE_SETS[
1540                 VIEW_STATE_FOCUSED | VIEW_STATE_PRESSED];
1541         PRESSED_FOCUSED_WINDOW_FOCUSED_STATE_SET = VIEW_STATE_SETS[
1542                 VIEW_STATE_WINDOW_FOCUSED | VIEW_STATE_FOCUSED
1543                 | VIEW_STATE_PRESSED];
1544         PRESSED_FOCUSED_SELECTED_STATE_SET = VIEW_STATE_SETS[
1545                 VIEW_STATE_SELECTED | VIEW_STATE_FOCUSED
1546                 | VIEW_STATE_PRESSED];
1547         PRESSED_FOCUSED_SELECTED_WINDOW_FOCUSED_STATE_SET = VIEW_STATE_SETS[
1548                 VIEW_STATE_WINDOW_FOCUSED | VIEW_STATE_SELECTED
1549                 | VIEW_STATE_FOCUSED | VIEW_STATE_PRESSED];
1550         PRESSED_ENABLED_STATE_SET = VIEW_STATE_SETS[
1551                 VIEW_STATE_ENABLED | VIEW_STATE_PRESSED];
1552         PRESSED_ENABLED_WINDOW_FOCUSED_STATE_SET = VIEW_STATE_SETS[
1553                 VIEW_STATE_WINDOW_FOCUSED | VIEW_STATE_ENABLED
1554                 | VIEW_STATE_PRESSED];
1555         PRESSED_ENABLED_SELECTED_STATE_SET = VIEW_STATE_SETS[
1556                 VIEW_STATE_SELECTED | VIEW_STATE_ENABLED
1557                 | VIEW_STATE_PRESSED];
1558         PRESSED_ENABLED_SELECTED_WINDOW_FOCUSED_STATE_SET = VIEW_STATE_SETS[
1559                 VIEW_STATE_WINDOW_FOCUSED | VIEW_STATE_SELECTED
1560                 | VIEW_STATE_ENABLED | VIEW_STATE_PRESSED];
1561         PRESSED_ENABLED_FOCUSED_STATE_SET = VIEW_STATE_SETS[
1562                 VIEW_STATE_FOCUSED | VIEW_STATE_ENABLED
1563                 | VIEW_STATE_PRESSED];
1564         PRESSED_ENABLED_FOCUSED_WINDOW_FOCUSED_STATE_SET = VIEW_STATE_SETS[
1565                 VIEW_STATE_WINDOW_FOCUSED | VIEW_STATE_FOCUSED
1566                 | VIEW_STATE_ENABLED | VIEW_STATE_PRESSED];
1567         PRESSED_ENABLED_FOCUSED_SELECTED_STATE_SET = VIEW_STATE_SETS[
1568                 VIEW_STATE_SELECTED | VIEW_STATE_FOCUSED
1569                 | VIEW_STATE_ENABLED | VIEW_STATE_PRESSED];
1570         PRESSED_ENABLED_FOCUSED_SELECTED_WINDOW_FOCUSED_STATE_SET = VIEW_STATE_SETS[
1571                 VIEW_STATE_WINDOW_FOCUSED | VIEW_STATE_SELECTED
1572                 | VIEW_STATE_FOCUSED| VIEW_STATE_ENABLED
1573                 | VIEW_STATE_PRESSED];
1574     }
1575
1576     /**
1577      * Accessibility event types that are dispatched for text population.
1578      */
1579     private static final int POPULATING_ACCESSIBILITY_EVENT_TYPES =
1580             AccessibilityEvent.TYPE_VIEW_CLICKED
1581             | AccessibilityEvent.TYPE_VIEW_LONG_CLICKED
1582             | AccessibilityEvent.TYPE_VIEW_SELECTED
1583             | AccessibilityEvent.TYPE_VIEW_FOCUSED
1584             | AccessibilityEvent.TYPE_WINDOW_STATE_CHANGED
1585             | AccessibilityEvent.TYPE_VIEW_HOVER_ENTER
1586             | AccessibilityEvent.TYPE_VIEW_HOVER_EXIT
1587             | AccessibilityEvent.TYPE_VIEW_TEXT_CHANGED
1588             | AccessibilityEvent.TYPE_VIEW_TEXT_SELECTION_CHANGED
1589             | AccessibilityEvent.TYPE_VIEW_ACCESSIBILITY_FOCUSED
1590             | AccessibilityEvent.TYPE_VIEW_TEXT_TRAVERSED_AT_MOVEMENT_GRANULARITY;
1591
1592     /**
1593      * Temporary Rect currently for use in setBackground().  This will probably
1594      * be extended in the future to hold our own class with more than just
1595      * a Rect. :)
1596      */
1597     static final ThreadLocal<Rect> sThreadLocal = new ThreadLocal<Rect>();
1598
1599     /**
1600      * Map used to store views' tags.
1601      */
1602     private SparseArray<Object> mKeyedTags;
1603
1604     /**
1605      * The next available accessibility id.
1606      */
1607     private static int sNextAccessibilityViewId;
1608
1609     /**
1610      * The animation currently associated with this view.
1611      * @hide
1612      */
1613     protected Animation mCurrentAnimation = null;
1614
1615     /**
1616      * Width as measured during measure pass.
1617      * {@hide}
1618      */
1619     @ViewDebug.ExportedProperty(category = "measurement")
1620     int mMeasuredWidth;
1621
1622     /**
1623      * Height as measured during measure pass.
1624      * {@hide}
1625      */
1626     @ViewDebug.ExportedProperty(category = "measurement")
1627     int mMeasuredHeight;
1628
1629     /**
1630      * Flag to indicate that this view was marked INVALIDATED, or had its display list
1631      * invalidated, prior to the current drawing iteration. If true, the view must re-draw
1632      * its display list. This flag, used only when hw accelerated, allows us to clear the
1633      * flag while retaining this information until it's needed (at getDisplayList() time and
1634      * in drawChild(), when we decide to draw a view's children's display lists into our own).
1635      *
1636      * {@hide}
1637      */
1638     boolean mRecreateDisplayList = false;
1639
1640     /**
1641      * The view's identifier.
1642      * {@hide}
1643      *
1644      * @see #setId(int)
1645      * @see #getId()
1646      */
1647     @ViewDebug.ExportedProperty(resolveId = true)
1648     int mID = NO_ID;
1649
1650     /**
1651      * The stable ID of this view for accessibility purposes.
1652      */
1653     int mAccessibilityViewId = NO_ID;
1654
1655     private int mAccessibilityCursorPosition = ACCESSIBILITY_CURSOR_POSITION_UNDEFINED;
1656
1657     SendViewStateChangedAccessibilityEvent mSendViewStateChangedAccessibilityEvent;
1658
1659     /**
1660      * The view's tag.
1661      * {@hide}
1662      *
1663      * @see #setTag(Object)
1664      * @see #getTag()
1665      */
1666     protected Object mTag = null;
1667
1668     // for mPrivateFlags:
1669     /** {@hide} */
1670     static final int PFLAG_WANTS_FOCUS                 = 0x00000001;
1671     /** {@hide} */
1672     static final int PFLAG_FOCUSED                     = 0x00000002;
1673     /** {@hide} */
1674     static final int PFLAG_SELECTED                    = 0x00000004;
1675     /** {@hide} */
1676     static final int PFLAG_IS_ROOT_NAMESPACE           = 0x00000008;
1677     /** {@hide} */
1678     static final int PFLAG_HAS_BOUNDS                  = 0x00000010;
1679     /** {@hide} */
1680     static final int PFLAG_DRAWN                       = 0x00000020;
1681     /**
1682      * When this flag is set, this view is running an animation on behalf of its
1683      * children and should therefore not cancel invalidate requests, even if they
1684      * lie outside of this view's bounds.
1685      *
1686      * {@hide}
1687      */
1688     static final int PFLAG_DRAW_ANIMATION              = 0x00000040;
1689     /** {@hide} */
1690     static final int PFLAG_SKIP_DRAW                   = 0x00000080;
1691     /** {@hide} */
1692     static final int PFLAG_ONLY_DRAWS_BACKGROUND       = 0x00000100;
1693     /** {@hide} */
1694     static final int PFLAG_REQUEST_TRANSPARENT_REGIONS = 0x00000200;
1695     /** {@hide} */
1696     static final int PFLAG_DRAWABLE_STATE_DIRTY        = 0x00000400;
1697     /** {@hide} */
1698     static final int PFLAG_MEASURED_DIMENSION_SET      = 0x00000800;
1699     /** {@hide} */
1700     static final int PFLAG_FORCE_LAYOUT                = 0x00001000;
1701     /** {@hide} */
1702     static final int PFLAG_LAYOUT_REQUIRED             = 0x00002000;
1703
1704     private static final int PFLAG_PRESSED             = 0x00004000;
1705
1706     /** {@hide} */
1707     static final int PFLAG_DRAWING_CACHE_VALID         = 0x00008000;
1708     /**
1709      * Flag used to indicate that this view should be drawn once more (and only once
1710      * more) after its animation has completed.
1711      * {@hide}
1712      */
1713     static final int PFLAG_ANIMATION_STARTED           = 0x00010000;
1714
1715     private static final int PFLAG_SAVE_STATE_CALLED   = 0x00020000;
1716
1717     /**
1718      * Indicates that the View returned true when onSetAlpha() was called and that
1719      * the alpha must be restored.
1720      * {@hide}
1721      */
1722     static final int PFLAG_ALPHA_SET                   = 0x00040000;
1723
1724     /**
1725      * Set by {@link #setScrollContainer(boolean)}.
1726      */
1727     static final int PFLAG_SCROLL_CONTAINER            = 0x00080000;
1728
1729     /**
1730      * Set by {@link #setScrollContainer(boolean)}.
1731      */
1732     static final int PFLAG_SCROLL_CONTAINER_ADDED      = 0x00100000;
1733
1734     /**
1735      * View flag indicating whether this view was invalidated (fully or partially.)
1736      *
1737      * @hide
1738      */
1739     static final int PFLAG_DIRTY                       = 0x00200000;
1740
1741     /**
1742      * View flag indicating whether this view was invalidated by an opaque
1743      * invalidate request.
1744      *
1745      * @hide
1746      */
1747     static final int PFLAG_DIRTY_OPAQUE                = 0x00400000;
1748
1749     /**
1750      * Mask for {@link #PFLAG_DIRTY} and {@link #PFLAG_DIRTY_OPAQUE}.
1751      *
1752      * @hide
1753      */
1754     static final int PFLAG_DIRTY_MASK                  = 0x00600000;
1755
1756     /**
1757      * Indicates whether the background is opaque.
1758      *
1759      * @hide
1760      */
1761     static final int PFLAG_OPAQUE_BACKGROUND           = 0x00800000;
1762
1763     /**
1764      * Indicates whether the scrollbars are opaque.
1765      *
1766      * @hide
1767      */
1768     static final int PFLAG_OPAQUE_SCROLLBARS           = 0x01000000;
1769
1770     /**
1771      * Indicates whether the view is opaque.
1772      *
1773      * @hide
1774      */
1775     static final int PFLAG_OPAQUE_MASK                 = 0x01800000;
1776
1777     /**
1778      * Indicates a prepressed state;
1779      * the short time between ACTION_DOWN and recognizing
1780      * a 'real' press. Prepressed is used to recognize quick taps
1781      * even when they are shorter than ViewConfiguration.getTapTimeout().
1782      *
1783      * @hide
1784      */
1785     private static final int PFLAG_PREPRESSED          = 0x02000000;
1786
1787     /**
1788      * Indicates whether the view is temporarily detached.
1789      *
1790      * @hide
1791      */
1792     static final int PFLAG_CANCEL_NEXT_UP_EVENT        = 0x04000000;
1793
1794     /**
1795      * Indicates that we should awaken scroll bars once attached
1796      *
1797      * @hide
1798      */
1799     private static final int PFLAG_AWAKEN_SCROLL_BARS_ON_ATTACH = 0x08000000;
1800
1801     /**
1802      * Indicates that the view has received HOVER_ENTER.  Cleared on HOVER_EXIT.
1803      * @hide
1804      */
1805     private static final int PFLAG_HOVERED             = 0x10000000;
1806
1807     /**
1808      * no longer needed, should be reused
1809      */
1810     private static final int PFLAG_DOES_NOTHING_REUSE_PLEASE = 0x20000000;
1811
1812     /** {@hide} */
1813     static final int PFLAG_ACTIVATED                   = 0x40000000;
1814
1815     /**
1816      * Indicates that this view was specifically invalidated, not just dirtied because some
1817      * child view was invalidated. The flag is used to determine when we need to recreate
1818      * a view's display list (as opposed to just returning a reference to its existing
1819      * display list).
1820      *
1821      * @hide
1822      */
1823     static final int PFLAG_INVALIDATED                 = 0x80000000;
1824
1825     /**
1826      * Masks for mPrivateFlags2, as generated by dumpFlags():
1827      *
1828      * |-------|-------|-------|-------|
1829      *                                 1 PFLAG2_DRAG_CAN_ACCEPT
1830      *                                1  PFLAG2_DRAG_HOVERED
1831      *                              11   PFLAG2_LAYOUT_DIRECTION_MASK
1832      *                             1     PFLAG2_LAYOUT_DIRECTION_RESOLVED_RTL
1833      *                            1      PFLAG2_LAYOUT_DIRECTION_RESOLVED
1834      *                            11     PFLAG2_LAYOUT_DIRECTION_RESOLVED_MASK
1835      *                           1       PFLAG2_TEXT_DIRECTION_FLAGS[1]
1836      *                          1        PFLAG2_TEXT_DIRECTION_FLAGS[2]
1837      *                          11       PFLAG2_TEXT_DIRECTION_FLAGS[3]
1838      *                         1         PFLAG2_TEXT_DIRECTION_FLAGS[4]
1839      *                         1 1       PFLAG2_TEXT_DIRECTION_FLAGS[5]
1840      *                         111       PFLAG2_TEXT_DIRECTION_MASK
1841      *                        1          PFLAG2_TEXT_DIRECTION_RESOLVED
1842      *                       1           PFLAG2_TEXT_DIRECTION_RESOLVED_DEFAULT
1843      *                     111           PFLAG2_TEXT_DIRECTION_RESOLVED_MASK
1844      *                    1              PFLAG2_TEXT_ALIGNMENT_FLAGS[1]
1845      *                   1               PFLAG2_TEXT_ALIGNMENT_FLAGS[2]
1846      *                   11              PFLAG2_TEXT_ALIGNMENT_FLAGS[3]
1847      *                  1                PFLAG2_TEXT_ALIGNMENT_FLAGS[4]
1848      *                  1 1              PFLAG2_TEXT_ALIGNMENT_FLAGS[5]
1849      *                  11               PFLAG2_TEXT_ALIGNMENT_FLAGS[6]
1850      *                  111              PFLAG2_TEXT_ALIGNMENT_MASK
1851      *                 1                 PFLAG2_TEXT_ALIGNMENT_RESOLVED
1852      *                1                  PFLAG2_TEXT_ALIGNMENT_RESOLVED_DEFAULT
1853      *              111                  PFLAG2_TEXT_ALIGNMENT_RESOLVED_MASK
1854      *           111                     PFLAG2_IMPORTANT_FOR_ACCESSIBILITY_MASK
1855      *         11                        PFLAG2_ACCESSIBILITY_LIVE_REGION_MASK
1856      *       1                           PFLAG2_ACCESSIBILITY_FOCUSED
1857      *      1                            PFLAG2_SUBTREE_ACCESSIBILITY_STATE_CHANGED
1858      *     1                             PFLAG2_VIEW_QUICK_REJECTED
1859      *    1                              PFLAG2_PADDING_RESOLVED
1860      *   1                               PFLAG2_DRAWABLE_RESOLVED
1861      *  1                                PFLAG2_HAS_TRANSIENT_STATE
1862      * |-------|-------|-------|-------|
1863      */
1864
1865     /**
1866      * Indicates that this view has reported that it can accept the current drag's content.
1867      * Cleared when the drag operation concludes.
1868      * @hide
1869      */
1870     static final int PFLAG2_DRAG_CAN_ACCEPT            = 0x00000001;
1871
1872     /**
1873      * Indicates that this view is currently directly under the drag location in a
1874      * drag-and-drop operation involving content that it can accept.  Cleared when
1875      * the drag exits the view, or when the drag operation concludes.
1876      * @hide
1877      */
1878     static final int PFLAG2_DRAG_HOVERED               = 0x00000002;
1879
1880     /** @hide */
1881     @IntDef({
1882         LAYOUT_DIRECTION_LTR,
1883         LAYOUT_DIRECTION_RTL,
1884         LAYOUT_DIRECTION_INHERIT,
1885         LAYOUT_DIRECTION_LOCALE
1886     })
1887     @Retention(RetentionPolicy.SOURCE)
1888     // Not called LayoutDirection to avoid conflict with android.util.LayoutDirection
1889     public @interface LayoutDir {}
1890
1891     /** @hide */
1892     @IntDef({
1893         LAYOUT_DIRECTION_LTR,
1894         LAYOUT_DIRECTION_RTL
1895     })
1896     @Retention(RetentionPolicy.SOURCE)
1897     public @interface ResolvedLayoutDir {}
1898
1899     /**
1900      * Horizontal layout direction of this view is from Left to Right.
1901      * Use with {@link #setLayoutDirection}.
1902      */
1903     public static final int LAYOUT_DIRECTION_LTR = LayoutDirection.LTR;
1904
1905     /**
1906      * Horizontal layout direction of this view is from Right to Left.
1907      * Use with {@link #setLayoutDirection}.
1908      */
1909     public static final int LAYOUT_DIRECTION_RTL = LayoutDirection.RTL;
1910
1911     /**
1912      * Horizontal layout direction of this view is inherited from its parent.
1913      * Use with {@link #setLayoutDirection}.
1914      */
1915     public static final int LAYOUT_DIRECTION_INHERIT = LayoutDirection.INHERIT;
1916
1917     /**
1918      * Horizontal layout direction of this view is from deduced from the default language
1919      * script for the locale. Use with {@link #setLayoutDirection}.
1920      */
1921     public static final int LAYOUT_DIRECTION_LOCALE = LayoutDirection.LOCALE;
1922
1923     /**
1924      * Bit shift to get the horizontal layout direction. (bits after DRAG_HOVERED)
1925      * @hide
1926      */
1927     static final int PFLAG2_LAYOUT_DIRECTION_MASK_SHIFT = 2;
1928
1929     /**
1930      * Mask for use with private flags indicating bits used for horizontal layout direction.
1931      * @hide
1932      */
1933     static final int PFLAG2_LAYOUT_DIRECTION_MASK = 0x00000003 << PFLAG2_LAYOUT_DIRECTION_MASK_SHIFT;
1934
1935     /**
1936      * Indicates whether the view horizontal layout direction has been resolved and drawn to the
1937      * right-to-left direction.
1938      * @hide
1939      */
1940     static final int PFLAG2_LAYOUT_DIRECTION_RESOLVED_RTL = 4 << PFLAG2_LAYOUT_DIRECTION_MASK_SHIFT;
1941
1942     /**
1943      * Indicates whether the view horizontal layout direction has been resolved.
1944      * @hide
1945      */
1946     static final int PFLAG2_LAYOUT_DIRECTION_RESOLVED = 8 << PFLAG2_LAYOUT_DIRECTION_MASK_SHIFT;
1947
1948     /**
1949      * Mask for use with private flags indicating bits used for resolved horizontal layout direction.
1950      * @hide
1951      */
1952     static final int PFLAG2_LAYOUT_DIRECTION_RESOLVED_MASK = 0x0000000C
1953             << PFLAG2_LAYOUT_DIRECTION_MASK_SHIFT;
1954
1955     /*
1956      * Array of horizontal layout direction flags for mapping attribute "layoutDirection" to correct
1957      * flag value.
1958      * @hide
1959      */
1960     private static final int[] LAYOUT_DIRECTION_FLAGS = {
1961             LAYOUT_DIRECTION_LTR,
1962             LAYOUT_DIRECTION_RTL,
1963             LAYOUT_DIRECTION_INHERIT,
1964             LAYOUT_DIRECTION_LOCALE
1965     };
1966
1967     /**
1968      * Default horizontal layout direction.
1969      */
1970     private static final int LAYOUT_DIRECTION_DEFAULT = LAYOUT_DIRECTION_INHERIT;
1971
1972     /**
1973      * Default horizontal layout direction.
1974      * @hide
1975      */
1976     static final int LAYOUT_DIRECTION_RESOLVED_DEFAULT = LAYOUT_DIRECTION_LTR;
1977
1978     /**
1979      * Text direction is inherited thru {@link ViewGroup}
1980      */
1981     public static final int TEXT_DIRECTION_INHERIT = 0;
1982
1983     /**
1984      * Text direction is using "first strong algorithm". The first strong directional character
1985      * determines the paragraph direction. If there is no strong directional character, the
1986      * paragraph direction is the view's resolved layout direction.
1987      */
1988     public static final int TEXT_DIRECTION_FIRST_STRONG = 1;
1989
1990     /**
1991      * Text direction is using "any-RTL" algorithm. The paragraph direction is RTL if it contains
1992      * any strong RTL character, otherwise it is LTR if it contains any strong LTR characters.
1993      * If there are neither, the paragraph direction is the view's resolved layout direction.
1994      */
1995     public static final int TEXT_DIRECTION_ANY_RTL = 2;
1996
1997     /**
1998      * Text direction is forced to LTR.
1999      */
2000     public static final int TEXT_DIRECTION_LTR = 3;
2001
2002     /**
2003      * Text direction is forced to RTL.
2004      */
2005     public static final int TEXT_DIRECTION_RTL = 4;
2006
2007     /**
2008      * Text direction is coming from the system Locale.
2009      */
2010     public static final int TEXT_DIRECTION_LOCALE = 5;
2011
2012     /**
2013      * Default text direction is inherited
2014      */
2015     private static final int TEXT_DIRECTION_DEFAULT = TEXT_DIRECTION_INHERIT;
2016
2017     /**
2018      * Default resolved text direction
2019      * @hide
2020      */
2021     static final int TEXT_DIRECTION_RESOLVED_DEFAULT = TEXT_DIRECTION_FIRST_STRONG;
2022
2023     /**
2024      * Bit shift to get the horizontal layout direction. (bits after LAYOUT_DIRECTION_RESOLVED)
2025      * @hide
2026      */
2027     static final int PFLAG2_TEXT_DIRECTION_MASK_SHIFT = 6;
2028
2029     /**
2030      * Mask for use with private flags indicating bits used for text direction.
2031      * @hide
2032      */
2033     static final int PFLAG2_TEXT_DIRECTION_MASK = 0x00000007
2034             << PFLAG2_TEXT_DIRECTION_MASK_SHIFT;
2035
2036     /**
2037      * Array of text direction flags for mapping attribute "textDirection" to correct
2038      * flag value.
2039      * @hide
2040      */
2041     private static final int[] PFLAG2_TEXT_DIRECTION_FLAGS = {
2042             TEXT_DIRECTION_INHERIT << PFLAG2_TEXT_DIRECTION_MASK_SHIFT,
2043             TEXT_DIRECTION_FIRST_STRONG << PFLAG2_TEXT_DIRECTION_MASK_SHIFT,
2044             TEXT_DIRECTION_ANY_RTL << PFLAG2_TEXT_DIRECTION_MASK_SHIFT,
2045             TEXT_DIRECTION_LTR << PFLAG2_TEXT_DIRECTION_MASK_SHIFT,
2046             TEXT_DIRECTION_RTL << PFLAG2_TEXT_DIRECTION_MASK_SHIFT,
2047             TEXT_DIRECTION_LOCALE << PFLAG2_TEXT_DIRECTION_MASK_SHIFT
2048     };
2049
2050     /**
2051      * Indicates whether the view text direction has been resolved.
2052      * @hide
2053      */
2054     static final int PFLAG2_TEXT_DIRECTION_RESOLVED = 0x00000008
2055             << PFLAG2_TEXT_DIRECTION_MASK_SHIFT;
2056
2057     /**
2058      * Bit shift to get the horizontal layout direction. (bits after DRAG_HOVERED)
2059      * @hide
2060      */
2061     static final int PFLAG2_TEXT_DIRECTION_RESOLVED_MASK_SHIFT = 10;
2062
2063     /**
2064      * Mask for use with private flags indicating bits used for resolved text direction.
2065      * @hide
2066      */
2067     static final int PFLAG2_TEXT_DIRECTION_RESOLVED_MASK = 0x00000007
2068             << PFLAG2_TEXT_DIRECTION_RESOLVED_MASK_SHIFT;
2069
2070     /**
2071      * Indicates whether the view text direction has been resolved to the "first strong" heuristic.
2072      * @hide
2073      */
2074     static final int PFLAG2_TEXT_DIRECTION_RESOLVED_DEFAULT =
2075             TEXT_DIRECTION_RESOLVED_DEFAULT << PFLAG2_TEXT_DIRECTION_RESOLVED_MASK_SHIFT;
2076
2077     /** @hide */
2078     @IntDef({
2079         TEXT_ALIGNMENT_INHERIT,
2080         TEXT_ALIGNMENT_GRAVITY,
2081         TEXT_ALIGNMENT_CENTER,
2082         TEXT_ALIGNMENT_TEXT_START,
2083         TEXT_ALIGNMENT_TEXT_END,
2084         TEXT_ALIGNMENT_VIEW_START,
2085         TEXT_ALIGNMENT_VIEW_END
2086     })
2087     @Retention(RetentionPolicy.SOURCE)
2088     public @interface TextAlignment {}
2089
2090     /**
2091      * Default text alignment. The text alignment of this View is inherited from its parent.
2092      * Use with {@link #setTextAlignment(int)}
2093      */
2094     public static final int TEXT_ALIGNMENT_INHERIT = 0;
2095
2096     /**
2097      * Default for the root view. The gravity determines the text alignment, ALIGN_NORMAL,
2098      * ALIGN_CENTER, or ALIGN_OPPOSITE, which are relative to each paragraph’s text direction.
2099      *
2100      * Use with {@link #setTextAlignment(int)}
2101      */
2102     public static final int TEXT_ALIGNMENT_GRAVITY = 1;
2103
2104     /**
2105      * Align to the start of the paragraph, e.g. ALIGN_NORMAL.
2106      *
2107      * Use with {@link #setTextAlignment(int)}
2108      */
2109     public static final int TEXT_ALIGNMENT_TEXT_START = 2;
2110
2111     /**
2112      * Align to the end of the paragraph, e.g. ALIGN_OPPOSITE.
2113      *
2114      * Use with {@link #setTextAlignment(int)}
2115      */
2116     public static final int TEXT_ALIGNMENT_TEXT_END = 3;
2117
2118     /**
2119      * Center the paragraph, e.g. ALIGN_CENTER.
2120      *
2121      * Use with {@link #setTextAlignment(int)}
2122      */
2123     public static final int TEXT_ALIGNMENT_CENTER = 4;
2124
2125     /**
2126      * Align to the start of the view, which is ALIGN_LEFT if the view’s resolved
2127      * layoutDirection is LTR, and ALIGN_RIGHT otherwise.
2128      *
2129      * Use with {@link #setTextAlignment(int)}
2130      */
2131     public static final int TEXT_ALIGNMENT_VIEW_START = 5;
2132
2133     /**
2134      * Align to the end of the view, which is ALIGN_RIGHT if the view’s resolved
2135      * layoutDirection is LTR, and ALIGN_LEFT otherwise.
2136      *
2137      * Use with {@link #setTextAlignment(int)}
2138      */
2139     public static final int TEXT_ALIGNMENT_VIEW_END = 6;
2140
2141     /**
2142      * Default text alignment is inherited
2143      */
2144     private static final int TEXT_ALIGNMENT_DEFAULT = TEXT_ALIGNMENT_GRAVITY;
2145
2146     /**
2147      * Default resolved text alignment
2148      * @hide
2149      */
2150     static final int TEXT_ALIGNMENT_RESOLVED_DEFAULT = TEXT_ALIGNMENT_GRAVITY;
2151
2152     /**
2153       * Bit shift to get the horizontal layout direction. (bits after DRAG_HOVERED)
2154       * @hide
2155       */
2156     static final int PFLAG2_TEXT_ALIGNMENT_MASK_SHIFT = 13;
2157
2158     /**
2159       * Mask for use with private flags indicating bits used for text alignment.
2160       * @hide
2161       */
2162     static final int PFLAG2_TEXT_ALIGNMENT_MASK = 0x00000007 << PFLAG2_TEXT_ALIGNMENT_MASK_SHIFT;
2163
2164     /**
2165      * Array of text direction flags for mapping attribute "textAlignment" to correct
2166      * flag value.
2167      * @hide
2168      */
2169     private static final int[] PFLAG2_TEXT_ALIGNMENT_FLAGS = {
2170             TEXT_ALIGNMENT_INHERIT << PFLAG2_TEXT_ALIGNMENT_MASK_SHIFT,
2171             TEXT_ALIGNMENT_GRAVITY << PFLAG2_TEXT_ALIGNMENT_MASK_SHIFT,
2172             TEXT_ALIGNMENT_TEXT_START << PFLAG2_TEXT_ALIGNMENT_MASK_SHIFT,
2173             TEXT_ALIGNMENT_TEXT_END << PFLAG2_TEXT_ALIGNMENT_MASK_SHIFT,
2174             TEXT_ALIGNMENT_CENTER << PFLAG2_TEXT_ALIGNMENT_MASK_SHIFT,
2175             TEXT_ALIGNMENT_VIEW_START << PFLAG2_TEXT_ALIGNMENT_MASK_SHIFT,
2176             TEXT_ALIGNMENT_VIEW_END << PFLAG2_TEXT_ALIGNMENT_MASK_SHIFT
2177     };
2178
2179     /**
2180      * Indicates whether the view text alignment has been resolved.
2181      * @hide
2182      */
2183     static final int PFLAG2_TEXT_ALIGNMENT_RESOLVED = 0x00000008 << PFLAG2_TEXT_ALIGNMENT_MASK_SHIFT;
2184
2185     /**
2186      * Bit shift to get the resolved text alignment.
2187      * @hide
2188      */
2189     static final int PFLAG2_TEXT_ALIGNMENT_RESOLVED_MASK_SHIFT = 17;
2190
2191     /**
2192      * Mask for use with private flags indicating bits used for text alignment.
2193      * @hide
2194      */
2195     static final int PFLAG2_TEXT_ALIGNMENT_RESOLVED_MASK = 0x00000007
2196             << PFLAG2_TEXT_ALIGNMENT_RESOLVED_MASK_SHIFT;
2197
2198     /**
2199      * Indicates whether if the view text alignment has been resolved to gravity
2200      */
2201     private static final int PFLAG2_TEXT_ALIGNMENT_RESOLVED_DEFAULT =
2202             TEXT_ALIGNMENT_RESOLVED_DEFAULT << PFLAG2_TEXT_ALIGNMENT_RESOLVED_MASK_SHIFT;
2203
2204     // Accessiblity constants for mPrivateFlags2
2205
2206     /**
2207      * Shift for the bits in {@link #mPrivateFlags2} related to the
2208      * "importantForAccessibility" attribute.
2209      */
2210     static final int PFLAG2_IMPORTANT_FOR_ACCESSIBILITY_SHIFT = 20;
2211
2212     /**
2213      * Automatically determine whether a view is important for accessibility.
2214      */
2215     public static final int IMPORTANT_FOR_ACCESSIBILITY_AUTO = 0x00000000;
2216
2217     /**
2218      * The view is important for accessibility.
2219      */
2220     public static final int IMPORTANT_FOR_ACCESSIBILITY_YES = 0x00000001;
2221
2222     /**
2223      * The view is not important for accessibility.
2224      */
2225     public static final int IMPORTANT_FOR_ACCESSIBILITY_NO = 0x00000002;
2226
2227     /**
2228      * The view is not important for accessibility, nor are any of its
2229      * descendant views.
2230      */
2231     public static final int IMPORTANT_FOR_ACCESSIBILITY_NO_HIDE_DESCENDANTS = 0x00000004;
2232
2233     /**
2234      * The default whether the view is important for accessibility.
2235      */
2236     static final int IMPORTANT_FOR_ACCESSIBILITY_DEFAULT = IMPORTANT_FOR_ACCESSIBILITY_AUTO;
2237
2238     /**
2239      * Mask for obtainig the bits which specify how to determine
2240      * whether a view is important for accessibility.
2241      */
2242     static final int PFLAG2_IMPORTANT_FOR_ACCESSIBILITY_MASK = (IMPORTANT_FOR_ACCESSIBILITY_AUTO
2243         | IMPORTANT_FOR_ACCESSIBILITY_YES | IMPORTANT_FOR_ACCESSIBILITY_NO
2244         | IMPORTANT_FOR_ACCESSIBILITY_NO_HIDE_DESCENDANTS)
2245         << PFLAG2_IMPORTANT_FOR_ACCESSIBILITY_SHIFT;
2246
2247     /**
2248      * Shift for the bits in {@link #mPrivateFlags2} related to the
2249      * "accessibilityLiveRegion" attribute.
2250      */
2251     static final int PFLAG2_ACCESSIBILITY_LIVE_REGION_SHIFT = 23;
2252
2253     /**
2254      * Live region mode specifying that accessibility services should not
2255      * automatically announce changes to this view. This is the default live
2256      * region mode for most views.
2257      * <p>
2258      * Use with {@link #setAccessibilityLiveRegion(int)}.
2259      */
2260     public static final int ACCESSIBILITY_LIVE_REGION_NONE = 0x00000000;
2261
2262     /**
2263      * Live region mode specifying that accessibility services should announce
2264      * changes to this view.
2265      * <p>
2266      * Use with {@link #setAccessibilityLiveRegion(int)}.
2267      */
2268     public static final int ACCESSIBILITY_LIVE_REGION_POLITE = 0x00000001;
2269
2270     /**
2271      * Live region mode specifying that accessibility services should interrupt
2272      * ongoing speech to immediately announce changes to this view.
2273      * <p>
2274      * Use with {@link #setAccessibilityLiveRegion(int)}.
2275      */
2276     public static final int ACCESSIBILITY_LIVE_REGION_ASSERTIVE = 0x00000002;
2277
2278     /**
2279      * The default whether the view is important for accessibility.
2280      */
2281     static final int ACCESSIBILITY_LIVE_REGION_DEFAULT = ACCESSIBILITY_LIVE_REGION_NONE;
2282
2283     /**
2284      * Mask for obtaining the bits which specify a view's accessibility live
2285      * region mode.
2286      */
2287     static final int PFLAG2_ACCESSIBILITY_LIVE_REGION_MASK = (ACCESSIBILITY_LIVE_REGION_NONE
2288             | ACCESSIBILITY_LIVE_REGION_POLITE | ACCESSIBILITY_LIVE_REGION_ASSERTIVE)
2289             << PFLAG2_ACCESSIBILITY_LIVE_REGION_SHIFT;
2290
2291     /**
2292      * Flag indicating whether a view has accessibility focus.
2293      */
2294     static final int PFLAG2_ACCESSIBILITY_FOCUSED = 0x04000000;
2295
2296     /**
2297      * Flag whether the accessibility state of the subtree rooted at this view changed.
2298      */
2299     static final int PFLAG2_SUBTREE_ACCESSIBILITY_STATE_CHANGED = 0x08000000;
2300
2301     /**
2302      * Flag indicating whether a view failed the quickReject() check in draw(). This condition
2303      * is used to check whether later changes to the view's transform should invalidate the
2304      * view to force the quickReject test to run again.
2305      */
2306     static final int PFLAG2_VIEW_QUICK_REJECTED = 0x10000000;
2307
2308     /**
2309      * Flag indicating that start/end padding has been resolved into left/right padding
2310      * for use in measurement, layout, drawing, etc. This is set by {@link #resolvePadding()}
2311      * and checked by {@link #measure(int, int)} to determine if padding needs to be resolved
2312      * during measurement. In some special cases this is required such as when an adapter-based
2313      * view measures prospective children without attaching them to a window.
2314      */
2315     static final int PFLAG2_PADDING_RESOLVED = 0x20000000;
2316
2317     /**
2318      * Flag indicating that the start/end drawables has been resolved into left/right ones.
2319      */
2320     static final int PFLAG2_DRAWABLE_RESOLVED = 0x40000000;
2321
2322     /**
2323      * Indicates that the view is tracking some sort of transient state
2324      * that the app should not need to be aware of, but that the framework
2325      * should take special care to preserve.
2326      */
2327     static final int PFLAG2_HAS_TRANSIENT_STATE = 0x80000000;
2328
2329     /**
2330      * Group of bits indicating that RTL properties resolution is done.
2331      */
2332     static final int ALL_RTL_PROPERTIES_RESOLVED = PFLAG2_LAYOUT_DIRECTION_RESOLVED |
2333             PFLAG2_TEXT_DIRECTION_RESOLVED |
2334             PFLAG2_TEXT_ALIGNMENT_RESOLVED |
2335             PFLAG2_PADDING_RESOLVED |
2336             PFLAG2_DRAWABLE_RESOLVED;
2337
2338     // There are a couple of flags left in mPrivateFlags2
2339
2340     /* End of masks for mPrivateFlags2 */
2341
2342     /**
2343      * Masks for mPrivateFlags3, as generated by dumpFlags():
2344      *
2345      * |-------|-------|-------|-------|
2346      *                                 1 PFLAG3_VIEW_IS_ANIMATING_TRANSFORM
2347      *                                1  PFLAG3_VIEW_IS_ANIMATING_ALPHA
2348      *                               1   PFLAG3_IS_LAID_OUT
2349      *                              1    PFLAG3_MEASURE_NEEDED_BEFORE_LAYOUT
2350      *                             1     PFLAG3_CALLED_SUPER
2351      * |-------|-------|-------|-------|
2352      */
2353
2354     /**
2355      * Flag indicating that view has a transform animation set on it. This is used to track whether
2356      * an animation is cleared between successive frames, in order to tell the associated
2357      * DisplayList to clear its animation matrix.
2358      */
2359     static final int PFLAG3_VIEW_IS_ANIMATING_TRANSFORM = 0x1;
2360
2361     /**
2362      * Flag indicating that view has an alpha animation set on it. This is used to track whether an
2363      * animation is cleared between successive frames, in order to tell the associated
2364      * DisplayList to restore its alpha value.
2365      */
2366     static final int PFLAG3_VIEW_IS_ANIMATING_ALPHA = 0x2;
2367
2368     /**
2369      * Flag indicating that the view has been through at least one layout since it
2370      * was last attached to a window.
2371      */
2372     static final int PFLAG3_IS_LAID_OUT = 0x4;
2373
2374     /**
2375      * Flag indicating that a call to measure() was skipped and should be done
2376      * instead when layout() is invoked.
2377      */
2378     static final int PFLAG3_MEASURE_NEEDED_BEFORE_LAYOUT = 0x8;
2379
2380     /**
2381      * Flag indicating that an overridden method correctly called down to
2382      * the superclass implementation as required by the API spec.
2383      */
2384     static final int PFLAG3_CALLED_SUPER = 0x10;
2385
2386     /**
2387      * Flag indicating that we're in the process of applying window insets.
2388      */
2389     static final int PFLAG3_APPLYING_INSETS = 0x20;
2390
2391     /**
2392      * Flag indicating that we're in the process of fitting system windows using the old method.
2393      */
2394     static final int PFLAG3_FITTING_SYSTEM_WINDOWS = 0x40;
2395
2396     /**
2397      * Flag indicating that nested scrolling is enabled for this view.
2398      * The view will optionally cooperate with views up its parent chain to allow for
2399      * integrated nested scrolling along the same axis.
2400      */
2401     static final int PFLAG3_NESTED_SCROLLING_ENABLED = 0x80;
2402
2403     /**
2404      * Flag indicating that outline was invalidated and should be rebuilt the next time
2405      * the DisplayList is updated.
2406      */
2407     static final int PFLAG3_OUTLINE_INVALID = 0x100;
2408
2409     /* End of masks for mPrivateFlags3 */
2410
2411     static final int DRAG_MASK = PFLAG2_DRAG_CAN_ACCEPT | PFLAG2_DRAG_HOVERED;
2412
2413     /**
2414      * Always allow a user to over-scroll this view, provided it is a
2415      * view that can scroll.
2416      *
2417      * @see #getOverScrollMode()
2418      * @see #setOverScrollMode(int)
2419      */
2420     public static final int OVER_SCROLL_ALWAYS = 0;
2421
2422     /**
2423      * Allow a user to over-scroll this view only if the content is large
2424      * enough to meaningfully scroll, provided it is a view that can scroll.
2425      *
2426      * @see #getOverScrollMode()
2427      * @see #setOverScrollMode(int)
2428      */
2429     public static final int OVER_SCROLL_IF_CONTENT_SCROLLS = 1;
2430
2431     /**
2432      * Never allow a user to over-scroll this view.
2433      *
2434      * @see #getOverScrollMode()
2435      * @see #setOverScrollMode(int)
2436      */
2437     public static final int OVER_SCROLL_NEVER = 2;
2438
2439     /**
2440      * Special constant for {@link #setSystemUiVisibility(int)}: View has
2441      * requested the system UI (status bar) to be visible (the default).
2442      *
2443      * @see #setSystemUiVisibility(int)
2444      */
2445     public static final int SYSTEM_UI_FLAG_VISIBLE = 0;
2446
2447     /**
2448      * Flag for {@link #setSystemUiVisibility(int)}: View has requested the
2449      * system UI to enter an unobtrusive "low profile" mode.
2450      *
2451      * <p>This is for use in games, book readers, video players, or any other
2452      * "immersive" application where the usual system chrome is deemed too distracting.
2453      *
2454      * <p>In low profile mode, the status bar and/or navigation icons may dim.
2455      *
2456      * @see #setSystemUiVisibility(int)
2457      */
2458     public static final int SYSTEM_UI_FLAG_LOW_PROFILE = 0x00000001;
2459
2460     /**
2461      * Flag for {@link #setSystemUiVisibility(int)}: View has requested that the
2462      * system navigation be temporarily hidden.
2463      *
2464      * <p>This is an even less obtrusive state than that called for by
2465      * {@link #SYSTEM_UI_FLAG_LOW_PROFILE}; on devices that draw essential navigation controls
2466      * (Home, Back, and the like) on screen, <code>SYSTEM_UI_FLAG_HIDE_NAVIGATION</code> will cause
2467      * those to disappear. This is useful (in conjunction with the
2468      * {@link android.view.WindowManager.LayoutParams#FLAG_FULLSCREEN FLAG_FULLSCREEN} and
2469      * {@link android.view.WindowManager.LayoutParams#FLAG_LAYOUT_IN_SCREEN FLAG_LAYOUT_IN_SCREEN}
2470      * window flags) for displaying content using every last pixel on the display.
2471      *
2472      * <p>There is a limitation: because navigation controls are so important, the least user
2473      * interaction will cause them to reappear immediately.  When this happens, both
2474      * this flag and {@link #SYSTEM_UI_FLAG_FULLSCREEN} will be cleared automatically,
2475      * so that both elements reappear at the same time.
2476      *
2477      * @see #setSystemUiVisibility(int)
2478      */
2479     public static final int SYSTEM_UI_FLAG_HIDE_NAVIGATION = 0x00000002;
2480
2481     /**
2482      * Flag for {@link #setSystemUiVisibility(int)}: View has requested to go
2483      * into the normal fullscreen mode so that its content can take over the screen
2484      * while still allowing the user to interact with the application.
2485      *
2486      * <p>This has the same visual effect as
2487      * {@link android.view.WindowManager.LayoutParams#FLAG_FULLSCREEN
2488      * WindowManager.LayoutParams.FLAG_FULLSCREEN},
2489      * meaning that non-critical screen decorations (such as the status bar) will be
2490      * hidden while the user is in the View's window, focusing the experience on
2491      * that content.  Unlike the window flag, if you are using ActionBar in
2492      * overlay mode with {@link Window#FEATURE_ACTION_BAR_OVERLAY
2493      * Window.FEATURE_ACTION_BAR_OVERLAY}, then enabling this flag will also
2494      * hide the action bar.
2495      *
2496      * <p>This approach to going fullscreen is best used over the window flag when
2497      * it is a transient state -- that is, the application does this at certain
2498      * points in its user interaction where it wants to allow the user to focus
2499      * on content, but not as a continuous state.  For situations where the application
2500      * would like to simply stay full screen the entire time (such as a game that
2501      * wants to take over the screen), the
2502      * {@link android.view.WindowManager.LayoutParams#FLAG_FULLSCREEN window flag}
2503      * is usually a better approach.  The state set here will be removed by the system
2504      * in various situations (such as the user moving to another application) like
2505      * the other system UI states.
2506      *
2507      * <p>When using this flag, the application should provide some easy facility
2508      * for the user to go out of it.  A common example would be in an e-book
2509      * reader, where tapping on the screen brings back whatever screen and UI
2510      * decorations that had been hidden while the user was immersed in reading
2511      * the book.
2512      *
2513      * @see #setSystemUiVisibility(int)
2514      */
2515     public static final int SYSTEM_UI_FLAG_FULLSCREEN = 0x00000004;
2516
2517     /**
2518      * Flag for {@link #setSystemUiVisibility(int)}: When using other layout
2519      * flags, we would like a stable view of the content insets given to
2520      * {@link #fitSystemWindows(Rect)}.  This means that the insets seen there
2521      * will always represent the worst case that the application can expect
2522      * as a continuous state.  In the stock Android UI this is the space for
2523      * the system bar, nav bar, and status bar, but not more transient elements
2524      * such as an input method.
2525      *
2526      * The stable layout your UI sees is based on the system UI modes you can
2527      * switch to.  That is, if you specify {@link #SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN}
2528      * then you will get a stable layout for changes of the
2529      * {@link #SYSTEM_UI_FLAG_FULLSCREEN} mode; if you specify
2530      * {@link #SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN} and
2531      * {@link #SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION}, then you can transition
2532      * to {@link #SYSTEM_UI_FLAG_FULLSCREEN} and {@link #SYSTEM_UI_FLAG_HIDE_NAVIGATION}
2533      * with a stable layout.  (Note that you should avoid using
2534      * {@link #SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION} by itself.)
2535      *
2536      * If you have set the window flag {@link WindowManager.LayoutParams#FLAG_FULLSCREEN}
2537      * to hide the status bar (instead of using {@link #SYSTEM_UI_FLAG_FULLSCREEN}),
2538      * then a hidden status bar will be considered a "stable" state for purposes
2539      * here.  This allows your UI to continually hide the status bar, while still
2540      * using the system UI flags to hide the action bar while still retaining
2541      * a stable layout.  Note that changing the window fullscreen flag will never
2542      * provide a stable layout for a clean transition.
2543      *
2544      * <p>If you are using ActionBar in
2545      * overlay mode with {@link Window#FEATURE_ACTION_BAR_OVERLAY
2546      * Window.FEATURE_ACTION_BAR_OVERLAY}, this flag will also impact the
2547      * insets it adds to those given to the application.
2548      */
2549     public static final int SYSTEM_UI_FLAG_LAYOUT_STABLE = 0x00000100;
2550
2551     /**
2552      * Flag for {@link #setSystemUiVisibility(int)}: View would like its window
2553      * to be layed out as if it has requested
2554      * {@link #SYSTEM_UI_FLAG_HIDE_NAVIGATION}, even if it currently hasn't.  This
2555      * allows it to avoid artifacts when switching in and out of that mode, at
2556      * the expense that some of its user interface may be covered by screen
2557      * decorations when they are shown.  You can perform layout of your inner
2558      * UI elements to account for the navigation system UI through the
2559      * {@link #fitSystemWindows(Rect)} method.
2560      */
2561     public static final int SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION = 0x00000200;
2562
2563     /**
2564      * Flag for {@link #setSystemUiVisibility(int)}: View would like its window
2565      * to be layed out as if it has requested
2566      * {@link #SYSTEM_UI_FLAG_FULLSCREEN}, even if it currently hasn't.  This
2567      * allows it to avoid artifacts when switching in and out of that mode, at
2568      * the expense that some of its user interface may be covered by screen
2569      * decorations when they are shown.  You can perform layout of your inner
2570      * UI elements to account for non-fullscreen system UI through the
2571      * {@link #fitSystemWindows(Rect)} method.
2572      */
2573     public static final int SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN = 0x00000400;
2574
2575     /**
2576      * Flag for {@link #setSystemUiVisibility(int)}: View would like to remain interactive when
2577      * hiding the navigation bar with {@link #SYSTEM_UI_FLAG_HIDE_NAVIGATION}.  If this flag is
2578      * not set, {@link #SYSTEM_UI_FLAG_HIDE_NAVIGATION} will be force cleared by the system on any
2579      * user interaction.
2580      * <p>Since this flag is a modifier for {@link #SYSTEM_UI_FLAG_HIDE_NAVIGATION}, it only
2581      * has an effect when used in combination with that flag.</p>
2582      */
2583     public static final int SYSTEM_UI_FLAG_IMMERSIVE = 0x00000800;
2584
2585     /**
2586      * Flag for {@link #setSystemUiVisibility(int)}: View would like to remain interactive when
2587      * hiding the status bar with {@link #SYSTEM_UI_FLAG_FULLSCREEN} and/or hiding the navigation
2588      * bar with {@link #SYSTEM_UI_FLAG_HIDE_NAVIGATION}.  Use this flag to create an immersive
2589      * experience while also hiding the system bars.  If this flag is not set,
2590      * {@link #SYSTEM_UI_FLAG_HIDE_NAVIGATION} will be force cleared by the system on any user
2591      * interaction, and {@link #SYSTEM_UI_FLAG_FULLSCREEN} will be force-cleared by the system
2592      * if the user swipes from the top of the screen.
2593      * <p>When system bars are hidden in immersive mode, they can be revealed temporarily with
2594      * system gestures, such as swiping from the top of the screen.  These transient system bars
2595      * will overlay app’s content, may have some degree of transparency, and will automatically
2596      * hide after a short timeout.
2597      * </p><p>Since this flag is a modifier for {@link #SYSTEM_UI_FLAG_FULLSCREEN} and
2598      * {@link #SYSTEM_UI_FLAG_HIDE_NAVIGATION}, it only has an effect when used in combination
2599      * with one or both of those flags.</p>
2600      */
2601     public static final int SYSTEM_UI_FLAG_IMMERSIVE_STICKY = 0x00001000;
2602
2603     /**
2604      * @deprecated Use {@link #SYSTEM_UI_FLAG_LOW_PROFILE} instead.
2605      */
2606     public static final int STATUS_BAR_HIDDEN = SYSTEM_UI_FLAG_LOW_PROFILE;
2607
2608     /**
2609      * @deprecated Use {@link #SYSTEM_UI_FLAG_VISIBLE} instead.
2610      */
2611     public static final int STATUS_BAR_VISIBLE = SYSTEM_UI_FLAG_VISIBLE;
2612
2613     /**
2614      * @hide
2615      *
2616      * NOTE: This flag may only be used in subtreeSystemUiVisibility. It is masked
2617      * out of the public fields to keep the undefined bits out of the developer's way.
2618      *
2619      * Flag to make the status bar not expandable.  Unless you also
2620      * set {@link #STATUS_BAR_DISABLE_NOTIFICATION_ICONS}, new notifications will continue to show.
2621      */
2622     public static final int STATUS_BAR_DISABLE_EXPAND = 0x00010000;
2623
2624     /**
2625      * @hide
2626      *
2627      * NOTE: This flag may only be used in subtreeSystemUiVisibility. It is masked
2628      * out of the public fields to keep the undefined bits out of the developer's way.
2629      *
2630      * Flag to hide notification icons and scrolling ticker text.
2631      */
2632     public static final int STATUS_BAR_DISABLE_NOTIFICATION_ICONS = 0x00020000;
2633
2634     /**
2635      * @hide
2636      *
2637      * NOTE: This flag may only be used in subtreeSystemUiVisibility. It is masked
2638      * out of the public fields to keep the undefined bits out of the developer's way.
2639      *
2640      * Flag to disable incoming notification alerts.  This will not block
2641      * icons, but it will block sound, vibrating and other visual or aural notifications.
2642      */
2643     public static final int STATUS_BAR_DISABLE_NOTIFICATION_ALERTS = 0x00040000;
2644
2645     /**
2646      * @hide
2647      *
2648      * NOTE: This flag may only be used in subtreeSystemUiVisibility. It is masked
2649      * out of the public fields to keep the undefined bits out of the developer's way.
2650      *
2651      * Flag to hide only the scrolling ticker.  Note that
2652      * {@link #STATUS_BAR_DISABLE_NOTIFICATION_ICONS} implies
2653      * {@link #STATUS_BAR_DISABLE_NOTIFICATION_TICKER}.
2654      */
2655     public static final int STATUS_BAR_DISABLE_NOTIFICATION_TICKER = 0x00080000;
2656
2657     /**
2658      * @hide
2659      *
2660      * NOTE: This flag may only be used in subtreeSystemUiVisibility. It is masked
2661      * out of the public fields to keep the undefined bits out of the developer's way.
2662      *
2663      * Flag to hide the center system info area.
2664      */
2665     public static final int STATUS_BAR_DISABLE_SYSTEM_INFO = 0x00100000;
2666
2667     /**
2668      * @hide
2669      *
2670      * NOTE: This flag may only be used in subtreeSystemUiVisibility. It is masked
2671      * out of the public fields to keep the undefined bits out of the developer's way.
2672      *
2673      * Flag to hide only the home button.  Don't use this
2674      * unless you're a special part of the system UI (i.e., setup wizard, keyguard).
2675      */
2676     public static final int STATUS_BAR_DISABLE_HOME = 0x00200000;
2677
2678     /**
2679      * @hide
2680      *
2681      * NOTE: This flag may only be used in subtreeSystemUiVisibility. It is masked
2682      * out of the public fields to keep the undefined bits out of the developer's way.
2683      *
2684      * Flag to hide only the back button. Don't use this
2685      * unless you're a special part of the system UI (i.e., setup wizard, keyguard).
2686      */
2687     public static final int STATUS_BAR_DISABLE_BACK = 0x00400000;
2688
2689     /**
2690      * @hide
2691      *
2692      * NOTE: This flag may only be used in subtreeSystemUiVisibility. It is masked
2693      * out of the public fields to keep the undefined bits out of the developer's way.
2694      *
2695      * Flag to hide only the clock.  You might use this if your activity has
2696      * its own clock making the status bar's clock redundant.
2697      */
2698     public static final int STATUS_BAR_DISABLE_CLOCK = 0x00800000;
2699
2700     /**
2701      * @hide
2702      *
2703      * NOTE: This flag may only be used in subtreeSystemUiVisibility. It is masked
2704      * out of the public fields to keep the undefined bits out of the developer's way.
2705      *
2706      * Flag to hide only the recent apps button. Don't use this
2707      * unless you're a special part of the system UI (i.e., setup wizard, keyguard).
2708      */
2709     public static final int STATUS_BAR_DISABLE_RECENT = 0x01000000;
2710
2711     /**
2712      * @hide
2713      *
2714      * NOTE: This flag may only be used in subtreeSystemUiVisibility. It is masked
2715      * out of the public fields to keep the undefined bits out of the developer's way.
2716      *
2717      * Flag to disable the global search gesture. Don't use this
2718      * unless you're a special part of the system UI (i.e., setup wizard, keyguard).
2719      */
2720     public static final int STATUS_BAR_DISABLE_SEARCH = 0x02000000;
2721
2722     /**
2723      * @hide
2724      *
2725      * NOTE: This flag may only be used in subtreeSystemUiVisibility. It is masked
2726      * out of the public fields to keep the undefined bits out of the developer's way.
2727      *
2728      * Flag to specify that the status bar is displayed in transient mode.
2729      */
2730     public static final int STATUS_BAR_TRANSIENT = 0x04000000;
2731
2732     /**
2733      * @hide
2734      *
2735      * NOTE: This flag may only be used in subtreeSystemUiVisibility. It is masked
2736      * out of the public fields to keep the undefined bits out of the developer's way.
2737      *
2738      * Flag to specify that the navigation bar is displayed in transient mode.
2739      */
2740     public static final int NAVIGATION_BAR_TRANSIENT = 0x08000000;
2741
2742     /**
2743      * @hide
2744      *
2745      * NOTE: This flag may only be used in subtreeSystemUiVisibility. It is masked
2746      * out of the public fields to keep the undefined bits out of the developer's way.
2747      *
2748      * Flag to specify that the hidden status bar would like to be shown.
2749      */
2750     public static final int STATUS_BAR_UNHIDE = 0x10000000;
2751
2752     /**
2753      * @hide
2754      *
2755      * NOTE: This flag may only be used in subtreeSystemUiVisibility. It is masked
2756      * out of the public fields to keep the undefined bits out of the developer's way.
2757      *
2758      * Flag to specify that the hidden navigation bar would like to be shown.
2759      */
2760     public static final int NAVIGATION_BAR_UNHIDE = 0x20000000;
2761
2762     /**
2763      * @hide
2764      *
2765      * NOTE: This flag may only be used in subtreeSystemUiVisibility. It is masked
2766      * out of the public fields to keep the undefined bits out of the developer's way.
2767      *
2768      * Flag to specify that the status bar is displayed in translucent mode.
2769      */
2770     public static final int STATUS_BAR_TRANSLUCENT = 0x40000000;
2771
2772     /**
2773      * @hide
2774      *
2775      * NOTE: This flag may only be used in subtreeSystemUiVisibility. It is masked
2776      * out of the public fields to keep the undefined bits out of the developer's way.
2777      *
2778      * Flag to specify that the navigation bar is displayed in translucent mode.
2779      */
2780     public static final int NAVIGATION_BAR_TRANSLUCENT = 0x80000000;
2781
2782     /**
2783      * @hide
2784      *
2785      * Whether Recents is visible or not.
2786      */
2787     public static final int RECENT_APPS_VISIBLE = 0x00004000;
2788
2789     /**
2790      * @hide
2791      *
2792      * Makes system ui transparent.
2793      */
2794     public static final int SYSTEM_UI_TRANSPARENT = 0x00008000;
2795
2796     /**
2797      * @hide
2798      */
2799     public static final int PUBLIC_STATUS_BAR_VISIBILITY_MASK = 0x00003FFF;
2800
2801     /**
2802      * These are the system UI flags that can be cleared by events outside
2803      * of an application.  Currently this is just the ability to tap on the
2804      * screen while hiding the navigation bar to have it return.
2805      * @hide
2806      */
2807     public static final int SYSTEM_UI_CLEARABLE_FLAGS =
2808             SYSTEM_UI_FLAG_LOW_PROFILE | SYSTEM_UI_FLAG_HIDE_NAVIGATION
2809             | SYSTEM_UI_FLAG_FULLSCREEN;
2810
2811     /**
2812      * Flags that can impact the layout in relation to system UI.
2813      */
2814     public static final int SYSTEM_UI_LAYOUT_FLAGS =
2815             SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION
2816             | SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN;
2817
2818     /** @hide */
2819     @IntDef(flag = true,
2820             value = { FIND_VIEWS_WITH_TEXT, FIND_VIEWS_WITH_CONTENT_DESCRIPTION })
2821     @Retention(RetentionPolicy.SOURCE)
2822     public @interface FindViewFlags {}
2823
2824     /**
2825      * Find views that render the specified text.
2826      *
2827      * @see #findViewsWithText(ArrayList, CharSequence, int)
2828      */
2829     public static final int FIND_VIEWS_WITH_TEXT = 0x00000001;
2830
2831     /**
2832      * Find find views that contain the specified content description.
2833      *
2834      * @see #findViewsWithText(ArrayList, CharSequence, int)
2835      */
2836     public static final int FIND_VIEWS_WITH_CONTENT_DESCRIPTION = 0x00000002;
2837
2838     /**
2839      * Find views that contain {@link AccessibilityNodeProvider}. Such
2840      * a View is a root of virtual view hierarchy and may contain the searched
2841      * text. If this flag is set Views with providers are automatically
2842      * added and it is a responsibility of the client to call the APIs of
2843      * the provider to determine whether the virtual tree rooted at this View
2844      * contains the text, i.e. getting the list of {@link AccessibilityNodeInfo}s
2845      * representing the virtual views with this text.
2846      *
2847      * @see #findViewsWithText(ArrayList, CharSequence, int)
2848      *
2849      * @hide
2850      */
2851     public static final int FIND_VIEWS_WITH_ACCESSIBILITY_NODE_PROVIDERS = 0x00000004;
2852
2853     /**
2854      * The undefined cursor position.
2855      *
2856      * @hide
2857      */
2858     public static final int ACCESSIBILITY_CURSOR_POSITION_UNDEFINED = -1;
2859
2860     /**
2861      * Indicates that the screen has changed state and is now off.
2862      *
2863      * @see #onScreenStateChanged(int)
2864      */
2865     public static final int SCREEN_STATE_OFF = 0x0;
2866
2867     /**
2868      * Indicates that the screen has changed state and is now on.
2869      *
2870      * @see #onScreenStateChanged(int)
2871      */
2872     public static final int SCREEN_STATE_ON = 0x1;
2873
2874     /**
2875      * Indicates no axis of view scrolling.
2876      */
2877     public static final int SCROLL_AXIS_NONE = 0;
2878
2879     /**
2880      * Indicates scrolling along the horizontal axis.
2881      */
2882     public static final int SCROLL_AXIS_HORIZONTAL = 1 << 0;
2883
2884     /**
2885      * Indicates scrolling along the vertical axis.
2886      */
2887     public static final int SCROLL_AXIS_VERTICAL = 1 << 1;
2888
2889     /**
2890      * Controls the over-scroll mode for this view.
2891      * See {@link #overScrollBy(int, int, int, int, int, int, int, int, boolean)},
2892      * {@link #OVER_SCROLL_ALWAYS}, {@link #OVER_SCROLL_IF_CONTENT_SCROLLS},
2893      * and {@link #OVER_SCROLL_NEVER}.
2894      */
2895     private int mOverScrollMode;
2896
2897     /**
2898      * The parent this view is attached to.
2899      * {@hide}
2900      *
2901      * @see #getParent()
2902      */
2903     protected ViewParent mParent;
2904
2905     /**
2906      * {@hide}
2907      */
2908     AttachInfo mAttachInfo;
2909
2910     /**
2911      * {@hide}
2912      */
2913     @ViewDebug.ExportedProperty(flagMapping = {
2914         @ViewDebug.FlagToString(mask = PFLAG_FORCE_LAYOUT, equals = PFLAG_FORCE_LAYOUT,
2915                 name = "FORCE_LAYOUT"),
2916         @ViewDebug.FlagToString(mask = PFLAG_LAYOUT_REQUIRED, equals = PFLAG_LAYOUT_REQUIRED,
2917                 name = "LAYOUT_REQUIRED"),
2918         @ViewDebug.FlagToString(mask = PFLAG_DRAWING_CACHE_VALID, equals = PFLAG_DRAWING_CACHE_VALID,
2919             name = "DRAWING_CACHE_INVALID", outputIf = false),
2920         @ViewDebug.FlagToString(mask = PFLAG_DRAWN, equals = PFLAG_DRAWN, name = "DRAWN", outputIf = true),
2921         @ViewDebug.FlagToString(mask = PFLAG_DRAWN, equals = PFLAG_DRAWN, name = "NOT_DRAWN", outputIf = false),
2922         @ViewDebug.FlagToString(mask = PFLAG_DIRTY_MASK, equals = PFLAG_DIRTY_OPAQUE, name = "DIRTY_OPAQUE"),
2923         @ViewDebug.FlagToString(mask = PFLAG_DIRTY_MASK, equals = PFLAG_DIRTY, name = "DIRTY")
2924     }, formatToHexString = true)
2925     int mPrivateFlags;
2926     int mPrivateFlags2;
2927     int mPrivateFlags3;
2928
2929     /**
2930      * This view's request for the visibility of the status bar.
2931      * @hide
2932      */
2933     @ViewDebug.ExportedProperty(flagMapping = {
2934         @ViewDebug.FlagToString(mask = SYSTEM_UI_FLAG_LOW_PROFILE,
2935                                 equals = SYSTEM_UI_FLAG_LOW_PROFILE,
2936                                 name = "SYSTEM_UI_FLAG_LOW_PROFILE", outputIf = true),
2937         @ViewDebug.FlagToString(mask = SYSTEM_UI_FLAG_HIDE_NAVIGATION,
2938                                 equals = SYSTEM_UI_FLAG_HIDE_NAVIGATION,
2939                                 name = "SYSTEM_UI_FLAG_HIDE_NAVIGATION", outputIf = true),
2940         @ViewDebug.FlagToString(mask = PUBLIC_STATUS_BAR_VISIBILITY_MASK,
2941                                 equals = SYSTEM_UI_FLAG_VISIBLE,
2942                                 name = "SYSTEM_UI_FLAG_VISIBLE", outputIf = true)
2943     }, formatToHexString = true)
2944     int mSystemUiVisibility;
2945
2946     /**
2947      * Reference count for transient state.
2948      * @see #setHasTransientState(boolean)
2949      */
2950     int mTransientStateCount = 0;
2951
2952     /**
2953      * Count of how many windows this view has been attached to.
2954      */
2955     int mWindowAttachCount;
2956
2957     /**
2958      * The layout parameters associated with this view and used by the parent
2959      * {@link android.view.ViewGroup} to determine how this view should be
2960      * laid out.
2961      * {@hide}
2962      */
2963     protected ViewGroup.LayoutParams mLayoutParams;
2964
2965     /**
2966      * The view flags hold various views states.
2967      * {@hide}
2968      */
2969     @ViewDebug.ExportedProperty(formatToHexString = true)
2970     int mViewFlags;
2971
2972     static class TransformationInfo {
2973         /**
2974          * The transform matrix for the View. This transform is calculated internally
2975          * based on the translation, rotation, and scale properties.
2976          *
2977          * Do *not* use this variable directly; instead call getMatrix(), which will
2978          * load the value from the View's RenderNode.
2979          */
2980         private final Matrix mMatrix = new Matrix();
2981
2982         /**
2983          * The inverse transform matrix for the View. This transform is calculated
2984          * internally based on the translation, rotation, and scale properties.
2985          *
2986          * Do *not* use this variable directly; instead call getInverseMatrix(),
2987          * which will load the value from the View's RenderNode.
2988          */
2989         private Matrix mInverseMatrix;
2990
2991         /**
2992          * The opacity of the View. This is a value from 0 to 1, where 0 means
2993          * completely transparent and 1 means completely opaque.
2994          */
2995         @ViewDebug.ExportedProperty
2996         float mAlpha = 1f;
2997
2998         /**
2999          * The opacity of the view as manipulated by the Fade transition. This is a hidden
3000          * property only used by transitions, which is composited with the other alpha
3001          * values to calculate the final visual alpha value.
3002          */
3003         float mTransitionAlpha = 1f;
3004     }
3005
3006     TransformationInfo mTransformationInfo;
3007
3008     /**
3009      * Current clip bounds. to which all drawing of this view are constrained.
3010      */
3011     Rect mClipBounds = null;
3012
3013     private boolean mLastIsOpaque;
3014
3015     /**
3016      * The distance in pixels from the left edge of this view's parent
3017      * to the left edge of this view.
3018      * {@hide}
3019      */
3020     @ViewDebug.ExportedProperty(category = "layout")
3021     protected int mLeft;
3022     /**
3023      * The distance in pixels from the left edge of this view's parent
3024      * to the right edge of this view.
3025      * {@hide}
3026      */
3027     @ViewDebug.ExportedProperty(category = "layout")
3028     protected int mRight;
3029     /**
3030      * The distance in pixels from the top edge of this view's parent
3031      * to the top edge of this view.
3032      * {@hide}
3033      */
3034     @ViewDebug.ExportedProperty(category = "layout")
3035     protected int mTop;
3036     /**
3037      * The distance in pixels from the top edge of this view's parent
3038      * to the bottom edge of this view.
3039      * {@hide}
3040      */
3041     @ViewDebug.ExportedProperty(category = "layout")
3042     protected int mBottom;
3043
3044     /**
3045      * The offset, in pixels, by which the content of this view is scrolled
3046      * horizontally.
3047      * {@hide}
3048      */
3049     @ViewDebug.ExportedProperty(category = "scrolling")
3050     protected int mScrollX;
3051     /**
3052      * The offset, in pixels, by which the content of this view is scrolled
3053      * vertically.
3054      * {@hide}
3055      */
3056     @ViewDebug.ExportedProperty(category = "scrolling")
3057     protected int mScrollY;
3058
3059     /**
3060      * The left padding in pixels, that is the distance in pixels between the
3061      * left edge of this view and the left edge of its content.
3062      * {@hide}
3063      */
3064     @ViewDebug.ExportedProperty(category = "padding")
3065     protected int mPaddingLeft = 0;
3066     /**
3067      * The right padding in pixels, that is the distance in pixels between the
3068      * right edge of this view and the right edge of its content.
3069      * {@hide}
3070      */
3071     @ViewDebug.ExportedProperty(category = "padding")
3072     protected int mPaddingRight = 0;
3073     /**
3074      * The top padding in pixels, that is the distance in pixels between the
3075      * top edge of this view and the top edge of its content.
3076      * {@hide}
3077      */
3078     @ViewDebug.ExportedProperty(category = "padding")
3079     protected int mPaddingTop;
3080     /**
3081      * The bottom padding in pixels, that is the distance in pixels between the
3082      * bottom edge of this view and the bottom edge of its content.
3083      * {@hide}
3084      */
3085     @ViewDebug.ExportedProperty(category = "padding")
3086     protected int mPaddingBottom;
3087
3088     /**
3089      * The layout insets in pixels, that is the distance in pixels between the
3090      * visible edges of this view its bounds.
3091      */
3092     private Insets mLayoutInsets;
3093
3094     /**
3095      * Briefly describes the view and is primarily used for accessibility support.
3096      */
3097     private CharSequence mContentDescription;
3098
3099     /**
3100      * Specifies the id of a view for which this view serves as a label for
3101      * accessibility purposes.
3102      */
3103     private int mLabelForId = View.NO_ID;
3104
3105     /**
3106      * Predicate for matching labeled view id with its label for
3107      * accessibility purposes.
3108      */
3109     private MatchLabelForPredicate mMatchLabelForPredicate;
3110
3111     /**
3112      * Predicate for matching a view by its id.
3113      */
3114     private MatchIdPredicate mMatchIdPredicate;
3115
3116     /**
3117      * Cache the paddingRight set by the user to append to the scrollbar's size.
3118      *
3119      * @hide
3120      */
3121     @ViewDebug.ExportedProperty(category = "padding")
3122     protected int mUserPaddingRight;
3123
3124     /**
3125      * Cache the paddingBottom set by the user to append to the scrollbar's size.
3126      *
3127      * @hide
3128      */
3129     @ViewDebug.ExportedProperty(category = "padding")
3130     protected int mUserPaddingBottom;
3131
3132     /**
3133      * Cache the paddingLeft set by the user to append to the scrollbar's size.
3134      *
3135      * @hide
3136      */
3137     @ViewDebug.ExportedProperty(category = "padding")
3138     protected int mUserPaddingLeft;
3139
3140     /**
3141      * Cache the paddingStart set by the user to append to the scrollbar's size.
3142      *
3143      */
3144     @ViewDebug.ExportedProperty(category = "padding")
3145     int mUserPaddingStart;
3146
3147     /**
3148      * Cache the paddingEnd set by the user to append to the scrollbar's size.
3149      *
3150      */
3151     @ViewDebug.ExportedProperty(category = "padding")
3152     int mUserPaddingEnd;
3153
3154     /**
3155      * Cache initial left padding.
3156      *
3157      * @hide
3158      */
3159     int mUserPaddingLeftInitial;
3160
3161     /**
3162      * Cache initial right padding.
3163      *
3164      * @hide
3165      */
3166     int mUserPaddingRightInitial;
3167
3168     /**
3169      * Default undefined padding
3170      */
3171     private static final int UNDEFINED_PADDING = Integer.MIN_VALUE;
3172
3173     /**
3174      * Cache if a left padding has been defined
3175      */
3176     private boolean mLeftPaddingDefined = false;
3177
3178     /**
3179      * Cache if a right padding has been defined
3180      */
3181     private boolean mRightPaddingDefined = false;
3182
3183     /**
3184      * @hide
3185      */
3186     int mOldWidthMeasureSpec = Integer.MIN_VALUE;
3187     /**
3188      * @hide
3189      */
3190     int mOldHeightMeasureSpec = Integer.MIN_VALUE;
3191
3192     private LongSparseLongArray mMeasureCache;
3193
3194     @ViewDebug.ExportedProperty(deepExport = true, prefix = "bg_")
3195     private Drawable mBackground;
3196     private TintInfo mBackgroundTint;
3197
3198     /**
3199      * RenderNode used for backgrounds.
3200      * <p>
3201      * When non-null and valid, this is expected to contain an up-to-date copy
3202      * of the background drawable. It is cleared on temporary detach, and reset
3203      * on cleanup.
3204      */
3205     private RenderNode mBackgroundRenderNode;
3206
3207     private int mBackgroundResource;
3208     private boolean mBackgroundSizeChanged;
3209
3210     private String mTransitionName;
3211
3212     private static class TintInfo {
3213         ColorStateList mTintList;
3214         PorterDuff.Mode mTintMode;
3215         boolean mHasTintMode;
3216         boolean mHasTintList;
3217     }
3218
3219     static class ListenerInfo {
3220         /**
3221          * Listener used to dispatch focus change events.
3222          * This field should be made private, so it is hidden from the SDK.
3223          * {@hide}
3224          */
3225         protected OnFocusChangeListener mOnFocusChangeListener;
3226
3227         /**
3228          * Listeners for layout change events.
3229          */
3230         private ArrayList<OnLayoutChangeListener> mOnLayoutChangeListeners;
3231
3232         /**
3233          * Listeners for attach events.
3234          */
3235         private CopyOnWriteArrayList<OnAttachStateChangeListener> mOnAttachStateChangeListeners;
3236
3237         /**
3238          * Listener used to dispatch click events.
3239          * This field should be made private, so it is hidden from the SDK.
3240          * {@hide}
3241          */
3242         public OnClickListener mOnClickListener;
3243
3244         /**
3245          * Listener used to dispatch long click events.
3246          * This field should be made private, so it is hidden from the SDK.
3247          * {@hide}
3248          */
3249         protected OnLongClickListener mOnLongClickListener;
3250
3251         /**
3252          * Listener used to build the context menu.
3253          * This field should be made private, so it is hidden from the SDK.
3254          * {@hide}
3255          */
3256         protected OnCreateContextMenuListener mOnCreateContextMenuListener;
3257
3258         private OnKeyListener mOnKeyListener;
3259
3260         private OnTouchListener mOnTouchListener;
3261
3262         private OnHoverListener mOnHoverListener;
3263
3264         private OnGenericMotionListener mOnGenericMotionListener;
3265
3266         private OnDragListener mOnDragListener;
3267
3268         private OnSystemUiVisibilityChangeListener mOnSystemUiVisibilityChangeListener;
3269
3270         OnApplyWindowInsetsListener mOnApplyWindowInsetsListener;
3271     }
3272
3273     ListenerInfo mListenerInfo;
3274
3275     /**
3276      * The application environment this view lives in.
3277      * This field should be made private, so it is hidden from the SDK.
3278      * {@hide}
3279      */
3280     @ViewDebug.ExportedProperty(deepExport = true)
3281     protected Context mContext;
3282
3283     private final Resources mResources;
3284
3285     private ScrollabilityCache mScrollCache;
3286
3287     private int[] mDrawableState = null;
3288
3289     ViewOutlineProvider mOutlineProvider = ViewOutlineProvider.BACKGROUND;
3290
3291     /**
3292      * Animator that automatically runs based on state changes.
3293      */
3294     private StateListAnimator mStateListAnimator;
3295
3296     /**
3297      * When this view has focus and the next focus is {@link #FOCUS_LEFT},
3298      * the user may specify which view to go to next.
3299      */
3300     private int mNextFocusLeftId = View.NO_ID;
3301
3302     /**
3303      * When this view has focus and the next focus is {@link #FOCUS_RIGHT},
3304      * the user may specify which view to go to next.
3305      */
3306     private int mNextFocusRightId = View.NO_ID;
3307
3308     /**
3309      * When this view has focus and the next focus is {@link #FOCUS_UP},
3310      * the user may specify which view to go to next.
3311      */
3312     private int mNextFocusUpId = View.NO_ID;
3313
3314     /**
3315      * When this view has focus and the next focus is {@link #FOCUS_DOWN},
3316      * the user may specify which view to go to next.
3317      */
3318     private int mNextFocusDownId = View.NO_ID;
3319
3320     /**
3321      * When this view has focus and the next focus is {@link #FOCUS_FORWARD},
3322      * the user may specify which view to go to next.
3323      */
3324     int mNextFocusForwardId = View.NO_ID;
3325
3326     private CheckForLongPress mPendingCheckForLongPress;
3327     private CheckForTap mPendingCheckForTap = null;
3328     private PerformClick mPerformClick;
3329     private SendViewScrolledAccessibilityEvent mSendViewScrolledAccessibilityEvent;
3330
3331     private UnsetPressedState mUnsetPressedState;
3332
3333     /**
3334      * Whether the long press's action has been invoked.  The tap's action is invoked on the
3335      * up event while a long press is invoked as soon as the long press duration is reached, so
3336      * a long press could be performed before the tap is checked, in which case the tap's action
3337      * should not be invoked.
3338      */
3339     private boolean mHasPerformedLongPress;
3340
3341     /**
3342      * The minimum height of the view. We'll try our best to have the height
3343      * of this view to at least this amount.
3344      */
3345     @ViewDebug.ExportedProperty(category = "measurement")
3346     private int mMinHeight;
3347
3348     /**
3349      * The minimum width of the view. We'll try our best to have the width
3350      * of this view to at least this amount.
3351      */
3352     @ViewDebug.ExportedProperty(category = "measurement")
3353     private int mMinWidth;
3354
3355     /**
3356      * The delegate to handle touch events that are physically in this view
3357      * but should be handled by another view.
3358      */
3359     private TouchDelegate mTouchDelegate = null;
3360
3361     /**
3362      * Solid color to use as a background when creating the drawing cache. Enables
3363      * the cache to use 16 bit bitmaps instead of 32 bit.
3364      */
3365     private int mDrawingCacheBackgroundColor = 0;
3366
3367     /**
3368      * Special tree observer used when mAttachInfo is null.
3369      */
3370     private ViewTreeObserver mFloatingTreeObserver;
3371
3372     /**
3373      * Cache the touch slop from the context that created the view.
3374      */
3375     private int mTouchSlop;
3376
3377     /**
3378      * Object that handles automatic animation of view properties.
3379      */
3380     private ViewPropertyAnimator mAnimator = null;
3381
3382     /**
3383      * Flag indicating that a drag can cross window boundaries.  When
3384      * {@link #startDrag(ClipData, DragShadowBuilder, Object, int)} is called
3385      * with this flag set, all visible applications will be able to participate
3386      * in the drag operation and receive the dragged content.
3387      *
3388      * @hide
3389      */
3390     public static final int DRAG_FLAG_GLOBAL = 1;
3391
3392     /**
3393      * Vertical scroll factor cached by {@link #getVerticalScrollFactor}.
3394      */
3395     private float mVerticalScrollFactor;
3396
3397     /**
3398      * Position of the vertical scroll bar.
3399      */
3400     private int mVerticalScrollbarPosition;
3401
3402     /**
3403      * Position the scroll bar at the default position as determined by the system.
3404      */
3405     public static final int SCROLLBAR_POSITION_DEFAULT = 0;
3406
3407     /**
3408      * Position the scroll bar along the left edge.
3409      */
3410     public static final int SCROLLBAR_POSITION_LEFT = 1;
3411
3412     /**
3413      * Position the scroll bar along the right edge.
3414      */
3415     public static final int SCROLLBAR_POSITION_RIGHT = 2;
3416
3417     /**
3418      * Indicates that the view does not have a layer.
3419      *
3420      * @see #getLayerType()
3421      * @see #setLayerType(int, android.graphics.Paint)
3422      * @see #LAYER_TYPE_SOFTWARE
3423      * @see #LAYER_TYPE_HARDWARE
3424      */
3425     public static final int LAYER_TYPE_NONE = 0;
3426
3427     /**
3428      * <p>Indicates that the view has a software layer. A software layer is backed
3429      * by a bitmap and causes the view to be rendered using Android's software
3430      * rendering pipeline, even if hardware acceleration is enabled.</p>
3431      *
3432      * <p>Software layers have various usages:</p>
3433      * <p>When the application is not using hardware acceleration, a software layer
3434      * is useful to apply a specific color filter and/or blending mode and/or
3435      * translucency to a view and all its children.</p>
3436      * <p>When the application is using hardware acceleration, a software layer
3437      * is useful to render drawing primitives not supported by the hardware
3438      * accelerated pipeline. It can also be used to cache a complex view tree
3439      * into a texture and reduce the complexity of drawing operations. For instance,
3440      * when animating a complex view tree with a translation, a software layer can
3441      * be used to render the view tree only once.</p>
3442      * <p>Software layers should be avoided when the affected view tree updates
3443      * often. Every update will require to re-render the software layer, which can
3444      * potentially be slow (particularly when hardware acceleration is turned on
3445      * since the layer will have to be uploaded into a hardware texture after every
3446      * update.)</p>
3447      *
3448      * @see #getLayerType()
3449      * @see #setLayerType(int, android.graphics.Paint)
3450      * @see #LAYER_TYPE_NONE
3451      * @see #LAYER_TYPE_HARDWARE
3452      */
3453     public static final int LAYER_TYPE_SOFTWARE = 1;
3454
3455     /**
3456      * <p>Indicates that the view has a hardware layer. A hardware layer is backed
3457      * by a hardware specific texture (generally Frame Buffer Objects or FBO on
3458      * OpenGL hardware) and causes the view to be rendered using Android's hardware
3459      * rendering pipeline, but only if hardware acceleration is turned on for the
3460      * view hierarchy. When hardware acceleration is turned off, hardware layers
3461      * behave exactly as {@link #LAYER_TYPE_SOFTWARE software layers}.</p>
3462      *
3463      * <p>A hardware layer is useful to apply a specific color filter and/or
3464      * blending mode and/or translucency to a view and all its children.</p>
3465      * <p>A hardware layer can be used to cache a complex view tree into a
3466      * texture and reduce the complexity of drawing operations. For instance,
3467      * when animating a complex view tree with a translation, a hardware layer can
3468      * be used to render the view tree only once.</p>
3469      * <p>A hardware layer can also be used to increase the rendering quality when
3470      * rotation transformations are applied on a view. It can also be used to
3471      * prevent potential clipping issues when applying 3D transforms on a view.</p>
3472      *
3473      * @see #getLayerType()
3474      * @see #setLayerType(int, android.graphics.Paint)
3475      * @see #LAYER_TYPE_NONE
3476      * @see #LAYER_TYPE_SOFTWARE
3477      */
3478     public static final int LAYER_TYPE_HARDWARE = 2;
3479
3480     @ViewDebug.ExportedProperty(category = "drawing", mapping = {
3481             @ViewDebug.IntToString(from = LAYER_TYPE_NONE, to = "NONE"),
3482             @ViewDebug.IntToString(from = LAYER_TYPE_SOFTWARE, to = "SOFTWARE"),
3483             @ViewDebug.IntToString(from = LAYER_TYPE_HARDWARE, to = "HARDWARE")
3484     })
3485     int mLayerType = LAYER_TYPE_NONE;
3486     Paint mLayerPaint;
3487
3488     /**
3489      * Set to true when drawing cache is enabled and cannot be created.
3490      *
3491      * @hide
3492      */
3493     public boolean mCachingFailed;
3494     private Bitmap mDrawingCache;
3495     private Bitmap mUnscaledDrawingCache;
3496
3497     /**
3498      * RenderNode holding View properties, potentially holding a DisplayList of View content.
3499      * <p>
3500      * When non-null and valid, this is expected to contain an up-to-date copy
3501      * of the View content. Its DisplayList content is cleared on temporary detach and reset on
3502      * cleanup.
3503      */
3504     final RenderNode mRenderNode;
3505
3506     /**
3507      * Set to true when the view is sending hover accessibility events because it
3508      * is the innermost hovered view.
3509      */
3510     private boolean mSendingHoverAccessibilityEvents;
3511
3512     /**
3513      * Delegate for injecting accessibility functionality.
3514      */
3515     AccessibilityDelegate mAccessibilityDelegate;
3516
3517     /**
3518      * The view's overlay layer. Developers get a reference to the overlay via getOverlay()
3519      * and add/remove objects to/from the overlay directly through the Overlay methods.
3520      */
3521     ViewOverlay mOverlay;
3522
3523     /**
3524      * The currently active parent view for receiving delegated nested scrolling events.
3525      * This is set by {@link #startNestedScroll(int)} during a touch interaction and cleared
3526      * by {@link #stopNestedScroll()} at the same point where we clear
3527      * requestDisallowInterceptTouchEvent.
3528      */
3529     private ViewParent mNestedScrollingParent;
3530
3531     /**
3532      * Consistency verifier for debugging purposes.
3533      * @hide
3534      */
3535     protected final InputEventConsistencyVerifier mInputEventConsistencyVerifier =
3536             InputEventConsistencyVerifier.isInstrumentationEnabled() ?
3537                     new InputEventConsistencyVerifier(this, 0) : null;
3538
3539     private static final AtomicInteger sNextGeneratedId = new AtomicInteger(1);
3540
3541     private int[] mTempNestedScrollConsumed;
3542
3543     /**
3544      * An overlay is going to draw this View instead of being drawn as part of this
3545      * View's parent. mGhostView is the View in the Overlay that must be invalidated
3546      * when this view is invalidated.
3547      */
3548     GhostView mGhostView;
3549
3550     /**
3551      * Holds pairs of adjacent attribute data: attribute name followed by its value.
3552      * @hide
3553      */
3554     @ViewDebug.ExportedProperty(category = "attributes", hasAdjacentMapping = true)
3555     public String[] mAttributes;
3556
3557     /**
3558      * Maps a Resource id to its name.
3559      */
3560     private static SparseArray<String> mAttributeMap;
3561
3562     /**
3563      * Simple constructor to use when creating a view from code.
3564      *
3565      * @param context The Context the view is running in, through which it can
3566      *        access the current theme, resources, etc.
3567      */
3568     public View(Context context) {
3569         mContext = context;
3570         mResources = context != null ? context.getResources() : null;
3571         mViewFlags = SOUND_EFFECTS_ENABLED | HAPTIC_FEEDBACK_ENABLED;
3572         // Set some flags defaults
3573         mPrivateFlags2 =
3574                 (LAYOUT_DIRECTION_DEFAULT << PFLAG2_LAYOUT_DIRECTION_MASK_SHIFT) |
3575                 (TEXT_DIRECTION_DEFAULT << PFLAG2_TEXT_DIRECTION_MASK_SHIFT) |
3576                 (PFLAG2_TEXT_DIRECTION_RESOLVED_DEFAULT) |
3577                 (TEXT_ALIGNMENT_DEFAULT << PFLAG2_TEXT_ALIGNMENT_MASK_SHIFT) |
3578                 (PFLAG2_TEXT_ALIGNMENT_RESOLVED_DEFAULT) |
3579                 (IMPORTANT_FOR_ACCESSIBILITY_DEFAULT << PFLAG2_IMPORTANT_FOR_ACCESSIBILITY_SHIFT);
3580         mTouchSlop = ViewConfiguration.get(context).getScaledTouchSlop();
3581         setOverScrollMode(OVER_SCROLL_IF_CONTENT_SCROLLS);
3582         mUserPaddingStart = UNDEFINED_PADDING;
3583         mUserPaddingEnd = UNDEFINED_PADDING;
3584         mRenderNode = RenderNode.create(getClass().getName(), this);
3585
3586         if (!sCompatibilityDone && context != null) {
3587             final int targetSdkVersion = context.getApplicationInfo().targetSdkVersion;
3588
3589             // Older apps may need this compatibility hack for measurement.
3590             sUseBrokenMakeMeasureSpec = targetSdkVersion <= JELLY_BEAN_MR1;
3591
3592             // Older apps expect onMeasure() to always be called on a layout pass, regardless
3593             // of whether a layout was requested on that View.
3594             sIgnoreMeasureCache = targetSdkVersion < KITKAT;
3595
3596             sCompatibilityDone = true;
3597         }
3598     }
3599
3600     /**
3601      * Constructor that is called when inflating a view from XML. This is called
3602      * when a view is being constructed from an XML file, supplying attributes
3603      * that were specified in the XML file. This version uses a default style of
3604      * 0, so the only attribute values applied are those in the Context's Theme
3605      * and the given AttributeSet.
3606      *
3607      * <p>
3608      * The method onFinishInflate() will be called after all children have been
3609      * added.
3610      *
3611      * @param context The Context the view is running in, through which it can
3612      *        access the current theme, resources, etc.
3613      * @param attrs The attributes of the XML tag that is inflating the view.
3614      * @see #View(Context, AttributeSet, int)
3615      */
3616     public View(Context context, AttributeSet attrs) {
3617         this(context, attrs, 0);
3618     }
3619
3620     /**
3621      * Perform inflation from XML and apply a class-specific base style from a
3622      * theme attribute. This constructor of View allows subclasses to use their
3623      * own base style when they are inflating. For example, a Button class's
3624      * constructor would call this version of the super class constructor and
3625      * supply <code>R.attr.buttonStyle</code> for <var>defStyleAttr</var>; this
3626      * allows the theme's button style to modify all of the base view attributes
3627      * (in particular its background) as well as the Button class's attributes.
3628      *
3629      * @param context The Context the view is running in, through which it can
3630      *        access the current theme, resources, etc.
3631      * @param attrs The attributes of the XML tag that is inflating the view.
3632      * @param defStyleAttr An attribute in the current theme that contains a
3633      *        reference to a style resource that supplies default values for
3634      *        the view. Can be 0 to not look for defaults.
3635      * @see #View(Context, AttributeSet)
3636      */
3637     public View(Context context, AttributeSet attrs, int defStyleAttr) {
3638         this(context, attrs, defStyleAttr, 0);
3639     }
3640
3641     /**
3642      * Perform inflation from XML and apply a class-specific base style from a
3643      * theme attribute or style resource. This constructor of View allows
3644      * subclasses to use their own base style when they are inflating.
3645      * <p>
3646      * When determining the final value of a particular attribute, there are
3647      * four inputs that come into play:
3648      * <ol>
3649      * <li>Any attribute values in the given AttributeSet.
3650      * <li>The style resource specified in the AttributeSet (named "style").
3651      * <li>The default style specified by <var>defStyleAttr</var>.
3652      * <li>The default style specified by <var>defStyleRes</var>.
3653      * <li>The base values in this theme.
3654      * </ol>
3655      * <p>
3656      * Each of these inputs is considered in-order, with the first listed taking
3657      * precedence over the following ones. In other words, if in the
3658      * AttributeSet you have supplied <code>&lt;Button * textColor="#ff000000"&gt;</code>
3659      * , then the button's text will <em>always</em> be black, regardless of
3660      * what is specified in any of the styles.
3661      *
3662      * @param context The Context the view is running in, through which it can
3663      *        access the current theme, resources, etc.
3664      * @param attrs The attributes of the XML tag that is inflating the view.
3665      * @param defStyleAttr An attribute in the current theme that contains a
3666      *        reference to a style resource that supplies default values for
3667      *        the view. Can be 0 to not look for defaults.
3668      * @param defStyleRes A resource identifier of a style resource that
3669      *        supplies default values for the view, used only if
3670      *        defStyleAttr is 0 or can not be found in the theme. Can be 0
3671      *        to not look for defaults.
3672      * @see #View(Context, AttributeSet, int)
3673      */
3674     public View(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
3675         this(context);
3676
3677         final TypedArray a = context.obtainStyledAttributes(
3678                 attrs, com.android.internal.R.styleable.View, defStyleAttr, defStyleRes);
3679
3680         if (mDebugViewAttributes) {
3681             saveAttributeData(attrs, a);
3682         }
3683
3684         Drawable background = null;
3685
3686         int leftPadding = -1;
3687         int topPadding = -1;
3688         int rightPadding = -1;
3689         int bottomPadding = -1;
3690         int startPadding = UNDEFINED_PADDING;
3691         int endPadding = UNDEFINED_PADDING;
3692
3693         int padding = -1;
3694
3695         int viewFlagValues = 0;
3696         int viewFlagMasks = 0;
3697
3698         boolean setScrollContainer = false;
3699
3700         int x = 0;
3701         int y = 0;
3702
3703         float tx = 0;
3704         float ty = 0;
3705         float tz = 0;
3706         float elevation = 0;
3707         float rotation = 0;
3708         float rotationX = 0;
3709         float rotationY = 0;
3710         float sx = 1f;
3711         float sy = 1f;
3712         boolean transformSet = false;
3713
3714         int scrollbarStyle = SCROLLBARS_INSIDE_OVERLAY;
3715         int overScrollMode = mOverScrollMode;
3716         boolean initializeScrollbars = false;
3717
3718         boolean startPaddingDefined = false;
3719         boolean endPaddingDefined = false;
3720         boolean leftPaddingDefined = false;
3721         boolean rightPaddingDefined = false;
3722
3723         final int targetSdkVersion = context.getApplicationInfo().targetSdkVersion;
3724
3725         final int N = a.getIndexCount();
3726         for (int i = 0; i < N; i++) {
3727             int attr = a.getIndex(i);
3728             switch (attr) {
3729                 case com.android.internal.R.styleable.View_background:
3730                     background = a.getDrawable(attr);
3731                     break;
3732                 case com.android.internal.R.styleable.View_padding:
3733                     padding = a.getDimensionPixelSize(attr, -1);
3734                     mUserPaddingLeftInitial = padding;
3735                     mUserPaddingRightInitial = padding;
3736                     leftPaddingDefined = true;
3737                     rightPaddingDefined = true;
3738                     break;
3739                  case com.android.internal.R.styleable.View_paddingLeft:
3740                     leftPadding = a.getDimensionPixelSize(attr, -1);
3741                     mUserPaddingLeftInitial = leftPadding;
3742                     leftPaddingDefined = true;
3743                     break;
3744                 case com.android.internal.R.styleable.View_paddingTop:
3745                     topPadding = a.getDimensionPixelSize(attr, -1);
3746                     break;
3747                 case com.android.internal.R.styleable.View_paddingRight:
3748                     rightPadding = a.getDimensionPixelSize(attr, -1);
3749                     mUserPaddingRightInitial = rightPadding;
3750                     rightPaddingDefined = true;
3751                     break;
3752                 case com.android.internal.R.styleable.View_paddingBottom:
3753                     bottomPadding = a.getDimensionPixelSize(attr, -1);
3754                     break;
3755                 case com.android.internal.R.styleable.View_paddingStart:
3756                     startPadding = a.getDimensionPixelSize(attr, UNDEFINED_PADDING);
3757                     startPaddingDefined = (startPadding != UNDEFINED_PADDING);
3758                     break;
3759                 case com.android.internal.R.styleable.View_paddingEnd:
3760                     endPadding = a.getDimensionPixelSize(attr, UNDEFINED_PADDING);
3761                     endPaddingDefined = (endPadding != UNDEFINED_PADDING);
3762                     break;
3763                 case com.android.internal.R.styleable.View_scrollX:
3764                     x = a.getDimensionPixelOffset(attr, 0);
3765                     break;
3766                 case com.android.internal.R.styleable.View_scrollY:
3767                     y = a.getDimensionPixelOffset(attr, 0);
3768                     break;
3769                 case com.android.internal.R.styleable.View_alpha:
3770                     setAlpha(a.getFloat(attr, 1f));
3771                     break;
3772                 case com.android.internal.R.styleable.View_transformPivotX:
3773                     setPivotX(a.getDimensionPixelOffset(attr, 0));
3774                     break;
3775                 case com.android.internal.R.styleable.View_transformPivotY:
3776                     setPivotY(a.getDimensionPixelOffset(attr, 0));
3777                     break;
3778                 case com.android.internal.R.styleable.View_translationX:
3779                     tx = a.getDimensionPixelOffset(attr, 0);
3780                     transformSet = true;
3781                     break;
3782                 case com.android.internal.R.styleable.View_translationY:
3783                     ty = a.getDimensionPixelOffset(attr, 0);
3784                     transformSet = true;
3785                     break;
3786                 case com.android.internal.R.styleable.View_translationZ:
3787                     tz = a.getDimensionPixelOffset(attr, 0);
3788                     transformSet = true;
3789                     break;
3790                 case com.android.internal.R.styleable.View_elevation:
3791                     elevation = a.getDimensionPixelOffset(attr, 0);
3792                     transformSet = true;
3793                     break;
3794                 case com.android.internal.R.styleable.View_rotation:
3795                     rotation = a.getFloat(attr, 0);
3796                     transformSet = true;
3797                     break;
3798                 case com.android.internal.R.styleable.View_rotationX:
3799                     rotationX = a.getFloat(attr, 0);
3800                     transformSet = true;
3801                     break;
3802                 case com.android.internal.R.styleable.View_rotationY:
3803                     rotationY = a.getFloat(attr, 0);
3804                     transformSet = true;
3805                     break;
3806                 case com.android.internal.R.styleable.View_scaleX:
3807                     sx = a.getFloat(attr, 1f);
3808                     transformSet = true;
3809                     break;
3810                 case com.android.internal.R.styleable.View_scaleY:
3811                     sy = a.getFloat(attr, 1f);
3812                     transformSet = true;
3813                     break;
3814                 case com.android.internal.R.styleable.View_id:
3815                     mID = a.getResourceId(attr, NO_ID);
3816                     break;
3817                 case com.android.internal.R.styleable.View_tag:
3818                     mTag = a.getText(attr);
3819                     break;
3820                 case com.android.internal.R.styleable.View_fitsSystemWindows:
3821                     if (a.getBoolean(attr, false)) {
3822                         viewFlagValues |= FITS_SYSTEM_WINDOWS;
3823                         viewFlagMasks |= FITS_SYSTEM_WINDOWS;
3824                     }
3825                     break;
3826                 case com.android.internal.R.styleable.View_focusable:
3827                     if (a.getBoolean(attr, false)) {
3828                         viewFlagValues |= FOCUSABLE;
3829                         viewFlagMasks |= FOCUSABLE_MASK;
3830                     }
3831                     break;
3832                 case com.android.internal.R.styleable.View_focusableInTouchMode:
3833                     if (a.getBoolean(attr, false)) {
3834                         viewFlagValues |= FOCUSABLE_IN_TOUCH_MODE | FOCUSABLE;
3835                         viewFlagMasks |= FOCUSABLE_IN_TOUCH_MODE | FOCUSABLE_MASK;
3836                     }
3837                     break;
3838                 case com.android.internal.R.styleable.View_clickable:
3839                     if (a.getBoolean(attr, false)) {
3840                         viewFlagValues |= CLICKABLE;
3841                         viewFlagMasks |= CLICKABLE;
3842                     }
3843                     break;
3844                 case com.android.internal.R.styleable.View_longClickable:
3845                     if (a.getBoolean(attr, false)) {
3846                         viewFlagValues |= LONG_CLICKABLE;
3847                         viewFlagMasks |= LONG_CLICKABLE;
3848                     }
3849                     break;
3850                 case com.android.internal.R.styleable.View_saveEnabled:
3851                     if (!a.getBoolean(attr, true)) {
3852                         viewFlagValues |= SAVE_DISABLED;
3853                         viewFlagMasks |= SAVE_DISABLED_MASK;
3854                     }
3855                     break;
3856                 case com.android.internal.R.styleable.View_duplicateParentState:
3857                     if (a.getBoolean(attr, false)) {
3858                         viewFlagValues |= DUPLICATE_PARENT_STATE;
3859                         viewFlagMasks |= DUPLICATE_PARENT_STATE;
3860                     }
3861                     break;
3862                 case com.android.internal.R.styleable.View_visibility:
3863                     final int visibility = a.getInt(attr, 0);
3864                     if (visibility != 0) {
3865                         viewFlagValues |= VISIBILITY_FLAGS[visibility];
3866                         viewFlagMasks |= VISIBILITY_MASK;
3867                     }
3868                     break;
3869                 case com.android.internal.R.styleable.View_layoutDirection:
3870                     // Clear any layout direction flags (included resolved bits) already set
3871                     mPrivateFlags2 &=
3872                             ~(PFLAG2_LAYOUT_DIRECTION_MASK | PFLAG2_LAYOUT_DIRECTION_RESOLVED_MASK);
3873                     // Set the layout direction flags depending on the value of the attribute
3874                     final int layoutDirection = a.getInt(attr, -1);
3875                     final int value = (layoutDirection != -1) ?
3876                             LAYOUT_DIRECTION_FLAGS[layoutDirection] : LAYOUT_DIRECTION_DEFAULT;
3877                     mPrivateFlags2 |= (value << PFLAG2_LAYOUT_DIRECTION_MASK_SHIFT);
3878                     break;
3879                 case com.android.internal.R.styleable.View_drawingCacheQuality:
3880                     final int cacheQuality = a.getInt(attr, 0);
3881                     if (cacheQuality != 0) {
3882                         viewFlagValues |= DRAWING_CACHE_QUALITY_FLAGS[cacheQuality];
3883                         viewFlagMasks |= DRAWING_CACHE_QUALITY_MASK;
3884                     }
3885                     break;
3886                 case com.android.internal.R.styleable.View_contentDescription:
3887                     setContentDescription(a.getString(attr));
3888                     break;
3889                 case com.android.internal.R.styleable.View_labelFor:
3890                     setLabelFor(a.getResourceId(attr, NO_ID));
3891                     break;
3892                 case com.android.internal.R.styleable.View_soundEffectsEnabled:
3893                     if (!a.getBoolean(attr, true)) {
3894                         viewFlagValues &= ~SOUND_EFFECTS_ENABLED;
3895                         viewFlagMasks |= SOUND_EFFECTS_ENABLED;
3896                     }
3897                     break;
3898                 case com.android.internal.R.styleable.View_hapticFeedbackEnabled:
3899                     if (!a.getBoolean(attr, true)) {
3900                         viewFlagValues &= ~HAPTIC_FEEDBACK_ENABLED;
3901                         viewFlagMasks |= HAPTIC_FEEDBACK_ENABLED;
3902                     }
3903                     break;
3904                 case R.styleable.View_scrollbars:
3905                     final int scrollbars = a.getInt(attr, SCROLLBARS_NONE);
3906                     if (scrollbars != SCROLLBARS_NONE) {
3907                         viewFlagValues |= scrollbars;
3908                         viewFlagMasks |= SCROLLBARS_MASK;
3909                         initializeScrollbars = true;
3910                     }
3911                     break;
3912                 //noinspection deprecation
3913                 case R.styleable.View_fadingEdge:
3914                     if (targetSdkVersion >= ICE_CREAM_SANDWICH) {
3915                         // Ignore the attribute starting with ICS
3916                         break;
3917                     }
3918                     // With builds < ICS, fall through and apply fading edges
3919                 case R.styleable.View_requiresFadingEdge:
3920                     final int fadingEdge = a.getInt(attr, FADING_EDGE_NONE);
3921                     if (fadingEdge != FADING_EDGE_NONE) {
3922                         viewFlagValues |= fadingEdge;
3923                         viewFlagMasks |= FADING_EDGE_MASK;
3924                         initializeFadingEdgeInternal(a);
3925                     }
3926                     break;
3927                 case R.styleable.View_scrollbarStyle:
3928                     scrollbarStyle = a.getInt(attr, SCROLLBARS_INSIDE_OVERLAY);
3929                     if (scrollbarStyle != SCROLLBARS_INSIDE_OVERLAY) {
3930                         viewFlagValues |= scrollbarStyle & SCROLLBARS_STYLE_MASK;
3931                         viewFlagMasks |= SCROLLBARS_STYLE_MASK;
3932                     }
3933                     break;
3934                 case R.styleable.View_isScrollContainer:
3935                     setScrollContainer = true;
3936                     if (a.getBoolean(attr, false)) {
3937                         setScrollContainer(true);
3938                     }
3939                     break;
3940                 case com.android.internal.R.styleable.View_keepScreenOn:
3941                     if (a.getBoolean(attr, false)) {
3942                         viewFlagValues |= KEEP_SCREEN_ON;
3943                         viewFlagMasks |= KEEP_SCREEN_ON;
3944                     }
3945                     break;
3946                 case R.styleable.View_filterTouchesWhenObscured:
3947                     if (a.getBoolean(attr, false)) {
3948                         viewFlagValues |= FILTER_TOUCHES_WHEN_OBSCURED;
3949                         viewFlagMasks |= FILTER_TOUCHES_WHEN_OBSCURED;
3950                     }
3951                     break;
3952                 case R.styleable.View_nextFocusLeft:
3953                     mNextFocusLeftId = a.getResourceId(attr, View.NO_ID);
3954                     break;
3955                 case R.styleable.View_nextFocusRight:
3956                     mNextFocusRightId = a.getResourceId(attr, View.NO_ID);
3957                     break;
3958                 case R.styleable.View_nextFocusUp:
3959                     mNextFocusUpId = a.getResourceId(attr, View.NO_ID);
3960                     break;
3961                 case R.styleable.View_nextFocusDown:
3962                     mNextFocusDownId = a.getResourceId(attr, View.NO_ID);
3963                     break;
3964                 case R.styleable.View_nextFocusForward:
3965                     mNextFocusForwardId = a.getResourceId(attr, View.NO_ID);
3966                     break;
3967                 case R.styleable.View_minWidth:
3968                     mMinWidth = a.getDimensionPixelSize(attr, 0);
3969                     break;
3970                 case R.styleable.View_minHeight:
3971                     mMinHeight = a.getDimensionPixelSize(attr, 0);
3972                     break;
3973                 case R.styleable.View_onClick:
3974                     if (context.isRestricted()) {
3975                         throw new IllegalStateException("The android:onClick attribute cannot "
3976                                 + "be used within a restricted context");
3977                     }
3978
3979                     final String handlerName = a.getString(attr);
3980                     if (handlerName != null) {
3981                         setOnClickListener(new OnClickListener() {
3982                             private Method mHandler;
3983
3984                             public void onClick(View v) {
3985                                 if (mHandler == null) {
3986                                     try {
3987                                         mHandler = getContext().getClass().getMethod(handlerName,
3988                                                 View.class);
3989                                     } catch (NoSuchMethodException e) {
3990                                         int id = getId();
3991                                         String idText = id == NO_ID ? "" : " with id '"
3992                                                 + getContext().getResources().getResourceEntryName(
3993                                                     id) + "'";
3994                                         throw new IllegalStateException("Could not find a method " +
3995                                                 handlerName + "(View) in the activity "
3996                                                 + getContext().getClass() + " for onClick handler"
3997                                                 + " on view " + View.this.getClass() + idText, e);
3998                                     }
3999                                 }
4000
4001                                 try {
4002                                     mHandler.invoke(getContext(), View.this);
4003                                 } catch (IllegalAccessException e) {
4004                                     throw new IllegalStateException("Could not execute non "
4005                                             + "public method of the activity", e);
4006                                 } catch (InvocationTargetException e) {
4007                                     throw new IllegalStateException("Could not execute "
4008                                             + "method of the activity", e);
4009                                 }
4010                             }
4011                         });
4012                     }
4013                     break;
4014                 case R.styleable.View_overScrollMode:
4015                     overScrollMode = a.getInt(attr, OVER_SCROLL_IF_CONTENT_SCROLLS);
4016                     break;
4017                 case R.styleable.View_verticalScrollbarPosition:
4018                     mVerticalScrollbarPosition = a.getInt(attr, SCROLLBAR_POSITION_DEFAULT);
4019                     break;
4020                 case R.styleable.View_layerType:
4021                     setLayerType(a.getInt(attr, LAYER_TYPE_NONE), null);
4022                     break;
4023                 case R.styleable.View_textDirection:
4024                     // Clear any text direction flag already set
4025                     mPrivateFlags2 &= ~PFLAG2_TEXT_DIRECTION_MASK;
4026                     // Set the text direction flags depending on the value of the attribute
4027                     final int textDirection = a.getInt(attr, -1);
4028                     if (textDirection != -1) {
4029                         mPrivateFlags2 |= PFLAG2_TEXT_DIRECTION_FLAGS[textDirection];
4030                     }
4031                     break;
4032                 case R.styleable.View_textAlignment:
4033                     // Clear any text alignment flag already set
4034                     mPrivateFlags2 &= ~PFLAG2_TEXT_ALIGNMENT_MASK;
4035                     // Set the text alignment flag depending on the value of the attribute
4036                     final int textAlignment = a.getInt(attr, TEXT_ALIGNMENT_DEFAULT);
4037                     mPrivateFlags2 |= PFLAG2_TEXT_ALIGNMENT_FLAGS[textAlignment];
4038                     break;
4039                 case R.styleable.View_importantForAccessibility:
4040                     setImportantForAccessibility(a.getInt(attr,
4041                             IMPORTANT_FOR_ACCESSIBILITY_DEFAULT));
4042                     break;
4043                 case R.styleable.View_accessibilityLiveRegion:
4044                     setAccessibilityLiveRegion(a.getInt(attr, ACCESSIBILITY_LIVE_REGION_DEFAULT));
4045                     break;
4046                 case R.styleable.View_transitionName:
4047                     setTransitionName(a.getString(attr));
4048                     break;
4049                 case R.styleable.View_nestedScrollingEnabled:
4050                     setNestedScrollingEnabled(a.getBoolean(attr, false));
4051                     break;
4052                 case R.styleable.View_stateListAnimator:
4053                     setStateListAnimator(AnimatorInflater.loadStateListAnimator(context,
4054                             a.getResourceId(attr, 0)));
4055                     break;
4056                 case R.styleable.View_backgroundTint:
4057                     // This will get applied later during setBackground().
4058                     if (mBackgroundTint == null) {
4059                         mBackgroundTint = new TintInfo();
4060                     }
4061                     mBackgroundTint.mTintList = a.getColorStateList(
4062                             R.styleable.View_backgroundTint);
4063                     mBackgroundTint.mHasTintList = true;
4064                     break;
4065                 case R.styleable.View_backgroundTintMode:
4066                     // This will get applied later during setBackground().
4067                     if (mBackgroundTint == null) {
4068                         mBackgroundTint = new TintInfo();
4069                     }
4070                     mBackgroundTint.mTintMode = Drawable.parseTintMode(a.getInt(
4071                             R.styleable.View_backgroundTintMode, -1), null);
4072                     mBackgroundTint.mHasTintMode = true;
4073                     break;
4074                 case R.styleable.View_outlineProvider:
4075                     setOutlineProviderFromAttribute(a.getInt(R.styleable.View_outlineProvider,
4076                             PROVIDER_BACKGROUND));
4077                     break;
4078             }
4079         }
4080
4081         setOverScrollMode(overScrollMode);
4082
4083         // Cache start/end user padding as we cannot fully resolve padding here (we dont have yet
4084         // the resolved layout direction). Those cached values will be used later during padding
4085         // resolution.
4086         mUserPaddingStart = startPadding;
4087         mUserPaddingEnd = endPadding;
4088
4089         if (background != null) {
4090             setBackground(background);
4091         }
4092
4093         // setBackground above will record that padding is currently provided by the background.
4094         // If we have padding specified via xml, record that here instead and use it.
4095         mLeftPaddingDefined = leftPaddingDefined;
4096         mRightPaddingDefined = rightPaddingDefined;
4097
4098         if (padding >= 0) {
4099             leftPadding = padding;
4100             topPadding = padding;
4101             rightPadding = padding;
4102             bottomPadding = padding;
4103             mUserPaddingLeftInitial = padding;
4104             mUserPaddingRightInitial = padding;
4105         }
4106
4107         if (isRtlCompatibilityMode()) {
4108             // RTL compatibility mode: pre Jelly Bean MR1 case OR no RTL support case.
4109             // left / right padding are used if defined (meaning here nothing to do). If they are not
4110             // defined and start / end padding are defined (e.g. in Frameworks resources), then we use
4111             // start / end and resolve them as left / right (layout direction is not taken into account).
4112             // Padding from the background drawable is stored at this point in mUserPaddingLeftInitial
4113             // and mUserPaddingRightInitial) so drawable padding will be used as ultimate default if
4114             // defined.
4115             if (!mLeftPaddingDefined && startPaddingDefined) {
4116                 leftPadding = startPadding;
4117             }
4118             mUserPaddingLeftInitial = (leftPadding >= 0) ? leftPadding : mUserPaddingLeftInitial;
4119             if (!mRightPaddingDefined && endPaddingDefined) {
4120                 rightPadding = endPadding;
4121             }
4122             mUserPaddingRightInitial = (rightPadding >= 0) ? rightPadding : mUserPaddingRightInitial;
4123         } else {
4124             // Jelly Bean MR1 and after case: if start/end defined, they will override any left/right
4125             // values defined. Otherwise, left /right values are used.
4126             // Padding from the background drawable is stored at this point in mUserPaddingLeftInitial
4127             // and mUserPaddingRightInitial) so drawable padding will be used as ultimate default if
4128             // defined.
4129             final boolean hasRelativePadding = startPaddingDefined || endPaddingDefined;
4130
4131             if (mLeftPaddingDefined && !hasRelativePadding) {
4132                 mUserPaddingLeftInitial = leftPadding;
4133             }
4134             if (mRightPaddingDefined && !hasRelativePadding) {
4135                 mUserPaddingRightInitial = rightPadding;
4136             }
4137         }
4138
4139         internalSetPadding(
4140                 mUserPaddingLeftInitial,
4141                 topPadding >= 0 ? topPadding : mPaddingTop,
4142                 mUserPaddingRightInitial,
4143                 bottomPadding >= 0 ? bottomPadding : mPaddingBottom);
4144
4145         if (viewFlagMasks != 0) {
4146             setFlags(viewFlagValues, viewFlagMasks);
4147         }
4148
4149         if (initializeScrollbars) {
4150             initializeScrollbarsInternal(a);
4151         }
4152
4153         a.recycle();
4154
4155         // Needs to be called after mViewFlags is set
4156         if (scrollbarStyle != SCROLLBARS_INSIDE_OVERLAY) {
4157             recomputePadding();
4158         }
4159
4160         if (x != 0 || y != 0) {
4161             scrollTo(x, y);
4162         }
4163
4164         if (transformSet) {
4165             setTranslationX(tx);
4166             setTranslationY(ty);
4167             setTranslationZ(tz);
4168             setElevation(elevation);
4169             setRotation(rotation);
4170             setRotationX(rotationX);
4171             setRotationY(rotationY);
4172             setScaleX(sx);
4173             setScaleY(sy);
4174         }
4175
4176         if (!setScrollContainer && (viewFlagValues&SCROLLBARS_VERTICAL) != 0) {
4177             setScrollContainer(true);
4178         }
4179
4180         computeOpaqueFlags();
4181     }
4182
4183     /**
4184      * Non-public constructor for use in testing
4185      */
4186     View() {
4187         mResources = null;
4188         mRenderNode = RenderNode.create(getClass().getName(), this);
4189     }
4190
4191     private static SparseArray<String> getAttributeMap() {
4192         if (mAttributeMap == null) {
4193             mAttributeMap = new SparseArray<String>();
4194         }
4195         return mAttributeMap;
4196     }
4197
4198     private void saveAttributeData(AttributeSet attrs, TypedArray a) {
4199         int length = ((attrs == null ? 0 : attrs.getAttributeCount()) + a.getIndexCount()) * 2;
4200         mAttributes = new String[length];
4201
4202         int i = 0;
4203         if (attrs != null) {
4204             for (i = 0; i < attrs.getAttributeCount(); i += 2) {
4205                 mAttributes[i] = attrs.getAttributeName(i);
4206                 mAttributes[i + 1] = attrs.getAttributeValue(i);
4207             }
4208
4209         }
4210
4211         SparseArray<String> attributeMap = getAttributeMap();
4212         for (int j = 0; j < a.length(); ++j) {
4213             if (a.hasValue(j)) {
4214                 try {
4215                     int resourceId = a.getResourceId(j, 0);
4216                     if (resourceId == 0) {
4217                         continue;
4218                     }
4219
4220                     String resourceName = attributeMap.get(resourceId);
4221                     if (resourceName == null) {
4222                         resourceName = a.getResources().getResourceName(resourceId);
4223                         attributeMap.put(resourceId, resourceName);
4224                     }
4225
4226                     mAttributes[i] = resourceName;
4227                     mAttributes[i + 1] = a.getText(j).toString();
4228                     i += 2;
4229                 } catch (Resources.NotFoundException e) {
4230                     // if we can't get the resource name, we just ignore it
4231                 }
4232             }
4233         }
4234     }
4235
4236     public String toString() {
4237         StringBuilder out = new StringBuilder(128);
4238         out.append(getClass().getName());
4239         out.append('{');
4240         out.append(Integer.toHexString(System.identityHashCode(this)));
4241         out.append(' ');
4242         switch (mViewFlags&VISIBILITY_MASK) {
4243             case VISIBLE: out.append('V'); break;
4244             case INVISIBLE: out.append('I'); break;
4245             case GONE: out.append('G'); break;
4246             default: out.append('.'); break;
4247         }
4248         out.append((mViewFlags&FOCUSABLE_MASK) == FOCUSABLE ? 'F' : '.');
4249         out.append((mViewFlags&ENABLED_MASK) == ENABLED ? 'E' : '.');
4250         out.append((mViewFlags&DRAW_MASK) == WILL_NOT_DRAW ? '.' : 'D');
4251         out.append((mViewFlags&SCROLLBARS_HORIZONTAL) != 0 ? 'H' : '.');
4252         out.append((mViewFlags&SCROLLBARS_VERTICAL) != 0 ? 'V' : '.');
4253         out.append((mViewFlags&CLICKABLE) != 0 ? 'C' : '.');
4254         out.append((mViewFlags&LONG_CLICKABLE) != 0 ? 'L' : '.');
4255         out.append(' ');
4256         out.append((mPrivateFlags&PFLAG_IS_ROOT_NAMESPACE) != 0 ? 'R' : '.');
4257         out.append((mPrivateFlags&PFLAG_FOCUSED) != 0 ? 'F' : '.');
4258         out.append((mPrivateFlags&PFLAG_SELECTED) != 0 ? 'S' : '.');
4259         if ((mPrivateFlags&PFLAG_PREPRESSED) != 0) {
4260             out.append('p');
4261         } else {
4262             out.append((mPrivateFlags&PFLAG_PRESSED) != 0 ? 'P' : '.');
4263         }
4264         out.append((mPrivateFlags&PFLAG_HOVERED) != 0 ? 'H' : '.');
4265         out.append((mPrivateFlags&PFLAG_ACTIVATED) != 0 ? 'A' : '.');
4266         out.append((mPrivateFlags&PFLAG_INVALIDATED) != 0 ? 'I' : '.');
4267         out.append((mPrivateFlags&PFLAG_DIRTY_MASK) != 0 ? 'D' : '.');
4268         out.append(' ');
4269         out.append(mLeft);
4270         out.append(',');
4271         out.append(mTop);
4272         out.append('-');
4273         out.append(mRight);
4274         out.append(',');
4275         out.append(mBottom);
4276         final int id = getId();
4277         if (id != NO_ID) {
4278             out.append(" #");
4279             out.append(Integer.toHexString(id));
4280             final Resources r = mResources;
4281             if (Resources.resourceHasPackage(id) && r != null) {
4282                 try {
4283                     String pkgname;
4284                     switch (id&0xff000000) {
4285                         case 0x7f000000:
4286                             pkgname="app";
4287                             break;
4288                         case 0x01000000:
4289                             pkgname="android";
4290                             break;
4291                         default:
4292                             pkgname = r.getResourcePackageName(id);
4293                             break;
4294                     }
4295                     String typename = r.getResourceTypeName(id);
4296                     String entryname = r.getResourceEntryName(id);
4297                     out.append(" ");
4298                     out.append(pkgname);
4299                     out.append(":");
4300                     out.append(typename);
4301                     out.append("/");
4302                     out.append(entryname);
4303                 } catch (Resources.NotFoundException e) {
4304                 }
4305             }
4306         }
4307         out.append("}");
4308         return out.toString();
4309     }
4310
4311     /**
4312      * <p>
4313      * Initializes the fading edges from a given set of styled attributes. This
4314      * method should be called by subclasses that need fading edges and when an
4315      * instance of these subclasses is created programmatically rather than
4316      * being inflated from XML. This method is automatically called when the XML
4317      * is inflated.
4318      * </p>
4319      *
4320      * @param a the styled attributes set to initialize the fading edges from
4321      *
4322      * @removed
4323      */
4324     protected void initializeFadingEdge(TypedArray a) {
4325         // This method probably shouldn't have been included in the SDK to begin with.
4326         // It relies on 'a' having been initialized using an attribute filter array that is
4327         // not publicly available to the SDK. The old method has been renamed
4328         // to initializeFadingEdgeInternal and hidden for framework use only;
4329         // this one initializes using defaults to make it safe to call for apps.
4330
4331         TypedArray arr = mContext.obtainStyledAttributes(com.android.internal.R.styleable.View);
4332
4333         initializeFadingEdgeInternal(arr);
4334
4335         arr.recycle();
4336     }
4337
4338     /**
4339      * <p>
4340      * Initializes the fading edges from a given set of styled attributes. This
4341      * method should be called by subclasses that need fading edges and when an
4342      * instance of these subclasses is created programmatically rather than
4343      * being inflated from XML. This method is automatically called when the XML
4344      * is inflated.
4345      * </p>
4346      *
4347      * @param a the styled attributes set to initialize the fading edges from
4348      * @hide This is the real method; the public one is shimmed to be safe to call from apps.
4349      */
4350     protected void initializeFadingEdgeInternal(TypedArray a) {
4351         initScrollCache();
4352
4353         mScrollCache.fadingEdgeLength = a.getDimensionPixelSize(
4354                 R.styleable.View_fadingEdgeLength,
4355                 ViewConfiguration.get(mContext).getScaledFadingEdgeLength());
4356     }
4357
4358     /**
4359      * Returns the size of the vertical faded edges used to indicate that more
4360      * content in this view is visible.
4361      *
4362      * @return The size in pixels of the vertical faded edge or 0 if vertical
4363      *         faded edges are not enabled for this view.
4364      * @attr ref android.R.styleable#View_fadingEdgeLength
4365      */
4366     public int getVerticalFadingEdgeLength() {
4367         if (isVerticalFadingEdgeEnabled()) {
4368             ScrollabilityCache cache = mScrollCache;
4369             if (cache != null) {
4370                 return cache.fadingEdgeLength;
4371             }
4372         }
4373         return 0;
4374     }
4375
4376     /**
4377      * Set the size of the faded edge used to indicate that more content in this
4378      * view is available.  Will not change whether the fading edge is enabled; use
4379      * {@link #setVerticalFadingEdgeEnabled(boolean)} or
4380      * {@link #setHorizontalFadingEdgeEnabled(boolean)} to enable the fading edge
4381      * for the vertical or horizontal fading edges.
4382      *
4383      * @param length The size in pixels of the faded edge used to indicate that more
4384      *        content in this view is visible.
4385      */
4386     public void setFadingEdgeLength(int length) {
4387         initScrollCache();
4388         mScrollCache.fadingEdgeLength = length;
4389     }
4390
4391     /**
4392      * Returns the size of the horizontal faded edges used to indicate that more
4393      * content in this view is visible.
4394      *
4395      * @return The size in pixels of the horizontal faded edge or 0 if horizontal
4396      *         faded edges are not enabled for this view.
4397      * @attr ref android.R.styleable#View_fadingEdgeLength
4398      */
4399     public int getHorizontalFadingEdgeLength() {
4400         if (isHorizontalFadingEdgeEnabled()) {
4401             ScrollabilityCache cache = mScrollCache;
4402             if (cache != null) {
4403                 return cache.fadingEdgeLength;
4404             }
4405         }
4406         return 0;
4407     }
4408
4409     /**
4410      * Returns the width of the vertical scrollbar.
4411      *
4412      * @return The width in pixels of the vertical scrollbar or 0 if there
4413      *         is no vertical scrollbar.
4414      */
4415     public int getVerticalScrollbarWidth() {
4416         ScrollabilityCache cache = mScrollCache;
4417         if (cache != null) {
4418             ScrollBarDrawable scrollBar = cache.scrollBar;
4419             if (scrollBar != null) {
4420                 int size = scrollBar.getSize(true);
4421                 if (size <= 0) {
4422                     size = cache.scrollBarSize;
4423                 }
4424                 return size;
4425             }
4426             return 0;
4427         }
4428         return 0;
4429     }
4430
4431     /**
4432      * Returns the height of the horizontal scrollbar.
4433      *
4434      * @return The height in pixels of the horizontal scrollbar or 0 if
4435      *         there is no horizontal scrollbar.
4436      */
4437     protected int getHorizontalScrollbarHeight() {
4438         ScrollabilityCache cache = mScrollCache;
4439         if (cache != null) {
4440             ScrollBarDrawable scrollBar = cache.scrollBar;
4441             if (scrollBar != null) {
4442                 int size = scrollBar.getSize(false);
4443                 if (size <= 0) {
4444                     size = cache.scrollBarSize;
4445                 }
4446                 return size;
4447             }
4448             return 0;
4449         }
4450         return 0;
4451     }
4452
4453     /**
4454      * <p>
4455      * Initializes the scrollbars from a given set of styled attributes. This
4456      * method should be called by subclasses that need scrollbars and when an
4457      * instance of these subclasses is created programmatically rather than
4458      * being inflated from XML. This method is automatically called when the XML
4459      * is inflated.
4460      * </p>
4461      *
4462      * @param a the styled attributes set to initialize the scrollbars from
4463      *
4464      * @removed
4465      */
4466     protected void initializeScrollbars(TypedArray a) {
4467         // It's not safe to use this method from apps. The parameter 'a' must have been obtained
4468         // using the View filter array which is not available to the SDK. As such, internal
4469         // framework usage now uses initializeScrollbarsInternal and we grab a default
4470         // TypedArray with the right filter instead here.
4471         TypedArray arr = mContext.obtainStyledAttributes(com.android.internal.R.styleable.View);
4472
4473         initializeScrollbarsInternal(arr);
4474
4475         // We ignored the method parameter. Recycle the one we actually did use.
4476         arr.recycle();
4477     }
4478
4479     /**
4480      * <p>
4481      * Initializes the scrollbars from a given set of styled attributes. This
4482      * method should be called by subclasses that need scrollbars and when an
4483      * instance of these subclasses is created programmatically rather than
4484      * being inflated from XML. This method is automatically called when the XML
4485      * is inflated.
4486      * </p>
4487      *
4488      * @param a the styled attributes set to initialize the scrollbars from
4489      * @hide
4490      */
4491     protected void initializeScrollbarsInternal(TypedArray a) {
4492         initScrollCache();
4493
4494         final ScrollabilityCache scrollabilityCache = mScrollCache;
4495
4496         if (scrollabilityCache.scrollBar == null) {
4497             scrollabilityCache.scrollBar = new ScrollBarDrawable();
4498         }
4499
4500         final boolean fadeScrollbars = a.getBoolean(R.styleable.View_fadeScrollbars, true);
4501
4502         if (!fadeScrollbars) {
4503             scrollabilityCache.state = ScrollabilityCache.ON;
4504         }
4505         scrollabilityCache.fadeScrollBars = fadeScrollbars;
4506
4507
4508         scrollabilityCache.scrollBarFadeDuration = a.getInt(
4509                 R.styleable.View_scrollbarFadeDuration, ViewConfiguration
4510                         .getScrollBarFadeDuration());
4511         scrollabilityCache.scrollBarDefaultDelayBeforeFade = a.getInt(
4512                 R.styleable.View_scrollbarDefaultDelayBeforeFade,
4513                 ViewConfiguration.getScrollDefaultDelay());
4514
4515
4516         scrollabilityCache.scrollBarSize = a.getDimensionPixelSize(
4517                 com.android.internal.R.styleable.View_scrollbarSize,
4518                 ViewConfiguration.get(mContext).getScaledScrollBarSize());
4519
4520         Drawable track = a.getDrawable(R.styleable.View_scrollbarTrackHorizontal);
4521         scrollabilityCache.scrollBar.setHorizontalTrackDrawable(track);
4522
4523         Drawable thumb = a.getDrawable(R.styleable.View_scrollbarThumbHorizontal);
4524         if (thumb != null) {
4525             scrollabilityCache.scrollBar.setHorizontalThumbDrawable(thumb);
4526         }
4527
4528         boolean alwaysDraw = a.getBoolean(R.styleable.View_scrollbarAlwaysDrawHorizontalTrack,
4529                 false);
4530         if (alwaysDraw) {
4531             scrollabilityCache.scrollBar.setAlwaysDrawHorizontalTrack(true);
4532         }
4533
4534         track = a.getDrawable(R.styleable.View_scrollbarTrackVertical);
4535         scrollabilityCache.scrollBar.setVerticalTrackDrawable(track);
4536
4537         thumb = a.getDrawable(R.styleable.View_scrollbarThumbVertical);
4538         if (thumb != null) {
4539             scrollabilityCache.scrollBar.setVerticalThumbDrawable(thumb);
4540         }
4541
4542         alwaysDraw = a.getBoolean(R.styleable.View_scrollbarAlwaysDrawVerticalTrack,
4543                 false);
4544         if (alwaysDraw) {
4545             scrollabilityCache.scrollBar.setAlwaysDrawVerticalTrack(true);
4546         }
4547
4548         // Apply layout direction to the new Drawables if needed
4549         final int layoutDirection = getLayoutDirection();
4550         if (track != null) {
4551             track.setLayoutDirection(layoutDirection);
4552         }
4553         if (thumb != null) {
4554             thumb.setLayoutDirection(layoutDirection);
4555         }
4556
4557         // Re-apply user/background padding so that scrollbar(s) get added
4558         resolvePadding();
4559     }
4560
4561     /**
4562      * <p>
4563      * Initalizes the scrollability cache if necessary.
4564      * </p>
4565      */
4566     private void initScrollCache() {
4567         if (mScrollCache == null) {
4568             mScrollCache = new ScrollabilityCache(ViewConfiguration.get(mContext), this);
4569         }
4570     }
4571
4572     private ScrollabilityCache getScrollCache() {
4573         initScrollCache();
4574         return mScrollCache;
4575     }
4576
4577     /**
4578      * Set the position of the vertical scroll bar. Should be one of
4579      * {@link #SCROLLBAR_POSITION_DEFAULT}, {@link #SCROLLBAR_POSITION_LEFT} or
4580      * {@link #SCROLLBAR_POSITION_RIGHT}.
4581      *
4582      * @param position Where the vertical scroll bar should be positioned.
4583      */
4584     public void setVerticalScrollbarPosition(int position) {
4585         if (mVerticalScrollbarPosition != position) {
4586             mVerticalScrollbarPosition = position;
4587             computeOpaqueFlags();
4588             resolvePadding();
4589         }
4590     }
4591
4592     /**
4593      * @return The position where the vertical scroll bar will show, if applicable.
4594      * @see #setVerticalScrollbarPosition(int)
4595      */
4596     public int getVerticalScrollbarPosition() {
4597         return mVerticalScrollbarPosition;
4598     }
4599
4600     ListenerInfo getListenerInfo() {
4601         if (mListenerInfo != null) {
4602             return mListenerInfo;
4603         }
4604         mListenerInfo = new ListenerInfo();
4605         return mListenerInfo;
4606     }
4607
4608     /**
4609      * Register a callback to be invoked when focus of this view changed.
4610      *
4611      * @param l The callback that will run.
4612      */
4613     public void setOnFocusChangeListener(OnFocusChangeListener l) {
4614         getListenerInfo().mOnFocusChangeListener = l;
4615     }
4616
4617     /**
4618      * Add a listener that will be called when the bounds of the view change due to
4619      * layout processing.
4620      *
4621      * @param listener The listener that will be called when layout bounds change.
4622      */
4623     public void addOnLayoutChangeListener(OnLayoutChangeListener listener) {
4624         ListenerInfo li = getListenerInfo();
4625         if (li.mOnLayoutChangeListeners == null) {
4626             li.mOnLayoutChangeListeners = new ArrayList<OnLayoutChangeListener>();
4627         }
4628         if (!li.mOnLayoutChangeListeners.contains(listener)) {
4629             li.mOnLayoutChangeListeners.add(listener);
4630         }
4631     }
4632
4633     /**
4634      * Remove a listener for layout changes.
4635      *
4636      * @param listener The listener for layout bounds change.
4637      */
4638     public void removeOnLayoutChangeListener(OnLayoutChangeListener listener) {
4639         ListenerInfo li = mListenerInfo;
4640         if (li == null || li.mOnLayoutChangeListeners == null) {
4641             return;
4642         }
4643         li.mOnLayoutChangeListeners.remove(listener);
4644     }
4645
4646     /**
4647      * Add a listener for attach state changes.
4648      *
4649      * This listener will be called whenever this view is attached or detached
4650      * from a window. Remove the listener using
4651      * {@link #removeOnAttachStateChangeListener(OnAttachStateChangeListener)}.
4652      *
4653      * @param listener Listener to attach
4654      * @see #removeOnAttachStateChangeListener(OnAttachStateChangeListener)
4655      */
4656     public void addOnAttachStateChangeListener(OnAttachStateChangeListener listener) {
4657         ListenerInfo li = getListenerInfo();
4658         if (li.mOnAttachStateChangeListeners == null) {
4659             li.mOnAttachStateChangeListeners
4660                     = new CopyOnWriteArrayList<OnAttachStateChangeListener>();
4661         }
4662         li.mOnAttachStateChangeListeners.add(listener);
4663     }
4664
4665     /**
4666      * Remove a listener for attach state changes. The listener will receive no further
4667      * notification of window attach/detach events.
4668      *
4669      * @param listener Listener to remove
4670      * @see #addOnAttachStateChangeListener(OnAttachStateChangeListener)
4671      */
4672     public void removeOnAttachStateChangeListener(OnAttachStateChangeListener listener) {
4673         ListenerInfo li = mListenerInfo;
4674         if (li == null || li.mOnAttachStateChangeListeners == null) {
4675             return;
4676         }
4677         li.mOnAttachStateChangeListeners.remove(listener);
4678     }
4679
4680     /**
4681      * Returns the focus-change callback registered for this view.
4682      *
4683      * @return The callback, or null if one is not registered.
4684      */
4685     public OnFocusChangeListener getOnFocusChangeListener() {
4686         ListenerInfo li = mListenerInfo;
4687         return li != null ? li.mOnFocusChangeListener : null;
4688     }
4689
4690     /**
4691      * Register a callback to be invoked when this view is clicked. If this view is not
4692      * clickable, it becomes clickable.
4693      *
4694      * @param l The callback that will run
4695      *
4696      * @see #setClickable(boolean)
4697      */
4698     public void setOnClickListener(OnClickListener l) {
4699         if (!isClickable()) {
4700             setClickable(true);
4701         }
4702         getListenerInfo().mOnClickListener = l;
4703     }
4704
4705     /**
4706      * Return whether this view has an attached OnClickListener.  Returns
4707      * true if there is a listener, false if there is none.
4708      */
4709     public boolean hasOnClickListeners() {
4710         ListenerInfo li = mListenerInfo;
4711         return (li != null && li.mOnClickListener != null);
4712     }
4713
4714     /**
4715      * Register a callback to be invoked when this view is clicked and held. If this view is not
4716      * long clickable, it becomes long clickable.
4717      *
4718      * @param l The callback that will run
4719      *
4720      * @see #setLongClickable(boolean)
4721      */
4722     public void setOnLongClickListener(OnLongClickListener l) {
4723         if (!isLongClickable()) {
4724             setLongClickable(true);
4725         }
4726         getListenerInfo().mOnLongClickListener = l;
4727     }
4728
4729     /**
4730      * Register a callback to be invoked when the context menu for this view is
4731      * being built. If this view is not long clickable, it becomes long clickable.
4732      *
4733      * @param l The callback that will run
4734      *
4735      */
4736     public void setOnCreateContextMenuListener(OnCreateContextMenuListener l) {
4737         if (!isLongClickable()) {
4738             setLongClickable(true);
4739         }
4740         getListenerInfo().mOnCreateContextMenuListener = l;
4741     }
4742
4743     /**
4744      * Call this view's OnClickListener, if it is defined.  Performs all normal
4745      * actions associated with clicking: reporting accessibility event, playing
4746      * a sound, etc.
4747      *
4748      * @return True there was an assigned OnClickListener that was called, false
4749      *         otherwise is returned.
4750      */
4751     public boolean performClick() {
4752         final boolean result;
4753         final ListenerInfo li = mListenerInfo;
4754         if (li != null && li.mOnClickListener != null) {
4755             playSoundEffect(SoundEffectConstants.CLICK);
4756             li.mOnClickListener.onClick(this);
4757             result = true;
4758         } else {
4759             result = false;
4760         }
4761
4762         sendAccessibilityEvent(AccessibilityEvent.TYPE_VIEW_CLICKED);
4763         return result;
4764     }
4765
4766     /**
4767      * Directly call any attached OnClickListener.  Unlike {@link #performClick()},
4768      * this only calls the listener, and does not do any associated clicking
4769      * actions like reporting an accessibility event.
4770      *
4771      * @return True there was an assigned OnClickListener that was called, false
4772      *         otherwise is returned.
4773      */
4774     public boolean callOnClick() {
4775         ListenerInfo li = mListenerInfo;
4776         if (li != null && li.mOnClickListener != null) {
4777             li.mOnClickListener.onClick(this);
4778             return true;
4779         }
4780         return false;
4781     }
4782
4783     /**
4784      * Call this view's OnLongClickListener, if it is defined. Invokes the context menu if the
4785      * OnLongClickListener did not consume the event.
4786      *
4787      * @return True if one of the above receivers consumed the event, false otherwise.
4788      */
4789     public boolean performLongClick() {
4790         sendAccessibilityEvent(AccessibilityEvent.TYPE_VIEW_LONG_CLICKED);
4791
4792         boolean handled = false;
4793         ListenerInfo li = mListenerInfo;
4794         if (li != null && li.mOnLongClickListener != null) {
4795             handled = li.mOnLongClickListener.onLongClick(View.this);
4796         }
4797         if (!handled) {
4798             handled = showContextMenu();
4799         }
4800         if (handled) {
4801             performHapticFeedback(HapticFeedbackConstants.LONG_PRESS);
4802         }
4803         return handled;
4804     }
4805
4806     /**
4807      * Performs button-related actions during a touch down event.
4808      *
4809      * @param event The event.
4810      * @return True if the down was consumed.
4811      *
4812      * @hide
4813      */
4814     protected boolean performButtonActionOnTouchDown(MotionEvent event) {
4815         if ((event.getButtonState() & MotionEvent.BUTTON_SECONDARY) != 0) {
4816             if (showContextMenu(event.getX(), event.getY(), event.getMetaState())) {
4817                 return true;
4818             }
4819         }
4820         return false;
4821     }
4822
4823     /**
4824      * Bring up the context menu for this view.
4825      *
4826      * @return Whether a context menu was displayed.
4827      */
4828     public boolean showContextMenu() {
4829         return getParent().showContextMenuForChild(this);
4830     }
4831
4832     /**
4833      * Bring up the context menu for this view, referring to the item under the specified point.
4834      *
4835      * @param x The referenced x coordinate.
4836      * @param y The referenced y coordinate.
4837      * @param metaState The keyboard modifiers that were pressed.
4838      * @return Whether a context menu was displayed.
4839      *
4840      * @hide
4841      */
4842     public boolean showContextMenu(float x, float y, int metaState) {
4843         return showContextMenu();
4844     }
4845
4846     /**
4847      * Start an action mode.
4848      *
4849      * @param callback Callback that will control the lifecycle of the action mode
4850      * @return The new action mode if it is started, null otherwise
4851      *
4852      * @see ActionMode
4853      */
4854     public ActionMode startActionMode(ActionMode.Callback callback) {
4855         ViewParent parent = getParent();
4856         if (parent == null) return null;
4857         return parent.startActionModeForChild(this, callback);
4858     }
4859
4860     /**
4861      * Register a callback to be invoked when a hardware key is pressed in this view.
4862      * Key presses in software input methods will generally not trigger the methods of
4863      * this listener.
4864      * @param l the key listener to attach to this view
4865      */
4866     public void setOnKeyListener(OnKeyListener l) {
4867         getListenerInfo().mOnKeyListener = l;
4868     }
4869
4870     /**
4871      * Register a callback to be invoked when a touch event is sent to this view.
4872      * @param l the touch listener to attach to this view
4873      */
4874     public void setOnTouchListener(OnTouchListener l) {
4875         getListenerInfo().mOnTouchListener = l;
4876     }
4877
4878     /**
4879      * Register a callback to be invoked when a generic motion event is sent to this view.
4880      * @param l the generic motion listener to attach to this view
4881      */
4882     public void setOnGenericMotionListener(OnGenericMotionListener l) {
4883         getListenerInfo().mOnGenericMotionListener = l;
4884     }
4885
4886     /**
4887      * Register a callback to be invoked when a hover event is sent to this view.
4888      * @param l the hover listener to attach to this view
4889      */
4890     public void setOnHoverListener(OnHoverListener l) {
4891         getListenerInfo().mOnHoverListener = l;
4892     }
4893
4894     /**
4895      * Register a drag event listener callback object for this View. The parameter is
4896      * an implementation of {@link android.view.View.OnDragListener}. To send a drag event to a
4897      * View, the system calls the
4898      * {@link android.view.View.OnDragListener#onDrag(View,DragEvent)} method.
4899      * @param l An implementation of {@link android.view.View.OnDragListener}.
4900      */
4901     public void setOnDragListener(OnDragListener l) {
4902         getListenerInfo().mOnDragListener = l;
4903     }
4904
4905     /**
4906      * Give this view focus. This will cause
4907      * {@link #onFocusChanged(boolean, int, android.graphics.Rect)} to be called.
4908      *
4909      * Note: this does not check whether this {@link View} should get focus, it just
4910      * gives it focus no matter what.  It should only be called internally by framework
4911      * code that knows what it is doing, namely {@link #requestFocus(int, Rect)}.
4912      *
4913      * @param direction values are {@link View#FOCUS_UP}, {@link View#FOCUS_DOWN},
4914      *        {@link View#FOCUS_LEFT} or {@link View#FOCUS_RIGHT}. This is the direction which
4915      *        focus moved when requestFocus() is called. It may not always
4916      *        apply, in which case use the default View.FOCUS_DOWN.
4917      * @param previouslyFocusedRect The rectangle of the view that had focus
4918      *        prior in this View's coordinate system.
4919      */
4920     void handleFocusGainInternal(@FocusRealDirection int direction, Rect previouslyFocusedRect) {
4921         if (DBG) {
4922             System.out.println(this + " requestFocus()");
4923         }
4924
4925         if ((mPrivateFlags & PFLAG_FOCUSED) == 0) {
4926             mPrivateFlags |= PFLAG_FOCUSED;
4927
4928             View oldFocus = (mAttachInfo != null) ? getRootView().findFocus() : null;
4929
4930             if (mParent != null) {
4931                 mParent.requestChildFocus(this, this);
4932             }
4933
4934             if (mAttachInfo != null) {
4935                 mAttachInfo.mTreeObserver.dispatchOnGlobalFocusChange(oldFocus, this);
4936             }
4937
4938             onFocusChanged(true, direction, previouslyFocusedRect);
4939             refreshDrawableState();
4940         }
4941     }
4942
4943     /**
4944      * Populates <code>outRect</code> with the hotspot bounds. By default,
4945      * the hotspot bounds are identical to the screen bounds.
4946      *
4947      * @param outRect rect to populate with hotspot bounds
4948      * @hide Only for internal use by views and widgets.
4949      */
4950     public void getHotspotBounds(Rect outRect) {
4951         final Drawable background = getBackground();
4952         if (background != null) {
4953             background.getHotspotBounds(outRect);
4954         } else {
4955             getBoundsOnScreen(outRect);
4956         }
4957     }
4958
4959     /**
4960      * Request that a rectangle of this view be visible on the screen,
4961      * scrolling if necessary just enough.
4962      *
4963      * <p>A View should call this if it maintains some notion of which part
4964      * of its content is interesting.  For example, a text editing view
4965      * should call this when its cursor moves.
4966      *
4967      * @param rectangle The rectangle.
4968      * @return Whether any parent scrolled.
4969      */
4970     public boolean requestRectangleOnScreen(Rect rectangle) {
4971         return requestRectangleOnScreen(rectangle, false);
4972     }
4973
4974     /**
4975      * Request that a rectangle of this view be visible on the screen,
4976      * scrolling if necessary just enough.
4977      *
4978      * <p>A View should call this if it maintains some notion of which part
4979      * of its content is interesting.  For example, a text editing view
4980      * should call this when its cursor moves.
4981      *
4982      * <p>When <code>immediate</code> is set to true, scrolling will not be
4983      * animated.
4984      *
4985      * @param rectangle The rectangle.
4986      * @param immediate True to forbid animated scrolling, false otherwise
4987      * @return Whether any parent scrolled.
4988      */
4989     public boolean requestRectangleOnScreen(Rect rectangle, boolean immediate) {
4990         if (mParent == null) {
4991             return false;
4992         }
4993
4994         View child = this;
4995
4996         RectF position = (mAttachInfo != null) ? mAttachInfo.mTmpTransformRect : new RectF();
4997         position.set(rectangle);
4998
4999         ViewParent parent = mParent;
5000         boolean scrolled = false;
5001         while (parent != null) {
5002             rectangle.set((int) position.left, (int) position.top,
5003                     (int) position.right, (int) position.bottom);
5004
5005             scrolled |= parent.requestChildRectangleOnScreen(child,
5006                     rectangle, immediate);
5007
5008             if (!child.hasIdentityMatrix()) {
5009                 child.getMatrix().mapRect(position);
5010             }
5011
5012             position.offset(child.mLeft, child.mTop);
5013
5014             if (!(parent instanceof View)) {
5015                 break;
5016             }
5017
5018             View parentView = (View) parent;
5019
5020             position.offset(-parentView.getScrollX(), -parentView.getScrollY());
5021
5022             child = parentView;
5023             parent = child.getParent();
5024         }
5025
5026         return scrolled;
5027     }
5028
5029     /**
5030      * Called when this view wants to give up focus. If focus is cleared
5031      * {@link #onFocusChanged(boolean, int, android.graphics.Rect)} is called.
5032      * <p>
5033      * <strong>Note:</strong> When a View clears focus the framework is trying
5034      * to give focus to the first focusable View from the top. Hence, if this
5035      * View is the first from the top that can take focus, then all callbacks
5036      * related to clearing focus will be invoked after which the framework will
5037      * give focus to this view.
5038      * </p>
5039      */
5040     public void clearFocus() {
5041         if (DBG) {
5042             System.out.println(this + " clearFocus()");
5043         }
5044
5045         clearFocusInternal(null, true, true);
5046     }
5047
5048     /**
5049      * Clears focus from the view, optionally propagating the change up through
5050      * the parent hierarchy and requesting that the root view place new focus.
5051      *
5052      * @param propagate whether to propagate the change up through the parent
5053      *            hierarchy
5054      * @param refocus when propagate is true, specifies whether to request the
5055      *            root view place new focus
5056      */
5057     void clearFocusInternal(View focused, boolean propagate, boolean refocus) {
5058         if ((mPrivateFlags & PFLAG_FOCUSED) != 0) {
5059             mPrivateFlags &= ~PFLAG_FOCUSED;
5060
5061             if (propagate && mParent != null) {
5062                 mParent.clearChildFocus(this);
5063             }
5064
5065             onFocusChanged(false, 0, null);
5066             refreshDrawableState();
5067
5068             if (propagate && (!refocus || !rootViewRequestFocus())) {
5069                 notifyGlobalFocusCleared(this);
5070             }
5071         }
5072     }
5073
5074     void notifyGlobalFocusCleared(View oldFocus) {
5075         if (oldFocus != null && mAttachInfo != null) {
5076             mAttachInfo.mTreeObserver.dispatchOnGlobalFocusChange(oldFocus, null);
5077         }
5078     }
5079
5080     boolean rootViewRequestFocus() {
5081         final View root = getRootView();
5082         return root != null && root.requestFocus();
5083     }
5084
5085     /**
5086      * Called internally by the view system when a new view is getting focus.
5087      * This is what clears the old focus.
5088      * <p>
5089      * <b>NOTE:</b> The parent view's focused child must be updated manually
5090      * after calling this method. Otherwise, the view hierarchy may be left in
5091      * an inconstent state.
5092      */
5093     void unFocus(View focused) {
5094         if (DBG) {
5095             System.out.println(this + " unFocus()");
5096         }
5097
5098         clearFocusInternal(focused, false, false);
5099     }
5100
5101     /**
5102      * Returns true if this view has focus iteself, or is the ancestor of the
5103      * view that has focus.
5104      *
5105      * @return True if this view has or contains focus, false otherwise.
5106      */
5107     @ViewDebug.ExportedProperty(category = "focus")
5108     public boolean hasFocus() {
5109         return (mPrivateFlags & PFLAG_FOCUSED) != 0;
5110     }
5111
5112     /**
5113      * Returns true if this view is focusable or if it contains a reachable View
5114      * for which {@link #hasFocusable()} returns true. A "reachable hasFocusable()"
5115      * is a View whose parents do not block descendants focus.
5116      *
5117      * Only {@link #VISIBLE} views are considered focusable.
5118      *
5119      * @return True if the view is focusable or if the view contains a focusable
5120      *         View, false otherwise.
5121      *
5122      * @see ViewGroup#FOCUS_BLOCK_DESCENDANTS
5123      * @see ViewGroup#getTouchscreenBlocksFocus()
5124      */
5125     public boolean hasFocusable() {
5126         if (!isFocusableInTouchMode()) {
5127             for (ViewParent p = mParent; p instanceof ViewGroup; p = p.getParent()) {
5128                 final ViewGroup g = (ViewGroup) p;
5129                 if (g.shouldBlockFocusForTouchscreen()) {
5130                     return false;
5131                 }
5132             }
5133         }
5134         return (mViewFlags & VISIBILITY_MASK) == VISIBLE && isFocusable();
5135     }
5136
5137     /**
5138      * Called by the view system when the focus state of this view changes.
5139      * When the focus change event is caused by directional navigation, direction
5140      * and previouslyFocusedRect provide insight into where the focus is coming from.
5141      * When overriding, be sure to call up through to the super class so that
5142      * the standard focus handling will occur.
5143      *
5144      * @param gainFocus True if the View has focus; false otherwise.
5145      * @param direction The direction focus has moved when requestFocus()
5146      *                  is called to give this view focus. Values are
5147      *                  {@link #FOCUS_UP}, {@link #FOCUS_DOWN}, {@link #FOCUS_LEFT},
5148      *                  {@link #FOCUS_RIGHT}, {@link #FOCUS_FORWARD}, or {@link #FOCUS_BACKWARD}.
5149      *                  It may not always apply, in which case use the default.
5150      * @param previouslyFocusedRect The rectangle, in this view's coordinate
5151      *        system, of the previously focused view.  If applicable, this will be
5152      *        passed in as finer grained information about where the focus is coming
5153      *        from (in addition to direction).  Will be <code>null</code> otherwise.
5154      */
5155     protected void onFocusChanged(boolean gainFocus, @FocusDirection int direction,
5156             @Nullable Rect previouslyFocusedRect) {
5157         if (gainFocus) {
5158             sendAccessibilityEvent(AccessibilityEvent.TYPE_VIEW_FOCUSED);
5159         } else {
5160             notifyViewAccessibilityStateChangedIfNeeded(
5161                     AccessibilityEvent.CONTENT_CHANGE_TYPE_UNDEFINED);
5162         }
5163
5164         InputMethodManager imm = InputMethodManager.peekInstance();
5165         if (!gainFocus) {
5166             if (isPressed()) {
5167                 setPressed(false);
5168             }
5169             if (imm != null && mAttachInfo != null
5170                     && mAttachInfo.mHasWindowFocus) {
5171                 imm.focusOut(this);
5172             }
5173             onFocusLost();
5174         } else if (imm != null && mAttachInfo != null
5175                 && mAttachInfo.mHasWindowFocus) {
5176             imm.focusIn(this);
5177         }
5178
5179         invalidate(true);
5180         ListenerInfo li = mListenerInfo;
5181         if (li != null && li.mOnFocusChangeListener != null) {
5182             li.mOnFocusChangeListener.onFocusChange(this, gainFocus);
5183         }
5184
5185         if (mAttachInfo != null) {
5186             mAttachInfo.mKeyDispatchState.reset(this);
5187         }
5188     }
5189
5190     /**
5191      * Sends an accessibility event of the given type. If accessibility is
5192      * not enabled this method has no effect. The default implementation calls
5193      * {@link #onInitializeAccessibilityEvent(AccessibilityEvent)} first
5194      * to populate information about the event source (this View), then calls
5195      * {@link #dispatchPopulateAccessibilityEvent(AccessibilityEvent)} to
5196      * populate the text content of the event source including its descendants,
5197      * and last calls
5198      * {@link ViewParent#requestSendAccessibilityEvent(View, AccessibilityEvent)}
5199      * on its parent to resuest sending of the event to interested parties.
5200      * <p>
5201      * If an {@link AccessibilityDelegate} has been specified via calling
5202      * {@link #setAccessibilityDelegate(AccessibilityDelegate)} its
5203      * {@link AccessibilityDelegate#sendAccessibilityEvent(View, int)} is
5204      * responsible for handling this call.
5205      * </p>
5206      *
5207      * @param eventType The type of the event to send, as defined by several types from
5208      * {@link android.view.accessibility.AccessibilityEvent}, such as
5209      * {@link android.view.accessibility.AccessibilityEvent#TYPE_VIEW_CLICKED} or
5210      * {@link android.view.accessibility.AccessibilityEvent#TYPE_VIEW_HOVER_ENTER}.
5211      *
5212      * @see #onInitializeAccessibilityEvent(AccessibilityEvent)
5213      * @see #dispatchPopulateAccessibilityEvent(AccessibilityEvent)
5214      * @see ViewParent#requestSendAccessibilityEvent(View, AccessibilityEvent)
5215      * @see AccessibilityDelegate
5216      */
5217     public void sendAccessibilityEvent(int eventType) {
5218         if (mAccessibilityDelegate != null) {
5219             mAccessibilityDelegate.sendAccessibilityEvent(this, eventType);
5220         } else {
5221             sendAccessibilityEventInternal(eventType);
5222         }
5223     }
5224
5225     /**
5226      * Convenience method for sending a {@link AccessibilityEvent#TYPE_ANNOUNCEMENT}
5227      * {@link AccessibilityEvent} to make an announcement which is related to some
5228      * sort of a context change for which none of the events representing UI transitions
5229      * is a good fit. For example, announcing a new page in a book. If accessibility
5230      * is not enabled this method does nothing.
5231      *
5232      * @param text The announcement text.
5233      */
5234     public void announceForAccessibility(CharSequence text) {
5235         if (AccessibilityManager.getInstance(mContext).isEnabled() && mParent != null) {
5236             AccessibilityEvent event = AccessibilityEvent.obtain(
5237                     AccessibilityEvent.TYPE_ANNOUNCEMENT);
5238             onInitializeAccessibilityEvent(event);
5239             event.getText().add(text);
5240             event.setContentDescription(null);
5241             mParent.requestSendAccessibilityEvent(this, event);
5242         }
5243     }
5244
5245     /**
5246      * @see #sendAccessibilityEvent(int)
5247      *
5248      * Note: Called from the default {@link AccessibilityDelegate}.
5249      */
5250     void sendAccessibilityEventInternal(int eventType) {
5251         if (AccessibilityManager.getInstance(mContext).isEnabled()) {
5252             sendAccessibilityEventUnchecked(AccessibilityEvent.obtain(eventType));
5253         }
5254     }
5255
5256     /**
5257      * This method behaves exactly as {@link #sendAccessibilityEvent(int)} but
5258      * takes as an argument an empty {@link AccessibilityEvent} and does not
5259      * perform a check whether accessibility is enabled.
5260      * <p>
5261      * If an {@link AccessibilityDelegate} has been specified via calling
5262      * {@link #setAccessibilityDelegate(AccessibilityDelegate)} its
5263      * {@link AccessibilityDelegate#sendAccessibilityEventUnchecked(View, AccessibilityEvent)}
5264      * is responsible for handling this call.
5265      * </p>
5266      *
5267      * @param event The event to send.
5268      *
5269      * @see #sendAccessibilityEvent(int)
5270      */
5271     public void sendAccessibilityEventUnchecked(AccessibilityEvent event) {
5272         if (mAccessibilityDelegate != null) {
5273             mAccessibilityDelegate.sendAccessibilityEventUnchecked(this, event);
5274         } else {
5275             sendAccessibilityEventUncheckedInternal(event);
5276         }
5277     }
5278
5279     /**
5280      * @see #sendAccessibilityEventUnchecked(AccessibilityEvent)
5281      *
5282      * Note: Called from the default {@link AccessibilityDelegate}.
5283      */
5284     void sendAccessibilityEventUncheckedInternal(AccessibilityEvent event) {
5285         if (!isShown()) {
5286             return;
5287         }
5288         onInitializeAccessibilityEvent(event);
5289         // Only a subset of accessibility events populates text content.
5290         if ((event.getEventType() & POPULATING_ACCESSIBILITY_EVENT_TYPES) != 0) {
5291             dispatchPopulateAccessibilityEvent(event);
5292         }
5293         // In the beginning we called #isShown(), so we know that getParent() is not null.
5294         getParent().requestSendAccessibilityEvent(this, event);
5295     }
5296
5297     /**
5298      * Dispatches an {@link AccessibilityEvent} to the {@link View} first and then
5299      * to its children for adding their text content to the event. Note that the
5300      * event text is populated in a separate dispatch path since we add to the
5301      * event not only the text of the source but also the text of all its descendants.
5302      * A typical implementation will call
5303      * {@link #onPopulateAccessibilityEvent(AccessibilityEvent)} on the this view
5304      * and then call the {@link #dispatchPopulateAccessibilityEvent(AccessibilityEvent)}
5305      * on each child. Override this method if custom population of the event text
5306      * content is required.
5307      * <p>
5308      * If an {@link AccessibilityDelegate} has been specified via calling
5309      * {@link #setAccessibilityDelegate(AccessibilityDelegate)} its
5310      * {@link AccessibilityDelegate#dispatchPopulateAccessibilityEvent(View, AccessibilityEvent)}
5311      * is responsible for handling this call.
5312      * </p>
5313      * <p>
5314      * <em>Note:</em> Accessibility events of certain types are not dispatched for
5315      * populating the event text via this method. For details refer to {@link AccessibilityEvent}.
5316      * </p>
5317      *
5318      * @param event The event.
5319      *
5320      * @return True if the event population was completed.
5321      */
5322     public boolean dispatchPopulateAccessibilityEvent(AccessibilityEvent event) {
5323         if (mAccessibilityDelegate != null) {
5324             return mAccessibilityDelegate.dispatchPopulateAccessibilityEvent(this, event);
5325         } else {
5326             return dispatchPopulateAccessibilityEventInternal(event);
5327         }
5328     }
5329
5330     /**
5331      * @see #dispatchPopulateAccessibilityEvent(AccessibilityEvent)
5332      *
5333      * Note: Called from the default {@link AccessibilityDelegate}.
5334      */
5335     boolean dispatchPopulateAccessibilityEventInternal(AccessibilityEvent event) {
5336         onPopulateAccessibilityEvent(event);
5337         return false;
5338     }
5339
5340     /**
5341      * Called from {@link #dispatchPopulateAccessibilityEvent(AccessibilityEvent)}
5342      * giving a chance to this View to populate the accessibility event with its
5343      * text content. While this method is free to modify event
5344      * attributes other than text content, doing so should normally be performed in
5345      * {@link #onInitializeAccessibilityEvent(AccessibilityEvent)}.
5346      * <p>
5347      * Example: Adding formatted date string to an accessibility event in addition
5348      *          to the text added by the super implementation:
5349      * <pre> public void onPopulateAccessibilityEvent(AccessibilityEvent event) {
5350      *     super.onPopulateAccessibilityEvent(event);
5351      *     final int flags = DateUtils.FORMAT_SHOW_DATE | DateUtils.FORMAT_SHOW_WEEKDAY;
5352      *     String selectedDateUtterance = DateUtils.formatDateTime(mContext,
5353      *         mCurrentDate.getTimeInMillis(), flags);
5354      *     event.getText().add(selectedDateUtterance);
5355      * }</pre>
5356      * <p>
5357      * If an {@link AccessibilityDelegate} has been specified via calling
5358      * {@link #setAccessibilityDelegate(AccessibilityDelegate)} its
5359      * {@link AccessibilityDelegate#onPopulateAccessibilityEvent(View, AccessibilityEvent)}
5360      * is responsible for handling this call.
5361      * </p>
5362      * <p class="note"><strong>Note:</strong> Always call the super implementation before adding
5363      * information to the event, in case the default implementation has basic information to add.
5364      * </p>
5365      *
5366      * @param event The accessibility event which to populate.
5367      *
5368      * @see #sendAccessibilityEvent(int)
5369      * @see #dispatchPopulateAccessibilityEvent(AccessibilityEvent)
5370      */
5371     public void onPopulateAccessibilityEvent(AccessibilityEvent event) {
5372         if (mAccessibilityDelegate != null) {
5373             mAccessibilityDelegate.onPopulateAccessibilityEvent(this, event);
5374         } else {
5375             onPopulateAccessibilityEventInternal(event);
5376         }
5377     }
5378
5379     /**
5380      * @see #onPopulateAccessibilityEvent(AccessibilityEvent)
5381      *
5382      * Note: Called from the default {@link AccessibilityDelegate}.
5383      */
5384     void onPopulateAccessibilityEventInternal(AccessibilityEvent event) {
5385     }
5386
5387     /**
5388      * Initializes an {@link AccessibilityEvent} with information about
5389      * this View which is the event source. In other words, the source of
5390      * an accessibility event is the view whose state change triggered firing
5391      * the event.
5392      * <p>
5393      * Example: Setting the password property of an event in addition
5394      *          to properties set by the super implementation:
5395      * <pre> public void onInitializeAccessibilityEvent(AccessibilityEvent event) {
5396      *     super.onInitializeAccessibilityEvent(event);
5397      *     event.setPassword(true);
5398      * }</pre>
5399      * <p>
5400      * If an {@link AccessibilityDelegate} has been specified via calling
5401      * {@link #setAccessibilityDelegate(AccessibilityDelegate)} its
5402      * {@link AccessibilityDelegate#onInitializeAccessibilityEvent(View, AccessibilityEvent)}
5403      * is responsible for handling this call.
5404      * </p>
5405      * <p class="note"><strong>Note:</strong> Always call the super implementation before adding
5406      * information to the event, in case the default implementation has basic information to add.
5407      * </p>
5408      * @param event The event to initialize.
5409      *
5410      * @see #sendAccessibilityEvent(int)
5411      * @see #dispatchPopulateAccessibilityEvent(AccessibilityEvent)
5412      */
5413     public void onInitializeAccessibilityEvent(AccessibilityEvent event) {
5414         if (mAccessibilityDelegate != null) {
5415             mAccessibilityDelegate.onInitializeAccessibilityEvent(this, event);
5416         } else {
5417             onInitializeAccessibilityEventInternal(event);
5418         }
5419     }
5420
5421     /**
5422      * @see #onInitializeAccessibilityEvent(AccessibilityEvent)
5423      *
5424      * Note: Called from the default {@link AccessibilityDelegate}.
5425      */
5426     void onInitializeAccessibilityEventInternal(AccessibilityEvent event) {
5427         event.setSource(this);
5428         event.setClassName(View.class.getName());
5429         event.setPackageName(getContext().getPackageName());
5430         event.setEnabled(isEnabled());
5431         event.setContentDescription(mContentDescription);
5432
5433         switch (event.getEventType()) {
5434             case AccessibilityEvent.TYPE_VIEW_FOCUSED: {
5435                 ArrayList<View> focusablesTempList = (mAttachInfo != null)
5436                         ? mAttachInfo.mTempArrayList : new ArrayList<View>();
5437                 getRootView().addFocusables(focusablesTempList, View.FOCUS_FORWARD, FOCUSABLES_ALL);
5438                 event.setItemCount(focusablesTempList.size());
5439                 event.setCurrentItemIndex(focusablesTempList.indexOf(this));
5440                 if (mAttachInfo != null) {
5441                     focusablesTempList.clear();
5442                 }
5443             } break;
5444             case AccessibilityEvent.TYPE_VIEW_TEXT_SELECTION_CHANGED: {
5445                 CharSequence text = getIterableTextForAccessibility();
5446                 if (text != null && text.length() > 0) {
5447                     event.setFromIndex(getAccessibilitySelectionStart());
5448                     event.setToIndex(getAccessibilitySelectionEnd());
5449                     event.setItemCount(text.length());
5450                 }
5451             } break;
5452         }
5453     }
5454
5455     /**
5456      * Returns an {@link AccessibilityNodeInfo} representing this view from the
5457      * point of view of an {@link android.accessibilityservice.AccessibilityService}.
5458      * This method is responsible for obtaining an accessibility node info from a
5459      * pool of reusable instances and calling
5460      * {@link #onInitializeAccessibilityNodeInfo(AccessibilityNodeInfo)} on this view to
5461      * initialize the former.
5462      * <p>
5463      * Note: The client is responsible for recycling the obtained instance by calling
5464      *       {@link AccessibilityNodeInfo#recycle()} to minimize object creation.
5465      * </p>
5466      *
5467      * @return A populated {@link AccessibilityNodeInfo}.
5468      *
5469      * @see AccessibilityNodeInfo
5470      */
5471     public AccessibilityNodeInfo createAccessibilityNodeInfo() {
5472         if (mAccessibilityDelegate != null) {
5473             return mAccessibilityDelegate.createAccessibilityNodeInfo(this);
5474         } else {
5475             return createAccessibilityNodeInfoInternal();
5476         }
5477     }
5478
5479     /**
5480      * @see #createAccessibilityNodeInfo()
5481      */
5482     AccessibilityNodeInfo createAccessibilityNodeInfoInternal() {
5483         AccessibilityNodeProvider provider = getAccessibilityNodeProvider();
5484         if (provider != null) {
5485             return provider.createAccessibilityNodeInfo(View.NO_ID);
5486         } else {
5487             AccessibilityNodeInfo info = AccessibilityNodeInfo.obtain(this);
5488             onInitializeAccessibilityNodeInfo(info);
5489             return info;
5490         }
5491     }
5492
5493     /**
5494      * Initializes an {@link AccessibilityNodeInfo} with information about this view.
5495      * The base implementation sets:
5496      * <ul>
5497      *   <li>{@link AccessibilityNodeInfo#setParent(View)},</li>
5498      *   <li>{@link AccessibilityNodeInfo#setBoundsInParent(Rect)},</li>
5499      *   <li>{@link AccessibilityNodeInfo#setBoundsInScreen(Rect)},</li>
5500      *   <li>{@link AccessibilityNodeInfo#setPackageName(CharSequence)},</li>
5501      *   <li>{@link AccessibilityNodeInfo#setClassName(CharSequence)},</li>
5502      *   <li>{@link AccessibilityNodeInfo#setContentDescription(CharSequence)},</li>
5503      *   <li>{@link AccessibilityNodeInfo#setEnabled(boolean)},</li>
5504      *   <li>{@link AccessibilityNodeInfo#setClickable(boolean)},</li>
5505      *   <li>{@link AccessibilityNodeInfo#setFocusable(boolean)},</li>
5506      *   <li>{@link AccessibilityNodeInfo#setFocused(boolean)},</li>
5507      *   <li>{@link AccessibilityNodeInfo#setLongClickable(boolean)},</li>
5508      *   <li>{@link AccessibilityNodeInfo#setSelected(boolean)},</li>
5509      * </ul>
5510      * <p>
5511      * Subclasses should override this method, call the super implementation,
5512      * and set additional attributes.
5513      * </p>
5514      * <p>
5515      * If an {@link AccessibilityDelegate} has been specified via calling
5516      * {@link #setAccessibilityDelegate(AccessibilityDelegate)} its
5517      * {@link AccessibilityDelegate#onInitializeAccessibilityNodeInfo(View, AccessibilityNodeInfo)}
5518      * is responsible for handling this call.
5519      * </p>
5520      *
5521      * @param info The instance to initialize.
5522      */
5523     public void onInitializeAccessibilityNodeInfo(AccessibilityNodeInfo info) {
5524         if (mAccessibilityDelegate != null) {
5525             mAccessibilityDelegate.onInitializeAccessibilityNodeInfo(this, info);
5526         } else {
5527             onInitializeAccessibilityNodeInfoInternal(info);
5528         }
5529     }
5530
5531     /**
5532      * Gets the location of this view in screen coordintates.
5533      *
5534      * @param outRect The output location
5535      * @hide
5536      */
5537     public void getBoundsOnScreen(Rect outRect) {
5538         if (mAttachInfo == null) {
5539             return;
5540         }
5541
5542         RectF position = mAttachInfo.mTmpTransformRect;
5543         position.set(0, 0, mRight - mLeft, mBottom - mTop);
5544
5545         if (!hasIdentityMatrix()) {
5546             getMatrix().mapRect(position);
5547         }
5548
5549         position.offset(mLeft, mTop);
5550
5551         ViewParent parent = mParent;
5552         while (parent instanceof View) {
5553             View parentView = (View) parent;
5554
5555             position.offset(-parentView.mScrollX, -parentView.mScrollY);
5556
5557             if (!parentView.hasIdentityMatrix()) {
5558                 parentView.getMatrix().mapRect(position);
5559             }
5560
5561             position.offset(parentView.mLeft, parentView.mTop);
5562
5563             parent = parentView.mParent;
5564         }
5565
5566         if (parent instanceof ViewRootImpl) {
5567             ViewRootImpl viewRootImpl = (ViewRootImpl) parent;
5568             position.offset(0, -viewRootImpl.mCurScrollY);
5569         }
5570
5571         position.offset(mAttachInfo.mWindowLeft, mAttachInfo.mWindowTop);
5572
5573         outRect.set((int) (position.left + 0.5f), (int) (position.top + 0.5f),
5574                 (int) (position.right + 0.5f), (int) (position.bottom + 0.5f));
5575     }
5576
5577     /**
5578      * @see #onInitializeAccessibilityNodeInfo(AccessibilityNodeInfo)
5579      *
5580      * Note: Called from the default {@link AccessibilityDelegate}.
5581      */
5582     void onInitializeAccessibilityNodeInfoInternal(AccessibilityNodeInfo info) {
5583         Rect bounds = mAttachInfo.mTmpInvalRect;
5584
5585         getDrawingRect(bounds);
5586         info.setBoundsInParent(bounds);
5587
5588         getBoundsOnScreen(bounds);
5589         info.setBoundsInScreen(bounds);
5590
5591         ViewParent parent = getParentForAccessibility();
5592         if (parent instanceof View) {
5593             info.setParent((View) parent);
5594         }
5595
5596         if (mID != View.NO_ID) {
5597             View rootView = getRootView();
5598             if (rootView == null) {
5599                 rootView = this;
5600             }
5601             View label = rootView.findLabelForView(this, mID);
5602             if (label != null) {
5603                 info.setLabeledBy(label);
5604             }
5605
5606             if ((mAttachInfo.mAccessibilityFetchFlags
5607                     & AccessibilityNodeInfo.FLAG_REPORT_VIEW_IDS) != 0
5608                     && Resources.resourceHasPackage(mID)) {
5609                 try {
5610                     String viewId = getResources().getResourceName(mID);
5611                     info.setViewIdResourceName(viewId);
5612                 } catch (Resources.NotFoundException nfe) {
5613                     /* ignore */
5614                 }
5615             }
5616         }
5617
5618         if (mLabelForId != View.NO_ID) {
5619             View rootView = getRootView();
5620             if (rootView == null) {
5621                 rootView = this;
5622             }
5623             View labeled = rootView.findViewInsideOutShouldExist(this, mLabelForId);
5624             if (labeled != null) {
5625                 info.setLabelFor(labeled);
5626             }
5627         }
5628
5629         info.setVisibleToUser(isVisibleToUser());
5630
5631         info.setPackageName(mContext.getPackageName());
5632         info.setClassName(View.class.getName());
5633         info.setContentDescription(getContentDescription());
5634
5635         info.setEnabled(isEnabled());
5636         info.setClickable(isClickable());
5637         info.setFocusable(isFocusable());
5638         info.setFocused(isFocused());
5639         info.setAccessibilityFocused(isAccessibilityFocused());
5640         info.setSelected(isSelected());
5641         info.setLongClickable(isLongClickable());
5642         info.setLiveRegion(getAccessibilityLiveRegion());
5643
5644         // TODO: These make sense only if we are in an AdapterView but all
5645         // views can be selected. Maybe from accessibility perspective
5646         // we should report as selectable view in an AdapterView.
5647         info.addAction(AccessibilityNodeInfo.ACTION_SELECT);
5648         info.addAction(AccessibilityNodeInfo.ACTION_CLEAR_SELECTION);
5649
5650         if (isFocusable()) {
5651             if (isFocused()) {
5652                 info.addAction(AccessibilityNodeInfo.ACTION_CLEAR_FOCUS);
5653             } else {
5654                 info.addAction(AccessibilityNodeInfo.ACTION_FOCUS);
5655             }
5656         }
5657
5658         if (!isAccessibilityFocused()) {
5659             info.addAction(AccessibilityNodeInfo.ACTION_ACCESSIBILITY_FOCUS);
5660         } else {
5661             info.addAction(AccessibilityNodeInfo.ACTION_CLEAR_ACCESSIBILITY_FOCUS);
5662         }
5663
5664         if (isClickable() && isEnabled()) {
5665             info.addAction(AccessibilityNodeInfo.ACTION_CLICK);
5666         }
5667
5668         if (isLongClickable() && isEnabled()) {
5669             info.addAction(AccessibilityNodeInfo.ACTION_LONG_CLICK);
5670         }
5671
5672         CharSequence text = getIterableTextForAccessibility();
5673         if (text != null && text.length() > 0) {
5674             info.setTextSelection(getAccessibilitySelectionStart(), getAccessibilitySelectionEnd());
5675
5676             info.addAction(AccessibilityNodeInfo.ACTION_SET_SELECTION);
5677             info.addAction(AccessibilityNodeInfo.ACTION_NEXT_AT_MOVEMENT_GRANULARITY);
5678             info.addAction(AccessibilityNodeInfo.ACTION_PREVIOUS_AT_MOVEMENT_GRANULARITY);
5679             info.setMovementGranularities(AccessibilityNodeInfo.MOVEMENT_GRANULARITY_CHARACTER
5680                     | AccessibilityNodeInfo.MOVEMENT_GRANULARITY_WORD
5681                     | AccessibilityNodeInfo.MOVEMENT_GRANULARITY_PARAGRAPH);
5682         }
5683     }
5684
5685     private View findLabelForView(View view, int labeledId) {
5686         if (mMatchLabelForPredicate == null) {
5687             mMatchLabelForPredicate = new MatchLabelForPredicate();
5688         }
5689         mMatchLabelForPredicate.mLabeledId = labeledId;
5690         return findViewByPredicateInsideOut(view, mMatchLabelForPredicate);
5691     }
5692
5693     /**
5694      * Computes whether this view is visible to the user. Such a view is
5695      * attached, visible, all its predecessors are visible, it is not clipped
5696      * entirely by its predecessors, and has an alpha greater than zero.
5697      *
5698      * @return Whether the view is visible on the screen.
5699      *
5700      * @hide
5701      */
5702     protected boolean isVisibleToUser() {
5703         return isVisibleToUser(null);
5704     }
5705
5706     /**
5707      * Computes whether the given portion of this view is visible to the user.
5708      * Such a view is attached, visible, all its predecessors are visible,
5709      * has an alpha greater than zero, and the specified portion is not
5710      * clipped entirely by its predecessors.
5711      *
5712      * @param boundInView the portion of the view to test; coordinates should be relative; may be
5713      *                    <code>null</code>, and the entire view will be tested in this case.
5714      *                    When <code>true</code> is returned by the function, the actual visible
5715      *                    region will be stored in this parameter; that is, if boundInView is fully
5716      *                    contained within the view, no modification will be made, otherwise regions
5717      *                    outside of the visible area of the view will be clipped.
5718      *
5719      * @return Whether the specified portion of the view is visible on the screen.
5720      *
5721      * @hide
5722      */
5723     protected boolean isVisibleToUser(Rect boundInView) {
5724         if (mAttachInfo != null) {
5725             // Attached to invisible window means this view is not visible.
5726             if (mAttachInfo.mWindowVisibility != View.VISIBLE) {
5727                 return false;
5728             }
5729             // An invisible predecessor or one with alpha zero means
5730             // that this view is not visible to the user.
5731             Object current = this;
5732             while (current instanceof View) {
5733                 View view = (View) current;
5734                 // We have attach info so this view is attached and there is no
5735                 // need to check whether we reach to ViewRootImpl on the way up.
5736                 if (view.getAlpha() <= 0 || view.getTransitionAlpha() <= 0 ||
5737                         view.getVisibility() != VISIBLE) {
5738                     return false;
5739                 }
5740                 current = view.mParent;
5741             }
5742             // Check if the view is entirely covered by its predecessors.
5743             Rect visibleRect = mAttachInfo.mTmpInvalRect;
5744             Point offset = mAttachInfo.mPoint;
5745             if (!getGlobalVisibleRect(visibleRect, offset)) {
5746                 return false;
5747             }
5748             // Check if the visible portion intersects the rectangle of interest.
5749             if (boundInView != null) {
5750                 visibleRect.offset(-offset.x, -offset.y);
5751                 return boundInView.intersect(visibleRect);
5752             }
5753             return true;
5754         }
5755         return false;
5756     }
5757
5758     /**
5759      * Computes a point on which a sequence of a down/up event can be sent to
5760      * trigger clicking this view. This method is for the exclusive use by the
5761      * accessibility layer to determine where to send a click event in explore
5762      * by touch mode.
5763      *
5764      * @param interactiveRegion The interactive portion of this window.
5765      * @param outPoint The point to populate.
5766      * @return True of such a point exists.
5767      */
5768     boolean computeClickPointInScreenForAccessibility(Region interactiveRegion,
5769             Point outPoint) {
5770         // Since the interactive portion of the view is a region but as a view
5771         // may have a transformation matrix which cannot be applied to a
5772         // region we compute the view bounds rectangle and all interactive
5773         // predecessor's and sibling's (siblings of predecessors included)
5774         // rectangles that intersect the view bounds. At the
5775         // end if the view was partially covered by another interactive
5776         // view we compute the view's interactive region and pick a point
5777         // on its boundary path as regions do not offer APIs to get inner
5778         // points. Note that the the code is optimized to fail early and
5779         // avoid unnecessary allocations plus computations.
5780
5781         // The current approach has edge cases that may produce false
5782         // positives or false negatives. For example, a portion of the
5783         // view may be covered by an interactive descendant of a
5784         // predecessor, which we do not compute. Also a view may be handling
5785         // raw touch events instead registering click listeners, which
5786         // we cannot compute. Despite these limitations this approach will
5787         // work most of the time and it is a huge improvement over just
5788         // blindly sending the down and up events in the center of the
5789         // view.
5790
5791         // Cannot click on an unattached view.
5792         if (mAttachInfo == null) {
5793             return false;
5794         }
5795
5796         // Attached to an invisible window means this view is not visible.
5797         if (mAttachInfo.mWindowVisibility != View.VISIBLE) {
5798             return false;
5799         }
5800
5801         RectF bounds = mAttachInfo.mTmpTransformRect;
5802         bounds.set(0, 0, getWidth(), getHeight());
5803         List<RectF> intersections = mAttachInfo.mTmpRectList;
5804         intersections.clear();
5805
5806         if (mParent instanceof ViewGroup) {
5807             ViewGroup parentGroup = (ViewGroup) mParent;
5808             if (!parentGroup.translateBoundsAndIntersectionsInWindowCoordinates(
5809                     this, bounds, intersections)) {
5810                 intersections.clear();
5811                 return false;
5812             }
5813         }
5814
5815         // Take into account the window location.
5816         final int dx = mAttachInfo.mWindowLeft;
5817         final int dy = mAttachInfo.mWindowTop;
5818         bounds.offset(dx, dy);
5819         offsetRects(intersections, dx, dy);
5820
5821         if (intersections.isEmpty() && interactiveRegion == null) {
5822             outPoint.set((int) bounds.centerX(), (int) bounds.centerY());
5823         } else {
5824             // This view is partially covered by other views, then compute
5825             // the not covered region and pick a point on its boundary.
5826             Region region = new Region();
5827             region.set((int) bounds.left, (int) bounds.top,
5828                     (int) bounds.right, (int) bounds.bottom);
5829
5830             final int intersectionCount = intersections.size();
5831             for (int i = intersectionCount - 1; i >= 0; i--) {
5832                 RectF intersection = intersections.remove(i);
5833                 region.op((int) intersection.left, (int) intersection.top,
5834                         (int) intersection.right, (int) intersection.bottom,
5835                         Region.Op.DIFFERENCE);
5836             }
5837
5838             // If the view is completely covered, done.
5839             if (region.isEmpty()) {
5840                 return false;
5841             }
5842
5843             // Take into account the interactive portion of the window
5844             // as the rest is covered by other windows. If no such a region
5845             // then the whole window is interactive.
5846             if (interactiveRegion != null) {
5847                 region.op(interactiveRegion, Region.Op.INTERSECT);
5848             }
5849
5850             // If the view is completely covered, done.
5851             if (region.isEmpty()) {
5852                 return false;
5853             }
5854
5855             // Try a shortcut here.
5856             if (region.isRect()) {
5857                 Rect regionBounds = mAttachInfo.mTmpInvalRect;
5858                 region.getBounds(regionBounds);
5859                 outPoint.set(regionBounds.centerX(), regionBounds.centerY());
5860                 return true;
5861             }
5862
5863             // Get the a point on the region boundary path.
5864             Path path = region.getBoundaryPath();
5865             PathMeasure pathMeasure = new PathMeasure(path, false);
5866             final float[] coordinates = mAttachInfo.mTmpTransformLocation;
5867
5868             // Without loss of generality pick a point.
5869             final float point = pathMeasure.getLength() * 0.01f;
5870             if (!pathMeasure.getPosTan(point, coordinates, null)) {
5871                 return false;
5872             }
5873
5874             outPoint.set(Math.round(coordinates[0]), Math.round(coordinates[1]));
5875         }
5876
5877         return true;
5878     }
5879
5880     static void offsetRects(List<RectF> rects, float offsetX, float offsetY) {
5881         final int rectCount = rects.size();
5882         for (int i = 0; i < rectCount; i++) {
5883             RectF intersection = rects.get(i);
5884             intersection.offset(offsetX, offsetY);
5885         }
5886     }
5887
5888     /**
5889      * Returns the delegate for implementing accessibility support via
5890      * composition. For more details see {@link AccessibilityDelegate}.
5891      *
5892      * @return The delegate, or null if none set.
5893      *
5894      * @hide
5895      */
5896     public AccessibilityDelegate getAccessibilityDelegate() {
5897         return mAccessibilityDelegate;
5898     }
5899
5900     /**
5901      * Sets a delegate for implementing accessibility support via composition as
5902      * opposed to inheritance. The delegate's primary use is for implementing
5903      * backwards compatible widgets. For more details see {@link AccessibilityDelegate}.
5904      *
5905      * @param delegate The delegate instance.
5906      *
5907      * @see AccessibilityDelegate
5908      */
5909     public void setAccessibilityDelegate(AccessibilityDelegate delegate) {
5910         mAccessibilityDelegate = delegate;
5911     }
5912
5913     /**
5914      * Gets the provider for managing a virtual view hierarchy rooted at this View
5915      * and reported to {@link android.accessibilityservice.AccessibilityService}s
5916      * that explore the window content.
5917      * <p>
5918      * If this method returns an instance, this instance is responsible for managing
5919      * {@link AccessibilityNodeInfo}s describing the virtual sub-tree rooted at this
5920      * View including the one representing the View itself. Similarly the returned
5921      * instance is responsible for performing accessibility actions on any virtual
5922      * view or the root view itself.
5923      * </p>
5924      * <p>
5925      * If an {@link AccessibilityDelegate} has been specified via calling
5926      * {@link #setAccessibilityDelegate(AccessibilityDelegate)} its
5927      * {@link AccessibilityDelegate#getAccessibilityNodeProvider(View)}
5928      * is responsible for handling this call.
5929      * </p>
5930      *
5931      * @return The provider.
5932      *
5933      * @see AccessibilityNodeProvider
5934      */
5935     public AccessibilityNodeProvider getAccessibilityNodeProvider() {
5936         if (mAccessibilityDelegate != null) {
5937             return mAccessibilityDelegate.getAccessibilityNodeProvider(this);
5938         } else {
5939             return null;
5940         }
5941     }
5942
5943     /**
5944      * Gets the unique identifier of this view on the screen for accessibility purposes.
5945      * If this {@link View} is not attached to any window, {@value #NO_ID} is returned.
5946      *
5947      * @return The view accessibility id.
5948      *
5949      * @hide
5950      */
5951     public int getAccessibilityViewId() {
5952         if (mAccessibilityViewId == NO_ID) {
5953             mAccessibilityViewId = sNextAccessibilityViewId++;
5954         }
5955         return mAccessibilityViewId;
5956     }
5957
5958     /**
5959      * Gets the unique identifier of the window in which this View reseides.
5960      *
5961      * @return The window accessibility id.
5962      *
5963      * @hide
5964      */
5965     public int getAccessibilityWindowId() {
5966         return mAttachInfo != null ? mAttachInfo.mAccessibilityWindowId
5967                 : AccessibilityNodeInfo.UNDEFINED_ITEM_ID;
5968     }
5969
5970     /**
5971      * Gets the {@link View} description. It briefly describes the view and is
5972      * primarily used for accessibility support. Set this property to enable
5973      * better accessibility support for your application. This is especially
5974      * true for views that do not have textual representation (For example,
5975      * ImageButton).
5976      *
5977      * @return The content description.
5978      *
5979      * @attr ref android.R.styleable#View_contentDescription
5980      */
5981     @ViewDebug.ExportedProperty(category = "accessibility")
5982     public CharSequence getContentDescription() {
5983         return mContentDescription;
5984     }
5985
5986     /**
5987      * Sets the {@link View} description. It briefly describes the view and is
5988      * primarily used for accessibility support. Set this property to enable
5989      * better accessibility support for your application. This is especially
5990      * true for views that do not have textual representation (For example,
5991      * ImageButton).
5992      *
5993      * @param contentDescription The content description.
5994      *
5995      * @attr ref android.R.styleable#View_contentDescription
5996      */
5997     @RemotableViewMethod
5998     public void setContentDescription(CharSequence contentDescription) {
5999         if (mContentDescription == null) {
6000             if (contentDescription == null) {
6001                 return;
6002             }
6003         } else if (mContentDescription.equals(contentDescription)) {
6004             return;
6005         }
6006         mContentDescription = contentDescription;
6007         final boolean nonEmptyDesc = contentDescription != null && contentDescription.length() > 0;
6008         if (nonEmptyDesc && getImportantForAccessibility() == IMPORTANT_FOR_ACCESSIBILITY_AUTO) {
6009             setImportantForAccessibility(IMPORTANT_FOR_ACCESSIBILITY_YES);
6010             notifySubtreeAccessibilityStateChangedIfNeeded();
6011         } else {
6012             notifyViewAccessibilityStateChangedIfNeeded(
6013                     AccessibilityEvent.CONTENT_CHANGE_TYPE_CONTENT_DESCRIPTION);
6014         }
6015     }
6016
6017     /**
6018      * Gets the id of a view for which this view serves as a label for
6019      * accessibility purposes.
6020      *
6021      * @return The labeled view id.
6022      */
6023     @ViewDebug.ExportedProperty(category = "accessibility")
6024     public int getLabelFor() {
6025         return mLabelForId;
6026     }
6027
6028     /**
6029      * Sets the id of a view for which this view serves as a label for
6030      * accessibility purposes.
6031      *
6032      * @param id The labeled view id.
6033      */
6034     @RemotableViewMethod
6035     public void setLabelFor(int id) {
6036         mLabelForId = id;
6037         if (mLabelForId != View.NO_ID
6038                 && mID == View.NO_ID) {
6039             mID = generateViewId();
6040         }
6041     }
6042
6043     /**
6044      * Invoked whenever this view loses focus, either by losing window focus or by losing
6045      * focus within its window. This method can be used to clear any state tied to the
6046      * focus. For instance, if a button is held pressed with the trackball and the window
6047      * loses focus, this method can be used to cancel the press.
6048      *
6049      * Subclasses of View overriding this method should always call super.onFocusLost().
6050      *
6051      * @see #onFocusChanged(boolean, int, android.graphics.Rect)
6052      * @see #onWindowFocusChanged(boolean)
6053      *
6054      * @hide pending API council approval
6055      */
6056     protected void onFocusLost() {
6057         resetPressedState();
6058     }
6059
6060     private void resetPressedState() {
6061         if ((mViewFlags & ENABLED_MASK) == DISABLED) {
6062             return;
6063         }
6064
6065         if (isPressed()) {
6066             setPressed(false);
6067
6068             if (!mHasPerformedLongPress) {
6069                 removeLongPressCallback();
6070             }
6071         }
6072     }
6073
6074     /**
6075      * Returns true if this view has focus
6076      *
6077      * @return True if this view has focus, false otherwise.
6078      */
6079     @ViewDebug.ExportedProperty(category = "focus")
6080     public boolean isFocused() {
6081         return (mPrivateFlags & PFLAG_FOCUSED) != 0;
6082     }
6083
6084     /**
6085      * Find the view in the hierarchy rooted at this view that currently has
6086      * focus.
6087      *
6088      * @return The view that currently has focus, or null if no focused view can
6089      *         be found.
6090      */
6091     public View findFocus() {
6092         return (mPrivateFlags & PFLAG_FOCUSED) != 0 ? this : null;
6093     }
6094
6095     /**
6096      * Indicates whether this view is one of the set of scrollable containers in
6097      * its window.
6098      *
6099      * @return whether this view is one of the set of scrollable containers in
6100      * its window
6101      *
6102      * @attr ref android.R.styleable#View_isScrollContainer
6103      */
6104     public boolean isScrollContainer() {
6105         return (mPrivateFlags & PFLAG_SCROLL_CONTAINER_ADDED) != 0;
6106     }
6107
6108     /**
6109      * Change whether this view is one of the set of scrollable containers in
6110      * its window.  This will be used to determine whether the window can
6111      * resize or must pan when a soft input area is open -- scrollable
6112      * containers allow the window to use resize mode since the container
6113      * will appropriately shrink.
6114      *
6115      * @attr ref android.R.styleable#View_isScrollContainer
6116      */
6117     public void setScrollContainer(boolean isScrollContainer) {
6118         if (isScrollContainer) {
6119             if (mAttachInfo != null && (mPrivateFlags&PFLAG_SCROLL_CONTAINER_ADDED) == 0) {
6120                 mAttachInfo.mScrollContainers.add(this);
6121                 mPrivateFlags |= PFLAG_SCROLL_CONTAINER_ADDED;
6122             }
6123             mPrivateFlags |= PFLAG_SCROLL_CONTAINER;
6124         } else {
6125             if ((mPrivateFlags&PFLAG_SCROLL_CONTAINER_ADDED) != 0) {
6126                 mAttachInfo.mScrollContainers.remove(this);
6127             }
6128             mPrivateFlags &= ~(PFLAG_SCROLL_CONTAINER|PFLAG_SCROLL_CONTAINER_ADDED);
6129         }
6130     }
6131
6132     /**
6133      * Returns the quality of the drawing cache.
6134      *
6135      * @return One of {@link #DRAWING_CACHE_QUALITY_AUTO},
6136      *         {@link #DRAWING_CACHE_QUALITY_LOW}, or {@link #DRAWING_CACHE_QUALITY_HIGH}
6137      *
6138      * @see #setDrawingCacheQuality(int)
6139      * @see #setDrawingCacheEnabled(boolean)
6140      * @see #isDrawingCacheEnabled()
6141      *
6142      * @attr ref android.R.styleable#View_drawingCacheQuality
6143      */
6144     @DrawingCacheQuality
6145     public int getDrawingCacheQuality() {
6146         return mViewFlags & DRAWING_CACHE_QUALITY_MASK;
6147     }
6148
6149     /**
6150      * Set the drawing cache quality of this view. This value is used only when the
6151      * drawing cache is enabled
6152      *
6153      * @param quality One of {@link #DRAWING_CACHE_QUALITY_AUTO},
6154      *        {@link #DRAWING_CACHE_QUALITY_LOW}, or {@link #DRAWING_CACHE_QUALITY_HIGH}
6155      *
6156      * @see #getDrawingCacheQuality()
6157      * @see #setDrawingCacheEnabled(boolean)
6158      * @see #isDrawingCacheEnabled()
6159      *
6160      * @attr ref android.R.styleable#View_drawingCacheQuality
6161      */
6162     public void setDrawingCacheQuality(@DrawingCacheQuality int quality) {
6163         setFlags(quality, DRAWING_CACHE_QUALITY_MASK);
6164     }
6165
6166     /**
6167      * Returns whether the screen should remain on, corresponding to the current
6168      * value of {@link #KEEP_SCREEN_ON}.
6169      *
6170      * @return Returns true if {@link #KEEP_SCREEN_ON} is set.
6171      *
6172      * @see #setKeepScreenOn(boolean)
6173      *
6174      * @attr ref android.R.styleable#View_keepScreenOn
6175      */
6176     public boolean getKeepScreenOn() {
6177         return (mViewFlags & KEEP_SCREEN_ON) != 0;
6178     }
6179
6180     /**
6181      * Controls whether the screen should remain on, modifying the
6182      * value of {@link #KEEP_SCREEN_ON}.
6183      *
6184      * @param keepScreenOn Supply true to set {@link #KEEP_SCREEN_ON}.
6185      *
6186      * @see #getKeepScreenOn()
6187      *
6188      * @attr ref android.R.styleable#View_keepScreenOn
6189      */
6190     public void setKeepScreenOn(boolean keepScreenOn) {
6191         setFlags(keepScreenOn ? KEEP_SCREEN_ON : 0, KEEP_SCREEN_ON);
6192     }
6193
6194     /**
6195      * Gets the id of the view to use when the next focus is {@link #FOCUS_LEFT}.
6196      * @return The next focus ID, or {@link #NO_ID} if the framework should decide automatically.
6197      *
6198      * @attr ref android.R.styleable#View_nextFocusLeft
6199      */
6200     public int getNextFocusLeftId() {
6201         return mNextFocusLeftId;
6202     }
6203
6204     /**
6205      * Sets the id of the view to use when the next focus is {@link #FOCUS_LEFT}.
6206      * @param nextFocusLeftId The next focus ID, or {@link #NO_ID} if the framework should
6207      * decide automatically.
6208      *
6209      * @attr ref android.R.styleable#View_nextFocusLeft
6210      */
6211     public void setNextFocusLeftId(int nextFocusLeftId) {
6212         mNextFocusLeftId = nextFocusLeftId;
6213     }
6214
6215     /**
6216      * Gets the id of the view to use when the next focus is {@link #FOCUS_RIGHT}.
6217      * @return The next focus ID, or {@link #NO_ID} if the framework should decide automatically.
6218      *
6219      * @attr ref android.R.styleable#View_nextFocusRight
6220      */
6221     public int getNextFocusRightId() {
6222         return mNextFocusRightId;
6223     }
6224
6225     /**
6226      * Sets the id of the view to use when the next focus is {@link #FOCUS_RIGHT}.
6227      * @param nextFocusRightId The next focus ID, or {@link #NO_ID} if the framework should
6228      * decide automatically.
6229      *
6230      * @attr ref android.R.styleable#View_nextFocusRight
6231      */
6232     public void setNextFocusRightId(int nextFocusRightId) {
6233         mNextFocusRightId = nextFocusRightId;
6234     }
6235
6236     /**
6237      * Gets the id of the view to use when the next focus is {@link #FOCUS_UP}.
6238      * @return The next focus ID, or {@link #NO_ID} if the framework should decide automatically.
6239      *
6240      * @attr ref android.R.styleable#View_nextFocusUp
6241      */
6242     public int getNextFocusUpId() {
6243         return mNextFocusUpId;
6244     }
6245
6246     /**
6247      * Sets the id of the view to use when the next focus is {@link #FOCUS_UP}.
6248      * @param nextFocusUpId The next focus ID, or {@link #NO_ID} if the framework should
6249      * decide automatically.
6250      *
6251      * @attr ref android.R.styleable#View_nextFocusUp
6252      */
6253     public void setNextFocusUpId(int nextFocusUpId) {
6254         mNextFocusUpId = nextFocusUpId;
6255     }
6256
6257     /**
6258      * Gets the id of the view to use when the next focus is {@link #FOCUS_DOWN}.
6259      * @return The next focus ID, or {@link #NO_ID} if the framework should decide automatically.
6260      *
6261      * @attr ref android.R.styleable#View_nextFocusDown
6262      */
6263     public int getNextFocusDownId() {
6264         return mNextFocusDownId;
6265     }
6266
6267     /**
6268      * Sets the id of the view to use when the next focus is {@link #FOCUS_DOWN}.
6269      * @param nextFocusDownId The next focus ID, or {@link #NO_ID} if the framework should
6270      * decide automatically.
6271      *
6272      * @attr ref android.R.styleable#View_nextFocusDown
6273      */
6274     public void setNextFocusDownId(int nextFocusDownId) {
6275         mNextFocusDownId = nextFocusDownId;
6276     }
6277
6278     /**
6279      * Gets the id of the view to use when the next focus is {@link #FOCUS_FORWARD}.
6280      * @return The next focus ID, or {@link #NO_ID} if the framework should decide automatically.
6281      *
6282      * @attr ref android.R.styleable#View_nextFocusForward
6283      */
6284     public int getNextFocusForwardId() {
6285         return mNextFocusForwardId;
6286     }
6287
6288     /**
6289      * Sets the id of the view to use when the next focus is {@link #FOCUS_FORWARD}.
6290      * @param nextFocusForwardId The next focus ID, or {@link #NO_ID} if the framework should
6291      * decide automatically.
6292      *
6293      * @attr ref android.R.styleable#View_nextFocusForward
6294      */
6295     public void setNextFocusForwardId(int nextFocusForwardId) {
6296         mNextFocusForwardId = nextFocusForwardId;
6297     }
6298
6299     /**
6300      * Returns the visibility of this view and all of its ancestors
6301      *
6302      * @return True if this view and all of its ancestors are {@link #VISIBLE}
6303      */
6304     public boolean isShown() {
6305         View current = this;
6306         //noinspection ConstantConditions
6307         do {
6308             if ((current.mViewFlags & VISIBILITY_MASK) != VISIBLE) {
6309                 return false;
6310             }
6311             ViewParent parent = current.mParent;
6312             if (parent == null) {
6313                 return false; // We are not attached to the view root
6314             }
6315             if (!(parent instanceof View)) {
6316                 return true;
6317             }
6318             current = (View) parent;
6319         } while (current != null);
6320
6321         return false;
6322     }
6323
6324     /**
6325      * Called by the view hierarchy when the content insets for a window have
6326      * changed, to allow it to adjust its content to fit within those windows.
6327      * The content insets tell you the space that the status bar, input method,
6328      * and other system windows infringe on the application's window.
6329      *
6330      * <p>You do not normally need to deal with this function, since the default
6331      * window decoration given to applications takes care of applying it to the
6332      * content of the window.  If you use {@link #SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN}
6333      * or {@link #SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION} this will not be the case,
6334      * and your content can be placed under those system elements.  You can then
6335      * use this method within your view hierarchy if you have parts of your UI
6336      * which you would like to ensure are not being covered.
6337      *
6338      * <p>The default implementation of this method simply applies the content
6339      * insets to the view's padding, consuming that content (modifying the
6340      * insets to be 0), and returning true.  This behavior is off by default, but can
6341      * be enabled through {@link #setFitsSystemWindows(boolean)}.
6342      *
6343      * <p>This function's traversal down the hierarchy is depth-first.  The same content
6344      * insets object is propagated down the hierarchy, so any changes made to it will
6345      * be seen by all following views (including potentially ones above in
6346      * the hierarchy since this is a depth-first traversal).  The first view
6347      * that returns true will abort the entire traversal.
6348      *
6349      * <p>The default implementation works well for a situation where it is
6350      * used with a container that covers the entire window, allowing it to
6351      * apply the appropriate insets to its content on all edges.  If you need
6352      * a more complicated layout (such as two different views fitting system
6353      * windows, one on the top of the window, and one on the bottom),
6354      * you can override the method and handle the insets however you would like.
6355      * Note that the insets provided by the framework are always relative to the
6356      * far edges of the window, not accounting for the location of the called view
6357      * within that window.  (In fact when this method is called you do not yet know
6358      * where the layout will place the view, as it is done before layout happens.)
6359      *
6360      * <p>Note: unlike many View methods, there is no dispatch phase to this
6361      * call.  If you are overriding it in a ViewGroup and want to allow the
6362      * call to continue to your children, you must be sure to call the super
6363      * implementation.
6364      *
6365      * <p>Here is a sample layout that makes use of fitting system windows
6366      * to have controls for a video view placed inside of the window decorations
6367      * that it hides and shows.  This can be used with code like the second
6368      * sample (video player) shown in {@link #setSystemUiVisibility(int)}.
6369      *
6370      * {@sample development/samples/ApiDemos/res/layout/video_player.xml complete}
6371      *
6372      * @param insets Current content insets of the window.  Prior to
6373      * {@link android.os.Build.VERSION_CODES#JELLY_BEAN} you must not modify
6374      * the insets or else you and Android will be unhappy.
6375      *
6376      * @return {@code true} if this view applied the insets and it should not
6377      * continue propagating further down the hierarchy, {@code false} otherwise.
6378      * @see #getFitsSystemWindows()
6379      * @see #setFitsSystemWindows(boolean)
6380      * @see #setSystemUiVisibility(int)
6381      *
6382      * @deprecated As of API 20 use {@link #dispatchApplyWindowInsets(WindowInsets)} to apply
6383      * insets to views. Views should override {@link #onApplyWindowInsets(WindowInsets)} or use
6384      * {@link #setOnApplyWindowInsetsListener(android.view.View.OnApplyWindowInsetsListener)}
6385      * to implement handling their own insets.
6386      */
6387     protected boolean fitSystemWindows(Rect insets) {
6388         if ((mPrivateFlags3 & PFLAG3_APPLYING_INSETS) == 0) {
6389             if (insets == null) {
6390                 // Null insets by definition have already been consumed.
6391                 // This call cannot apply insets since there are none to apply,
6392                 // so return false.
6393                 return false;
6394             }
6395             // If we're not in the process of dispatching the newer apply insets call,
6396             // that means we're not in the compatibility path. Dispatch into the newer
6397             // apply insets path and take things from there.
6398             try {
6399                 mPrivateFlags3 |= PFLAG3_FITTING_SYSTEM_WINDOWS;
6400                 return dispatchApplyWindowInsets(new WindowInsets(insets)).isConsumed();
6401             } finally {
6402                 mPrivateFlags3 &= ~PFLAG3_FITTING_SYSTEM_WINDOWS;
6403             }
6404         } else {
6405             // We're being called from the newer apply insets path.
6406             // Perform the standard fallback behavior.
6407             return fitSystemWindowsInt(insets);
6408         }
6409     }
6410
6411     private boolean fitSystemWindowsInt(Rect insets) {
6412         if ((mViewFlags & FITS_SYSTEM_WINDOWS) == FITS_SYSTEM_WINDOWS) {
6413             mUserPaddingStart = UNDEFINED_PADDING;
6414             mUserPaddingEnd = UNDEFINED_PADDING;
6415             Rect localInsets = sThreadLocal.get();
6416             if (localInsets == null) {
6417                 localInsets = new Rect();
6418                 sThreadLocal.set(localInsets);
6419             }
6420             boolean res = computeFitSystemWindows(insets, localInsets);
6421             mUserPaddingLeftInitial = localInsets.left;
6422             mUserPaddingRightInitial = localInsets.right;
6423             internalSetPadding(localInsets.left, localInsets.top,
6424                     localInsets.right, localInsets.bottom);
6425             return res;
6426         }
6427         return false;
6428     }
6429
6430     /**
6431      * Called when the view should apply {@link WindowInsets} according to its internal policy.
6432      *
6433      * <p>This method should be overridden by views that wish to apply a policy different from or
6434      * in addition to the default behavior. Clients that wish to force a view subtree
6435      * to apply insets should call {@link #dispatchApplyWindowInsets(WindowInsets)}.</p>
6436      *
6437      * <p>Clients may supply an {@link OnApplyWindowInsetsListener} to a view. If one is set
6438      * it will be called during dispatch instead of this method. The listener may optionally
6439      * call this method from its own implementation if it wishes to apply the view's default
6440      * insets policy in addition to its own.</p>
6441      *
6442      * <p>Implementations of this method should either return the insets parameter unchanged
6443      * or a new {@link WindowInsets} cloned from the supplied insets with any insets consumed
6444      * that this view applied itself. This allows new inset types added in future platform
6445      * versions to pass through existing implementations unchanged without being erroneously
6446      * consumed.</p>
6447      *
6448      * <p>By default if a view's {@link #setFitsSystemWindows(boolean) fitsSystemWindows}
6449      * property is set then the view will consume the system window insets and apply them
6450      * as padding for the view.</p>
6451      *
6452      * @param insets Insets to apply
6453      * @return The supplied insets with any applied insets consumed
6454      */
6455     public WindowInsets onApplyWindowInsets(WindowInsets insets) {
6456         if ((mPrivateFlags3 & PFLAG3_FITTING_SYSTEM_WINDOWS) == 0) {
6457             // We weren't called from within a direct call to fitSystemWindows,
6458             // call into it as a fallback in case we're in a class that overrides it
6459             // and has logic to perform.
6460             if (fitSystemWindows(insets.getSystemWindowInsets())) {
6461                 return insets.consumeSystemWindowInsets();
6462             }
6463         } else {
6464             // We were called from within a direct call to fitSystemWindows.
6465             if (fitSystemWindowsInt(insets.getSystemWindowInsets())) {
6466                 return insets.consumeSystemWindowInsets();
6467             }
6468         }
6469         return insets;
6470     }
6471
6472     /**
6473      * Set an {@link OnApplyWindowInsetsListener} to take over the policy for applying
6474      * window insets to this view. The listener's
6475      * {@link OnApplyWindowInsetsListener#onApplyWindowInsets(View, WindowInsets) onApplyWindowInsets}
6476      * method will be called instead of the view's
6477      * {@link #onApplyWindowInsets(WindowInsets) onApplyWindowInsets} method.
6478      *
6479      * @param listener Listener to set
6480      *
6481      * @see #onApplyWindowInsets(WindowInsets)
6482      */
6483     public void setOnApplyWindowInsetsListener(OnApplyWindowInsetsListener listener) {
6484         getListenerInfo().mOnApplyWindowInsetsListener = listener;
6485     }
6486
6487     /**
6488      * Request to apply the given window insets to this view or another view in its subtree.
6489      *
6490      * <p>This method should be called by clients wishing to apply insets corresponding to areas
6491      * obscured by window decorations or overlays. This can include the status and navigation bars,
6492      * action bars, input methods and more. New inset categories may be added in the future.
6493      * The method returns the insets provided minus any that were applied by this view or its
6494      * children.</p>
6495      *
6496      * <p>Clients wishing to provide custom behavior should override the
6497      * {@link #onApplyWindowInsets(WindowInsets)} method or alternatively provide a
6498      * {@link OnApplyWindowInsetsListener} via the
6499      * {@link #setOnApplyWindowInsetsListener(View.OnApplyWindowInsetsListener) setOnApplyWindowInsetsListener}
6500      * method.</p>
6501      *
6502      * <p>This method replaces the older {@link #fitSystemWindows(Rect) fitSystemWindows} method.
6503      * </p>
6504      *
6505      * @param insets Insets to apply
6506      * @return The provided insets minus the insets that were consumed
6507      */
6508     public WindowInsets dispatchApplyWindowInsets(WindowInsets insets) {
6509         try {
6510             mPrivateFlags3 |= PFLAG3_APPLYING_INSETS;
6511             if (mListenerInfo != null && mListenerInfo.mOnApplyWindowInsetsListener != null) {
6512                 return mListenerInfo.mOnApplyWindowInsetsListener.onApplyWindowInsets(this, insets);
6513             } else {
6514                 return onApplyWindowInsets(insets);
6515             }
6516         } finally {
6517             mPrivateFlags3 &= ~PFLAG3_APPLYING_INSETS;
6518         }
6519     }
6520
6521     /**
6522      * @hide Compute the insets that should be consumed by this view and the ones
6523      * that should propagate to those under it.
6524      */
6525     protected boolean computeFitSystemWindows(Rect inoutInsets, Rect outLocalInsets) {
6526         if ((mViewFlags & OPTIONAL_FITS_SYSTEM_WINDOWS) == 0
6527                 || mAttachInfo == null
6528                 || ((mAttachInfo.mSystemUiVisibility & SYSTEM_UI_LAYOUT_FLAGS) == 0
6529                         && !mAttachInfo.mOverscanRequested)) {
6530             outLocalInsets.set(inoutInsets);
6531             inoutInsets.set(0, 0, 0, 0);
6532             return true;
6533         } else {
6534             // The application wants to take care of fitting system window for
6535             // the content...  however we still need to take care of any overscan here.
6536             final Rect overscan = mAttachInfo.mOverscanInsets;
6537             outLocalInsets.set(overscan);
6538             inoutInsets.left -= overscan.left;
6539             inoutInsets.top -= overscan.top;
6540             inoutInsets.right -= overscan.right;
6541             inoutInsets.bottom -= overscan.bottom;
6542             return false;
6543         }
6544     }
6545
6546     /**
6547      * Compute insets that should be consumed by this view and the ones that should propagate
6548      * to those under it.
6549      *
6550      * @param in Insets currently being processed by this View, likely received as a parameter
6551      *           to {@link #onApplyWindowInsets(WindowInsets)}.
6552      * @param outLocalInsets A Rect that will receive the insets that should be consumed
6553      *                       by this view
6554      * @return Insets that should be passed along to views under this one
6555      */
6556     public WindowInsets computeSystemWindowInsets(WindowInsets in, Rect outLocalInsets) {
6557         if ((mViewFlags & OPTIONAL_FITS_SYSTEM_WINDOWS) == 0
6558                 || mAttachInfo == null
6559                 || (mAttachInfo.mSystemUiVisibility & SYSTEM_UI_LAYOUT_FLAGS) == 0) {
6560             outLocalInsets.set(in.getSystemWindowInsets());
6561             return in.consumeSystemWindowInsets();
6562         } else {
6563             outLocalInsets.set(0, 0, 0, 0);
6564             return in;
6565         }
6566     }
6567
6568     /**
6569      * Sets whether or not this view should account for system screen decorations
6570      * such as the status bar and inset its content; that is, controlling whether
6571      * the default implementation of {@link #fitSystemWindows(Rect)} will be
6572      * executed.  See that method for more details.
6573      *
6574      * <p>Note that if you are providing your own implementation of
6575      * {@link #fitSystemWindows(Rect)}, then there is no need to set this
6576      * flag to true -- your implementation will be overriding the default
6577      * implementation that checks this flag.
6578      *
6579      * @param fitSystemWindows If true, then the default implementation of
6580      * {@link #fitSystemWindows(Rect)} will be executed.
6581      *
6582      * @attr ref android.R.styleable#View_fitsSystemWindows
6583      * @see #getFitsSystemWindows()
6584      * @see #fitSystemWindows(Rect)
6585      * @see #setSystemUiVisibility(int)
6586      */
6587     public void setFitsSystemWindows(boolean fitSystemWindows) {
6588         setFlags(fitSystemWindows ? FITS_SYSTEM_WINDOWS : 0, FITS_SYSTEM_WINDOWS);
6589     }
6590
6591     /**
6592      * Check for state of {@link #setFitsSystemWindows(boolean)}. If this method
6593      * returns {@code true}, the default implementation of {@link #fitSystemWindows(Rect)}
6594      * will be executed.
6595      *
6596      * @return {@code true} if the default implementation of
6597      * {@link #fitSystemWindows(Rect)} will be executed.
6598      *
6599      * @attr ref android.R.styleable#View_fitsSystemWindows
6600      * @see #setFitsSystemWindows(boolean)
6601      * @see #fitSystemWindows(Rect)
6602      * @see #setSystemUiVisibility(int)
6603      */
6604     @ViewDebug.ExportedProperty
6605     public boolean getFitsSystemWindows() {
6606         return (mViewFlags & FITS_SYSTEM_WINDOWS) == FITS_SYSTEM_WINDOWS;
6607     }
6608
6609     /** @hide */
6610     public boolean fitsSystemWindows() {
6611         return getFitsSystemWindows();
6612     }
6613
6614     /**
6615      * Ask that a new dispatch of {@link #fitSystemWindows(Rect)} be performed.
6616      * @deprecated Use {@link #requestApplyInsets()} for newer platform versions.
6617      */
6618     public void requestFitSystemWindows() {
6619         if (mParent != null) {
6620             mParent.requestFitSystemWindows();
6621         }
6622     }
6623
6624     /**
6625      * Ask that a new dispatch of {@link #onApplyWindowInsets(WindowInsets)} be performed.
6626      */
6627     public void requestApplyInsets() {
6628         requestFitSystemWindows();
6629     }
6630
6631     /**
6632      * For use by PhoneWindow to make its own system window fitting optional.
6633      * @hide
6634      */
6635     public void makeOptionalFitsSystemWindows() {
6636         setFlags(OPTIONAL_FITS_SYSTEM_WINDOWS, OPTIONAL_FITS_SYSTEM_WINDOWS);
6637     }
6638
6639     /**
6640      * Returns the visibility status for this view.
6641      *
6642      * @return One of {@link #VISIBLE}, {@link #INVISIBLE}, or {@link #GONE}.
6643      * @attr ref android.R.styleable#View_visibility
6644      */
6645     @ViewDebug.ExportedProperty(mapping = {
6646         @ViewDebug.IntToString(from = VISIBLE,   to = "VISIBLE"),
6647         @ViewDebug.IntToString(from = INVISIBLE, to = "INVISIBLE"),
6648         @ViewDebug.IntToString(from = GONE,      to = "GONE")
6649     })
6650     @Visibility
6651     public int getVisibility() {
6652         return mViewFlags & VISIBILITY_MASK;
6653     }
6654
6655     /**
6656      * Set the enabled state of this view.
6657      *
6658      * @param visibility One of {@link #VISIBLE}, {@link #INVISIBLE}, or {@link #GONE}.
6659      * @attr ref android.R.styleable#View_visibility
6660      */
6661     @RemotableViewMethod
6662     public void setVisibility(@Visibility int visibility) {
6663         setFlags(visibility, VISIBILITY_MASK);
6664         if (mBackground != null) mBackground.setVisible(visibility == VISIBLE, false);
6665     }
6666
6667     /**
6668      * Returns the enabled status for this view. The interpretation of the
6669      * enabled state varies by subclass.
6670      *
6671      * @return True if this view is enabled, false otherwise.
6672      */
6673     @ViewDebug.ExportedProperty
6674     public boolean isEnabled() {
6675         return (mViewFlags & ENABLED_MASK) == ENABLED;
6676     }
6677
6678     /**
6679      * Set the enabled state of this view. The interpretation of the enabled
6680      * state varies by subclass.
6681      *
6682      * @param enabled True if this view is enabled, false otherwise.
6683      */
6684     @RemotableViewMethod
6685     public void setEnabled(boolean enabled) {
6686         if (enabled == isEnabled()) return;
6687
6688         setFlags(enabled ? ENABLED : DISABLED, ENABLED_MASK);
6689
6690         /*
6691          * The View most likely has to change its appearance, so refresh
6692          * the drawable state.
6693          */
6694         refreshDrawableState();
6695
6696         // Invalidate too, since the default behavior for views is to be
6697         // be drawn at 50% alpha rather than to change the drawable.
6698         invalidate(true);
6699
6700         if (!enabled) {
6701             cancelPendingInputEvents();
6702         }
6703     }
6704
6705     /**
6706      * Set whether this view can receive the focus.
6707      *
6708      * Setting this to false will also ensure that this view is not focusable
6709      * in touch mode.
6710      *
6711      * @param focusable If true, this view can receive the focus.
6712      *
6713      * @see #setFocusableInTouchMode(boolean)
6714      * @attr ref android.R.styleable#View_focusable
6715      */
6716     public void setFocusable(boolean focusable) {
6717         if (!focusable) {
6718             setFlags(0, FOCUSABLE_IN_TOUCH_MODE);
6719         }
6720         setFlags(focusable ? FOCUSABLE : NOT_FOCUSABLE, FOCUSABLE_MASK);
6721     }
6722
6723     /**
6724      * Set whether this view can receive focus while in touch mode.
6725      *
6726      * Setting this to true will also ensure that this view is focusable.
6727      *
6728      * @param focusableInTouchMode If true, this view can receive the focus while
6729      *   in touch mode.
6730      *
6731      * @see #setFocusable(boolean)
6732      * @attr ref android.R.styleable#View_focusableInTouchMode
6733      */
6734     public void setFocusableInTouchMode(boolean focusableInTouchMode) {
6735         // Focusable in touch mode should always be set before the focusable flag
6736         // otherwise, setting the focusable flag will trigger a focusableViewAvailable()
6737         // which, in touch mode, will not successfully request focus on this view
6738         // because the focusable in touch mode flag is not set
6739         setFlags(focusableInTouchMode ? FOCUSABLE_IN_TOUCH_MODE : 0, FOCUSABLE_IN_TOUCH_MODE);
6740         if (focusableInTouchMode) {
6741             setFlags(FOCUSABLE, FOCUSABLE_MASK);
6742         }
6743     }
6744
6745     /**
6746      * Set whether this view should have sound effects enabled for events such as
6747      * clicking and touching.
6748      *
6749      * <p>You may wish to disable sound effects for a view if you already play sounds,
6750      * for instance, a dial key that plays dtmf tones.
6751      *
6752      * @param soundEffectsEnabled whether sound effects are enabled for this view.
6753      * @see #isSoundEffectsEnabled()
6754      * @see #playSoundEffect(int)
6755      * @attr ref android.R.styleable#View_soundEffectsEnabled
6756      */
6757     public void setSoundEffectsEnabled(boolean soundEffectsEnabled) {
6758         setFlags(soundEffectsEnabled ? SOUND_EFFECTS_ENABLED: 0, SOUND_EFFECTS_ENABLED);
6759     }
6760
6761     /**
6762      * @return whether this view should have sound effects enabled for events such as
6763      *     clicking and touching.
6764      *
6765      * @see #setSoundEffectsEnabled(boolean)
6766      * @see #playSoundEffect(int)
6767      * @attr ref android.R.styleable#View_soundEffectsEnabled
6768      */
6769     @ViewDebug.ExportedProperty
6770     public boolean isSoundEffectsEnabled() {
6771         return SOUND_EFFECTS_ENABLED == (mViewFlags & SOUND_EFFECTS_ENABLED);
6772     }
6773
6774     /**
6775      * Set whether this view should have haptic feedback for events such as
6776      * long presses.
6777      *
6778      * <p>You may wish to disable haptic feedback if your view already controls
6779      * its own haptic feedback.
6780      *
6781      * @param hapticFeedbackEnabled whether haptic feedback enabled for this view.
6782      * @see #isHapticFeedbackEnabled()
6783      * @see #performHapticFeedback(int)
6784      * @attr ref android.R.styleable#View_hapticFeedbackEnabled
6785      */
6786     public void setHapticFeedbackEnabled(boolean hapticFeedbackEnabled) {
6787         setFlags(hapticFeedbackEnabled ? HAPTIC_FEEDBACK_ENABLED: 0, HAPTIC_FEEDBACK_ENABLED);
6788     }
6789
6790     /**
6791      * @return whether this view should have haptic feedback enabled for events
6792      * long presses.
6793      *
6794      * @see #setHapticFeedbackEnabled(boolean)
6795      * @see #performHapticFeedback(int)
6796      * @attr ref android.R.styleable#View_hapticFeedbackEnabled
6797      */
6798     @ViewDebug.ExportedProperty
6799     public boolean isHapticFeedbackEnabled() {
6800         return HAPTIC_FEEDBACK_ENABLED == (mViewFlags & HAPTIC_FEEDBACK_ENABLED);
6801     }
6802
6803     /**
6804      * Returns the layout direction for this view.
6805      *
6806      * @return One of {@link #LAYOUT_DIRECTION_LTR},
6807      *   {@link #LAYOUT_DIRECTION_RTL},
6808      *   {@link #LAYOUT_DIRECTION_INHERIT} or
6809      *   {@link #LAYOUT_DIRECTION_LOCALE}.
6810      *
6811      * @attr ref android.R.styleable#View_layoutDirection
6812      *
6813      * @hide
6814      */
6815     @ViewDebug.ExportedProperty(category = "layout", mapping = {
6816         @ViewDebug.IntToString(from = LAYOUT_DIRECTION_LTR,     to = "LTR"),
6817         @ViewDebug.IntToString(from = LAYOUT_DIRECTION_RTL,     to = "RTL"),
6818         @ViewDebug.IntToString(from = LAYOUT_DIRECTION_INHERIT, to = "INHERIT"),
6819         @ViewDebug.IntToString(from = LAYOUT_DIRECTION_LOCALE,  to = "LOCALE")
6820     })
6821     @LayoutDir
6822     public int getRawLayoutDirection() {
6823         return (mPrivateFlags2 & PFLAG2_LAYOUT_DIRECTION_MASK) >> PFLAG2_LAYOUT_DIRECTION_MASK_SHIFT;
6824     }
6825
6826     /**
6827      * Set the layout direction for this view. This will propagate a reset of layout direction
6828      * resolution to the view's children and resolve layout direction for this view.
6829      *
6830      * @param layoutDirection the layout direction to set. Should be one of:
6831      *
6832      * {@link #LAYOUT_DIRECTION_LTR},
6833      * {@link #LAYOUT_DIRECTION_RTL},
6834      * {@link #LAYOUT_DIRECTION_INHERIT},
6835      * {@link #LAYOUT_DIRECTION_LOCALE}.
6836      *
6837      * Resolution will be done if the value is set to LAYOUT_DIRECTION_INHERIT. The resolution
6838      * proceeds up the parent chain of the view to get the value. If there is no parent, then it
6839      * will return the default {@link #LAYOUT_DIRECTION_LTR}.
6840      *
6841      * @attr ref android.R.styleable#View_layoutDirection
6842      */
6843     @RemotableViewMethod
6844     public void setLayoutDirection(@LayoutDir int layoutDirection) {
6845         if (getRawLayoutDirection() != layoutDirection) {
6846             // Reset the current layout direction and the resolved one
6847             mPrivateFlags2 &= ~PFLAG2_LAYOUT_DIRECTION_MASK;
6848             resetRtlProperties();
6849             // Set the new layout direction (filtered)
6850             mPrivateFlags2 |=
6851                     ((layoutDirection << PFLAG2_LAYOUT_DIRECTION_MASK_SHIFT) & PFLAG2_LAYOUT_DIRECTION_MASK);
6852             // We need to resolve all RTL properties as they all depend on layout direction
6853             resolveRtlPropertiesIfNeeded();
6854             requestLayout();
6855             invalidate(true);
6856         }
6857     }
6858
6859     /**
6860      * Returns the resolved layout direction for this view.
6861      *
6862      * @return {@link #LAYOUT_DIRECTION_RTL} if the layout direction is RTL or returns
6863      * {@link #LAYOUT_DIRECTION_LTR} if the layout direction is not RTL.
6864      *
6865      * For compatibility, this will return {@link #LAYOUT_DIRECTION_LTR} if API version
6866      * is lower than {@link android.os.Build.VERSION_CODES#JELLY_BEAN_MR1}.
6867      *
6868      * @attr ref android.R.styleable#View_layoutDirection
6869      */
6870     @ViewDebug.ExportedProperty(category = "layout", mapping = {
6871         @ViewDebug.IntToString(from = LAYOUT_DIRECTION_LTR, to = "RESOLVED_DIRECTION_LTR"),
6872         @ViewDebug.IntToString(from = LAYOUT_DIRECTION_RTL, to = "RESOLVED_DIRECTION_RTL")
6873     })
6874     @ResolvedLayoutDir
6875     public int getLayoutDirection() {
6876         final int targetSdkVersion = getContext().getApplicationInfo().targetSdkVersion;
6877         if (targetSdkVersion < JELLY_BEAN_MR1) {
6878             mPrivateFlags2 |= PFLAG2_LAYOUT_DIRECTION_RESOLVED;
6879             return LAYOUT_DIRECTION_RESOLVED_DEFAULT;
6880         }
6881         return ((mPrivateFlags2 & PFLAG2_LAYOUT_DIRECTION_RESOLVED_RTL) ==
6882                 PFLAG2_LAYOUT_DIRECTION_RESOLVED_RTL) ? LAYOUT_DIRECTION_RTL : LAYOUT_DIRECTION_LTR;
6883     }
6884
6885     /**
6886      * Indicates whether or not this view's layout is right-to-left. This is resolved from
6887      * layout attribute and/or the inherited value from the parent
6888      *
6889      * @return true if the layout is right-to-left.
6890      *
6891      * @hide
6892      */
6893     @ViewDebug.ExportedProperty(category = "layout")
6894     public boolean isLayoutRtl() {
6895         return (getLayoutDirection() == LAYOUT_DIRECTION_RTL);
6896     }
6897
6898     /**
6899      * Indicates whether the view is currently tracking transient state that the
6900      * app should not need to concern itself with saving and restoring, but that
6901      * the framework should take special note to preserve when possible.
6902      *
6903      * <p>A view with transient state cannot be trivially rebound from an external
6904      * data source, such as an adapter binding item views in a list. This may be
6905      * because the view is performing an animation, tracking user selection
6906      * of content, or similar.</p>
6907      *
6908      * @return true if the view has transient state
6909      */
6910     @ViewDebug.ExportedProperty(category = "layout")
6911     public boolean hasTransientState() {
6912         return (mPrivateFlags2 & PFLAG2_HAS_TRANSIENT_STATE) == PFLAG2_HAS_TRANSIENT_STATE;
6913     }
6914
6915     /**
6916      * Set whether this view is currently tracking transient state that the
6917      * framework should attempt to preserve when possible. This flag is reference counted,
6918      * so every call to setHasTransientState(true) should be paired with a later call
6919      * to setHasTransientState(false).
6920      *
6921      * <p>A view with transient state cannot be trivially rebound from an external
6922      * data source, such as an adapter binding item views in a list. This may be
6923      * because the view is performing an animation, tracking user selection
6924      * of content, or similar.</p>
6925      *
6926      * @param hasTransientState true if this view has transient state
6927      */
6928     public void setHasTransientState(boolean hasTransientState) {
6929         mTransientStateCount = hasTransientState ? mTransientStateCount + 1 :
6930                 mTransientStateCount - 1;
6931         if (mTransientStateCount < 0) {
6932             mTransientStateCount = 0;
6933             Log.e(VIEW_LOG_TAG, "hasTransientState decremented below 0: " +
6934                     "unmatched pair of setHasTransientState calls");
6935         } else if ((hasTransientState && mTransientStateCount == 1) ||
6936                 (!hasTransientState && mTransientStateCount == 0)) {
6937             // update flag if we've just incremented up from 0 or decremented down to 0
6938             mPrivateFlags2 = (mPrivateFlags2 & ~PFLAG2_HAS_TRANSIENT_STATE) |
6939                     (hasTransientState ? PFLAG2_HAS_TRANSIENT_STATE : 0);
6940             if (mParent != null) {
6941                 try {
6942                     mParent.childHasTransientStateChanged(this, hasTransientState);
6943                 } catch (AbstractMethodError e) {
6944                     Log.e(VIEW_LOG_TAG, mParent.getClass().getSimpleName() +
6945                             " does not fully implement ViewParent", e);
6946                 }
6947             }
6948         }
6949     }
6950
6951     /**
6952      * Returns true if this view is currently attached to a window.
6953      */
6954     public boolean isAttachedToWindow() {
6955         return mAttachInfo != null;
6956     }
6957
6958     /**
6959      * Returns true if this view has been through at least one layout since it
6960      * was last attached to or detached from a window.
6961      */
6962     public boolean isLaidOut() {
6963         return (mPrivateFlags3 & PFLAG3_IS_LAID_OUT) == PFLAG3_IS_LAID_OUT;
6964     }
6965
6966     /**
6967      * If this view doesn't do any drawing on its own, set this flag to
6968      * allow further optimizations. By default, this flag is not set on
6969      * View, but could be set on some View subclasses such as ViewGroup.
6970      *
6971      * Typically, if you override {@link #onDraw(android.graphics.Canvas)}
6972      * you should clear this flag.
6973      *
6974      * @param willNotDraw whether or not this View draw on its own
6975      */
6976     public void setWillNotDraw(boolean willNotDraw) {
6977         setFlags(willNotDraw ? WILL_NOT_DRAW : 0, DRAW_MASK);
6978     }
6979
6980     /**
6981      * Returns whether or not this View draws on its own.
6982      *
6983      * @return true if this view has nothing to draw, false otherwise
6984      */
6985     @ViewDebug.ExportedProperty(category = "drawing")
6986     public boolean willNotDraw() {
6987         return (mViewFlags & DRAW_MASK) == WILL_NOT_DRAW;
6988     }
6989
6990     /**
6991      * When a View's drawing cache is enabled, drawing is redirected to an
6992      * offscreen bitmap. Some views, like an ImageView, must be able to
6993      * bypass this mechanism if they already draw a single bitmap, to avoid
6994      * unnecessary usage of the memory.
6995      *
6996      * @param willNotCacheDrawing true if this view does not cache its
6997      *        drawing, false otherwise
6998      */
6999     public void setWillNotCacheDrawing(boolean willNotCacheDrawing) {
7000         setFlags(willNotCacheDrawing ? WILL_NOT_CACHE_DRAWING : 0, WILL_NOT_CACHE_DRAWING);
7001     }
7002
7003     /**
7004      * Returns whether or not this View can cache its drawing or not.
7005      *
7006      * @return true if this view does not cache its drawing, false otherwise
7007      */
7008     @ViewDebug.ExportedProperty(category = "drawing")
7009     public boolean willNotCacheDrawing() {
7010         return (mViewFlags & WILL_NOT_CACHE_DRAWING) == WILL_NOT_CACHE_DRAWING;
7011     }
7012
7013     /**
7014      * Indicates whether this view reacts to click events or not.
7015      *
7016      * @return true if the view is clickable, false otherwise
7017      *
7018      * @see #setClickable(boolean)
7019      * @attr ref android.R.styleable#View_clickable
7020      */
7021     @ViewDebug.ExportedProperty
7022     public boolean isClickable() {
7023         return (mViewFlags & CLICKABLE) == CLICKABLE;
7024     }
7025
7026     /**
7027      * Enables or disables click events for this view. When a view
7028      * is clickable it will change its state to "pressed" on every click.
7029      * Subclasses should set the view clickable to visually react to
7030      * user's clicks.
7031      *
7032      * @param clickable true to make the view clickable, false otherwise
7033      *
7034      * @see #isClickable()
7035      * @attr ref android.R.styleable#View_clickable
7036      */
7037     public void setClickable(boolean clickable) {
7038         setFlags(clickable ? CLICKABLE : 0, CLICKABLE);
7039     }
7040
7041     /**
7042      * Indicates whether this view reacts to long click events or not.
7043      *
7044      * @return true if the view is long clickable, false otherwise
7045      *
7046      * @see #setLongClickable(boolean)
7047      * @attr ref android.R.styleable#View_longClickable
7048      */
7049     public boolean isLongClickable() {
7050         return (mViewFlags & LONG_CLICKABLE) == LONG_CLICKABLE;
7051     }
7052
7053     /**
7054      * Enables or disables long click events for this view. When a view is long
7055      * clickable it reacts to the user holding down the button for a longer
7056      * duration than a tap. This event can either launch the listener or a
7057      * context menu.
7058      *
7059      * @param longClickable true to make the view long clickable, false otherwise
7060      * @see #isLongClickable()
7061      * @attr ref android.R.styleable#View_longClickable
7062      */
7063     public void setLongClickable(boolean longClickable) {
7064         setFlags(longClickable ? LONG_CLICKABLE : 0, LONG_CLICKABLE);
7065     }
7066
7067     /**
7068      * Sets the pressed state for this view and provides a touch coordinate for
7069      * animation hinting.
7070      *
7071      * @param pressed Pass true to set the View's internal state to "pressed",
7072      *            or false to reverts the View's internal state from a
7073      *            previously set "pressed" state.
7074      * @param x The x coordinate of the touch that caused the press
7075      * @param y The y coordinate of the touch that caused the press
7076      */
7077     private void setPressed(boolean pressed, float x, float y) {
7078         if (pressed) {
7079             drawableHotspotChanged(x, y);
7080         }
7081
7082         setPressed(pressed);
7083     }
7084
7085     /**
7086      * Sets the pressed state for this view.
7087      *
7088      * @see #isClickable()
7089      * @see #setClickable(boolean)
7090      *
7091      * @param pressed Pass true to set the View's internal state to "pressed", or false to reverts
7092      *        the View's internal state from a previously set "pressed" state.
7093      */
7094     public void setPressed(boolean pressed) {
7095         final boolean needsRefresh = pressed != ((mPrivateFlags & PFLAG_PRESSED) == PFLAG_PRESSED);
7096
7097         if (pressed) {
7098             mPrivateFlags |= PFLAG_PRESSED;
7099         } else {
7100             mPrivateFlags &= ~PFLAG_PRESSED;
7101         }
7102
7103         if (needsRefresh) {
7104             refreshDrawableState();
7105         }
7106         dispatchSetPressed(pressed);
7107     }
7108
7109     /**
7110      * Dispatch setPressed to all of this View's children.
7111      *
7112      * @see #setPressed(boolean)
7113      *
7114      * @param pressed The new pressed state
7115      */
7116     protected void dispatchSetPressed(boolean pressed) {
7117     }
7118
7119     /**
7120      * Indicates whether the view is currently in pressed state. Unless
7121      * {@link #setPressed(boolean)} is explicitly called, only clickable views can enter
7122      * the pressed state.
7123      *
7124      * @see #setPressed(boolean)
7125      * @see #isClickable()
7126      * @see #setClickable(boolean)
7127      *
7128      * @return true if the view is currently pressed, false otherwise
7129      */
7130     @ViewDebug.ExportedProperty
7131     public boolean isPressed() {
7132         return (mPrivateFlags & PFLAG_PRESSED) == PFLAG_PRESSED;
7133     }
7134
7135     /**
7136      * Indicates whether this view will save its state (that is,
7137      * whether its {@link #onSaveInstanceState} method will be called).
7138      *
7139      * @return Returns true if the view state saving is enabled, else false.
7140      *
7141      * @see #setSaveEnabled(boolean)
7142      * @attr ref android.R.styleable#View_saveEnabled
7143      */
7144     public boolean isSaveEnabled() {
7145         return (mViewFlags & SAVE_DISABLED_MASK) != SAVE_DISABLED;
7146     }
7147
7148     /**
7149      * Controls whether the saving of this view's state is
7150      * enabled (that is, whether its {@link #onSaveInstanceState} method
7151      * will be called).  Note that even if freezing is enabled, the
7152      * view still must have an id assigned to it (via {@link #setId(int)})
7153      * for its state to be saved.  This flag can only disable the
7154      * saving of this view; any child views may still have their state saved.
7155      *
7156      * @param enabled Set to false to <em>disable</em> state saving, or true
7157      * (the default) to allow it.
7158      *
7159      * @see #isSaveEnabled()
7160      * @see #setId(int)
7161      * @see #onSaveInstanceState()
7162      * @attr ref android.R.styleable#View_saveEnabled
7163      */
7164     public void setSaveEnabled(boolean enabled) {
7165         setFlags(enabled ? 0 : SAVE_DISABLED, SAVE_DISABLED_MASK);
7166     }
7167
7168     /**
7169      * Gets whether the framework should discard touches when the view's
7170      * window is obscured by another visible window.
7171      * Refer to the {@link View} security documentation for more details.
7172      *
7173      * @return True if touch filtering is enabled.
7174      *
7175      * @see #setFilterTouchesWhenObscured(boolean)
7176      * @attr ref android.R.styleable#View_filterTouchesWhenObscured
7177      */
7178     @ViewDebug.ExportedProperty
7179     public boolean getFilterTouchesWhenObscured() {
7180         return (mViewFlags & FILTER_TOUCHES_WHEN_OBSCURED) != 0;
7181     }
7182
7183     /**
7184      * Sets whether the framework should discard touches when the view's
7185      * window is obscured by another visible window.
7186      * Refer to the {@link View} security documentation for more details.
7187      *
7188      * @param enabled True if touch filtering should be enabled.
7189      *
7190      * @see #getFilterTouchesWhenObscured
7191      * @attr ref android.R.styleable#View_filterTouchesWhenObscured
7192      */
7193     public void setFilterTouchesWhenObscured(boolean enabled) {
7194         setFlags(enabled ? FILTER_TOUCHES_WHEN_OBSCURED : 0,
7195                 FILTER_TOUCHES_WHEN_OBSCURED);
7196     }
7197
7198     /**
7199      * Indicates whether the entire hierarchy under this view will save its
7200      * state when a state saving traversal occurs from its parent.  The default
7201      * is true; if false, these views will not be saved unless
7202      * {@link #saveHierarchyState(SparseArray)} is called directly on this view.
7203      *
7204      * @return Returns true if the view state saving from parent is enabled, else false.
7205      *
7206      * @see #setSaveFromParentEnabled(boolean)
7207      */
7208     public boolean isSaveFromParentEnabled() {
7209         return (mViewFlags & PARENT_SAVE_DISABLED_MASK) != PARENT_SAVE_DISABLED;
7210     }
7211
7212     /**
7213      * Controls whether the entire hierarchy under this view will save its
7214      * state when a state saving traversal occurs from its parent.  The default
7215      * is true; if false, these views will not be saved unless
7216      * {@link #saveHierarchyState(SparseArray)} is called directly on this view.
7217      *
7218      * @param enabled Set to false to <em>disable</em> state saving, or true
7219      * (the default) to allow it.
7220      *
7221      * @see #isSaveFromParentEnabled()
7222      * @see #setId(int)
7223      * @see #onSaveInstanceState()
7224      */
7225     public void setSaveFromParentEnabled(boolean enabled) {
7226         setFlags(enabled ? 0 : PARENT_SAVE_DISABLED, PARENT_SAVE_DISABLED_MASK);
7227     }
7228
7229
7230     /**
7231      * Returns whether this View is able to take focus.
7232      *
7233      * @return True if this view can take focus, or false otherwise.
7234      * @attr ref android.R.styleable#View_focusable
7235      */
7236     @ViewDebug.ExportedProperty(category = "focus")
7237     public final boolean isFocusable() {
7238         return FOCUSABLE == (mViewFlags & FOCUSABLE_MASK);
7239     }
7240
7241     /**
7242      * When a view is focusable, it may not want to take focus when in touch mode.
7243      * For example, a button would like focus when the user is navigating via a D-pad
7244      * so that the user can click on it, but once the user starts touching the screen,
7245      * the button shouldn't take focus
7246      * @return Whether the view is focusable in touch mode.
7247      * @attr ref android.R.styleable#View_focusableInTouchMode
7248      */
7249     @ViewDebug.ExportedProperty
7250     public final boolean isFocusableInTouchMode() {
7251         return FOCUSABLE_IN_TOUCH_MODE == (mViewFlags & FOCUSABLE_IN_TOUCH_MODE);
7252     }
7253
7254     /**
7255      * Find the nearest view in the specified direction that can take focus.
7256      * This does not actually give focus to that view.
7257      *
7258      * @param direction One of FOCUS_UP, FOCUS_DOWN, FOCUS_LEFT, and FOCUS_RIGHT
7259      *
7260      * @return The nearest focusable in the specified direction, or null if none
7261      *         can be found.
7262      */
7263     public View focusSearch(@FocusRealDirection int direction) {
7264         if (mParent != null) {
7265             return mParent.focusSearch(this, direction);
7266         } else {
7267             return null;
7268         }
7269     }
7270
7271     /**
7272      * This method is the last chance for the focused view and its ancestors to
7273      * respond to an arrow key. This is called when the focused view did not
7274      * consume the key internally, nor could the view system find a new view in
7275      * the requested direction to give focus to.
7276      *
7277      * @param focused The currently focused view.
7278      * @param direction The direction focus wants to move. One of FOCUS_UP,
7279      *        FOCUS_DOWN, FOCUS_LEFT, and FOCUS_RIGHT.
7280      * @return True if the this view consumed this unhandled move.
7281      */
7282     public boolean dispatchUnhandledMove(View focused, @FocusRealDirection int direction) {
7283         return false;
7284     }
7285
7286     /**
7287      * If a user manually specified the next view id for a particular direction,
7288      * use the root to look up the view.
7289      * @param root The root view of the hierarchy containing this view.
7290      * @param direction One of FOCUS_UP, FOCUS_DOWN, FOCUS_LEFT, FOCUS_RIGHT, FOCUS_FORWARD,
7291      * or FOCUS_BACKWARD.
7292      * @return The user specified next view, or null if there is none.
7293      */
7294     View findUserSetNextFocus(View root, @FocusDirection int direction) {
7295         switch (direction) {
7296             case FOCUS_LEFT:
7297                 if (mNextFocusLeftId == View.NO_ID) return null;
7298                 return findViewInsideOutShouldExist(root, mNextFocusLeftId);
7299             case FOCUS_RIGHT:
7300                 if (mNextFocusRightId == View.NO_ID) return null;
7301                 return findViewInsideOutShouldExist(root, mNextFocusRightId);
7302             case FOCUS_UP:
7303                 if (mNextFocusUpId == View.NO_ID) return null;
7304                 return findViewInsideOutShouldExist(root, mNextFocusUpId);
7305             case FOCUS_DOWN:
7306                 if (mNextFocusDownId == View.NO_ID) return null;
7307                 return findViewInsideOutShouldExist(root, mNextFocusDownId);
7308             case FOCUS_FORWARD:
7309                 if (mNextFocusForwardId == View.NO_ID) return null;
7310                 return findViewInsideOutShouldExist(root, mNextFocusForwardId);
7311             case FOCUS_BACKWARD: {
7312                 if (mID == View.NO_ID) return null;
7313                 final int id = mID;
7314                 return root.findViewByPredicateInsideOut(this, new Predicate<View>() {
7315                     @Override
7316                     public boolean apply(View t) {
7317                         return t.mNextFocusForwardId == id;
7318                     }
7319                 });
7320             }
7321         }
7322         return null;
7323     }
7324
7325     private View findViewInsideOutShouldExist(View root, int id) {
7326         if (mMatchIdPredicate == null) {
7327             mMatchIdPredicate = new MatchIdPredicate();
7328         }
7329         mMatchIdPredicate.mId = id;
7330         View result = root.findViewByPredicateInsideOut(this, mMatchIdPredicate);
7331         if (result == null) {
7332             Log.w(VIEW_LOG_TAG, "couldn't find view with id " + id);
7333         }
7334         return result;
7335     }
7336
7337     /**
7338      * Find and return all focusable views that are descendants of this view,
7339      * possibly including this view if it is focusable itself.
7340      *
7341      * @param direction The direction of the focus
7342      * @return A list of focusable views
7343      */
7344     public ArrayList<View> getFocusables(@FocusDirection int direction) {
7345         ArrayList<View> result = new ArrayList<View>(24);
7346         addFocusables(result, direction);
7347         return result;
7348     }
7349
7350     /**
7351      * Add any focusable views that are descendants of this view (possibly
7352      * including this view if it is focusable itself) to views.  If we are in touch mode,
7353      * only add views that are also focusable in touch mode.
7354      *
7355      * @param views Focusable views found so far
7356      * @param direction The direction of the focus
7357      */
7358     public void addFocusables(ArrayList<View> views, @FocusDirection int direction) {
7359         addFocusables(views, direction, FOCUSABLES_TOUCH_MODE);
7360     }
7361
7362     /**
7363      * Adds any focusable views that are descendants of this view (possibly
7364      * including this view if it is focusable itself) to views. This method
7365      * adds all focusable views regardless if we are in touch mode or
7366      * only views focusable in touch mode if we are in touch mode or
7367      * only views that can take accessibility focus if accessibility is enabeld
7368      * depending on the focusable mode paramater.
7369      *
7370      * @param views Focusable views found so far or null if all we are interested is
7371      *        the number of focusables.
7372      * @param direction The direction of the focus.
7373      * @param focusableMode The type of focusables to be added.
7374      *
7375      * @see #FOCUSABLES_ALL
7376      * @see #FOCUSABLES_TOUCH_MODE
7377      */
7378     public void addFocusables(ArrayList<View> views, @FocusDirection int direction,
7379             @FocusableMode int focusableMode) {
7380         if (views == null) {
7381             return;
7382         }
7383         if (!isFocusable()) {
7384             return;
7385         }
7386         if ((focusableMode & FOCUSABLES_TOUCH_MODE) == FOCUSABLES_TOUCH_MODE
7387                 && isInTouchMode() && !isFocusableInTouchMode()) {
7388             return;
7389         }
7390         views.add(this);
7391     }
7392
7393     /**
7394      * Finds the Views that contain given text. The containment is case insensitive.
7395      * The search is performed by either the text that the View renders or the content
7396      * description that describes the view for accessibility purposes and the view does
7397      * not render or both. Clients can specify how the search is to be performed via
7398      * passing the {@link #FIND_VIEWS_WITH_TEXT} and
7399      * {@link #FIND_VIEWS_WITH_CONTENT_DESCRIPTION} flags.
7400      *
7401      * @param outViews The output list of matching Views.
7402      * @param searched The text to match against.
7403      *
7404      * @see #FIND_VIEWS_WITH_TEXT
7405      * @see #FIND_VIEWS_WITH_CONTENT_DESCRIPTION
7406      * @see #setContentDescription(CharSequence)
7407      */
7408     public void findViewsWithText(ArrayList<View> outViews, CharSequence searched,
7409             @FindViewFlags int flags) {
7410         if (getAccessibilityNodeProvider() != null) {
7411             if ((flags & FIND_VIEWS_WITH_ACCESSIBILITY_NODE_PROVIDERS) != 0) {
7412                 outViews.add(this);
7413             }
7414         } else if ((flags & FIND_VIEWS_WITH_CONTENT_DESCRIPTION) != 0
7415                 && (searched != null && searched.length() > 0)
7416                 && (mContentDescription != null && mContentDescription.length() > 0)) {
7417             String searchedLowerCase = searched.toString().toLowerCase();
7418             String contentDescriptionLowerCase = mContentDescription.toString().toLowerCase();
7419             if (contentDescriptionLowerCase.contains(searchedLowerCase)) {
7420                 outViews.add(this);
7421             }
7422         }
7423     }
7424
7425     /**
7426      * Find and return all touchable views that are descendants of this view,
7427      * possibly including this view if it is touchable itself.
7428      *
7429      * @return A list of touchable views
7430      */
7431     public ArrayList<View> getTouchables() {
7432         ArrayList<View> result = new ArrayList<View>();
7433         addTouchables(result);
7434         return result;
7435     }
7436
7437     /**
7438      * Add any touchable views that are descendants of this view (possibly
7439      * including this view if it is touchable itself) to views.
7440      *
7441      * @param views Touchable views found so far
7442      */
7443     public void addTouchables(ArrayList<View> views) {
7444         final int viewFlags = mViewFlags;
7445
7446         if (((viewFlags & CLICKABLE) == CLICKABLE || (viewFlags & LONG_CLICKABLE) == LONG_CLICKABLE)
7447                 && (viewFlags & ENABLED_MASK) == ENABLED) {
7448             views.add(this);
7449         }
7450     }
7451
7452     /**
7453      * Returns whether this View is accessibility focused.
7454      *
7455      * @return True if this View is accessibility focused.
7456      */
7457     public boolean isAccessibilityFocused() {
7458         return (mPrivateFlags2 & PFLAG2_ACCESSIBILITY_FOCUSED) != 0;
7459     }
7460
7461     /**
7462      * Call this to try to give accessibility focus to this view.
7463      *
7464      * A view will not actually take focus if {@link AccessibilityManager#isEnabled()}
7465      * returns false or the view is no visible or the view already has accessibility
7466      * focus.
7467      *
7468      * See also {@link #focusSearch(int)}, which is what you call to say that you
7469      * have focus, and you want your parent to look for the next one.
7470      *
7471      * @return Whether this view actually took accessibility focus.
7472      *
7473      * @hide
7474      */
7475     public boolean requestAccessibilityFocus() {
7476         AccessibilityManager manager = AccessibilityManager.getInstance(mContext);
7477         if (!manager.isEnabled() || !manager.isTouchExplorationEnabled()) {
7478             return false;
7479         }
7480         if ((mViewFlags & VISIBILITY_MASK) != VISIBLE) {
7481             return false;
7482         }
7483         if ((mPrivateFlags2 & PFLAG2_ACCESSIBILITY_FOCUSED) == 0) {
7484             mPrivateFlags2 |= PFLAG2_ACCESSIBILITY_FOCUSED;
7485             ViewRootImpl viewRootImpl = getViewRootImpl();
7486             if (viewRootImpl != null) {
7487                 viewRootImpl.setAccessibilityFocus(this, null);
7488             }
7489             invalidate();
7490             sendAccessibilityEvent(AccessibilityEvent.TYPE_VIEW_ACCESSIBILITY_FOCUSED);
7491             return true;
7492         }
7493         return false;
7494     }
7495
7496     /**
7497      * Call this to try to clear accessibility focus of this view.
7498      *
7499      * See also {@link #focusSearch(int)}, which is what you call to say that you
7500      * have focus, and you want your parent to look for the next one.
7501      *
7502      * @hide
7503      */
7504     public void clearAccessibilityFocus() {
7505         clearAccessibilityFocusNoCallbacks();
7506         // Clear the global reference of accessibility focus if this
7507         // view or any of its descendants had accessibility focus.
7508         ViewRootImpl viewRootImpl = getViewRootImpl();
7509         if (viewRootImpl != null) {
7510             View focusHost = viewRootImpl.getAccessibilityFocusedHost();
7511             if (focusHost != null && ViewRootImpl.isViewDescendantOf(focusHost, this)) {
7512                 viewRootImpl.setAccessibilityFocus(null, null);
7513             }
7514         }
7515     }
7516
7517     private void sendAccessibilityHoverEvent(int eventType) {
7518         // Since we are not delivering to a client accessibility events from not
7519         // important views (unless the clinet request that) we need to fire the
7520         // event from the deepest view exposed to the client. As a consequence if
7521         // the user crosses a not exposed view the client will see enter and exit
7522         // of the exposed predecessor followed by and enter and exit of that same
7523         // predecessor when entering and exiting the not exposed descendant. This
7524         // is fine since the client has a clear idea which view is hovered at the
7525         // price of a couple more events being sent. This is a simple and
7526         // working solution.
7527         View source = this;
7528         while (true) {
7529             if (source.includeForAccessibility()) {
7530                 source.sendAccessibilityEvent(eventType);
7531                 return;
7532             }
7533             ViewParent parent = source.getParent();
7534             if (parent instanceof View) {
7535                 source = (View) parent;
7536             } else {
7537                 return;
7538             }
7539         }
7540     }
7541
7542     /**
7543      * Clears accessibility focus without calling any callback methods
7544      * normally invoked in {@link #clearAccessibilityFocus()}. This method
7545      * is used for clearing accessibility focus when giving this focus to
7546      * another view.
7547      */
7548     void clearAccessibilityFocusNoCallbacks() {
7549         if ((mPrivateFlags2 & PFLAG2_ACCESSIBILITY_FOCUSED) != 0) {
7550             mPrivateFlags2 &= ~PFLAG2_ACCESSIBILITY_FOCUSED;
7551             invalidate();
7552             sendAccessibilityEvent(AccessibilityEvent.TYPE_VIEW_ACCESSIBILITY_FOCUS_CLEARED);
7553         }
7554     }
7555
7556     /**
7557      * Call this to try to give focus to a specific view or to one of its
7558      * descendants.
7559      *
7560      * A view will not actually take focus if it is not focusable ({@link #isFocusable} returns
7561      * false), or if it is focusable and it is not focusable in touch mode
7562      * ({@link #isFocusableInTouchMode}) while the device is in touch mode.
7563      *
7564      * See also {@link #focusSearch(int)}, which is what you call to say that you
7565      * have focus, and you want your parent to look for the next one.
7566      *
7567      * This is equivalent to calling {@link #requestFocus(int, Rect)} with arguments
7568      * {@link #FOCUS_DOWN} and <code>null</code>.
7569      *
7570      * @return Whether this view or one of its descendants actually took focus.
7571      */
7572     public final boolean requestFocus() {
7573         return requestFocus(View.FOCUS_DOWN);
7574     }
7575
7576     /**
7577      * Call this to try to give focus to a specific view or to one of its
7578      * descendants and give it a hint about what direction focus is heading.
7579      *
7580      * A view will not actually take focus if it is not focusable ({@link #isFocusable} returns
7581      * false), or if it is focusable and it is not focusable in touch mode
7582      * ({@link #isFocusableInTouchMode}) while the device is in touch mode.
7583      *
7584      * See also {@link #focusSearch(int)}, which is what you call to say that you
7585      * have focus, and you want your parent to look for the next one.
7586      *
7587      * This is equivalent to calling {@link #requestFocus(int, Rect)} with
7588      * <code>null</code> set for the previously focused rectangle.
7589      *
7590      * @param direction One of FOCUS_UP, FOCUS_DOWN, FOCUS_LEFT, and FOCUS_RIGHT
7591      * @return Whether this view or one of its descendants actually took focus.
7592      */
7593     public final boolean requestFocus(int direction) {
7594         return requestFocus(direction, null);
7595     }
7596
7597     /**
7598      * Call this to try to give focus to a specific view or to one of its descendants
7599      * and give it hints about the direction and a specific rectangle that the focus
7600      * is coming from.  The rectangle can help give larger views a finer grained hint
7601      * about where focus is coming from, and therefore, where to show selection, or
7602      * forward focus change internally.
7603      *
7604      * A view will not actually take focus if it is not focusable ({@link #isFocusable} returns
7605      * false), or if it is focusable and it is not focusable in touch mode
7606      * ({@link #isFocusableInTouchMode}) while the device is in touch mode.
7607      *
7608      * A View will not take focus if it is not visible.
7609      *
7610      * A View will not take focus if one of its parents has
7611      * {@link android.view.ViewGroup#getDescendantFocusability()} equal to
7612      * {@link ViewGroup#FOCUS_BLOCK_DESCENDANTS}.
7613      *
7614      * See also {@link #focusSearch(int)}, which is what you call to say that you
7615      * have focus, and you want your parent to look for the next one.
7616      *
7617      * You may wish to override this method if your custom {@link View} has an internal
7618      * {@link View} that it wishes to forward the request to.
7619      *
7620      * @param direction One of FOCUS_UP, FOCUS_DOWN, FOCUS_LEFT, and FOCUS_RIGHT
7621      * @param previouslyFocusedRect The rectangle (in this View's coordinate system)
7622      *        to give a finer grained hint about where focus is coming from.  May be null
7623      *        if there is no hint.
7624      * @return Whether this view or one of its descendants actually took focus.
7625      */
7626     public boolean requestFocus(int direction, Rect previouslyFocusedRect) {
7627         return requestFocusNoSearch(direction, previouslyFocusedRect);
7628     }
7629
7630     private boolean requestFocusNoSearch(int direction, Rect previouslyFocusedRect) {
7631         // need to be focusable
7632         if ((mViewFlags & FOCUSABLE_MASK) != FOCUSABLE ||
7633                 (mViewFlags & VISIBILITY_MASK) != VISIBLE) {
7634             return false;
7635         }
7636
7637         // need to be focusable in touch mode if in touch mode
7638         if (isInTouchMode() &&
7639             (FOCUSABLE_IN_TOUCH_MODE != (mViewFlags & FOCUSABLE_IN_TOUCH_MODE))) {
7640                return false;
7641         }
7642
7643         // need to not have any parents blocking us
7644         if (hasAncestorThatBlocksDescendantFocus()) {
7645             return false;
7646         }
7647
7648         handleFocusGainInternal(direction, previouslyFocusedRect);
7649         return true;
7650     }
7651
7652     /**
7653      * Call this to try to give focus to a specific view or to one of its descendants. This is a
7654      * special variant of {@link #requestFocus() } that will allow views that are not focuable in
7655      * touch mode to request focus when they are touched.
7656      *
7657      * @return Whether this view or one of its descendants actually took focus.
7658      *
7659      * @see #isInTouchMode()
7660      *
7661      */
7662     public final boolean requestFocusFromTouch() {
7663         // Leave touch mode if we need to
7664         if (isInTouchMode()) {
7665             ViewRootImpl viewRoot = getViewRootImpl();
7666             if (viewRoot != null) {
7667                 viewRoot.ensureTouchMode(false);
7668             }
7669         }
7670         return requestFocus(View.FOCUS_DOWN);
7671     }
7672
7673     /**
7674      * @return Whether any ancestor of this view blocks descendant focus.
7675      */
7676     private boolean hasAncestorThatBlocksDescendantFocus() {
7677         final boolean focusableInTouchMode = isFocusableInTouchMode();
7678         ViewParent ancestor = mParent;
7679         while (ancestor instanceof ViewGroup) {
7680             final ViewGroup vgAncestor = (ViewGroup) ancestor;
7681             if (vgAncestor.getDescendantFocusability() == ViewGroup.FOCUS_BLOCK_DESCENDANTS
7682                     || (!focusableInTouchMode && vgAncestor.shouldBlockFocusForTouchscreen())) {
7683                 return true;
7684             } else {
7685                 ancestor = vgAncestor.getParent();
7686             }
7687         }
7688         return false;
7689     }
7690
7691     /**
7692      * Gets the mode for determining whether this View is important for accessibility
7693      * which is if it fires accessibility events and if it is reported to
7694      * accessibility services that query the screen.
7695      *
7696      * @return The mode for determining whether a View is important for accessibility.
7697      *
7698      * @attr ref android.R.styleable#View_importantForAccessibility
7699      *
7700      * @see #IMPORTANT_FOR_ACCESSIBILITY_YES
7701      * @see #IMPORTANT_FOR_ACCESSIBILITY_NO
7702      * @see #IMPORTANT_FOR_ACCESSIBILITY_NO_HIDE_DESCENDANTS
7703      * @see #IMPORTANT_FOR_ACCESSIBILITY_AUTO
7704      */
7705     @ViewDebug.ExportedProperty(category = "accessibility", mapping = {
7706             @ViewDebug.IntToString(from = IMPORTANT_FOR_ACCESSIBILITY_AUTO, to = "auto"),
7707             @ViewDebug.IntToString(from = IMPORTANT_FOR_ACCESSIBILITY_YES, to = "yes"),
7708             @ViewDebug.IntToString(from = IMPORTANT_FOR_ACCESSIBILITY_NO, to = "no"),
7709             @ViewDebug.IntToString(from = IMPORTANT_FOR_ACCESSIBILITY_NO_HIDE_DESCENDANTS,
7710                     to = "noHideDescendants")
7711         })
7712     public int getImportantForAccessibility() {
7713         return (mPrivateFlags2 & PFLAG2_IMPORTANT_FOR_ACCESSIBILITY_MASK)
7714                 >> PFLAG2_IMPORTANT_FOR_ACCESSIBILITY_SHIFT;
7715     }
7716
7717     /**
7718      * Sets the live region mode for this view. This indicates to accessibility
7719      * services whether they should automatically notify the user about changes
7720      * to the view's content description or text, or to the content descriptions
7721      * or text of the view's children (where applicable).
7722      * <p>
7723      * For example, in a login screen with a TextView that displays an "incorrect
7724      * password" notification, that view should be marked as a live region with
7725      * mode {@link #ACCESSIBILITY_LIVE_REGION_POLITE}.
7726      * <p>
7727      * To disable change notifications for this view, use
7728      * {@link #ACCESSIBILITY_LIVE_REGION_NONE}. This is the default live region
7729      * mode for most views.
7730      * <p>
7731      * To indicate that the user should be notified of changes, use
7732      * {@link #ACCESSIBILITY_LIVE_REGION_POLITE}.
7733      * <p>
7734      * If the view's changes should interrupt ongoing speech and notify the user
7735      * immediately, use {@link #ACCESSIBILITY_LIVE_REGION_ASSERTIVE}.
7736      *
7737      * @param mode The live region mode for this view, one of:
7738      *        <ul>
7739      *        <li>{@link #ACCESSIBILITY_LIVE_REGION_NONE}
7740      *        <li>{@link #ACCESSIBILITY_LIVE_REGION_POLITE}
7741      *        <li>{@link #ACCESSIBILITY_LIVE_REGION_ASSERTIVE}
7742      *        </ul>
7743      * @attr ref android.R.styleable#View_accessibilityLiveRegion
7744      */
7745     public void setAccessibilityLiveRegion(int mode) {
7746         if (mode != getAccessibilityLiveRegion()) {
7747             mPrivateFlags2 &= ~PFLAG2_ACCESSIBILITY_LIVE_REGION_MASK;
7748             mPrivateFlags2 |= (mode << PFLAG2_ACCESSIBILITY_LIVE_REGION_SHIFT)
7749                     & PFLAG2_ACCESSIBILITY_LIVE_REGION_MASK;
7750             notifyViewAccessibilityStateChangedIfNeeded(
7751                     AccessibilityEvent.CONTENT_CHANGE_TYPE_UNDEFINED);
7752         }
7753     }
7754
7755     /**
7756      * Gets the live region mode for this View.
7757      *
7758      * @return The live region mode for the view.
7759      *
7760      * @attr ref android.R.styleable#View_accessibilityLiveRegion
7761      *
7762      * @see #setAccessibilityLiveRegion(int)
7763      */
7764     public int getAccessibilityLiveRegion() {
7765         return (mPrivateFlags2 & PFLAG2_ACCESSIBILITY_LIVE_REGION_MASK)
7766                 >> PFLAG2_ACCESSIBILITY_LIVE_REGION_SHIFT;
7767     }
7768
7769     /**
7770      * Sets how to determine whether this view is important for accessibility
7771      * which is if it fires accessibility events and if it is reported to
7772      * accessibility services that query the screen.
7773      *
7774      * @param mode How to determine whether this view is important for accessibility.
7775      *
7776      * @attr ref android.R.styleable#View_importantForAccessibility
7777      *
7778      * @see #IMPORTANT_FOR_ACCESSIBILITY_YES
7779      * @see #IMPORTANT_FOR_ACCESSIBILITY_NO
7780      * @see #IMPORTANT_FOR_ACCESSIBILITY_NO_HIDE_DESCENDANTS
7781      * @see #IMPORTANT_FOR_ACCESSIBILITY_AUTO
7782      */
7783     public void setImportantForAccessibility(int mode) {
7784         final int oldMode = getImportantForAccessibility();
7785         if (mode != oldMode) {
7786             // If we're moving between AUTO and another state, we might not need
7787             // to send a subtree changed notification. We'll store the computed
7788             // importance, since we'll need to check it later to make sure.
7789             final boolean maySkipNotify = oldMode == IMPORTANT_FOR_ACCESSIBILITY_AUTO
7790                     || mode == IMPORTANT_FOR_ACCESSIBILITY_AUTO;
7791             final boolean oldIncludeForAccessibility = maySkipNotify && includeForAccessibility();
7792             mPrivateFlags2 &= ~PFLAG2_IMPORTANT_FOR_ACCESSIBILITY_MASK;
7793             mPrivateFlags2 |= (mode << PFLAG2_IMPORTANT_FOR_ACCESSIBILITY_SHIFT)
7794                     & PFLAG2_IMPORTANT_FOR_ACCESSIBILITY_MASK;
7795             if (!maySkipNotify || oldIncludeForAccessibility != includeForAccessibility()) {
7796                 notifySubtreeAccessibilityStateChangedIfNeeded();
7797             } else {
7798                 notifyViewAccessibilityStateChangedIfNeeded(
7799                         AccessibilityEvent.CONTENT_CHANGE_TYPE_UNDEFINED);
7800             }
7801         }
7802     }
7803
7804     /**
7805      * Computes whether this view should be exposed for accessibility. In
7806      * general, views that are interactive or provide information are exposed
7807      * while views that serve only as containers are hidden.
7808      * <p>
7809      * If an ancestor of this view has importance
7810      * {@link #IMPORTANT_FOR_ACCESSIBILITY_NO_HIDE_DESCENDANTS}, this method
7811      * returns <code>false</code>.
7812      * <p>
7813      * Otherwise, the value is computed according to the view's
7814      * {@link #getImportantForAccessibility()} value:
7815      * <ol>
7816      * <li>{@link #IMPORTANT_FOR_ACCESSIBILITY_NO} or
7817      * {@link #IMPORTANT_FOR_ACCESSIBILITY_NO_HIDE_DESCENDANTS}, return <code>false
7818      * </code>
7819      * <li>{@link #IMPORTANT_FOR_ACCESSIBILITY_YES}, return <code>true</code>
7820      * <li>{@link #IMPORTANT_FOR_ACCESSIBILITY_AUTO}, return <code>true</code> if
7821      * view satisfies any of the following:
7822      * <ul>
7823      * <li>Is actionable, e.g. {@link #isClickable()},
7824      * {@link #isLongClickable()}, or {@link #isFocusable()}
7825      * <li>Has an {@link AccessibilityDelegate}
7826      * <li>Has an interaction listener, e.g. {@link OnTouchListener},
7827      * {@link OnKeyListener}, etc.
7828      * <li>Is an accessibility live region, e.g.
7829      * {@link #getAccessibilityLiveRegion()} is not
7830      * {@link #ACCESSIBILITY_LIVE_REGION_NONE}.
7831      * </ul>
7832      * </ol>
7833      *
7834      * @return Whether the view is exposed for accessibility.
7835      * @see #setImportantForAccessibility(int)
7836      * @see #getImportantForAccessibility()
7837      */
7838     public boolean isImportantForAccessibility() {
7839         final int mode = (mPrivateFlags2 & PFLAG2_IMPORTANT_FOR_ACCESSIBILITY_MASK)
7840                 >> PFLAG2_IMPORTANT_FOR_ACCESSIBILITY_SHIFT;
7841         if (mode == IMPORTANT_FOR_ACCESSIBILITY_NO
7842                 || mode == IMPORTANT_FOR_ACCESSIBILITY_NO_HIDE_DESCENDANTS) {
7843             return false;
7844         }
7845
7846         // Check parent mode to ensure we're not hidden.
7847         ViewParent parent = mParent;
7848         while (parent instanceof View) {
7849             if (((View) parent).getImportantForAccessibility()
7850                     == IMPORTANT_FOR_ACCESSIBILITY_NO_HIDE_DESCENDANTS) {
7851                 return false;
7852             }
7853             parent = parent.getParent();
7854         }
7855
7856         return mode == IMPORTANT_FOR_ACCESSIBILITY_YES || isActionableForAccessibility()
7857                 || hasListenersForAccessibility() || getAccessibilityNodeProvider() != null
7858                 || getAccessibilityLiveRegion() != ACCESSIBILITY_LIVE_REGION_NONE;
7859     }
7860
7861     /**
7862      * Gets the parent for accessibility purposes. Note that the parent for
7863      * accessibility is not necessary the immediate parent. It is the first
7864      * predecessor that is important for accessibility.
7865      *
7866      * @return The parent for accessibility purposes.
7867      */
7868     public ViewParent getParentForAccessibility() {
7869         if (mParent instanceof View) {
7870             View parentView = (View) mParent;
7871             if (parentView.includeForAccessibility()) {
7872                 return mParent;
7873             } else {
7874                 return mParent.getParentForAccessibility();
7875             }
7876         }
7877         return null;
7878     }
7879
7880     /**
7881      * Adds the children of a given View for accessibility. Since some Views are
7882      * not important for accessibility the children for accessibility are not
7883      * necessarily direct children of the view, rather they are the first level of
7884      * descendants important for accessibility.
7885      *
7886      * @param children The list of children for accessibility.
7887      */
7888     public void addChildrenForAccessibility(ArrayList<View> children) {
7889
7890     }
7891
7892     /**
7893      * Whether to regard this view for accessibility. A view is regarded for
7894      * accessibility if it is important for accessibility or the querying
7895      * accessibility service has explicitly requested that view not
7896      * important for accessibility are regarded.
7897      *
7898      * @return Whether to regard the view for accessibility.
7899      *
7900      * @hide
7901      */
7902     public boolean includeForAccessibility() {
7903         if (mAttachInfo != null) {
7904             return (mAttachInfo.mAccessibilityFetchFlags
7905                     & AccessibilityNodeInfo.FLAG_INCLUDE_NOT_IMPORTANT_VIEWS) != 0
7906                     || isImportantForAccessibility();
7907         }
7908         return false;
7909     }
7910
7911     /**
7912      * Returns whether the View is considered actionable from
7913      * accessibility perspective. Such view are important for
7914      * accessibility.
7915      *
7916      * @return True if the view is actionable for accessibility.
7917      *
7918      * @hide
7919      */
7920     public boolean isActionableForAccessibility() {
7921         return (isClickable() || isLongClickable() || isFocusable());
7922     }
7923
7924     /**
7925      * Returns whether the View has registered callbacks which makes it
7926      * important for accessibility.
7927      *
7928      * @return True if the view is actionable for accessibility.
7929      */
7930     private boolean hasListenersForAccessibility() {
7931         ListenerInfo info = getListenerInfo();
7932         return mTouchDelegate != null || info.mOnKeyListener != null
7933                 || info.mOnTouchListener != null || info.mOnGenericMotionListener != null
7934                 || info.mOnHoverListener != null || info.mOnDragListener != null;
7935     }
7936
7937     /**
7938      * Notifies that the accessibility state of this view changed. The change
7939      * is local to this view and does not represent structural changes such
7940      * as children and parent. For example, the view became focusable. The
7941      * notification is at at most once every
7942      * {@link ViewConfiguration#getSendRecurringAccessibilityEventsInterval()}
7943      * to avoid unnecessary load to the system. Also once a view has a pending
7944      * notification this method is a NOP until the notification has been sent.
7945      *
7946      * @hide
7947      */
7948     public void notifyViewAccessibilityStateChangedIfNeeded(int changeType) {
7949         if (!AccessibilityManager.getInstance(mContext).isEnabled()) {
7950             return;
7951         }
7952         if (mSendViewStateChangedAccessibilityEvent == null) {
7953             mSendViewStateChangedAccessibilityEvent =
7954                     new SendViewStateChangedAccessibilityEvent();
7955         }
7956         mSendViewStateChangedAccessibilityEvent.runOrPost(changeType);
7957     }
7958
7959     /**
7960      * Notifies that the accessibility state of this view changed. The change
7961      * is *not* local to this view and does represent structural changes such
7962      * as children and parent. For example, the view size changed. The
7963      * notification is at at most once every
7964      * {@link ViewConfiguration#getSendRecurringAccessibilityEventsInterval()}
7965      * to avoid unnecessary load to the system. Also once a view has a pending
7966      * notification this method is a NOP until the notification has been sent.
7967      *
7968      * @hide
7969      */
7970     public void notifySubtreeAccessibilityStateChangedIfNeeded() {
7971         if (!AccessibilityManager.getInstance(mContext).isEnabled()) {
7972             return;
7973         }
7974         if ((mPrivateFlags2 & PFLAG2_SUBTREE_ACCESSIBILITY_STATE_CHANGED) == 0) {
7975             mPrivateFlags2 |= PFLAG2_SUBTREE_ACCESSIBILITY_STATE_CHANGED;
7976             if (mParent != null) {
7977                 try {
7978                     mParent.notifySubtreeAccessibilityStateChanged(
7979                             this, this, AccessibilityEvent.CONTENT_CHANGE_TYPE_SUBTREE);
7980                 } catch (AbstractMethodError e) {
7981                     Log.e(VIEW_LOG_TAG, mParent.getClass().getSimpleName() +
7982                             " does not fully implement ViewParent", e);
7983                 }
7984             }
7985         }
7986     }
7987
7988     /**
7989      * Reset the flag indicating the accessibility state of the subtree rooted
7990      * at this view changed.
7991      */
7992     void resetSubtreeAccessibilityStateChanged() {
7993         mPrivateFlags2 &= ~PFLAG2_SUBTREE_ACCESSIBILITY_STATE_CHANGED;
7994     }
7995
7996     /**
7997      * Performs the specified accessibility action on the view. For
7998      * possible accessibility actions look at {@link AccessibilityNodeInfo}.
7999      * <p>
8000      * If an {@link AccessibilityDelegate} has been specified via calling
8001      * {@link #setAccessibilityDelegate(AccessibilityDelegate)} its
8002      * {@link AccessibilityDelegate#performAccessibilityAction(View, int, Bundle)}
8003      * is responsible for handling this call.
8004      * </p>
8005      *
8006      * @param action The action to perform.
8007      * @param arguments Optional action arguments.
8008      * @return Whether the action was performed.
8009      */
8010     public boolean performAccessibilityAction(int action, Bundle arguments) {
8011       if (mAccessibilityDelegate != null) {
8012           return mAccessibilityDelegate.performAccessibilityAction(this, action, arguments);
8013       } else {
8014           return performAccessibilityActionInternal(action, arguments);
8015       }
8016     }
8017
8018    /**
8019     * @see #performAccessibilityAction(int, Bundle)
8020     *
8021     * Note: Called from the default {@link AccessibilityDelegate}.
8022     */
8023     boolean performAccessibilityActionInternal(int action, Bundle arguments) {
8024         switch (action) {
8025             case AccessibilityNodeInfo.ACTION_CLICK: {
8026                 if (isClickable()) {
8027                     performClick();
8028                     return true;
8029                 }
8030             } break;
8031             case AccessibilityNodeInfo.ACTION_LONG_CLICK: {
8032                 if (isLongClickable()) {
8033                     performLongClick();
8034                     return true;
8035                 }
8036             } break;
8037             case AccessibilityNodeInfo.ACTION_FOCUS: {
8038                 if (!hasFocus()) {
8039                     // Get out of touch mode since accessibility
8040                     // wants to move focus around.
8041                     getViewRootImpl().ensureTouchMode(false);
8042                     return requestFocus();
8043                 }
8044             } break;
8045             case AccessibilityNodeInfo.ACTION_CLEAR_FOCUS: {
8046                 if (hasFocus()) {
8047                     clearFocus();
8048                     return !isFocused();
8049                 }
8050             } break;
8051             case AccessibilityNodeInfo.ACTION_SELECT: {
8052                 if (!isSelected()) {
8053                     setSelected(true);
8054                     return isSelected();
8055                 }
8056             } break;
8057             case AccessibilityNodeInfo.ACTION_CLEAR_SELECTION: {
8058                 if (isSelected()) {
8059                     setSelected(false);
8060                     return !isSelected();
8061                 }
8062             } break;
8063             case AccessibilityNodeInfo.ACTION_ACCESSIBILITY_FOCUS: {
8064                 if (!isAccessibilityFocused()) {
8065                     return requestAccessibilityFocus();
8066                 }
8067             } break;
8068             case AccessibilityNodeInfo.ACTION_CLEAR_ACCESSIBILITY_FOCUS: {
8069                 if (isAccessibilityFocused()) {
8070                     clearAccessibilityFocus();
8071                     return true;
8072                 }
8073             } break;
8074             case AccessibilityNodeInfo.ACTION_NEXT_AT_MOVEMENT_GRANULARITY: {
8075                 if (arguments != null) {
8076                     final int granularity = arguments.getInt(
8077                             AccessibilityNodeInfo.ACTION_ARGUMENT_MOVEMENT_GRANULARITY_INT);
8078                     final boolean extendSelection = arguments.getBoolean(
8079                             AccessibilityNodeInfo.ACTION_ARGUMENT_EXTEND_SELECTION_BOOLEAN);
8080                     return traverseAtGranularity(granularity, true, extendSelection);
8081                 }
8082             } break;
8083             case AccessibilityNodeInfo.ACTION_PREVIOUS_AT_MOVEMENT_GRANULARITY: {
8084                 if (arguments != null) {
8085                     final int granularity = arguments.getInt(
8086                             AccessibilityNodeInfo.ACTION_ARGUMENT_MOVEMENT_GRANULARITY_INT);
8087                     final boolean extendSelection = arguments.getBoolean(
8088                             AccessibilityNodeInfo.ACTION_ARGUMENT_EXTEND_SELECTION_BOOLEAN);
8089                     return traverseAtGranularity(granularity, false, extendSelection);
8090                 }
8091             } break;
8092             case AccessibilityNodeInfo.ACTION_SET_SELECTION: {
8093                 CharSequence text = getIterableTextForAccessibility();
8094                 if (text == null) {
8095                     return false;
8096                 }
8097                 final int start = (arguments != null) ? arguments.getInt(
8098                         AccessibilityNodeInfo.ACTION_ARGUMENT_SELECTION_START_INT, -1) : -1;
8099                 final int end = (arguments != null) ? arguments.getInt(
8100                 AccessibilityNodeInfo.ACTION_ARGUMENT_SELECTION_END_INT, -1) : -1;
8101                 // Only cursor position can be specified (selection length == 0)
8102                 if ((getAccessibilitySelectionStart() != start
8103                         || getAccessibilitySelectionEnd() != end)
8104                         && (start == end)) {
8105                     setAccessibilitySelection(start, end);
8106                     notifyViewAccessibilityStateChangedIfNeeded(
8107                             AccessibilityEvent.CONTENT_CHANGE_TYPE_UNDEFINED);
8108                     return true;
8109                 }
8110             } break;
8111         }
8112         return false;
8113     }
8114
8115     private boolean traverseAtGranularity(int granularity, boolean forward,
8116             boolean extendSelection) {
8117         CharSequence text = getIterableTextForAccessibility();
8118         if (text == null || text.length() == 0) {
8119             return false;
8120         }
8121         TextSegmentIterator iterator = getIteratorForGranularity(granularity);
8122         if (iterator == null) {
8123             return false;
8124         }
8125         int current = getAccessibilitySelectionEnd();
8126         if (current == ACCESSIBILITY_CURSOR_POSITION_UNDEFINED) {
8127             current = forward ? 0 : text.length();
8128         }
8129         final int[] range = forward ? iterator.following(current) : iterator.preceding(current);
8130         if (range == null) {
8131             return false;
8132         }
8133         final int segmentStart = range[0];
8134         final int segmentEnd = range[1];
8135         int selectionStart;
8136         int selectionEnd;
8137         if (extendSelection && isAccessibilitySelectionExtendable()) {
8138             selectionStart = getAccessibilitySelectionStart();
8139             if (selectionStart == ACCESSIBILITY_CURSOR_POSITION_UNDEFINED) {
8140                 selectionStart = forward ? segmentStart : segmentEnd;
8141             }
8142             selectionEnd = forward ? segmentEnd : segmentStart;
8143         } else {
8144             selectionStart = selectionEnd= forward ? segmentEnd : segmentStart;
8145         }
8146         setAccessibilitySelection(selectionStart, selectionEnd);
8147         final int action = forward ? AccessibilityNodeInfo.ACTION_NEXT_AT_MOVEMENT_GRANULARITY
8148                 : AccessibilityNodeInfo.ACTION_PREVIOUS_AT_MOVEMENT_GRANULARITY;
8149         sendViewTextTraversedAtGranularityEvent(action, granularity, segmentStart, segmentEnd);
8150         return true;
8151     }
8152
8153     /**
8154      * Gets the text reported for accessibility purposes.
8155      *
8156      * @return The accessibility text.
8157      *
8158      * @hide
8159      */
8160     public CharSequence getIterableTextForAccessibility() {
8161         return getContentDescription();
8162     }
8163
8164     /**
8165      * Gets whether accessibility selection can be extended.
8166      *
8167      * @return If selection is extensible.
8168      *
8169      * @hide
8170      */
8171     public boolean isAccessibilitySelectionExtendable() {
8172         return false;
8173     }
8174
8175     /**
8176      * @hide
8177      */
8178     public int getAccessibilitySelectionStart() {
8179         return mAccessibilityCursorPosition;
8180     }
8181
8182     /**
8183      * @hide
8184      */
8185     public int getAccessibilitySelectionEnd() {
8186         return getAccessibilitySelectionStart();
8187     }
8188
8189     /**
8190      * @hide
8191      */
8192     public void setAccessibilitySelection(int start, int end) {
8193         if (start ==  end && end == mAccessibilityCursorPosition) {
8194             return;
8195         }
8196         if (start >= 0 && start == end && end <= getIterableTextForAccessibility().length()) {
8197             mAccessibilityCursorPosition = start;
8198         } else {
8199             mAccessibilityCursorPosition = ACCESSIBILITY_CURSOR_POSITION_UNDEFINED;
8200         }
8201         sendAccessibilityEvent(AccessibilityEvent.TYPE_VIEW_TEXT_SELECTION_CHANGED);
8202     }
8203
8204     private void sendViewTextTraversedAtGranularityEvent(int action, int granularity,
8205             int fromIndex, int toIndex) {
8206         if (mParent == null) {
8207             return;
8208         }
8209         AccessibilityEvent event = AccessibilityEvent.obtain(
8210                 AccessibilityEvent.TYPE_VIEW_TEXT_TRAVERSED_AT_MOVEMENT_GRANULARITY);
8211         onInitializeAccessibilityEvent(event);
8212         onPopulateAccessibilityEvent(event);
8213         event.setFromIndex(fromIndex);
8214         event.setToIndex(toIndex);
8215         event.setAction(action);
8216         event.setMovementGranularity(granularity);
8217         mParent.requestSendAccessibilityEvent(this, event);
8218     }
8219
8220     /**
8221      * @hide
8222      */
8223     public TextSegmentIterator getIteratorForGranularity(int granularity) {
8224         switch (granularity) {
8225             case AccessibilityNodeInfo.MOVEMENT_GRANULARITY_CHARACTER: {
8226                 CharSequence text = getIterableTextForAccessibility();
8227                 if (text != null && text.length() > 0) {
8228                     CharacterTextSegmentIterator iterator =
8229                         CharacterTextSegmentIterator.getInstance(
8230                                 mContext.getResources().getConfiguration().locale);
8231                     iterator.initialize(text.toString());
8232                     return iterator;
8233                 }
8234             } break;
8235             case AccessibilityNodeInfo.MOVEMENT_GRANULARITY_WORD: {
8236                 CharSequence text = getIterableTextForAccessibility();
8237                 if (text != null && text.length() > 0) {
8238                     WordTextSegmentIterator iterator =
8239                         WordTextSegmentIterator.getInstance(
8240                                 mContext.getResources().getConfiguration().locale);
8241                     iterator.initialize(text.toString());
8242                     return iterator;
8243                 }
8244             } break;
8245             case AccessibilityNodeInfo.MOVEMENT_GRANULARITY_PARAGRAPH: {
8246                 CharSequence text = getIterableTextForAccessibility();
8247                 if (text != null && text.length() > 0) {
8248                     ParagraphTextSegmentIterator iterator =
8249                         ParagraphTextSegmentIterator.getInstance();
8250                     iterator.initialize(text.toString());
8251                     return iterator;
8252                 }
8253             } break;
8254         }
8255         return null;
8256     }
8257
8258     /**
8259      * @hide
8260      */
8261     public void dispatchStartTemporaryDetach() {
8262         onStartTemporaryDetach();
8263     }
8264
8265     /**
8266      * This is called when a container is going to temporarily detach a child, with
8267      * {@link ViewGroup#detachViewFromParent(View) ViewGroup.detachViewFromParent}.
8268      * It will either be followed by {@link #onFinishTemporaryDetach()} or
8269      * {@link #onDetachedFromWindow()} when the container is done.
8270      */
8271     public void onStartTemporaryDetach() {
8272         removeUnsetPressCallback();
8273         mPrivateFlags |= PFLAG_CANCEL_NEXT_UP_EVENT;
8274     }
8275
8276     /**
8277      * @hide
8278      */
8279     public void dispatchFinishTemporaryDetach() {
8280         onFinishTemporaryDetach();
8281     }
8282
8283     /**
8284      * Called after {@link #onStartTemporaryDetach} when the container is done
8285      * changing the view.
8286      */
8287     public void onFinishTemporaryDetach() {
8288     }
8289
8290     /**
8291      * Return the global {@link KeyEvent.DispatcherState KeyEvent.DispatcherState}
8292      * for this view's window.  Returns null if the view is not currently attached
8293      * to the window.  Normally you will not need to use this directly, but
8294      * just use the standard high-level event callbacks like
8295      * {@link #onKeyDown(int, KeyEvent)}.
8296      */
8297     public KeyEvent.DispatcherState getKeyDispatcherState() {
8298         return mAttachInfo != null ? mAttachInfo.mKeyDispatchState : null;
8299     }
8300
8301     /**
8302      * Dispatch a key event before it is processed by any input method
8303      * associated with the view hierarchy.  This can be used to intercept
8304      * key events in special situations before the IME consumes them; a
8305      * typical example would be handling the BACK key to update the application's
8306      * UI instead of allowing the IME to see it and close itself.
8307      *
8308      * @param event The key event to be dispatched.
8309      * @return True if the event was handled, false otherwise.
8310      */
8311     public boolean dispatchKeyEventPreIme(KeyEvent event) {
8312         return onKeyPreIme(event.getKeyCode(), event);
8313     }
8314
8315     /**
8316      * Dispatch a key event to the next view on the focus path. This path runs
8317      * from the top of the view tree down to the currently focused view. If this
8318      * view has focus, it will dispatch to itself. Otherwise it will dispatch
8319      * the next node down the focus path. This method also fires any key
8320      * listeners.
8321      *
8322      * @param event The key event to be dispatched.
8323      * @return True if the event was handled, false otherwise.
8324      */
8325     public boolean dispatchKeyEvent(KeyEvent event) {
8326         if (mInputEventConsistencyVerifier != null) {
8327             mInputEventConsistencyVerifier.onKeyEvent(event, 0);
8328         }
8329
8330         // Give any attached key listener a first crack at the event.
8331         //noinspection SimplifiableIfStatement
8332         ListenerInfo li = mListenerInfo;
8333         if (li != null && li.mOnKeyListener != null && (mViewFlags & ENABLED_MASK) == ENABLED
8334                 && li.mOnKeyListener.onKey(this, event.getKeyCode(), event)) {
8335             return true;
8336         }
8337
8338         if (event.dispatch(this, mAttachInfo != null
8339                 ? mAttachInfo.mKeyDispatchState : null, this)) {
8340             return true;
8341         }
8342
8343         if (mInputEventConsistencyVerifier != null) {
8344             mInputEventConsistencyVerifier.onUnhandledEvent(event, 0);
8345         }
8346         return false;
8347     }
8348
8349     /**
8350      * Dispatches a key shortcut event.
8351      *
8352      * @param event The key event to be dispatched.
8353      * @return True if the event was handled by the view, false otherwise.
8354      */
8355     public boolean dispatchKeyShortcutEvent(KeyEvent event) {
8356         return onKeyShortcut(event.getKeyCode(), event);
8357     }
8358
8359     /**
8360      * Pass the touch screen motion event down to the target view, or this
8361      * view if it is the target.
8362      *
8363      * @param event The motion event to be dispatched.
8364      * @return True if the event was handled by the view, false otherwise.
8365      */
8366     public boolean dispatchTouchEvent(MotionEvent event) {
8367         boolean result = false;
8368
8369         if (mInputEventConsistencyVerifier != null) {
8370             mInputEventConsistencyVerifier.onTouchEvent(event, 0);
8371         }
8372
8373         final int actionMasked = event.getActionMasked();
8374         if (actionMasked == MotionEvent.ACTION_DOWN) {
8375             // Defensive cleanup for new gesture
8376             stopNestedScroll();
8377         }
8378
8379         if (onFilterTouchEventForSecurity(event)) {
8380             //noinspection SimplifiableIfStatement
8381             ListenerInfo li = mListenerInfo;
8382             if (li != null && li.mOnTouchListener != null
8383                     && (mViewFlags & ENABLED_MASK) == ENABLED
8384                     && li.mOnTouchListener.onTouch(this, event)) {
8385                 result = true;
8386             }
8387
8388             if (!result && onTouchEvent(event)) {
8389                 result = true;
8390             }
8391         }
8392
8393         if (!result && mInputEventConsistencyVerifier != null) {
8394             mInputEventConsistencyVerifier.onUnhandledEvent(event, 0);
8395         }
8396
8397         // Clean up after nested scrolls if this is the end of a gesture;
8398         // also cancel it if we tried an ACTION_DOWN but we didn't want the rest
8399         // of the gesture.
8400         if (actionMasked == MotionEvent.ACTION_UP ||
8401                 actionMasked == MotionEvent.ACTION_CANCEL ||
8402                 (actionMasked == MotionEvent.ACTION_DOWN && !result)) {
8403             stopNestedScroll();
8404         }
8405
8406         return result;
8407     }
8408
8409     /**
8410      * Filter the touch event to apply security policies.
8411      *
8412      * @param event The motion event to be filtered.
8413      * @return True if the event should be dispatched, false if the event should be dropped.
8414      *
8415      * @see #getFilterTouchesWhenObscured
8416      */
8417     public boolean onFilterTouchEventForSecurity(MotionEvent event) {
8418         //noinspection RedundantIfStatement
8419         if ((mViewFlags & FILTER_TOUCHES_WHEN_OBSCURED) != 0
8420                 && (event.getFlags() & MotionEvent.FLAG_WINDOW_IS_OBSCURED) != 0) {
8421             // Window is obscured, drop this touch.
8422             return false;
8423         }
8424         return true;
8425     }
8426
8427     /**
8428      * Pass a trackball motion event down to the focused view.
8429      *
8430      * @param event The motion event to be dispatched.
8431      * @return True if the event was handled by the view, false otherwise.
8432      */
8433     public boolean dispatchTrackballEvent(MotionEvent event) {
8434         if (mInputEventConsistencyVerifier != null) {
8435             mInputEventConsistencyVerifier.onTrackballEvent(event, 0);
8436         }
8437
8438         return onTrackballEvent(event);
8439     }
8440
8441     /**
8442      * Dispatch a generic motion event.
8443      * <p>
8444      * Generic motion events with source class {@link InputDevice#SOURCE_CLASS_POINTER}
8445      * are delivered to the view under the pointer.  All other generic motion events are
8446      * delivered to the focused view.  Hover events are handled specially and are delivered
8447      * to {@link #onHoverEvent(MotionEvent)}.
8448      * </p>
8449      *
8450      * @param event The motion event to be dispatched.
8451      * @return True if the event was handled by the view, false otherwise.
8452      */
8453     public boolean dispatchGenericMotionEvent(MotionEvent event) {
8454         if (mInputEventConsistencyVerifier != null) {
8455             mInputEventConsistencyVerifier.onGenericMotionEvent(event, 0);
8456         }
8457
8458         final int source = event.getSource();
8459         if ((source & InputDevice.SOURCE_CLASS_POINTER) != 0) {
8460             final int action = event.getAction();
8461             if (action == MotionEvent.ACTION_HOVER_ENTER
8462                     || action == MotionEvent.ACTION_HOVER_MOVE
8463                     || action == MotionEvent.ACTION_HOVER_EXIT) {
8464                 if (dispatchHoverEvent(event)) {
8465                     return true;
8466                 }
8467             } else if (dispatchGenericPointerEvent(event)) {
8468                 return true;
8469             }
8470         } else if (dispatchGenericFocusedEvent(event)) {
8471             return true;
8472         }
8473
8474         if (dispatchGenericMotionEventInternal(event)) {
8475             return true;
8476         }
8477
8478         if (mInputEventConsistencyVerifier != null) {
8479             mInputEventConsistencyVerifier.onUnhandledEvent(event, 0);
8480         }
8481         return false;
8482     }
8483
8484     private boolean dispatchGenericMotionEventInternal(MotionEvent event) {
8485         //noinspection SimplifiableIfStatement
8486         ListenerInfo li = mListenerInfo;
8487         if (li != null && li.mOnGenericMotionListener != null
8488                 && (mViewFlags & ENABLED_MASK) == ENABLED
8489                 && li.mOnGenericMotionListener.onGenericMotion(this, event)) {
8490             return true;
8491         }
8492
8493         if (onGenericMotionEvent(event)) {
8494             return true;
8495         }
8496
8497         if (mInputEventConsistencyVerifier != null) {
8498             mInputEventConsistencyVerifier.onUnhandledEvent(event, 0);
8499         }
8500         return false;
8501     }
8502
8503     /**
8504      * Dispatch a hover event.
8505      * <p>
8506      * Do not call this method directly.
8507      * Call {@link #dispatchGenericMotionEvent(MotionEvent)} instead.
8508      * </p>
8509      *
8510      * @param event The motion event to be dispatched.
8511      * @return True if the event was handled by the view, false otherwise.
8512      */
8513     protected boolean dispatchHoverEvent(MotionEvent event) {
8514         ListenerInfo li = mListenerInfo;
8515         //noinspection SimplifiableIfStatement
8516         if (li != null && li.mOnHoverListener != null
8517                 && (mViewFlags & ENABLED_MASK) == ENABLED
8518                 && li.mOnHoverListener.onHover(this, event)) {
8519             return true;
8520         }
8521
8522         return onHoverEvent(event);
8523     }
8524
8525     /**
8526      * Returns true if the view has a child to which it has recently sent
8527      * {@link MotionEvent#ACTION_HOVER_ENTER}.  If this view is hovered and
8528      * it does not have a hovered child, then it must be the innermost hovered view.
8529      * @hide
8530      */
8531     protected boolean hasHoveredChild() {
8532         return false;
8533     }
8534
8535     /**
8536      * Dispatch a generic motion event to the view under the first pointer.
8537      * <p>
8538      * Do not call this method directly.
8539      * Call {@link #dispatchGenericMotionEvent(MotionEvent)} instead.
8540      * </p>
8541      *
8542      * @param event The motion event to be dispatched.
8543      * @return True if the event was handled by the view, false otherwise.
8544      */
8545     protected boolean dispatchGenericPointerEvent(MotionEvent event) {
8546         return false;
8547     }
8548
8549     /**
8550      * Dispatch a generic motion event to the currently focused view.
8551      * <p>
8552      * Do not call this method directly.
8553      * Call {@link #dispatchGenericMotionEvent(MotionEvent)} instead.
8554      * </p>
8555      *
8556      * @param event The motion event to be dispatched.
8557      * @return True if the event was handled by the view, false otherwise.
8558      */
8559     protected boolean dispatchGenericFocusedEvent(MotionEvent event) {
8560         return false;
8561     }
8562
8563     /**
8564      * Dispatch a pointer event.
8565      * <p>
8566      * Dispatches touch related pointer events to {@link #onTouchEvent(MotionEvent)} and all
8567      * other events to {@link #onGenericMotionEvent(MotionEvent)}.  This separation of concerns
8568      * reinforces the invariant that {@link #onTouchEvent(MotionEvent)} is really about touches
8569      * and should not be expected to handle other pointing device features.
8570      * </p>
8571      *
8572      * @param event The motion event to be dispatched.
8573      * @return True if the event was handled by the view, false otherwise.
8574      * @hide
8575      */
8576     public final boolean dispatchPointerEvent(MotionEvent event) {
8577         if (event.isTouchEvent()) {
8578             return dispatchTouchEvent(event);
8579         } else {
8580             return dispatchGenericMotionEvent(event);
8581         }
8582     }
8583
8584     /**
8585      * Called when the window containing this view gains or loses window focus.
8586      * ViewGroups should override to route to their children.
8587      *
8588      * @param hasFocus True if the window containing this view now has focus,
8589      *        false otherwise.
8590      */
8591     public void dispatchWindowFocusChanged(boolean hasFocus) {
8592         onWindowFocusChanged(hasFocus);
8593     }
8594
8595     /**
8596      * Called when the window containing this view gains or loses focus.  Note
8597      * that this is separate from view focus: to receive key events, both
8598      * your view and its window must have focus.  If a window is displayed
8599      * on top of yours that takes input focus, then your own window will lose
8600      * focus but the view focus will remain unchanged.
8601      *
8602      * @param hasWindowFocus True if the window containing this view now has
8603      *        focus, false otherwise.
8604      */
8605     public void onWindowFocusChanged(boolean hasWindowFocus) {
8606         InputMethodManager imm = InputMethodManager.peekInstance();
8607         if (!hasWindowFocus) {
8608             if (isPressed()) {
8609                 setPressed(false);
8610             }
8611             if (imm != null && (mPrivateFlags & PFLAG_FOCUSED) != 0) {
8612                 imm.focusOut(this);
8613             }
8614             removeLongPressCallback();
8615             removeTapCallback();
8616             onFocusLost();
8617         } else if (imm != null && (mPrivateFlags & PFLAG_FOCUSED) != 0) {
8618             imm.focusIn(this);
8619         }
8620         refreshDrawableState();
8621     }
8622
8623     /**
8624      * Returns true if this view is in a window that currently has window focus.
8625      * Note that this is not the same as the view itself having focus.
8626      *
8627      * @return True if this view is in a window that currently has window focus.
8628      */
8629     public boolean hasWindowFocus() {
8630         return mAttachInfo != null && mAttachInfo.mHasWindowFocus;
8631     }
8632
8633     /**
8634      * Dispatch a view visibility change down the view hierarchy.
8635      * ViewGroups should override to route to their children.
8636      * @param changedView The view whose visibility changed. Could be 'this' or
8637      * an ancestor view.
8638      * @param visibility The new visibility of changedView: {@link #VISIBLE},
8639      * {@link #INVISIBLE} or {@link #GONE}.
8640      */
8641     protected void dispatchVisibilityChanged(@NonNull View changedView,
8642             @Visibility int visibility) {
8643         onVisibilityChanged(changedView, visibility);
8644     }
8645
8646     /**
8647      * Called when the visibility of the view or an ancestor of the view is changed.
8648      * @param changedView The view whose visibility changed. Could be 'this' or
8649      * an ancestor view.
8650      * @param visibility The new visibility of changedView: {@link #VISIBLE},
8651      * {@link #INVISIBLE} or {@link #GONE}.
8652      */
8653     protected void onVisibilityChanged(@NonNull View changedView, @Visibility int visibility) {
8654         if (visibility == VISIBLE) {
8655             if (mAttachInfo != null) {
8656                 initialAwakenScrollBars();
8657             } else {
8658                 mPrivateFlags |= PFLAG_AWAKEN_SCROLL_BARS_ON_ATTACH;
8659             }
8660         }
8661     }
8662
8663     /**
8664      * Dispatch a hint about whether this view is displayed. For instance, when
8665      * a View moves out of the screen, it might receives a display hint indicating
8666      * the view is not displayed. Applications should not <em>rely</em> on this hint
8667      * as there is no guarantee that they will receive one.
8668      *
8669      * @param hint A hint about whether or not this view is displayed:
8670      * {@link #VISIBLE} or {@link #INVISIBLE}.
8671      */
8672     public void dispatchDisplayHint(@Visibility int hint) {
8673         onDisplayHint(hint);
8674     }
8675
8676     /**
8677      * Gives this view a hint about whether is displayed or not. For instance, when
8678      * a View moves out of the screen, it might receives a display hint indicating
8679      * the view is not displayed. Applications should not <em>rely</em> on this hint
8680      * as there is no guarantee that they will receive one.
8681      *
8682      * @param hint A hint about whether or not this view is displayed:
8683      * {@link #VISIBLE} or {@link #INVISIBLE}.
8684      */
8685     protected void onDisplayHint(@Visibility int hint) {
8686     }
8687
8688     /**
8689      * Dispatch a window visibility change down the view hierarchy.
8690      * ViewGroups should override to route to their children.
8691      *
8692      * @param visibility The new visibility of the window.
8693      *
8694      * @see #onWindowVisibilityChanged(int)
8695      */
8696     public void dispatchWindowVisibilityChanged(@Visibility int visibility) {
8697         onWindowVisibilityChanged(visibility);
8698     }
8699
8700     /**
8701      * Called when the window containing has change its visibility
8702      * (between {@link #GONE}, {@link #INVISIBLE}, and {@link #VISIBLE}).  Note
8703      * that this tells you whether or not your window is being made visible
8704      * to the window manager; this does <em>not</em> tell you whether or not
8705      * your window is obscured by other windows on the screen, even if it
8706      * is itself visible.
8707      *
8708      * @param visibility The new visibility of the window.
8709      */
8710     protected void onWindowVisibilityChanged(@Visibility int visibility) {
8711         if (visibility == VISIBLE) {
8712             initialAwakenScrollBars();
8713         }
8714     }
8715
8716     /**
8717      * Returns the current visibility of the window this view is attached to
8718      * (either {@link #GONE}, {@link #INVISIBLE}, or {@link #VISIBLE}).
8719      *
8720      * @return Returns the current visibility of the view's window.
8721      */
8722     @Visibility
8723     public int getWindowVisibility() {
8724         return mAttachInfo != null ? mAttachInfo.mWindowVisibility : GONE;
8725     }
8726
8727     /**
8728      * Retrieve the overall visible display size in which the window this view is
8729      * attached to has been positioned in.  This takes into account screen
8730      * decorations above the window, for both cases where the window itself
8731      * is being position inside of them or the window is being placed under
8732      * then and covered insets are used for the window to position its content
8733      * inside.  In effect, this tells you the available area where content can
8734      * be placed and remain visible to users.
8735      *
8736      * <p>This function requires an IPC back to the window manager to retrieve
8737      * the requested information, so should not be used in performance critical
8738      * code like drawing.
8739      *
8740      * @param outRect Filled in with the visible display frame.  If the view
8741      * is not attached to a window, this is simply the raw display size.
8742      */
8743     public void getWindowVisibleDisplayFrame(Rect outRect) {
8744         if (mAttachInfo != null) {
8745             try {
8746                 mAttachInfo.mSession.getDisplayFrame(mAttachInfo.mWindow, outRect);
8747             } catch (RemoteException e) {
8748                 return;
8749             }
8750             // XXX This is really broken, and probably all needs to be done
8751             // in the window manager, and we need to know more about whether
8752             // we want the area behind or in front of the IME.
8753             final Rect insets = mAttachInfo.mVisibleInsets;
8754             outRect.left += insets.left;
8755             outRect.top += insets.top;
8756             outRect.right -= insets.right;
8757             outRect.bottom -= insets.bottom;
8758             return;
8759         }
8760         // The view is not attached to a display so we don't have a context.
8761         // Make a best guess about the display size.
8762         Display d = DisplayManagerGlobal.getInstance().getRealDisplay(Display.DEFAULT_DISPLAY);
8763         d.getRectSize(outRect);
8764     }
8765
8766     /**
8767      * Dispatch a notification about a resource configuration change down
8768      * the view hierarchy.
8769      * ViewGroups should override to route to their children.
8770      *
8771      * @param newConfig The new resource configuration.
8772      *
8773      * @see #onConfigurationChanged(android.content.res.Configuration)
8774      */
8775     public void dispatchConfigurationChanged(Configuration newConfig) {
8776         onConfigurationChanged(newConfig);
8777     }
8778
8779     /**
8780      * Called when the current configuration of the resources being used
8781      * by the application have changed.  You can use this to decide when
8782      * to reload resources that can changed based on orientation and other
8783      * configuration characterstics.  You only need to use this if you are
8784      * not relying on the normal {@link android.app.Activity} mechanism of
8785      * recreating the activity instance upon a configuration change.
8786      *
8787      * @param newConfig The new resource configuration.
8788      */
8789     protected void onConfigurationChanged(Configuration newConfig) {
8790     }
8791
8792     /**
8793      * Private function to aggregate all per-view attributes in to the view
8794      * root.
8795      */
8796     void dispatchCollectViewAttributes(AttachInfo attachInfo, int visibility) {
8797         performCollectViewAttributes(attachInfo, visibility);
8798     }
8799
8800     void performCollectViewAttributes(AttachInfo attachInfo, int visibility) {
8801         if ((visibility & VISIBILITY_MASK) == VISIBLE) {
8802             if ((mViewFlags & KEEP_SCREEN_ON) == KEEP_SCREEN_ON) {
8803                 attachInfo.mKeepScreenOn = true;
8804             }
8805             attachInfo.mSystemUiVisibility |= mSystemUiVisibility;
8806             ListenerInfo li = mListenerInfo;
8807             if (li != null && li.mOnSystemUiVisibilityChangeListener != null) {
8808                 attachInfo.mHasSystemUiListeners = true;
8809             }
8810         }
8811     }
8812
8813     void needGlobalAttributesUpdate(boolean force) {
8814         final AttachInfo ai = mAttachInfo;
8815         if (ai != null && !ai.mRecomputeGlobalAttributes) {
8816             if (force || ai.mKeepScreenOn || (ai.mSystemUiVisibility != 0)
8817                     || ai.mHasSystemUiListeners) {
8818                 ai.mRecomputeGlobalAttributes = true;
8819             }
8820         }
8821     }
8822
8823     /**
8824      * Returns whether the device is currently in touch mode.  Touch mode is entered
8825      * once the user begins interacting with the device by touch, and affects various
8826      * things like whether focus is always visible to the user.
8827      *
8828      * @return Whether the device is in touch mode.
8829      */
8830     @ViewDebug.ExportedProperty
8831     public boolean isInTouchMode() {
8832         if (mAttachInfo != null) {
8833             return mAttachInfo.mInTouchMode;
8834         } else {
8835             return ViewRootImpl.isInTouchMode();
8836         }
8837     }
8838
8839     /**
8840      * Returns the context the view is running in, through which it can
8841      * access the current theme, resources, etc.
8842      *
8843      * @return The view's Context.
8844      */
8845     @ViewDebug.CapturedViewProperty
8846     public final Context getContext() {
8847         return mContext;
8848     }
8849
8850     /**
8851      * Handle a key event before it is processed by any input method
8852      * associated with the view hierarchy.  This can be used to intercept
8853      * key events in special situations before the IME consumes them; a
8854      * typical example would be handling the BACK key to update the application's
8855      * UI instead of allowing the IME to see it and close itself.
8856      *
8857      * @param keyCode The value in event.getKeyCode().
8858      * @param event Description of the key event.
8859      * @return If you handled the event, return true. If you want to allow the
8860      *         event to be handled by the next receiver, return false.
8861      */
8862     public boolean onKeyPreIme(int keyCode, KeyEvent event) {
8863         return false;
8864     }
8865
8866     /**
8867      * Default implementation of {@link KeyEvent.Callback#onKeyDown(int, KeyEvent)
8868      * KeyEvent.Callback.onKeyDown()}: perform press of the view
8869      * when {@link KeyEvent#KEYCODE_DPAD_CENTER} or {@link KeyEvent#KEYCODE_ENTER}
8870      * is released, if the view is enabled and clickable.
8871      *
8872      * <p>Key presses in software keyboards will generally NOT trigger this listener,
8873      * although some may elect to do so in some situations. Do not rely on this to
8874      * catch software key presses.
8875      *
8876      * @param keyCode A key code that represents the button pressed, from
8877      *                {@link android.view.KeyEvent}.
8878      * @param event   The KeyEvent object that defines the button action.
8879      */
8880     public boolean onKeyDown(int keyCode, KeyEvent event) {
8881         boolean result = false;
8882
8883         if (KeyEvent.isConfirmKey(keyCode)) {
8884             if ((mViewFlags & ENABLED_MASK) == DISABLED) {
8885                 return true;
8886             }
8887             // Long clickable items don't necessarily have to be clickable
8888             if (((mViewFlags & CLICKABLE) == CLICKABLE ||
8889                     (mViewFlags & LONG_CLICKABLE) == LONG_CLICKABLE) &&
8890                     (event.getRepeatCount() == 0)) {
8891                 setPressed(true);
8892                 checkForLongClick(0);
8893                 return true;
8894             }
8895         }
8896         return result;
8897     }
8898
8899     /**
8900      * Default implementation of {@link KeyEvent.Callback#onKeyLongPress(int, KeyEvent)
8901      * KeyEvent.Callback.onKeyLongPress()}: always returns false (doesn't handle
8902      * the event).
8903      * <p>Key presses in software keyboards will generally NOT trigger this listener,
8904      * although some may elect to do so in some situations. Do not rely on this to
8905      * catch software key presses.
8906      */
8907     public boolean onKeyLongPress(int keyCode, KeyEvent event) {
8908         return false;
8909     }
8910
8911     /**
8912      * Default implementation of {@link KeyEvent.Callback#onKeyUp(int, KeyEvent)
8913      * KeyEvent.Callback.onKeyUp()}: perform clicking of the view
8914      * when {@link KeyEvent#KEYCODE_DPAD_CENTER} or
8915      * {@link KeyEvent#KEYCODE_ENTER} is released.
8916      * <p>Key presses in software keyboards will generally NOT trigger this listener,
8917      * although some may elect to do so in some situations. Do not rely on this to
8918      * catch software key presses.
8919      *
8920      * @param keyCode A key code that represents the button pressed, from
8921      *                {@link android.view.KeyEvent}.
8922      * @param event   The KeyEvent object that defines the button action.
8923      */
8924     public boolean onKeyUp(int keyCode, KeyEvent event) {
8925         if (KeyEvent.isConfirmKey(keyCode)) {
8926             if ((mViewFlags & ENABLED_MASK) == DISABLED) {
8927                 return true;
8928             }
8929             if ((mViewFlags & CLICKABLE) == CLICKABLE && isPressed()) {
8930                 setPressed(false);
8931
8932                 if (!mHasPerformedLongPress) {
8933                     // This is a tap, so remove the longpress check
8934                     removeLongPressCallback();
8935                     return performClick();
8936                 }
8937             }
8938         }
8939         return false;
8940     }
8941
8942     /**
8943      * Default implementation of {@link KeyEvent.Callback#onKeyMultiple(int, int, KeyEvent)
8944      * KeyEvent.Callback.onKeyMultiple()}: always returns false (doesn't handle
8945      * the event).
8946      * <p>Key presses in software keyboards will generally NOT trigger this listener,
8947      * although some may elect to do so in some situations. Do not rely on this to
8948      * catch software key presses.
8949      *
8950      * @param keyCode     A key code that represents the button pressed, from
8951      *                    {@link android.view.KeyEvent}.
8952      * @param repeatCount The number of times the action was made.
8953      * @param event       The KeyEvent object that defines the button action.
8954      */
8955     public boolean onKeyMultiple(int keyCode, int repeatCount, KeyEvent event) {
8956         return false;
8957     }
8958
8959     /**
8960      * Called on the focused view when a key shortcut event is not handled.
8961      * Override this method to implement local key shortcuts for the View.
8962      * Key shortcuts can also be implemented by setting the
8963      * {@link MenuItem#setShortcut(char, char) shortcut} property of menu items.
8964      *
8965      * @param keyCode The value in event.getKeyCode().
8966      * @param event Description of the key event.
8967      * @return If you handled the event, return true. If you want to allow the
8968      *         event to be handled by the next receiver, return false.
8969      */
8970     public boolean onKeyShortcut(int keyCode, KeyEvent event) {
8971         return false;
8972     }
8973
8974     /**
8975      * Check whether the called view is a text editor, in which case it
8976      * would make sense to automatically display a soft input window for
8977      * it.  Subclasses should override this if they implement
8978      * {@link #onCreateInputConnection(EditorInfo)} to return true if
8979      * a call on that method would return a non-null InputConnection, and
8980      * they are really a first-class editor that the user would normally
8981      * start typing on when the go into a window containing your view.
8982      *
8983      * <p>The default implementation always returns false.  This does
8984      * <em>not</em> mean that its {@link #onCreateInputConnection(EditorInfo)}
8985      * will not be called or the user can not otherwise perform edits on your
8986      * view; it is just a hint to the system that this is not the primary
8987      * purpose of this view.
8988      *
8989      * @return Returns true if this view is a text editor, else false.
8990      */
8991     public boolean onCheckIsTextEditor() {
8992         return false;
8993     }
8994
8995     /**
8996      * Create a new InputConnection for an InputMethod to interact
8997      * with the view.  The default implementation returns null, since it doesn't
8998      * support input methods.  You can override this to implement such support.
8999      * This is only needed for views that take focus and text input.
9000      *
9001      * <p>When implementing this, you probably also want to implement
9002      * {@link #onCheckIsTextEditor()} to indicate you will return a
9003      * non-null InputConnection.</p>
9004      *
9005      * <p>Also, take good care to fill in the {@link android.view.inputmethod.EditorInfo}
9006      * object correctly and in its entirety, so that the connected IME can rely
9007      * on its values. For example, {@link android.view.inputmethod.EditorInfo#initialSelStart}
9008      * and  {@link android.view.inputmethod.EditorInfo#initialSelEnd} members
9009      * must be filled in with the correct cursor position for IMEs to work correctly
9010      * with your application.</p>
9011      *
9012      * @param outAttrs Fill in with attribute information about the connection.
9013      */
9014     public InputConnection onCreateInputConnection(EditorInfo outAttrs) {
9015         return null;
9016     }
9017
9018     /**
9019      * Called by the {@link android.view.inputmethod.InputMethodManager}
9020      * when a view who is not the current
9021      * input connection target is trying to make a call on the manager.  The
9022      * default implementation returns false; you can override this to return
9023      * true for certain views if you are performing InputConnection proxying
9024      * to them.
9025      * @param view The View that is making the InputMethodManager call.
9026      * @return Return true to allow the call, false to reject.
9027      */
9028     public boolean checkInputConnectionProxy(View view) {
9029         return false;
9030     }
9031
9032     /**
9033      * Show the context menu for this view. It is not safe to hold on to the
9034      * menu after returning from this method.
9035      *
9036      * You should normally not overload this method. Overload
9037      * {@link #onCreateContextMenu(ContextMenu)} or define an
9038      * {@link OnCreateContextMenuListener} to add items to the context menu.
9039      *
9040      * @param menu The context menu to populate
9041      */
9042     public void createContextMenu(ContextMenu menu) {
9043         ContextMenuInfo menuInfo = getContextMenuInfo();
9044
9045         // Sets the current menu info so all items added to menu will have
9046         // my extra info set.
9047         ((MenuBuilder)menu).setCurrentMenuInfo(menuInfo);
9048
9049         onCreateContextMenu(menu);
9050         ListenerInfo li = mListenerInfo;
9051         if (li != null && li.mOnCreateContextMenuListener != null) {
9052             li.mOnCreateContextMenuListener.onCreateContextMenu(menu, this, menuInfo);
9053         }
9054
9055         // Clear the extra information so subsequent items that aren't mine don't
9056         // have my extra info.
9057         ((MenuBuilder)menu).setCurrentMenuInfo(null);
9058
9059         if (mParent != null) {
9060             mParent.createContextMenu(menu);
9061         }
9062     }
9063
9064     /**
9065      * Views should implement this if they have extra information to associate
9066      * with the context menu. The return result is supplied as a parameter to
9067      * the {@link OnCreateContextMenuListener#onCreateContextMenu(ContextMenu, View, ContextMenuInfo)}
9068      * callback.
9069      *
9070      * @return Extra information about the item for which the context menu
9071      *         should be shown. This information will vary across different
9072      *         subclasses of View.
9073      */
9074     protected ContextMenuInfo getContextMenuInfo() {
9075         return null;
9076     }
9077
9078     /**
9079      * Views should implement this if the view itself is going to add items to
9080      * the context menu.
9081      *
9082      * @param menu the context menu to populate
9083      */
9084     protected void onCreateContextMenu(ContextMenu menu) {
9085     }
9086
9087     /**
9088      * Implement this method to handle trackball motion events.  The
9089      * <em>relative</em> movement of the trackball since the last event
9090      * can be retrieve with {@link MotionEvent#getX MotionEvent.getX()} and
9091      * {@link MotionEvent#getY MotionEvent.getY()}.  These are normalized so
9092      * that a movement of 1 corresponds to the user pressing one DPAD key (so
9093      * they will often be fractional values, representing the more fine-grained
9094      * movement information available from a trackball).
9095      *
9096      * @param event The motion event.
9097      * @return True if the event was handled, false otherwise.
9098      */
9099     public boolean onTrackballEvent(MotionEvent event) {
9100         return false;
9101     }
9102
9103     /**
9104      * Implement this method to handle generic motion events.
9105      * <p>
9106      * Generic motion events describe joystick movements, mouse hovers, track pad
9107      * touches, scroll wheel movements and other input events.  The
9108      * {@link MotionEvent#getSource() source} of the motion event specifies
9109      * the class of input that was received.  Implementations of this method
9110      * must examine the bits in the source before processing the event.
9111      * The following code example shows how this is done.
9112      * </p><p>
9113      * Generic motion events with source class {@link InputDevice#SOURCE_CLASS_POINTER}
9114      * are delivered to the view under the pointer.  All other generic motion events are
9115      * delivered to the focused view.
9116      * </p>
9117      * <pre> public boolean onGenericMotionEvent(MotionEvent event) {
9118      *     if (event.isFromSource(InputDevice.SOURCE_CLASS_JOYSTICK)) {
9119      *         if (event.getAction() == MotionEvent.ACTION_MOVE) {
9120      *             // process the joystick movement...
9121      *             return true;
9122      *         }
9123      *     }
9124      *     if (event.isFromSource(InputDevice.SOURCE_CLASS_POINTER)) {
9125      *         switch (event.getAction()) {
9126      *             case MotionEvent.ACTION_HOVER_MOVE:
9127      *                 // process the mouse hover movement...
9128      *                 return true;
9129      *             case MotionEvent.ACTION_SCROLL:
9130      *                 // process the scroll wheel movement...
9131      *                 return true;
9132      *         }
9133      *     }
9134      *     return super.onGenericMotionEvent(event);
9135      * }</pre>
9136      *
9137      * @param event The generic motion event being processed.
9138      * @return True if the event was handled, false otherwise.
9139      */
9140     public boolean onGenericMotionEvent(MotionEvent event) {
9141         return false;
9142     }
9143
9144     /**
9145      * Implement this method to handle hover events.
9146      * <p>
9147      * This method is called whenever a pointer is hovering into, over, or out of the
9148      * bounds of a view and the view is not currently being touched.
9149      * Hover events are represented as pointer events with action
9150      * {@link MotionEvent#ACTION_HOVER_ENTER}, {@link MotionEvent#ACTION_HOVER_MOVE},
9151      * or {@link MotionEvent#ACTION_HOVER_EXIT}.
9152      * </p>
9153      * <ul>
9154      * <li>The view receives a hover event with action {@link MotionEvent#ACTION_HOVER_ENTER}
9155      * when the pointer enters the bounds of the view.</li>
9156      * <li>The view receives a hover event with action {@link MotionEvent#ACTION_HOVER_MOVE}
9157      * when the pointer has already entered the bounds of the view and has moved.</li>
9158      * <li>The view receives a hover event with action {@link MotionEvent#ACTION_HOVER_EXIT}
9159      * when the pointer has exited the bounds of the view or when the pointer is
9160      * about to go down due to a button click, tap, or similar user action that
9161      * causes the view to be touched.</li>
9162      * </ul>
9163      * <p>
9164      * The view should implement this method to return true to indicate that it is
9165      * handling the hover event, such as by changing its drawable state.
9166      * </p><p>
9167      * The default implementation calls {@link #setHovered} to update the hovered state
9168      * of the view when a hover enter or hover exit event is received, if the view
9169      * is enabled and is clickable.  The default implementation also sends hover
9170      * accessibility events.
9171      * </p>
9172      *
9173      * @param event The motion event that describes the hover.
9174      * @return True if the view handled the hover event.
9175      *
9176      * @see #isHovered
9177      * @see #setHovered
9178      * @see #onHoverChanged
9179      */
9180     public boolean onHoverEvent(MotionEvent event) {
9181         // The root view may receive hover (or touch) events that are outside the bounds of
9182         // the window.  This code ensures that we only send accessibility events for
9183         // hovers that are actually within the bounds of the root view.
9184         final int action = event.getActionMasked();
9185         if (!mSendingHoverAccessibilityEvents) {
9186             if ((action == MotionEvent.ACTION_HOVER_ENTER
9187                     || action == MotionEvent.ACTION_HOVER_MOVE)
9188                     && !hasHoveredChild()
9189                     && pointInView(event.getX(), event.getY())) {
9190                 sendAccessibilityHoverEvent(AccessibilityEvent.TYPE_VIEW_HOVER_ENTER);
9191                 mSendingHoverAccessibilityEvents = true;
9192             }
9193         } else {
9194             if (action == MotionEvent.ACTION_HOVER_EXIT
9195                     || (action == MotionEvent.ACTION_MOVE
9196                             && !pointInView(event.getX(), event.getY()))) {
9197                 mSendingHoverAccessibilityEvents = false;
9198                 sendAccessibilityHoverEvent(AccessibilityEvent.TYPE_VIEW_HOVER_EXIT);
9199             }
9200         }
9201
9202         if (isHoverable()) {
9203             switch (action) {
9204                 case MotionEvent.ACTION_HOVER_ENTER:
9205                     setHovered(true);
9206                     break;
9207                 case MotionEvent.ACTION_HOVER_EXIT:
9208                     setHovered(false);
9209                     break;
9210             }
9211
9212             // Dispatch the event to onGenericMotionEvent before returning true.
9213             // This is to provide compatibility with existing applications that
9214             // handled HOVER_MOVE events in onGenericMotionEvent and that would
9215             // break because of the new default handling for hoverable views
9216             // in onHoverEvent.
9217             // Note that onGenericMotionEvent will be called by default when
9218             // onHoverEvent returns false (refer to dispatchGenericMotionEvent).
9219             dispatchGenericMotionEventInternal(event);
9220             // The event was already handled by calling setHovered(), so always
9221             // return true.
9222             return true;
9223         }
9224
9225         return false;
9226     }
9227
9228     /**
9229      * Returns true if the view should handle {@link #onHoverEvent}
9230      * by calling {@link #setHovered} to change its hovered state.
9231      *
9232      * @return True if the view is hoverable.
9233      */
9234     private boolean isHoverable() {
9235         final int viewFlags = mViewFlags;
9236         if ((viewFlags & ENABLED_MASK) == DISABLED) {
9237             return false;
9238         }
9239
9240         return (viewFlags & CLICKABLE) == CLICKABLE
9241                 || (viewFlags & LONG_CLICKABLE) == LONG_CLICKABLE;
9242     }
9243
9244     /**
9245      * Returns true if the view is currently hovered.
9246      *
9247      * @return True if the view is currently hovered.
9248      *
9249      * @see #setHovered
9250      * @see #onHoverChanged
9251      */
9252     @ViewDebug.ExportedProperty
9253     public boolean isHovered() {
9254         return (mPrivateFlags & PFLAG_HOVERED) != 0;
9255     }
9256
9257     /**
9258      * Sets whether the view is currently hovered.
9259      * <p>
9260      * Calling this method also changes the drawable state of the view.  This
9261      * enables the view to react to hover by using different drawable resources
9262      * to change its appearance.
9263      * </p><p>
9264      * The {@link #onHoverChanged} method is called when the hovered state changes.
9265      * </p>
9266      *
9267      * @param hovered True if the view is hovered.
9268      *
9269      * @see #isHovered
9270      * @see #onHoverChanged
9271      */
9272     public void setHovered(boolean hovered) {
9273         if (hovered) {
9274             if ((mPrivateFlags & PFLAG_HOVERED) == 0) {
9275                 mPrivateFlags |= PFLAG_HOVERED;
9276                 refreshDrawableState();
9277                 onHoverChanged(true);
9278             }
9279         } else {
9280             if ((mPrivateFlags & PFLAG_HOVERED) != 0) {
9281                 mPrivateFlags &= ~PFLAG_HOVERED;
9282                 refreshDrawableState();
9283                 onHoverChanged(false);
9284             }
9285         }
9286     }
9287
9288     /**
9289      * Implement this method to handle hover state changes.
9290      * <p>
9291      * This method is called whenever the hover state changes as a result of a
9292      * call to {@link #setHovered}.
9293      * </p>
9294      *
9295      * @param hovered The current hover state, as returned by {@link #isHovered}.
9296      *
9297      * @see #isHovered
9298      * @see #setHovered
9299      */
9300     public void onHoverChanged(boolean hovered) {
9301     }
9302
9303     /**
9304      * Implement this method to handle touch screen motion events.
9305      * <p>
9306      * If this method is used to detect click actions, it is recommended that
9307      * the actions be performed by implementing and calling
9308      * {@link #performClick()}. This will ensure consistent system behavior,
9309      * including:
9310      * <ul>
9311      * <li>obeying click sound preferences
9312      * <li>dispatching OnClickListener calls
9313      * <li>handling {@link AccessibilityNodeInfo#ACTION_CLICK ACTION_CLICK} when
9314      * accessibility features are enabled
9315      * </ul>
9316      *
9317      * @param event The motion event.
9318      * @return True if the event was handled, false otherwise.
9319      */
9320     public boolean onTouchEvent(MotionEvent event) {
9321         final float x = event.getX();
9322         final float y = event.getY();
9323         final int viewFlags = mViewFlags;
9324
9325         if ((viewFlags & ENABLED_MASK) == DISABLED) {
9326             if (event.getAction() == MotionEvent.ACTION_UP && (mPrivateFlags & PFLAG_PRESSED) != 0) {
9327                 setPressed(false);
9328             }
9329             // A disabled view that is clickable still consumes the touch
9330             // events, it just doesn't respond to them.
9331             return (((viewFlags & CLICKABLE) == CLICKABLE ||
9332                     (viewFlags & LONG_CLICKABLE) == LONG_CLICKABLE));
9333         }
9334
9335         if (mTouchDelegate != null) {
9336             if (mTouchDelegate.onTouchEvent(event)) {
9337                 return true;
9338             }
9339         }
9340
9341         if (((viewFlags & CLICKABLE) == CLICKABLE ||
9342                 (viewFlags & LONG_CLICKABLE) == LONG_CLICKABLE)) {
9343             switch (event.getAction()) {
9344                 case MotionEvent.ACTION_UP:
9345                     boolean prepressed = (mPrivateFlags & PFLAG_PREPRESSED) != 0;
9346                     if ((mPrivateFlags & PFLAG_PRESSED) != 0 || prepressed) {
9347                         // take focus if we don't have it already and we should in
9348                         // touch mode.
9349                         boolean focusTaken = false;
9350                         if (isFocusable() && isFocusableInTouchMode() && !isFocused()) {
9351                             focusTaken = requestFocus();
9352                         }
9353
9354                         if (prepressed) {
9355                             // The button is being released before we actually
9356                             // showed it as pressed.  Make it show the pressed
9357                             // state now (before scheduling the click) to ensure
9358                             // the user sees it.
9359                             setPressed(true, x, y);
9360                        }
9361
9362                         if (!mHasPerformedLongPress) {
9363                             // This is a tap, so remove the longpress check
9364                             removeLongPressCallback();
9365
9366                             // Only perform take click actions if we were in the pressed state
9367                             if (!focusTaken) {
9368                                 // Use a Runnable and post this rather than calling
9369                                 // performClick directly. This lets other visual state
9370                                 // of the view update before click actions start.
9371                                 if (mPerformClick == null) {
9372                                     mPerformClick = new PerformClick();
9373                                 }
9374                                 if (!post(mPerformClick)) {
9375                                     performClick();
9376                                 }
9377                             }
9378                         }
9379
9380                         if (mUnsetPressedState == null) {
9381                             mUnsetPressedState = new UnsetPressedState();
9382                         }
9383
9384                         if (prepressed) {
9385                             postDelayed(mUnsetPressedState,
9386                                     ViewConfiguration.getPressedStateDuration());
9387                         } else if (!post(mUnsetPressedState)) {
9388                             // If the post failed, unpress right now
9389                             mUnsetPressedState.run();
9390                         }
9391
9392                         removeTapCallback();
9393                     }
9394                     break;
9395
9396                 case MotionEvent.ACTION_DOWN:
9397                     mHasPerformedLongPress = false;
9398
9399                     if (performButtonActionOnTouchDown(event)) {
9400                         break;
9401                     }
9402
9403                     // Walk up the hierarchy to determine if we're inside a scrolling container.
9404                     boolean isInScrollingContainer = isInScrollingContainer();
9405
9406                     // For views inside a scrolling container, delay the pressed feedback for
9407                     // a short period in case this is a scroll.
9408                     if (isInScrollingContainer) {
9409                         mPrivateFlags |= PFLAG_PREPRESSED;
9410                         if (mPendingCheckForTap == null) {
9411                             mPendingCheckForTap = new CheckForTap();
9412                         }
9413                         mPendingCheckForTap.x = event.getX();
9414                         mPendingCheckForTap.y = event.getY();
9415                         postDelayed(mPendingCheckForTap, ViewConfiguration.getTapTimeout());
9416                     } else {
9417                         // Not inside a scrolling container, so show the feedback right away
9418                         setPressed(true, x, y);
9419                         checkForLongClick(0);
9420                     }
9421                     break;
9422
9423                 case MotionEvent.ACTION_CANCEL:
9424                     setPressed(false);
9425                     removeTapCallback();
9426                     removeLongPressCallback();
9427                     break;
9428
9429                 case MotionEvent.ACTION_MOVE:
9430                     drawableHotspotChanged(x, y);
9431
9432                     // Be lenient about moving outside of buttons
9433                     if (!pointInView(x, y, mTouchSlop)) {
9434                         // Outside button
9435                         removeTapCallback();
9436                         if ((mPrivateFlags & PFLAG_PRESSED) != 0) {
9437                             // Remove any future long press/tap checks
9438                             removeLongPressCallback();
9439
9440                             setPressed(false);
9441                         }
9442                     }
9443                     break;
9444             }
9445
9446             return true;
9447         }
9448
9449         return false;
9450     }
9451
9452     /**
9453      * @hide
9454      */
9455     public boolean isInScrollingContainer() {
9456         ViewParent p = getParent();
9457         while (p != null && p instanceof ViewGroup) {
9458             if (((ViewGroup) p).shouldDelayChildPressedState()) {
9459                 return true;
9460             }
9461             p = p.getParent();
9462         }
9463         return false;
9464     }
9465
9466     /**
9467      * Remove the longpress detection timer.
9468      */
9469     private void removeLongPressCallback() {
9470         if (mPendingCheckForLongPress != null) {
9471           removeCallbacks(mPendingCheckForLongPress);
9472         }
9473     }
9474
9475     /**
9476      * Remove the pending click action
9477      */
9478     private void removePerformClickCallback() {
9479         if (mPerformClick != null) {
9480             removeCallbacks(mPerformClick);
9481         }
9482     }
9483
9484     /**
9485      * Remove the prepress detection timer.
9486      */
9487     private void removeUnsetPressCallback() {
9488         if ((mPrivateFlags & PFLAG_PRESSED) != 0 && mUnsetPressedState != null) {
9489             setPressed(false);
9490             removeCallbacks(mUnsetPressedState);
9491         }
9492     }
9493
9494     /**
9495      * Remove the tap detection timer.
9496      */
9497     private void removeTapCallback() {
9498         if (mPendingCheckForTap != null) {
9499             mPrivateFlags &= ~PFLAG_PREPRESSED;
9500             removeCallbacks(mPendingCheckForTap);
9501         }
9502     }
9503
9504     /**
9505      * Cancels a pending long press.  Your subclass can use this if you
9506      * want the context menu to come up if the user presses and holds
9507      * at the same place, but you don't want it to come up if they press
9508      * and then move around enough to cause scrolling.
9509      */
9510     public void cancelLongPress() {
9511         removeLongPressCallback();
9512
9513         /*
9514          * The prepressed state handled by the tap callback is a display
9515          * construct, but the tap callback will post a long press callback
9516          * less its own timeout. Remove it here.
9517          */
9518         removeTapCallback();
9519     }
9520
9521     /**
9522      * Remove the pending callback for sending a
9523      * {@link AccessibilityEvent#TYPE_VIEW_SCROLLED} accessibility event.
9524      */
9525     private void removeSendViewScrolledAccessibilityEventCallback() {
9526         if (mSendViewScrolledAccessibilityEvent != null) {
9527             removeCallbacks(mSendViewScrolledAccessibilityEvent);
9528             mSendViewScrolledAccessibilityEvent.mIsPending = false;
9529         }
9530     }
9531
9532     /**
9533      * Sets the TouchDelegate for this View.
9534      */
9535     public void setTouchDelegate(TouchDelegate delegate) {
9536         mTouchDelegate = delegate;
9537     }
9538
9539     /**
9540      * Gets the TouchDelegate for this View.
9541      */
9542     public TouchDelegate getTouchDelegate() {
9543         return mTouchDelegate;
9544     }
9545
9546     /**
9547      * Request unbuffered dispatch of the given stream of MotionEvents to this View.
9548      *
9549      * Until this View receives a corresponding {@link MotionEvent#ACTION_UP}, ask that the input
9550      * system not batch {@link MotionEvent}s but instead deliver them as soon as they're
9551      * available. This method should only be called for touch events.
9552      *
9553      * <p class="note">This api is not intended for most applications. Buffered dispatch
9554      * provides many of benefits, and just requesting unbuffered dispatch on most MotionEvent
9555      * streams will not improve your input latency. Side effects include: increased latency,
9556      * jittery scrolls and inability to take advantage of system resampling. Talk to your input
9557      * professional to see if {@link #requestUnbufferedDispatch(MotionEvent)} is right for
9558      * you.</p>
9559      */
9560     public final void requestUnbufferedDispatch(MotionEvent event) {
9561         final int action = event.getAction();
9562         if (mAttachInfo == null
9563                 || action != MotionEvent.ACTION_DOWN && action != MotionEvent.ACTION_MOVE
9564                 || !event.isTouchEvent()) {
9565             return;
9566         }
9567         mAttachInfo.mUnbufferedDispatchRequested = true;
9568     }
9569
9570     /**
9571      * Set flags controlling behavior of this view.
9572      *
9573      * @param flags Constant indicating the value which should be set
9574      * @param mask Constant indicating the bit range that should be changed
9575      */
9576     void setFlags(int flags, int mask) {
9577         final boolean accessibilityEnabled =
9578                 AccessibilityManager.getInstance(mContext).isEnabled();
9579         final boolean oldIncludeForAccessibility = accessibilityEnabled && includeForAccessibility();
9580
9581         int old = mViewFlags;
9582         mViewFlags = (mViewFlags & ~mask) | (flags & mask);
9583
9584         int changed = mViewFlags ^ old;
9585         if (changed == 0) {
9586             return;
9587         }
9588         int privateFlags = mPrivateFlags;
9589
9590         /* Check if the FOCUSABLE bit has changed */
9591         if (((changed & FOCUSABLE_MASK) != 0) &&
9592                 ((privateFlags & PFLAG_HAS_BOUNDS) !=0)) {
9593             if (((old & FOCUSABLE_MASK) == FOCUSABLE)
9594                     && ((privateFlags & PFLAG_FOCUSED) != 0)) {
9595                 /* Give up focus if we are no longer focusable */
9596                 clearFocus();
9597             } else if (((old & FOCUSABLE_MASK) == NOT_FOCUSABLE)
9598                     && ((privateFlags & PFLAG_FOCUSED) == 0)) {
9599                 /*
9600                  * Tell the view system that we are now available to take focus
9601                  * if no one else already has it.
9602                  */
9603                 if (mParent != null) mParent.focusableViewAvailable(this);
9604             }
9605         }
9606
9607         final int newVisibility = flags & VISIBILITY_MASK;
9608         if (newVisibility == VISIBLE) {
9609             if ((changed & VISIBILITY_MASK) != 0) {
9610                 /*
9611                  * If this view is becoming visible, invalidate it in case it changed while
9612                  * it was not visible. Marking it drawn ensures that the invalidation will
9613                  * go through.
9614                  */
9615                 mPrivateFlags |= PFLAG_DRAWN;
9616                 invalidate(true);
9617
9618                 needGlobalAttributesUpdate(true);
9619
9620                 // a view becoming visible is worth notifying the parent
9621                 // about in case nothing has focus.  even if this specific view
9622                 // isn't focusable, it may contain something that is, so let
9623                 // the root view try to give this focus if nothing else does.
9624                 if ((mParent != null) && (mBottom > mTop) && (mRight > mLeft)) {
9625                     mParent.focusableViewAvailable(this);
9626                 }
9627             }
9628         }
9629
9630         /* Check if the GONE bit has changed */
9631         if ((changed & GONE) != 0) {
9632             needGlobalAttributesUpdate(false);
9633             requestLayout();
9634
9635             if (((mViewFlags & VISIBILITY_MASK) == GONE)) {
9636                 if (hasFocus()) clearFocus();
9637                 clearAccessibilityFocus();
9638                 destroyDrawingCache();
9639                 if (mParent instanceof View) {
9640                     // GONE views noop invalidation, so invalidate the parent
9641                     ((View) mParent).invalidate(true);
9642                 }
9643                 // Mark the view drawn to ensure that it gets invalidated properly the next
9644                 // time it is visible and gets invalidated
9645                 mPrivateFlags |= PFLAG_DRAWN;
9646             }
9647             if (mAttachInfo != null) {
9648                 mAttachInfo.mViewVisibilityChanged = true;
9649             }
9650         }
9651
9652         /* Check if the VISIBLE bit has changed */
9653         if ((changed & INVISIBLE) != 0) {
9654             needGlobalAttributesUpdate(false);
9655             /*
9656              * If this view is becoming invisible, set the DRAWN flag so that
9657              * the next invalidate() will not be skipped.
9658              */
9659             mPrivateFlags |= PFLAG_DRAWN;
9660
9661             if (((mViewFlags & VISIBILITY_MASK) == INVISIBLE)) {
9662                 // root view becoming invisible shouldn't clear focus and accessibility focus
9663                 if (getRootView() != this) {
9664                     if (hasFocus()) clearFocus();
9665                     clearAccessibilityFocus();
9666                 }
9667             }
9668             if (mAttachInfo != null) {
9669                 mAttachInfo.mViewVisibilityChanged = true;
9670             }
9671         }
9672
9673         if ((changed & VISIBILITY_MASK) != 0) {
9674             // If the view is invisible, cleanup its display list to free up resources
9675             if (newVisibility != VISIBLE && mAttachInfo != null) {
9676                 cleanupDraw();
9677             }
9678
9679             if (mParent instanceof ViewGroup) {
9680                 ((ViewGroup) mParent).onChildVisibilityChanged(this,
9681                         (changed & VISIBILITY_MASK), newVisibility);
9682                 ((View) mParent).invalidate(true);
9683             } else if (mParent != null) {
9684                 mParent.invalidateChild(this, null);
9685             }
9686             dispatchVisibilityChanged(this, newVisibility);
9687
9688             notifySubtreeAccessibilityStateChangedIfNeeded();
9689         }
9690
9691         if ((changed & WILL_NOT_CACHE_DRAWING) != 0) {
9692             destroyDrawingCache();
9693         }
9694
9695         if ((changed & DRAWING_CACHE_ENABLED) != 0) {
9696             destroyDrawingCache();
9697             mPrivateFlags &= ~PFLAG_DRAWING_CACHE_VALID;
9698             invalidateParentCaches();
9699         }
9700
9701         if ((changed & DRAWING_CACHE_QUALITY_MASK) != 0) {
9702             destroyDrawingCache();
9703             mPrivateFlags &= ~PFLAG_DRAWING_CACHE_VALID;
9704         }
9705
9706         if ((changed & DRAW_MASK) != 0) {
9707             if ((mViewFlags & WILL_NOT_DRAW) != 0) {
9708                 if (mBackground != null) {
9709                     mPrivateFlags &= ~PFLAG_SKIP_DRAW;
9710                     mPrivateFlags |= PFLAG_ONLY_DRAWS_BACKGROUND;
9711                 } else {
9712                     mPrivateFlags |= PFLAG_SKIP_DRAW;
9713                 }
9714             } else {
9715                 mPrivateFlags &= ~PFLAG_SKIP_DRAW;
9716             }
9717             requestLayout();
9718             invalidate(true);
9719         }
9720
9721         if ((changed & KEEP_SCREEN_ON) != 0) {
9722             if (mParent != null && mAttachInfo != null && !mAttachInfo.mRecomputeGlobalAttributes) {
9723                 mParent.recomputeViewAttributes(this);
9724             }
9725         }
9726
9727         if (accessibilityEnabled) {
9728             if ((changed & FOCUSABLE_MASK) != 0 || (changed & VISIBILITY_MASK) != 0
9729                     || (changed & CLICKABLE) != 0 || (changed & LONG_CLICKABLE) != 0) {
9730                 if (oldIncludeForAccessibility != includeForAccessibility()) {
9731                     notifySubtreeAccessibilityStateChangedIfNeeded();
9732                 } else {
9733                     notifyViewAccessibilityStateChangedIfNeeded(
9734                             AccessibilityEvent.CONTENT_CHANGE_TYPE_UNDEFINED);
9735                 }
9736             } else if ((changed & ENABLED_MASK) != 0) {
9737                 notifyViewAccessibilityStateChangedIfNeeded(
9738                         AccessibilityEvent.CONTENT_CHANGE_TYPE_UNDEFINED);
9739             }
9740         }
9741     }
9742
9743     /**
9744      * Change the view's z order in the tree, so it's on top of other sibling
9745      * views. This ordering change may affect layout, if the parent container
9746      * uses an order-dependent layout scheme (e.g., LinearLayout). Prior
9747      * to {@link android.os.Build.VERSION_CODES#KITKAT} this
9748      * method should be followed by calls to {@link #requestLayout()} and
9749      * {@link View#invalidate()} on the view's parent to force the parent to redraw
9750      * with the new child ordering.
9751      *
9752      * @see ViewGroup#bringChildToFront(View)
9753      */
9754     public void bringToFront() {
9755         if (mParent != null) {
9756             mParent.bringChildToFront(this);
9757         }
9758     }
9759
9760     /**
9761      * This is called in response to an internal scroll in this view (i.e., the
9762      * view scrolled its own contents). This is typically as a result of
9763      * {@link #scrollBy(int, int)} or {@link #scrollTo(int, int)} having been
9764      * called.
9765      *
9766      * @param l Current horizontal scroll origin.
9767      * @param t Current vertical scroll origin.
9768      * @param oldl Previous horizontal scroll origin.
9769      * @param oldt Previous vertical scroll origin.
9770      */
9771     protected void onScrollChanged(int l, int t, int oldl, int oldt) {
9772         if (AccessibilityManager.getInstance(mContext).isEnabled()) {
9773             postSendViewScrolledAccessibilityEventCallback();
9774         }
9775
9776         mBackgroundSizeChanged = true;
9777
9778         final AttachInfo ai = mAttachInfo;
9779         if (ai != null) {
9780             ai.mViewScrollChanged = true;
9781         }
9782     }
9783
9784     /**
9785      * Interface definition for a callback to be invoked when the layout bounds of a view
9786      * changes due to layout processing.
9787      */
9788     public interface OnLayoutChangeListener {
9789         /**
9790          * Called when the layout bounds of a view changes due to layout processing.
9791          *
9792          * @param v The view whose bounds have changed.
9793          * @param left The new value of the view's left property.
9794          * @param top The new value of the view's top property.
9795          * @param right The new value of the view's right property.
9796          * @param bottom The new value of the view's bottom property.
9797          * @param oldLeft The previous value of the view's left property.
9798          * @param oldTop The previous value of the view's top property.
9799          * @param oldRight The previous value of the view's right property.
9800          * @param oldBottom The previous value of the view's bottom property.
9801          */
9802         void onLayoutChange(View v, int left, int top, int right, int bottom,
9803             int oldLeft, int oldTop, int oldRight, int oldBottom);
9804     }
9805
9806     /**
9807      * This is called during layout when the size of this view has changed. If
9808      * you were just added to the view hierarchy, you're called with the old
9809      * values of 0.
9810      *
9811      * @param w Current width of this view.
9812      * @param h Current height of this view.
9813      * @param oldw Old width of this view.
9814      * @param oldh Old height of this view.
9815      */
9816     protected void onSizeChanged(int w, int h, int oldw, int oldh) {
9817     }
9818
9819     /**
9820      * Called by draw to draw the child views. This may be overridden
9821      * by derived classes to gain control just before its children are drawn
9822      * (but after its own view has been drawn).
9823      * @param canvas the canvas on which to draw the view
9824      */
9825     protected void dispatchDraw(Canvas canvas) {
9826
9827     }
9828
9829     /**
9830      * Gets the parent of this view. Note that the parent is a
9831      * ViewParent and not necessarily a View.
9832      *
9833      * @return Parent of this view.
9834      */
9835     public final ViewParent getParent() {
9836         return mParent;
9837     }
9838
9839     /**
9840      * Set the horizontal scrolled position of your view. This will cause a call to
9841      * {@link #onScrollChanged(int, int, int, int)} and the view will be
9842      * invalidated.
9843      * @param value the x position to scroll to
9844      */
9845     public void setScrollX(int value) {
9846         scrollTo(value, mScrollY);
9847     }
9848
9849     /**
9850      * Set the vertical scrolled position of your view. This will cause a call to
9851      * {@link #onScrollChanged(int, int, int, int)} and the view will be
9852      * invalidated.
9853      * @param value the y position to scroll to
9854      */
9855     public void setScrollY(int value) {
9856         scrollTo(mScrollX, value);
9857     }
9858
9859     /**
9860      * Return the scrolled left position of this view. This is the left edge of
9861      * the displayed part of your view. You do not need to draw any pixels
9862      * farther left, since those are outside of the frame of your view on
9863      * screen.
9864      *
9865      * @return The left edge of the displayed part of your view, in pixels.
9866      */
9867     public final int getScrollX() {
9868         return mScrollX;
9869     }
9870
9871     /**
9872      * Return the scrolled top position of this view. This is the top edge of
9873      * the displayed part of your view. You do not need to draw any pixels above
9874      * it, since those are outside of the frame of your view on screen.
9875      *
9876      * @return The top edge of the displayed part of your view, in pixels.
9877      */
9878     public final int getScrollY() {
9879         return mScrollY;
9880     }
9881
9882     /**
9883      * Return the width of the your view.
9884      *
9885      * @return The width of your view, in pixels.
9886      */
9887     @ViewDebug.ExportedProperty(category = "layout")
9888     public final int getWidth() {
9889         return mRight - mLeft;
9890     }
9891
9892     /**
9893      * Return the height of your view.
9894      *
9895      * @return The height of your view, in pixels.
9896      */
9897     @ViewDebug.ExportedProperty(category = "layout")
9898     public final int getHeight() {
9899         return mBottom - mTop;
9900     }
9901
9902     /**
9903      * Return the visible drawing bounds of your view. Fills in the output
9904      * rectangle with the values from getScrollX(), getScrollY(),
9905      * getWidth(), and getHeight(). These bounds do not account for any
9906      * transformation properties currently set on the view, such as
9907      * {@link #setScaleX(float)} or {@link #setRotation(float)}.
9908      *
9909      * @param outRect The (scrolled) drawing bounds of the view.
9910      */
9911     public void getDrawingRect(Rect outRect) {
9912         outRect.left = mScrollX;
9913         outRect.top = mScrollY;
9914         outRect.right = mScrollX + (mRight - mLeft);
9915         outRect.bottom = mScrollY + (mBottom - mTop);
9916     }
9917
9918     /**
9919      * Like {@link #getMeasuredWidthAndState()}, but only returns the
9920      * raw width component (that is the result is masked by
9921      * {@link #MEASURED_SIZE_MASK}).
9922      *
9923      * @return The raw measured width of this view.
9924      */
9925     public final int getMeasuredWidth() {
9926         return mMeasuredWidth & MEASURED_SIZE_MASK;
9927     }
9928
9929     /**
9930      * Return the full width measurement information for this view as computed
9931      * by the most recent call to {@link #measure(int, int)}.  This result is a bit mask
9932      * as defined by {@link #MEASURED_SIZE_MASK} and {@link #MEASURED_STATE_TOO_SMALL}.
9933      * This should be used during measurement and layout calculations only. Use
9934      * {@link #getWidth()} to see how wide a view is after layout.
9935      *
9936      * @return The measured width of this view as a bit mask.
9937      */
9938     public final int getMeasuredWidthAndState() {
9939         return mMeasuredWidth;
9940     }
9941
9942     /**
9943      * Like {@link #getMeasuredHeightAndState()}, but only returns the
9944      * raw width component (that is the result is masked by
9945      * {@link #MEASURED_SIZE_MASK}).
9946      *
9947      * @return The raw measured height of this view.
9948      */
9949     public final int getMeasuredHeight() {
9950         return mMeasuredHeight & MEASURED_SIZE_MASK;
9951     }
9952
9953     /**
9954      * Return the full height measurement information for this view as computed
9955      * by the most recent call to {@link #measure(int, int)}.  This result is a bit mask
9956      * as defined by {@link #MEASURED_SIZE_MASK} and {@link #MEASURED_STATE_TOO_SMALL}.
9957      * This should be used during measurement and layout calculations only. Use
9958      * {@link #getHeight()} to see how wide a view is after layout.
9959      *
9960      * @return The measured width of this view as a bit mask.
9961      */
9962     public final int getMeasuredHeightAndState() {
9963         return mMeasuredHeight;
9964     }
9965
9966     /**
9967      * Return only the state bits of {@link #getMeasuredWidthAndState()}
9968      * and {@link #getMeasuredHeightAndState()}, combined into one integer.
9969      * The width component is in the regular bits {@link #MEASURED_STATE_MASK}
9970      * and the height component is at the shifted bits
9971      * {@link #MEASURED_HEIGHT_STATE_SHIFT}>>{@link #MEASURED_STATE_MASK}.
9972      */
9973     public final int getMeasuredState() {
9974         return (mMeasuredWidth&MEASURED_STATE_MASK)
9975                 | ((mMeasuredHeight>>MEASURED_HEIGHT_STATE_SHIFT)
9976                         & (MEASURED_STATE_MASK>>MEASURED_HEIGHT_STATE_SHIFT));
9977     }
9978
9979     /**
9980      * The transform matrix of this view, which is calculated based on the current
9981      * rotation, scale, and pivot properties.
9982      *
9983      * @see #getRotation()
9984      * @see #getScaleX()
9985      * @see #getScaleY()
9986      * @see #getPivotX()
9987      * @see #getPivotY()
9988      * @return The current transform matrix for the view
9989      */
9990     public Matrix getMatrix() {
9991         ensureTransformationInfo();
9992         final Matrix matrix = mTransformationInfo.mMatrix;
9993         mRenderNode.getMatrix(matrix);
9994         return matrix;
9995     }
9996
9997     /**
9998      * Returns true if the transform matrix is the identity matrix.
9999      * Recomputes the matrix if necessary.
10000      *
10001      * @return True if the transform matrix is the identity matrix, false otherwise.
10002      */
10003     final boolean hasIdentityMatrix() {
10004         return mRenderNode.hasIdentityMatrix();
10005     }
10006
10007     void ensureTransformationInfo() {
10008         if (mTransformationInfo == null) {
10009             mTransformationInfo = new TransformationInfo();
10010         }
10011     }
10012
10013    /**
10014      * Utility method to retrieve the inverse of the current mMatrix property.
10015      * We cache the matrix to avoid recalculating it when transform properties
10016      * have not changed.
10017      *
10018      * @return The inverse of the current matrix of this view.
10019      * @hide
10020      */
10021     public final Matrix getInverseMatrix() {
10022         ensureTransformationInfo();
10023         if (mTransformationInfo.mInverseMatrix == null) {
10024             mTransformationInfo.mInverseMatrix = new Matrix();
10025         }
10026         final Matrix matrix = mTransformationInfo.mInverseMatrix;
10027         mRenderNode.getInverseMatrix(matrix);
10028         return matrix;
10029     }
10030
10031     /**
10032      * Gets the distance along the Z axis from the camera to this view.
10033      *
10034      * @see #setCameraDistance(float)
10035      *
10036      * @return The distance along the Z axis.
10037      */
10038     public float getCameraDistance() {
10039         final float dpi = mResources.getDisplayMetrics().densityDpi;
10040         return -(mRenderNode.getCameraDistance() * dpi);
10041     }
10042
10043     /**
10044      * <p>Sets the distance along the Z axis (orthogonal to the X/Y plane on which
10045      * views are drawn) from the camera to this view. The camera's distance
10046      * affects 3D transformations, for instance rotations around the X and Y
10047      * axis. If the rotationX or rotationY properties are changed and this view is
10048      * large (more than half the size of the screen), it is recommended to always
10049      * use a camera distance that's greater than the height (X axis rotation) or
10050      * the width (Y axis rotation) of this view.</p>
10051      *
10052      * <p>The distance of the camera from the view plane can have an affect on the
10053      * perspective distortion of the view when it is rotated around the x or y axis.
10054      * For example, a large distance will result in a large viewing angle, and there
10055      * will not be much perspective distortion of the view as it rotates. A short
10056      * distance may cause much more perspective distortion upon rotation, and can
10057      * also result in some drawing artifacts if the rotated view ends up partially
10058      * behind the camera (which is why the recommendation is to use a distance at
10059      * least as far as the size of the view, if the view is to be rotated.)</p>
10060      *
10061      * <p>The distance is expressed in "depth pixels." The default distance depends
10062      * on the screen density. For instance, on a medium density display, the
10063      * default distance is 1280. On a high density display, the default distance
10064      * is 1920.</p>
10065      *
10066      * <p>If you want to specify a distance that leads to visually consistent
10067      * results across various densities, use the following formula:</p>
10068      * <pre>
10069      * float scale = context.getResources().getDisplayMetrics().density;
10070      * view.setCameraDistance(distance * scale);
10071      * </pre>
10072      *
10073      * <p>The density scale factor of a high density display is 1.5,
10074      * and 1920 = 1280 * 1.5.</p>
10075      *
10076      * @param distance The distance in "depth pixels", if negative the opposite
10077      *        value is used
10078      *
10079      * @see #setRotationX(float)
10080      * @see #setRotationY(float)
10081      */
10082     public void setCameraDistance(float distance) {
10083         final float dpi = mResources.getDisplayMetrics().densityDpi;
10084
10085         invalidateViewProperty(true, false);
10086         mRenderNode.setCameraDistance(-Math.abs(distance) / dpi);
10087         invalidateViewProperty(false, false);
10088
10089         invalidateParentIfNeededAndWasQuickRejected();
10090     }
10091
10092     /**
10093      * The degrees that the view is rotated around the pivot point.
10094      *
10095      * @see #setRotation(float)
10096      * @see #getPivotX()
10097      * @see #getPivotY()
10098      *
10099      * @return The degrees of rotation.
10100      */
10101     @ViewDebug.ExportedProperty(category = "drawing")
10102     public float getRotation() {
10103         return mRenderNode.getRotation();
10104     }
10105
10106     /**
10107      * Sets the degrees that the view is rotated around the pivot point. Increasing values
10108      * result in clockwise rotation.
10109      *
10110      * @param rotation The degrees of rotation.
10111      *
10112      * @see #getRotation()
10113      * @see #getPivotX()
10114      * @see #getPivotY()
10115      * @see #setRotationX(float)
10116      * @see #setRotationY(float)
10117      *
10118      * @attr ref android.R.styleable#View_rotation
10119      */
10120     public void setRotation(float rotation) {
10121         if (rotation != getRotation()) {
10122             // Double-invalidation is necessary to capture view's old and new areas
10123             invalidateViewProperty(true, false);
10124             mRenderNode.setRotation(rotation);
10125             invalidateViewProperty(false, true);
10126
10127             invalidateParentIfNeededAndWasQuickRejected();
10128             notifySubtreeAccessibilityStateChangedIfNeeded();
10129         }
10130     }
10131
10132     /**
10133      * The degrees that the view is rotated around the vertical axis through the pivot point.
10134      *
10135      * @see #getPivotX()
10136      * @see #getPivotY()
10137      * @see #setRotationY(float)
10138      *
10139      * @return The degrees of Y rotation.
10140      */
10141     @ViewDebug.ExportedProperty(category = "drawing")
10142     public float getRotationY() {
10143         return mRenderNode.getRotationY();
10144     }
10145
10146     /**
10147      * Sets the degrees that the view is rotated around the vertical axis through the pivot point.
10148      * Increasing values result in counter-clockwise rotation from the viewpoint of looking
10149      * down the y axis.
10150      *
10151      * When rotating large views, it is recommended to adjust the camera distance
10152      * accordingly. Refer to {@link #setCameraDistance(float)} for more information.
10153      *
10154      * @param rotationY The degrees of Y rotation.
10155      *
10156      * @see #getRotationY()
10157      * @see #getPivotX()
10158      * @see #getPivotY()
10159      * @see #setRotation(float)
10160      * @see #setRotationX(float)
10161      * @see #setCameraDistance(float)
10162      *
10163      * @attr ref android.R.styleable#View_rotationY
10164      */
10165     public void setRotationY(float rotationY) {
10166         if (rotationY != getRotationY()) {
10167             invalidateViewProperty(true, false);
10168             mRenderNode.setRotationY(rotationY);
10169             invalidateViewProperty(false, true);
10170
10171             invalidateParentIfNeededAndWasQuickRejected();
10172             notifySubtreeAccessibilityStateChangedIfNeeded();
10173         }
10174     }
10175
10176     /**
10177      * The degrees that the view is rotated around the horizontal axis through the pivot point.
10178      *
10179      * @see #getPivotX()
10180      * @see #getPivotY()
10181      * @see #setRotationX(float)
10182      *
10183      * @return The degrees of X rotation.
10184      */
10185     @ViewDebug.ExportedProperty(category = "drawing")
10186     public float getRotationX() {
10187         return mRenderNode.getRotationX();
10188     }
10189
10190     /**
10191      * Sets the degrees that the view is rotated around the horizontal axis through the pivot point.
10192      * Increasing values result in clockwise rotation from the viewpoint of looking down the
10193      * x axis.
10194      *
10195      * When rotating large views, it is recommended to adjust the camera distance
10196      * accordingly. Refer to {@link #setCameraDistance(float)} for more information.
10197      *
10198      * @param rotationX The degrees of X rotation.
10199      *
10200      * @see #getRotationX()
10201      * @see #getPivotX()
10202      * @see #getPivotY()
10203      * @see #setRotation(float)
10204      * @see #setRotationY(float)
10205      * @see #setCameraDistance(float)
10206      *
10207      * @attr ref android.R.styleable#View_rotationX
10208      */
10209     public void setRotationX(float rotationX) {
10210         if (rotationX != getRotationX()) {
10211             invalidateViewProperty(true, false);
10212             mRenderNode.setRotationX(rotationX);
10213             invalidateViewProperty(false, true);
10214
10215             invalidateParentIfNeededAndWasQuickRejected();
10216             notifySubtreeAccessibilityStateChangedIfNeeded();
10217         }
10218     }
10219
10220     /**
10221      * The amount that the view is scaled in x around the pivot point, as a proportion of
10222      * the view's unscaled width. A value of 1, the default, means that no scaling is applied.
10223      *
10224      * <p>By default, this is 1.0f.
10225      *
10226      * @see #getPivotX()
10227      * @see #getPivotY()
10228      * @return The scaling factor.
10229      */
10230     @ViewDebug.ExportedProperty(category = "drawing")
10231     public float getScaleX() {
10232         return mRenderNode.getScaleX();
10233     }
10234
10235     /**
10236      * Sets the amount that the view is scaled in x around the pivot point, as a proportion of
10237      * the view's unscaled width. A value of 1 means that no scaling is applied.
10238      *
10239      * @param scaleX The scaling factor.
10240      * @see #getPivotX()
10241      * @see #getPivotY()
10242      *
10243      * @attr ref android.R.styleable#View_scaleX
10244      */
10245     public void setScaleX(float scaleX) {
10246         if (scaleX != getScaleX()) {
10247             invalidateViewProperty(true, false);
10248             mRenderNode.setScaleX(scaleX);
10249             invalidateViewProperty(false, true);
10250
10251             invalidateParentIfNeededAndWasQuickRejected();
10252             notifySubtreeAccessibilityStateChangedIfNeeded();
10253         }
10254     }
10255
10256     /**
10257      * The amount that the view is scaled in y around the pivot point, as a proportion of
10258      * the view's unscaled height. A value of 1, the default, means that no scaling is applied.
10259      *
10260      * <p>By default, this is 1.0f.
10261      *
10262      * @see #getPivotX()
10263      * @see #getPivotY()
10264      * @return The scaling factor.
10265      */
10266     @ViewDebug.ExportedProperty(category = "drawing")
10267     public float getScaleY() {
10268         return mRenderNode.getScaleY();
10269     }
10270
10271     /**
10272      * Sets the amount that the view is scaled in Y around the pivot point, as a proportion of
10273      * the view's unscaled width. A value of 1 means that no scaling is applied.
10274      *
10275      * @param scaleY The scaling factor.
10276      * @see #getPivotX()
10277      * @see #getPivotY()
10278      *
10279      * @attr ref android.R.styleable#View_scaleY
10280      */
10281     public void setScaleY(float scaleY) {
10282         if (scaleY != getScaleY()) {
10283             invalidateViewProperty(true, false);
10284             mRenderNode.setScaleY(scaleY);
10285             invalidateViewProperty(false, true);
10286
10287             invalidateParentIfNeededAndWasQuickRejected();
10288             notifySubtreeAccessibilityStateChangedIfNeeded();
10289         }
10290     }
10291
10292     /**
10293      * The x location of the point around which the view is {@link #setRotation(float) rotated}
10294      * and {@link #setScaleX(float) scaled}.
10295      *
10296      * @see #getRotation()
10297      * @see #getScaleX()
10298      * @see #getScaleY()
10299      * @see #getPivotY()
10300      * @return The x location of the pivot point.
10301      *
10302      * @attr ref android.R.styleable#View_transformPivotX
10303      */
10304     @ViewDebug.ExportedProperty(category = "drawing")
10305     public float getPivotX() {
10306         return mRenderNode.getPivotX();
10307     }
10308
10309     /**
10310      * Sets the x location of the point around which the view is
10311      * {@link #setRotation(float) rotated} and {@link #setScaleX(float) scaled}.
10312      * By default, the pivot point is centered on the object.
10313      * Setting this property disables this behavior and causes the view to use only the
10314      * explicitly set pivotX and pivotY values.
10315      *
10316      * @param pivotX The x location of the pivot point.
10317      * @see #getRotation()
10318      * @see #getScaleX()
10319      * @see #getScaleY()
10320      * @see #getPivotY()
10321      *
10322      * @attr ref android.R.styleable#View_transformPivotX
10323      */
10324     public void setPivotX(float pivotX) {
10325         if (!mRenderNode.isPivotExplicitlySet() || pivotX != getPivotX()) {
10326             invalidateViewProperty(true, false);
10327             mRenderNode.setPivotX(pivotX);
10328             invalidateViewProperty(false, true);
10329
10330             invalidateParentIfNeededAndWasQuickRejected();
10331         }
10332     }
10333
10334     /**
10335      * The y location of the point around which the view is {@link #setRotation(float) rotated}
10336      * and {@link #setScaleY(float) scaled}.
10337      *
10338      * @see #getRotation()
10339      * @see #getScaleX()
10340      * @see #getScaleY()
10341      * @see #getPivotY()
10342      * @return The y location of the pivot point.
10343      *
10344      * @attr ref android.R.styleable#View_transformPivotY
10345      */
10346     @ViewDebug.ExportedProperty(category = "drawing")
10347     public float getPivotY() {
10348         return mRenderNode.getPivotY();
10349     }
10350
10351     /**
10352      * Sets the y location of the point around which the view is {@link #setRotation(float) rotated}
10353      * and {@link #setScaleY(float) scaled}. By default, the pivot point is centered on the object.
10354      * Setting this property disables this behavior and causes the view to use only the
10355      * explicitly set pivotX and pivotY values.
10356      *
10357      * @param pivotY The y location of the pivot point.
10358      * @see #getRotation()
10359      * @see #getScaleX()
10360      * @see #getScaleY()
10361      * @see #getPivotY()
10362      *
10363      * @attr ref android.R.styleable#View_transformPivotY
10364      */
10365     public void setPivotY(float pivotY) {
10366         if (!mRenderNode.isPivotExplicitlySet() || pivotY != getPivotY()) {
10367             invalidateViewProperty(true, false);
10368             mRenderNode.setPivotY(pivotY);
10369             invalidateViewProperty(false, true);
10370
10371             invalidateParentIfNeededAndWasQuickRejected();
10372         }
10373     }
10374
10375     /**
10376      * The opacity of the view. This is a value from 0 to 1, where 0 means the view is
10377      * completely transparent and 1 means the view is completely opaque.
10378      *
10379      * <p>By default this is 1.0f.
10380      * @return The opacity of the view.
10381      */
10382     @ViewDebug.ExportedProperty(category = "drawing")
10383     public float getAlpha() {
10384         return mTransformationInfo != null ? mTransformationInfo.mAlpha : 1;
10385     }
10386
10387     /**
10388      * Returns whether this View has content which overlaps.
10389      *
10390      * <p>This function, intended to be overridden by specific View types, is an optimization when
10391      * alpha is set on a view. If rendering overlaps in a view with alpha < 1, that view is drawn to
10392      * an offscreen buffer and then composited into place, which can be expensive. If the view has
10393      * no overlapping rendering, the view can draw each primitive with the appropriate alpha value
10394      * directly. An example of overlapping rendering is a TextView with a background image, such as
10395      * a Button. An example of non-overlapping rendering is a TextView with no background, or an
10396      * ImageView with only the foreground image. The default implementation returns true; subclasses
10397      * should override if they have cases which can be optimized.</p>
10398      *
10399      * <p>The current implementation of the saveLayer and saveLayerAlpha methods in {@link Canvas}
10400      * necessitates that a View return true if it uses the methods internally without passing the
10401      * {@link Canvas#CLIP_TO_LAYER_SAVE_FLAG}.</p>
10402      *
10403      * @return true if the content in this view might overlap, false otherwise.
10404      */
10405     @ViewDebug.ExportedProperty(category = "drawing")
10406     public boolean hasOverlappingRendering() {
10407         return true;
10408     }
10409
10410     /**
10411      * <p>Sets the opacity of the view. This is a value from 0 to 1, where 0 means the view is
10412      * completely transparent and 1 means the view is completely opaque.</p>
10413      *
10414      * <p> Note that setting alpha to a translucent value (0 < alpha < 1) can have significant
10415      * performance implications, especially for large views. It is best to use the alpha property
10416      * sparingly and transiently, as in the case of fading animations.</p>
10417      *
10418      * <p>For a view with a frequently changing alpha, such as during a fading animation, it is
10419      * strongly recommended for performance reasons to either override
10420      * {@link #hasOverlappingRendering()} to return false if appropriate, or setting a
10421      * {@link #setLayerType(int, android.graphics.Paint) layer type} on the view.</p>
10422      *
10423      * <p>If this view overrides {@link #onSetAlpha(int)} to return true, then this view is
10424      * responsible for applying the opacity itself.</p>
10425      *
10426      * <p>Note that if the view is backed by a
10427      * {@link #setLayerType(int, android.graphics.Paint) layer} and is associated with a
10428      * {@link #setLayerPaint(android.graphics.Paint) layer paint}, setting an alpha value less than
10429      * 1.0 will supercede the alpha of the layer paint.</p>
10430      *
10431      * @param alpha The opacity of the view.
10432      *
10433      * @see #hasOverlappingRendering()
10434      * @see #setLayerType(int, android.graphics.Paint)
10435      *
10436      * @attr ref android.R.styleable#View_alpha
10437      */
10438     public void setAlpha(float alpha) {
10439         ensureTransformationInfo();
10440         if (mTransformationInfo.mAlpha != alpha) {
10441             mTransformationInfo.mAlpha = alpha;
10442             if (onSetAlpha((int) (alpha * 255))) {
10443                 mPrivateFlags |= PFLAG_ALPHA_SET;
10444                 // subclass is handling alpha - don't optimize rendering cache invalidation
10445                 invalidateParentCaches();
10446                 invalidate(true);
10447             } else {
10448                 mPrivateFlags &= ~PFLAG_ALPHA_SET;
10449                 invalidateViewProperty(true, false);
10450                 mRenderNode.setAlpha(getFinalAlpha());
10451                 notifyViewAccessibilityStateChangedIfNeeded(
10452                         AccessibilityEvent.CONTENT_CHANGE_TYPE_UNDEFINED);
10453             }
10454         }
10455     }
10456
10457     /**
10458      * Faster version of setAlpha() which performs the same steps except there are
10459      * no calls to invalidate(). The caller of this function should perform proper invalidation
10460      * on the parent and this object. The return value indicates whether the subclass handles
10461      * alpha (the return value for onSetAlpha()).
10462      *
10463      * @param alpha The new value for the alpha property
10464      * @return true if the View subclass handles alpha (the return value for onSetAlpha()) and
10465      *         the new value for the alpha property is different from the old value
10466      */
10467     boolean setAlphaNoInvalidation(float alpha) {
10468         ensureTransformationInfo();
10469         if (mTransformationInfo.mAlpha != alpha) {
10470             mTransformationInfo.mAlpha = alpha;
10471             boolean subclassHandlesAlpha = onSetAlpha((int) (alpha * 255));
10472             if (subclassHandlesAlpha) {
10473                 mPrivateFlags |= PFLAG_ALPHA_SET;
10474                 return true;
10475             } else {
10476                 mPrivateFlags &= ~PFLAG_ALPHA_SET;
10477                 mRenderNode.setAlpha(getFinalAlpha());
10478             }
10479         }
10480         return false;
10481     }
10482
10483     /**
10484      * This property is hidden and intended only for use by the Fade transition, which
10485      * animates it to produce a visual translucency that does not side-effect (or get
10486      * affected by) the real alpha property. This value is composited with the other
10487      * alpha value (and the AlphaAnimation value, when that is present) to produce
10488      * a final visual translucency result, which is what is passed into the DisplayList.
10489      *
10490      * @hide
10491      */
10492     public void setTransitionAlpha(float alpha) {
10493         ensureTransformationInfo();
10494         if (mTransformationInfo.mTransitionAlpha != alpha) {
10495             mTransformationInfo.mTransitionAlpha = alpha;
10496             mPrivateFlags &= ~PFLAG_ALPHA_SET;
10497             invalidateViewProperty(true, false);
10498             mRenderNode.setAlpha(getFinalAlpha());
10499         }
10500     }
10501
10502     /**
10503      * Calculates the visual alpha of this view, which is a combination of the actual
10504      * alpha value and the transitionAlpha value (if set).
10505      */
10506     private float getFinalAlpha() {
10507         if (mTransformationInfo != null) {
10508             return mTransformationInfo.mAlpha * mTransformationInfo.mTransitionAlpha;
10509         }
10510         return 1;
10511     }
10512
10513     /**
10514      * This property is hidden and intended only for use by the Fade transition, which
10515      * animates it to produce a visual translucency that does not side-effect (or get
10516      * affected by) the real alpha property. This value is composited with the other
10517      * alpha value (and the AlphaAnimation value, when that is present) to produce
10518      * a final visual translucency result, which is what is passed into the DisplayList.
10519      *
10520      * @hide
10521      */
10522     @ViewDebug.ExportedProperty(category = "drawing")
10523     public float getTransitionAlpha() {
10524         return mTransformationInfo != null ? mTransformationInfo.mTransitionAlpha : 1;
10525     }
10526
10527     /**
10528      * Top position of this view relative to its parent.
10529      *
10530      * @return The top of this view, in pixels.
10531      */
10532     @ViewDebug.CapturedViewProperty
10533     public final int getTop() {
10534         return mTop;
10535     }
10536
10537     /**
10538      * Sets the top position of this view relative to its parent. This method is meant to be called
10539      * by the layout system and should not generally be called otherwise, because the property
10540      * may be changed at any time by the layout.
10541      *
10542      * @param top The top of this view, in pixels.
10543      */
10544     public final void setTop(int top) {
10545         if (top != mTop) {
10546             final boolean matrixIsIdentity = hasIdentityMatrix();
10547             if (matrixIsIdentity) {
10548                 if (mAttachInfo != null) {
10549                     int minTop;
10550                     int yLoc;
10551                     if (top < mTop) {
10552                         minTop = top;
10553                         yLoc = top - mTop;
10554                     } else {
10555                         minTop = mTop;
10556                         yLoc = 0;
10557                     }
10558                     invalidate(0, yLoc, mRight - mLeft, mBottom - minTop);
10559                 }
10560             } else {
10561                 // Double-invalidation is necessary to capture view's old and new areas
10562                 invalidate(true);
10563             }
10564
10565             int width = mRight - mLeft;
10566             int oldHeight = mBottom - mTop;
10567
10568             mTop = top;
10569             mRenderNode.setTop(mTop);
10570
10571             sizeChange(width, mBottom - mTop, width, oldHeight);
10572
10573             if (!matrixIsIdentity) {
10574                 mPrivateFlags |= PFLAG_DRAWN; // force another invalidation with the new orientation
10575                 invalidate(true);
10576             }
10577             mBackgroundSizeChanged = true;
10578             invalidateParentIfNeeded();
10579             if ((mPrivateFlags2 & PFLAG2_VIEW_QUICK_REJECTED) == PFLAG2_VIEW_QUICK_REJECTED) {
10580                 // View was rejected last time it was drawn by its parent; this may have changed
10581                 invalidateParentIfNeeded();
10582             }
10583         }
10584     }
10585
10586     /**
10587      * Bottom position of this view relative to its parent.
10588      *
10589      * @return The bottom of this view, in pixels.
10590      */
10591     @ViewDebug.CapturedViewProperty
10592     public final int getBottom() {
10593         return mBottom;
10594     }
10595
10596     /**
10597      * True if this view has changed since the last time being drawn.
10598      *
10599      * @return The dirty state of this view.
10600      */
10601     public boolean isDirty() {
10602         return (mPrivateFlags & PFLAG_DIRTY_MASK) != 0;
10603     }
10604
10605     /**
10606      * Sets the bottom position of this view relative to its parent. This method is meant to be
10607      * called by the layout system and should not generally be called otherwise, because the
10608      * property may be changed at any time by the layout.
10609      *
10610      * @param bottom The bottom of this view, in pixels.
10611      */
10612     public final void setBottom(int bottom) {
10613         if (bottom != mBottom) {
10614             final boolean matrixIsIdentity = hasIdentityMatrix();
10615             if (matrixIsIdentity) {
10616                 if (mAttachInfo != null) {
10617                     int maxBottom;
10618                     if (bottom < mBottom) {
10619                         maxBottom = mBottom;
10620                     } else {
10621                         maxBottom = bottom;
10622                     }
10623                     invalidate(0, 0, mRight - mLeft, maxBottom - mTop);
10624                 }
10625             } else {
10626                 // Double-invalidation is necessary to capture view's old and new areas
10627                 invalidate(true);
10628             }
10629
10630             int width = mRight - mLeft;
10631             int oldHeight = mBottom - mTop;
10632
10633             mBottom = bottom;
10634             mRenderNode.setBottom(mBottom);
10635
10636             sizeChange(width, mBottom - mTop, width, oldHeight);
10637
10638             if (!matrixIsIdentity) {
10639                 mPrivateFlags |= PFLAG_DRAWN; // force another invalidation with the new orientation
10640                 invalidate(true);
10641             }
10642             mBackgroundSizeChanged = true;
10643             invalidateParentIfNeeded();
10644             if ((mPrivateFlags2 & PFLAG2_VIEW_QUICK_REJECTED) == PFLAG2_VIEW_QUICK_REJECTED) {
10645                 // View was rejected last time it was drawn by its parent; this may have changed
10646                 invalidateParentIfNeeded();
10647             }
10648         }
10649     }
10650
10651     /**
10652      * Left position of this view relative to its parent.
10653      *
10654      * @return The left edge of this view, in pixels.
10655      */
10656     @ViewDebug.CapturedViewProperty
10657     public final int getLeft() {
10658         return mLeft;
10659     }
10660
10661     /**
10662      * Sets the left position of this view relative to its parent. This method is meant to be called
10663      * by the layout system and should not generally be called otherwise, because the property
10664      * may be changed at any time by the layout.
10665      *
10666      * @param left The left of this view, in pixels.
10667      */
10668     public final void setLeft(int left) {
10669         if (left != mLeft) {
10670             final boolean matrixIsIdentity = hasIdentityMatrix();
10671             if (matrixIsIdentity) {
10672                 if (mAttachInfo != null) {
10673                     int minLeft;
10674                     int xLoc;
10675                     if (left < mLeft) {
10676                         minLeft = left;
10677                         xLoc = left - mLeft;
10678                     } else {
10679                         minLeft = mLeft;
10680                         xLoc = 0;
10681                     }
10682                     invalidate(xLoc, 0, mRight - minLeft, mBottom - mTop);
10683                 }
10684             } else {
10685                 // Double-invalidation is necessary to capture view's old and new areas
10686                 invalidate(true);
10687             }
10688
10689             int oldWidth = mRight - mLeft;
10690             int height = mBottom - mTop;
10691
10692             mLeft = left;
10693             mRenderNode.setLeft(left);
10694
10695             sizeChange(mRight - mLeft, height, oldWidth, height);
10696
10697             if (!matrixIsIdentity) {
10698                 mPrivateFlags |= PFLAG_DRAWN; // force another invalidation with the new orientation
10699                 invalidate(true);
10700             }
10701             mBackgroundSizeChanged = true;
10702             invalidateParentIfNeeded();
10703             if ((mPrivateFlags2 & PFLAG2_VIEW_QUICK_REJECTED) == PFLAG2_VIEW_QUICK_REJECTED) {
10704                 // View was rejected last time it was drawn by its parent; this may have changed
10705                 invalidateParentIfNeeded();
10706             }
10707         }
10708     }
10709
10710     /**
10711      * Right position of this view relative to its parent.
10712      *
10713      * @return The right edge of this view, in pixels.
10714      */
10715     @ViewDebug.CapturedViewProperty
10716     public final int getRight() {
10717         return mRight;
10718     }
10719
10720     /**
10721      * Sets the right position of this view relative to its parent. This method is meant to be called
10722      * by the layout system and should not generally be called otherwise, because the property
10723      * may be changed at any time by the layout.
10724      *
10725      * @param right The right of this view, in pixels.
10726      */
10727     public final void setRight(int right) {
10728         if (right != mRight) {
10729             final boolean matrixIsIdentity = hasIdentityMatrix();
10730             if (matrixIsIdentity) {
10731                 if (mAttachInfo != null) {
10732                     int maxRight;
10733                     if (right < mRight) {
10734                         maxRight = mRight;
10735                     } else {
10736                         maxRight = right;
10737                     }
10738                     invalidate(0, 0, maxRight - mLeft, mBottom - mTop);
10739                 }
10740             } else {
10741                 // Double-invalidation is necessary to capture view's old and new areas
10742                 invalidate(true);
10743             }
10744
10745             int oldWidth = mRight - mLeft;
10746             int height = mBottom - mTop;
10747
10748             mRight = right;
10749             mRenderNode.setRight(mRight);
10750
10751             sizeChange(mRight - mLeft, height, oldWidth, height);
10752
10753             if (!matrixIsIdentity) {
10754                 mPrivateFlags |= PFLAG_DRAWN; // force another invalidation with the new orientation
10755                 invalidate(true);
10756             }
10757             mBackgroundSizeChanged = true;
10758             invalidateParentIfNeeded();
10759             if ((mPrivateFlags2 & PFLAG2_VIEW_QUICK_REJECTED) == PFLAG2_VIEW_QUICK_REJECTED) {
10760                 // View was rejected last time it was drawn by its parent; this may have changed
10761                 invalidateParentIfNeeded();
10762             }
10763         }
10764     }
10765
10766     /**
10767      * The visual x position of this view, in pixels. This is equivalent to the
10768      * {@link #setTranslationX(float) translationX} property plus the current
10769      * {@link #getLeft() left} property.
10770      *
10771      * @return The visual x position of this view, in pixels.
10772      */
10773     @ViewDebug.ExportedProperty(category = "drawing")
10774     public float getX() {
10775         return mLeft + getTranslationX();
10776     }
10777
10778     /**
10779      * Sets the visual x position of this view, in pixels. This is equivalent to setting the
10780      * {@link #setTranslationX(float) translationX} property to be the difference between
10781      * the x value passed in and the current {@link #getLeft() left} property.
10782      *
10783      * @param x The visual x position of this view, in pixels.
10784      */
10785     public void setX(float x) {
10786         setTranslationX(x - mLeft);
10787     }
10788
10789     /**
10790      * The visual y position of this view, in pixels. This is equivalent to the
10791      * {@link #setTranslationY(float) translationY} property plus the current
10792      * {@link #getTop() top} property.
10793      *
10794      * @return The visual y position of this view, in pixels.
10795      */
10796     @ViewDebug.ExportedProperty(category = "drawing")
10797     public float getY() {
10798         return mTop + getTranslationY();
10799     }
10800
10801     /**
10802      * Sets the visual y position of this view, in pixels. This is equivalent to setting the
10803      * {@link #setTranslationY(float) translationY} property to be the difference between
10804      * the y value passed in and the current {@link #getTop() top} property.
10805      *
10806      * @param y The visual y position of this view, in pixels.
10807      */
10808     public void setY(float y) {
10809         setTranslationY(y - mTop);
10810     }
10811
10812     /**
10813      * The visual z position of this view, in pixels. This is equivalent to the
10814      * {@link #setTranslationZ(float) translationZ} property plus the current
10815      * {@link #getElevation() elevation} property.
10816      *
10817      * @return The visual z position of this view, in pixels.
10818      */
10819     @ViewDebug.ExportedProperty(category = "drawing")
10820     public float getZ() {
10821         return getElevation() + getTranslationZ();
10822     }
10823
10824     /**
10825      * Sets the visual z position of this view, in pixels. This is equivalent to setting the
10826      * {@link #setTranslationZ(float) translationZ} property to be the difference between
10827      * the x value passed in and the current {@link #getElevation() elevation} property.
10828      *
10829      * @param z The visual z position of this view, in pixels.
10830      */
10831     public void setZ(float z) {
10832         setTranslationZ(z - getElevation());
10833     }
10834
10835     /**
10836      * The base elevation of this view relative to its parent, in pixels.
10837      *
10838      * @return The base depth position of the view, in pixels.
10839      */
10840     @ViewDebug.ExportedProperty(category = "drawing")
10841     public float getElevation() {
10842         return mRenderNode.getElevation();
10843     }
10844
10845     /**
10846      * Sets the base elevation of this view, in pixels.
10847      *
10848      * @attr ref android.R.styleable#View_elevation
10849      */
10850     public void setElevation(float elevation) {
10851         if (elevation != getElevation()) {
10852             invalidateViewProperty(true, false);
10853             mRenderNode.setElevation(elevation);
10854             invalidateViewProperty(false, true);
10855
10856             invalidateParentIfNeededAndWasQuickRejected();
10857         }
10858     }
10859
10860     /**
10861      * The horizontal location of this view relative to its {@link #getLeft() left} position.
10862      * This position is post-layout, in addition to wherever the object's
10863      * layout placed it.
10864      *
10865      * @return The horizontal position of this view relative to its left position, in pixels.
10866      */
10867     @ViewDebug.ExportedProperty(category = "drawing")
10868     public float getTranslationX() {
10869         return mRenderNode.getTranslationX();
10870     }
10871
10872     /**
10873      * Sets the horizontal location of this view relative to its {@link #getLeft() left} position.
10874      * This effectively positions the object post-layout, in addition to wherever the object's
10875      * layout placed it.
10876      *
10877      * @param translationX The horizontal position of this view relative to its left position,
10878      * in pixels.
10879      *
10880      * @attr ref android.R.styleable#View_translationX
10881      */
10882     public void setTranslationX(float translationX) {
10883         if (translationX != getTranslationX()) {
10884             invalidateViewProperty(true, false);
10885             mRenderNode.setTranslationX(translationX);
10886             invalidateViewProperty(false, true);
10887
10888             invalidateParentIfNeededAndWasQuickRejected();
10889             notifySubtreeAccessibilityStateChangedIfNeeded();
10890         }
10891     }
10892
10893     /**
10894      * The vertical location of this view relative to its {@link #getTop() top} position.
10895      * This position is post-layout, in addition to wherever the object's
10896      * layout placed it.
10897      *
10898      * @return The vertical position of this view relative to its top position,
10899      * in pixels.
10900      */
10901     @ViewDebug.ExportedProperty(category = "drawing")
10902     public float getTranslationY() {
10903         return mRenderNode.getTranslationY();
10904     }
10905
10906     /**
10907      * Sets the vertical location of this view relative to its {@link #getTop() top} position.
10908      * This effectively positions the object post-layout, in addition to wherever the object's
10909      * layout placed it.
10910      *
10911      * @param translationY The vertical position of this view relative to its top position,
10912      * in pixels.
10913      *
10914      * @attr ref android.R.styleable#View_translationY
10915      */
10916     public void setTranslationY(float translationY) {
10917         if (translationY != getTranslationY()) {
10918             invalidateViewProperty(true, false);
10919             mRenderNode.setTranslationY(translationY);
10920             invalidateViewProperty(false, true);
10921
10922             invalidateParentIfNeededAndWasQuickRejected();
10923         }
10924     }
10925
10926     /**
10927      * The depth location of this view relative to its {@link #getElevation() elevation}.
10928      *
10929      * @return The depth of this view relative to its elevation.
10930      */
10931     @ViewDebug.ExportedProperty(category = "drawing")
10932     public float getTranslationZ() {
10933         return mRenderNode.getTranslationZ();
10934     }
10935
10936     /**
10937      * Sets the depth location of this view relative to its {@link #getElevation() elevation}.
10938      *
10939      * @attr ref android.R.styleable#View_translationZ
10940      */
10941     public void setTranslationZ(float translationZ) {
10942         if (translationZ != getTranslationZ()) {
10943             invalidateViewProperty(true, false);
10944             mRenderNode.setTranslationZ(translationZ);
10945             invalidateViewProperty(false, true);
10946
10947             invalidateParentIfNeededAndWasQuickRejected();
10948         }
10949     }
10950
10951     /** @hide */
10952     public void setAnimationMatrix(Matrix matrix) {
10953         invalidateViewProperty(true, false);
10954         mRenderNode.setAnimationMatrix(matrix);
10955         invalidateViewProperty(false, true);
10956
10957         invalidateParentIfNeededAndWasQuickRejected();
10958     }
10959
10960     /**
10961      * Returns the current StateListAnimator if exists.
10962      *
10963      * @return StateListAnimator or null if it does not exists
10964      * @see    #setStateListAnimator(android.animation.StateListAnimator)
10965      */
10966     public StateListAnimator getStateListAnimator() {
10967         return mStateListAnimator;
10968     }
10969
10970     /**
10971      * Attaches the provided StateListAnimator to this View.
10972      * <p>
10973      * Any previously attached StateListAnimator will be detached.
10974      *
10975      * @param stateListAnimator The StateListAnimator to update the view
10976      * @see {@link android.animation.StateListAnimator}
10977      */
10978     public void setStateListAnimator(StateListAnimator stateListAnimator) {
10979         if (mStateListAnimator == stateListAnimator) {
10980             return;
10981         }
10982         if (mStateListAnimator != null) {
10983             mStateListAnimator.setTarget(null);
10984         }
10985         mStateListAnimator = stateListAnimator;
10986         if (stateListAnimator != null) {
10987             stateListAnimator.setTarget(this);
10988             if (isAttachedToWindow()) {
10989                 stateListAnimator.setState(getDrawableState());
10990             }
10991         }
10992     }
10993
10994     /**
10995      * Returns whether the Outline should be used to clip the contents of the View.
10996      * <p>
10997      * Note that this flag will only be respected if the View's Outline returns true from
10998      * {@link Outline#canClip()}.
10999      *
11000      * @see #setOutlineProvider(ViewOutlineProvider)
11001      * @see #setClipToOutline(boolean)
11002      */
11003     public final boolean getClipToOutline() {
11004         return mRenderNode.getClipToOutline();
11005     }
11006
11007     /**
11008      * Sets whether the View's Outline should be used to clip the contents of the View.
11009      * <p>
11010      * Only a single non-rectangular clip can be applied on a View at any time.
11011      * Circular clips from a {@link ViewAnimationUtils#createCircularReveal(View, int, int, float, float)
11012      * circular reveal} animation take priority over Outline clipping, and
11013      * child Outline clipping takes priority over Outline clipping done by a
11014      * parent.
11015      * <p>
11016      * Note that this flag will only be respected if the View's Outline returns true from
11017      * {@link Outline#canClip()}.
11018      *
11019      * @see #setOutlineProvider(ViewOutlineProvider)
11020      * @see #getClipToOutline()
11021      */
11022     public void setClipToOutline(boolean clipToOutline) {
11023         damageInParent();
11024         if (getClipToOutline() != clipToOutline) {
11025             mRenderNode.setClipToOutline(clipToOutline);
11026         }
11027     }
11028
11029     // correspond to the enum values of View_outlineProvider
11030     private static final int PROVIDER_BACKGROUND = 0;
11031     private static final int PROVIDER_NONE = 1;
11032     private static final int PROVIDER_BOUNDS = 2;
11033     private static final int PROVIDER_PADDED_BOUNDS = 3;
11034     private void setOutlineProviderFromAttribute(int providerInt) {
11035         switch (providerInt) {
11036             case PROVIDER_BACKGROUND:
11037                 setOutlineProvider(ViewOutlineProvider.BACKGROUND);
11038                 break;
11039             case PROVIDER_NONE:
11040                 setOutlineProvider(null);
11041                 break;
11042             case PROVIDER_BOUNDS:
11043                 setOutlineProvider(ViewOutlineProvider.BOUNDS);
11044                 break;
11045             case PROVIDER_PADDED_BOUNDS:
11046                 setOutlineProvider(ViewOutlineProvider.PADDED_BOUNDS);
11047                 break;
11048         }
11049     }
11050
11051     /**
11052      * Sets the {@link ViewOutlineProvider} of the view, which generates the Outline that defines
11053      * the shape of the shadow it casts, and enables outline clipping.
11054      * <p>
11055      * The default ViewOutlineProvider, {@link ViewOutlineProvider#BACKGROUND}, queries the Outline
11056      * from the View's background drawable, via {@link Drawable#getOutline(Outline)}. Changing the
11057      * outline provider with this method allows this behavior to be overridden.
11058      * <p>
11059      * If the ViewOutlineProvider is null, if querying it for an outline returns false,
11060      * or if the produced Outline is {@link Outline#isEmpty()}, shadows will not be cast.
11061      * <p>
11062      * Only outlines that return true from {@link Outline#canClip()} may be used for clipping.
11063      *
11064      * @see #setClipToOutline(boolean)
11065      * @see #getClipToOutline()
11066      * @see #getOutlineProvider()
11067      */
11068     public void setOutlineProvider(ViewOutlineProvider provider) {
11069         mOutlineProvider = provider;
11070         invalidateOutline();
11071     }
11072
11073     /**
11074      * Returns the current {@link ViewOutlineProvider} of the view, which generates the Outline
11075      * that defines the shape of the shadow it casts, and enables outline clipping.
11076      *
11077      * @see #setOutlineProvider(ViewOutlineProvider)
11078      */
11079     public ViewOutlineProvider getOutlineProvider() {
11080         return mOutlineProvider;
11081     }
11082
11083     /**
11084      * Called to rebuild this View's Outline from its {@link ViewOutlineProvider outline provider}
11085      *
11086      * @see #setOutlineProvider(ViewOutlineProvider)
11087      */
11088     public void invalidateOutline() {
11089         mPrivateFlags3 |= PFLAG3_OUTLINE_INVALID;
11090
11091         notifySubtreeAccessibilityStateChangedIfNeeded();
11092         invalidateViewProperty(false, false);
11093     }
11094
11095     /**
11096      * Internal version of {@link #invalidateOutline()} which invalidates the
11097      * outline without invalidating the view itself. This is intended to be called from
11098      * within methods in the View class itself which are the result of the view being
11099      * invalidated already. For example, when we are drawing the background of a View,
11100      * we invalidate the outline in case it changed in the meantime, but we do not
11101      * need to invalidate the view because we're already drawing the background as part
11102      * of drawing the view in response to an earlier invalidation of the view.
11103      */
11104     private void rebuildOutline() {
11105         // Unattached views ignore this signal, and outline is recomputed in onAttachedToWindow()
11106         if (mAttachInfo == null) return;
11107
11108         if (mOutlineProvider == null) {
11109             // no provider, remove outline
11110             mRenderNode.setOutline(null);
11111         } else {
11112             final Outline outline = mAttachInfo.mTmpOutline;
11113             outline.setEmpty();
11114             outline.setAlpha(1.0f);
11115
11116             mOutlineProvider.getOutline(this, outline);
11117             mRenderNode.setOutline(outline);
11118         }
11119     }
11120
11121     /**
11122      * HierarchyViewer only
11123      *
11124      * @hide
11125      */
11126     @ViewDebug.ExportedProperty(category = "drawing")
11127     public boolean hasShadow() {
11128         return mRenderNode.hasShadow();
11129     }
11130
11131
11132     /** @hide */
11133     public void setRevealClip(boolean shouldClip, float x, float y, float radius) {
11134         mRenderNode.setRevealClip(shouldClip, x, y, radius);
11135         invalidateViewProperty(false, false);
11136     }
11137
11138     /**
11139      * Hit rectangle in parent's coordinates
11140      *
11141      * @param outRect The hit rectangle of the view.
11142      */
11143     public void getHitRect(Rect outRect) {
11144         if (hasIdentityMatrix() || mAttachInfo == null) {
11145             outRect.set(mLeft, mTop, mRight, mBottom);
11146         } else {
11147             final RectF tmpRect = mAttachInfo.mTmpTransformRect;
11148             tmpRect.set(0, 0, getWidth(), getHeight());
11149             getMatrix().mapRect(tmpRect); // TODO: mRenderNode.mapRect(tmpRect)
11150             outRect.set((int) tmpRect.left + mLeft, (int) tmpRect.top + mTop,
11151                     (int) tmpRect.right + mLeft, (int) tmpRect.bottom + mTop);
11152         }
11153     }
11154
11155     /**
11156      * Determines whether the given point, in local coordinates is inside the view.
11157      */
11158     /*package*/ final boolean pointInView(float localX, float localY) {
11159         return localX >= 0 && localX < (mRight - mLeft)
11160                 && localY >= 0 && localY < (mBottom - mTop);
11161     }
11162
11163     /**
11164      * Utility method to determine whether the given point, in local coordinates,
11165      * is inside the view, where the area of the view is expanded by the slop factor.
11166      * This method is called while processing touch-move events to determine if the event
11167      * is still within the view.
11168      *
11169      * @hide
11170      */
11171     public boolean pointInView(float localX, float localY, float slop) {
11172         return localX >= -slop && localY >= -slop && localX < ((mRight - mLeft) + slop) &&
11173                 localY < ((mBottom - mTop) + slop);
11174     }
11175
11176     /**
11177      * When a view has focus and the user navigates away from it, the next view is searched for
11178      * starting from the rectangle filled in by this method.
11179      *
11180      * By default, the rectangle is the {@link #getDrawingRect(android.graphics.Rect)})
11181      * of the view.  However, if your view maintains some idea of internal selection,
11182      * such as a cursor, or a selected row or column, you should override this method and
11183      * fill in a more specific rectangle.
11184      *
11185      * @param r The rectangle to fill in, in this view's coordinates.
11186      */
11187     public void getFocusedRect(Rect r) {
11188         getDrawingRect(r);
11189     }
11190
11191     /**
11192      * If some part of this view is not clipped by any of its parents, then
11193      * return that area in r in global (root) coordinates. To convert r to local
11194      * coordinates (without taking possible View rotations into account), offset
11195      * it by -globalOffset (e.g. r.offset(-globalOffset.x, -globalOffset.y)).
11196      * If the view is completely clipped or translated out, return false.
11197      *
11198      * @param r If true is returned, r holds the global coordinates of the
11199      *        visible portion of this view.
11200      * @param globalOffset If true is returned, globalOffset holds the dx,dy
11201      *        between this view and its root. globalOffet may be null.
11202      * @return true if r is non-empty (i.e. part of the view is visible at the
11203      *         root level.
11204      */
11205     public boolean getGlobalVisibleRect(Rect r, Point globalOffset) {
11206         int width = mRight - mLeft;
11207         int height = mBottom - mTop;
11208         if (width > 0 && height > 0) {
11209             r.set(0, 0, width, height);
11210             if (globalOffset != null) {
11211                 globalOffset.set(-mScrollX, -mScrollY);
11212             }
11213             return mParent == null || mParent.getChildVisibleRect(this, r, globalOffset);
11214         }
11215         return false;
11216     }
11217
11218     public final boolean getGlobalVisibleRect(Rect r) {
11219         return getGlobalVisibleRect(r, null);
11220     }
11221
11222     public final boolean getLocalVisibleRect(Rect r) {
11223         final Point offset = mAttachInfo != null ? mAttachInfo.mPoint : new Point();
11224         if (getGlobalVisibleRect(r, offset)) {
11225             r.offset(-offset.x, -offset.y); // make r local
11226             return true;
11227         }
11228         return false;
11229     }
11230
11231     /**
11232      * Offset this view's vertical location by the specified number of pixels.
11233      *
11234      * @param offset the number of pixels to offset the view by
11235      */
11236     public void offsetTopAndBottom(int offset) {
11237         if (offset != 0) {
11238             final boolean matrixIsIdentity = hasIdentityMatrix();
11239             if (matrixIsIdentity) {
11240                 if (isHardwareAccelerated()) {
11241                     invalidateViewProperty(false, false);
11242                 } else {
11243                     final ViewParent p = mParent;
11244                     if (p != null && mAttachInfo != null) {
11245                         final Rect r = mAttachInfo.mTmpInvalRect;
11246                         int minTop;
11247                         int maxBottom;
11248                         int yLoc;
11249                         if (offset < 0) {
11250                             minTop = mTop + offset;
11251                             maxBottom = mBottom;
11252                             yLoc = offset;
11253                         } else {
11254                             minTop = mTop;
11255                             maxBottom = mBottom + offset;
11256                             yLoc = 0;
11257                         }
11258                         r.set(0, yLoc, mRight - mLeft, maxBottom - minTop);
11259                         p.invalidateChild(this, r);
11260                     }
11261                 }
11262             } else {
11263                 invalidateViewProperty(false, false);
11264             }
11265
11266             mTop += offset;
11267             mBottom += offset;
11268             mRenderNode.offsetTopAndBottom(offset);
11269             if (isHardwareAccelerated()) {
11270                 invalidateViewProperty(false, false);
11271             } else {
11272                 if (!matrixIsIdentity) {
11273                     invalidateViewProperty(false, true);
11274                 }
11275                 invalidateParentIfNeeded();
11276             }
11277             notifySubtreeAccessibilityStateChangedIfNeeded();
11278         }
11279     }
11280
11281     /**
11282      * Offset this view's horizontal location by the specified amount of pixels.
11283      *
11284      * @param offset the number of pixels to offset the view by
11285      */
11286     public void offsetLeftAndRight(int offset) {
11287         if (offset != 0) {
11288             final boolean matrixIsIdentity = hasIdentityMatrix();
11289             if (matrixIsIdentity) {
11290                 if (isHardwareAccelerated()) {
11291                     invalidateViewProperty(false, false);
11292                 } else {
11293                     final ViewParent p = mParent;
11294                     if (p != null && mAttachInfo != null) {
11295                         final Rect r = mAttachInfo.mTmpInvalRect;
11296                         int minLeft;
11297                         int maxRight;
11298                         if (offset < 0) {
11299                             minLeft = mLeft + offset;
11300                             maxRight = mRight;
11301                         } else {
11302                             minLeft = mLeft;
11303                             maxRight = mRight + offset;
11304                         }
11305                         r.set(0, 0, maxRight - minLeft, mBottom - mTop);
11306                         p.invalidateChild(this, r);
11307                     }
11308                 }
11309             } else {
11310                 invalidateViewProperty(false, false);
11311             }
11312
11313             mLeft += offset;
11314             mRight += offset;
11315             mRenderNode.offsetLeftAndRight(offset);
11316             if (isHardwareAccelerated()) {
11317                 invalidateViewProperty(false, false);
11318             } else {
11319                 if (!matrixIsIdentity) {
11320                     invalidateViewProperty(false, true);
11321                 }
11322                 invalidateParentIfNeeded();
11323             }
11324             notifySubtreeAccessibilityStateChangedIfNeeded();
11325         }
11326     }
11327
11328     /**
11329      * Get the LayoutParams associated with this view. All views should have
11330      * layout parameters. These supply parameters to the <i>parent</i> of this
11331      * view specifying how it should be arranged. There are many subclasses of
11332      * ViewGroup.LayoutParams, and these correspond to the different subclasses
11333      * of ViewGroup that are responsible for arranging their children.
11334      *
11335      * This method may return null if this View is not attached to a parent
11336      * ViewGroup or {@link #setLayoutParams(android.view.ViewGroup.LayoutParams)}
11337      * was not invoked successfully. When a View is attached to a parent
11338      * ViewGroup, this method must not return null.
11339      *
11340      * @return The LayoutParams associated with this view, or null if no
11341      *         parameters have been set yet
11342      */
11343     @ViewDebug.ExportedProperty(deepExport = true, prefix = "layout_")
11344     public ViewGroup.LayoutParams getLayoutParams() {
11345         return mLayoutParams;
11346     }
11347
11348     /**
11349      * Set the layout parameters associated with this view. These supply
11350      * parameters to the <i>parent</i> of this view specifying how it should be
11351      * arranged. There are many subclasses of ViewGroup.LayoutParams, and these
11352      * correspond to the different subclasses of ViewGroup that are responsible
11353      * for arranging their children.
11354      *
11355      * @param params The layout parameters for this view, cannot be null
11356      */
11357     public void setLayoutParams(ViewGroup.LayoutParams params) {
11358         if (params == null) {
11359             throw new NullPointerException("Layout parameters cannot be null");
11360         }
11361         mLayoutParams = params;
11362         resolveLayoutParams();
11363         if (mParent instanceof ViewGroup) {
11364             ((ViewGroup) mParent).onSetLayoutParams(this, params);
11365         }
11366         requestLayout();
11367     }
11368
11369     /**
11370      * Resolve the layout parameters depending on the resolved layout direction
11371      *
11372      * @hide
11373      */
11374     public void resolveLayoutParams() {
11375         if (mLayoutParams != null) {
11376             mLayoutParams.resolveLayoutDirection(getLayoutDirection());
11377         }
11378     }
11379
11380     /**
11381      * Set the scrolled position of your view. This will cause a call to
11382      * {@link #onScrollChanged(int, int, int, int)} and the view will be
11383      * invalidated.
11384      * @param x the x position to scroll to
11385      * @param y the y position to scroll to
11386      */
11387     public void scrollTo(int x, int y) {
11388         if (mScrollX != x || mScrollY != y) {
11389             int oldX = mScrollX;
11390             int oldY = mScrollY;
11391             mScrollX = x;
11392             mScrollY = y;
11393             invalidateParentCaches();
11394             onScrollChanged(mScrollX, mScrollY, oldX, oldY);
11395             if (!awakenScrollBars()) {
11396                 postInvalidateOnAnimation();
11397             }
11398         }
11399     }
11400
11401     /**
11402      * Move the scrolled position of your view. This will cause a call to
11403      * {@link #onScrollChanged(int, int, int, int)} and the view will be
11404      * invalidated.
11405      * @param x the amount of pixels to scroll by horizontally
11406      * @param y the amount of pixels to scroll by vertically
11407      */
11408     public void scrollBy(int x, int y) {
11409         scrollTo(mScrollX + x, mScrollY + y);
11410     }
11411
11412     /**
11413      * <p>Trigger the scrollbars to draw. When invoked this method starts an
11414      * animation to fade the scrollbars out after a default delay. If a subclass
11415      * provides animated scrolling, the start delay should equal the duration
11416      * of the scrolling animation.</p>
11417      *
11418      * <p>The animation starts only if at least one of the scrollbars is
11419      * enabled, as specified by {@link #isHorizontalScrollBarEnabled()} and
11420      * {@link #isVerticalScrollBarEnabled()}. When the animation is started,
11421      * this method returns true, and false otherwise. If the animation is
11422      * started, this method calls {@link #invalidate()}; in that case the
11423      * caller should not call {@link #invalidate()}.</p>
11424      *
11425      * <p>This method should be invoked every time a subclass directly updates
11426      * the scroll parameters.</p>
11427      *
11428      * <p>This method is automatically invoked by {@link #scrollBy(int, int)}
11429      * and {@link #scrollTo(int, int)}.</p>
11430      *
11431      * @return true if the animation is played, false otherwise
11432      *
11433      * @see #awakenScrollBars(int)
11434      * @see #scrollBy(int, int)
11435      * @see #scrollTo(int, int)
11436      * @see #isHorizontalScrollBarEnabled()
11437      * @see #isVerticalScrollBarEnabled()
11438      * @see #setHorizontalScrollBarEnabled(boolean)
11439      * @see #setVerticalScrollBarEnabled(boolean)
11440      */
11441     protected boolean awakenScrollBars() {
11442         return mScrollCache != null &&
11443                 awakenScrollBars(mScrollCache.scrollBarDefaultDelayBeforeFade, true);
11444     }
11445
11446     /**
11447      * Trigger the scrollbars to draw.
11448      * This method differs from awakenScrollBars() only in its default duration.
11449      * initialAwakenScrollBars() will show the scroll bars for longer than
11450      * usual to give the user more of a chance to notice them.
11451      *
11452      * @return true if the animation is played, false otherwise.
11453      */
11454     private boolean initialAwakenScrollBars() {
11455         return mScrollCache != null &&
11456                 awakenScrollBars(mScrollCache.scrollBarDefaultDelayBeforeFade * 4, true);
11457     }
11458
11459     /**
11460      * <p>
11461      * Trigger the scrollbars to draw. When invoked this method starts an
11462      * animation to fade the scrollbars out after a fixed delay. If a subclass
11463      * provides animated scrolling, the start delay should equal the duration of
11464      * the scrolling animation.
11465      * </p>
11466      *
11467      * <p>
11468      * The animation starts only if at least one of the scrollbars is enabled,
11469      * as specified by {@link #isHorizontalScrollBarEnabled()} and
11470      * {@link #isVerticalScrollBarEnabled()}. When the animation is started,
11471      * this method returns true, and false otherwise. If the animation is
11472      * started, this method calls {@link #invalidate()}; in that case the caller
11473      * should not call {@link #invalidate()}.
11474      * </p>
11475      *
11476      * <p>
11477      * This method should be invoked everytime a subclass directly updates the
11478      * scroll parameters.
11479      * </p>
11480      *
11481      * @param startDelay the delay, in milliseconds, after which the animation
11482      *        should start; when the delay is 0, the animation starts
11483      *        immediately
11484      * @return true if the animation is played, false otherwise
11485      *
11486      * @see #scrollBy(int, int)
11487      * @see #scrollTo(int, int)
11488      * @see #isHorizontalScrollBarEnabled()
11489      * @see #isVerticalScrollBarEnabled()
11490      * @see #setHorizontalScrollBarEnabled(boolean)
11491      * @see #setVerticalScrollBarEnabled(boolean)
11492      */
11493     protected boolean awakenScrollBars(int startDelay) {
11494         return awakenScrollBars(startDelay, true);
11495     }
11496
11497     /**
11498      * <p>
11499      * Trigger the scrollbars to draw. When invoked this method starts an
11500      * animation to fade the scrollbars out after a fixed delay. If a subclass
11501      * provides animated scrolling, the start delay should equal the duration of
11502      * the scrolling animation.
11503      * </p>
11504      *
11505      * <p>
11506      * The animation starts only if at least one of the scrollbars is enabled,
11507      * as specified by {@link #isHorizontalScrollBarEnabled()} and
11508      * {@link #isVerticalScrollBarEnabled()}. When the animation is started,
11509      * this method returns true, and false otherwise. If the animation is
11510      * started, this method calls {@link #invalidate()} if the invalidate parameter
11511      * is set to true; in that case the caller
11512      * should not call {@link #invalidate()}.
11513      * </p>
11514      *
11515      * <p>
11516      * This method should be invoked everytime a subclass directly updates the
11517      * scroll parameters.
11518      * </p>
11519      *
11520      * @param startDelay the delay, in milliseconds, after which the animation
11521      *        should start; when the delay is 0, the animation starts
11522      *        immediately
11523      *
11524      * @param invalidate Wheter this method should call invalidate
11525      *
11526      * @return true if the animation is played, false otherwise
11527      *
11528      * @see #scrollBy(int, int)
11529      * @see #scrollTo(int, int)
11530      * @see #isHorizontalScrollBarEnabled()
11531      * @see #isVerticalScrollBarEnabled()
11532      * @see #setHorizontalScrollBarEnabled(boolean)
11533      * @see #setVerticalScrollBarEnabled(boolean)
11534      */
11535     protected boolean awakenScrollBars(int startDelay, boolean invalidate) {
11536         final ScrollabilityCache scrollCache = mScrollCache;
11537
11538         if (scrollCache == null || !scrollCache.fadeScrollBars) {
11539             return false;
11540         }
11541
11542         if (scrollCache.scrollBar == null) {
11543             scrollCache.scrollBar = new ScrollBarDrawable();
11544         }
11545
11546         if (isHorizontalScrollBarEnabled() || isVerticalScrollBarEnabled()) {
11547
11548             if (invalidate) {
11549                 // Invalidate to show the scrollbars
11550                 postInvalidateOnAnimation();
11551             }
11552
11553             if (scrollCache.state == ScrollabilityCache.OFF) {
11554                 // FIXME: this is copied from WindowManagerService.
11555                 // We should get this value from the system when it
11556                 // is possible to do so.
11557                 final int KEY_REPEAT_FIRST_DELAY = 750;
11558                 startDelay = Math.max(KEY_REPEAT_FIRST_DELAY, startDelay);
11559             }
11560
11561             // Tell mScrollCache when we should start fading. This may
11562             // extend the fade start time if one was already scheduled
11563             long fadeStartTime = AnimationUtils.currentAnimationTimeMillis() + startDelay;
11564             scrollCache.fadeStartTime = fadeStartTime;
11565             scrollCache.state = ScrollabilityCache.ON;
11566
11567             // Schedule our fader to run, unscheduling any old ones first
11568             if (mAttachInfo != null) {
11569                 mAttachInfo.mHandler.removeCallbacks(scrollCache);
11570                 mAttachInfo.mHandler.postAtTime(scrollCache, fadeStartTime);
11571             }
11572
11573             return true;
11574         }
11575
11576         return false;
11577     }
11578
11579     /**
11580      * Do not invalidate views which are not visible and which are not running an animation. They
11581      * will not get drawn and they should not set dirty flags as if they will be drawn
11582      */
11583     private boolean skipInvalidate() {
11584         return (mViewFlags & VISIBILITY_MASK) != VISIBLE && mCurrentAnimation == null &&
11585                 (!(mParent instanceof ViewGroup) ||
11586                         !((ViewGroup) mParent).isViewTransitioning(this));
11587     }
11588
11589     /**
11590      * Mark the area defined by dirty as needing to be drawn. If the view is
11591      * visible, {@link #onDraw(android.graphics.Canvas)} will be called at some
11592      * point in the future.
11593      * <p>
11594      * This must be called from a UI thread. To call from a non-UI thread, call
11595      * {@link #postInvalidate()}.
11596      * <p>
11597      * <b>WARNING:</b> In API 19 and below, this method may be destructive to
11598      * {@code dirty}.
11599      *
11600      * @param dirty the rectangle representing the bounds of the dirty region
11601      */
11602     public void invalidate(Rect dirty) {
11603         final int scrollX = mScrollX;
11604         final int scrollY = mScrollY;
11605         invalidateInternal(dirty.left - scrollX, dirty.top - scrollY,
11606                 dirty.right - scrollX, dirty.bottom - scrollY, true, false);
11607     }
11608
11609     /**
11610      * Mark the area defined by the rect (l,t,r,b) as needing to be drawn. The
11611      * coordinates of the dirty rect are relative to the view. If the view is
11612      * visible, {@link #onDraw(android.graphics.Canvas)} will be called at some
11613      * point in the future.
11614      * <p>
11615      * This must be called from a UI thread. To call from a non-UI thread, call
11616      * {@link #postInvalidate()}.
11617      *
11618      * @param l the left position of the dirty region
11619      * @param t the top position of the dirty region
11620      * @param r the right position of the dirty region
11621      * @param b the bottom position of the dirty region
11622      */
11623     public void invalidate(int l, int t, int r, int b) {
11624         final int scrollX = mScrollX;
11625         final int scrollY = mScrollY;
11626         invalidateInternal(l - scrollX, t - scrollY, r - scrollX, b - scrollY, true, false);
11627     }
11628
11629     /**
11630      * Invalidate the whole view. If the view is visible,
11631      * {@link #onDraw(android.graphics.Canvas)} will be called at some point in
11632      * the future.
11633      * <p>
11634      * This must be called from a UI thread. To call from a non-UI thread, call
11635      * {@link #postInvalidate()}.
11636      */
11637     public void invalidate() {
11638         invalidate(true);
11639     }
11640
11641     /**
11642      * This is where the invalidate() work actually happens. A full invalidate()
11643      * causes the drawing cache to be invalidated, but this function can be
11644      * called with invalidateCache set to false to skip that invalidation step
11645      * for cases that do not need it (for example, a component that remains at
11646      * the same dimensions with the same content).
11647      *
11648      * @param invalidateCache Whether the drawing cache for this view should be
11649      *            invalidated as well. This is usually true for a full
11650      *            invalidate, but may be set to false if the View's contents or
11651      *            dimensions have not changed.
11652      */
11653     void invalidate(boolean invalidateCache) {
11654         invalidateInternal(0, 0, mRight - mLeft, mBottom - mTop, invalidateCache, true);
11655     }
11656
11657     void invalidateInternal(int l, int t, int r, int b, boolean invalidateCache,
11658             boolean fullInvalidate) {
11659         if (mGhostView != null) {
11660             mGhostView.invalidate(invalidateCache);
11661             return;
11662         }
11663
11664         if (skipInvalidate()) {
11665             return;
11666         }
11667
11668         if ((mPrivateFlags & (PFLAG_DRAWN | PFLAG_HAS_BOUNDS)) == (PFLAG_DRAWN | PFLAG_HAS_BOUNDS)
11669                 || (invalidateCache && (mPrivateFlags & PFLAG_DRAWING_CACHE_VALID) == PFLAG_DRAWING_CACHE_VALID)
11670                 || (mPrivateFlags & PFLAG_INVALIDATED) != PFLAG_INVALIDATED
11671                 || (fullInvalidate && isOpaque() != mLastIsOpaque)) {
11672             if (fullInvalidate) {
11673                 mLastIsOpaque = isOpaque();
11674                 mPrivateFlags &= ~PFLAG_DRAWN;
11675             }
11676
11677             mPrivateFlags |= PFLAG_DIRTY;
11678
11679             if (invalidateCache) {
11680                 mPrivateFlags |= PFLAG_INVALIDATED;
11681                 mPrivateFlags &= ~PFLAG_DRAWING_CACHE_VALID;
11682             }
11683
11684             // Propagate the damage rectangle to the parent view.
11685             final AttachInfo ai = mAttachInfo;
11686             final ViewParent p = mParent;
11687             if (p != null && ai != null && l < r && t < b) {
11688                 final Rect damage = ai.mTmpInvalRect;
11689                 damage.set(l, t, r, b);
11690                 p.invalidateChild(this, damage);
11691             }
11692
11693             // Damage the entire projection receiver, if necessary.
11694             if (mBackground != null && mBackground.isProjected()) {
11695                 final View receiver = getProjectionReceiver();
11696                 if (receiver != null) {
11697                     receiver.damageInParent();
11698                 }
11699             }
11700
11701             // Damage the entire IsolatedZVolume receiving this view's shadow.
11702             if (isHardwareAccelerated() && getZ() != 0) {
11703                 damageShadowReceiver();
11704             }
11705         }
11706     }
11707
11708     /**
11709      * @return this view's projection receiver, or {@code null} if none exists
11710      */
11711     private View getProjectionReceiver() {
11712         ViewParent p = getParent();
11713         while (p != null && p instanceof View) {
11714             final View v = (View) p;
11715             if (v.isProjectionReceiver()) {
11716                 return v;
11717             }
11718             p = p.getParent();
11719         }
11720
11721         return null;
11722     }
11723
11724     /**
11725      * @return whether the view is a projection receiver
11726      */
11727     private boolean isProjectionReceiver() {
11728         return mBackground != null;
11729     }
11730
11731     /**
11732      * Damage area of the screen that can be covered by this View's shadow.
11733      *
11734      * This method will guarantee that any changes to shadows cast by a View
11735      * are damaged on the screen for future redraw.
11736      */
11737     private void damageShadowReceiver() {
11738         final AttachInfo ai = mAttachInfo;
11739         if (ai != null) {
11740             ViewParent p = getParent();
11741             if (p != null && p instanceof ViewGroup) {
11742                 final ViewGroup vg = (ViewGroup) p;
11743                 vg.damageInParent();
11744             }
11745         }
11746     }
11747
11748     /**
11749      * Quick invalidation for View property changes (alpha, translationXY, etc.). We don't want to
11750      * set any flags or handle all of the cases handled by the default invalidation methods.
11751      * Instead, we just want to schedule a traversal in ViewRootImpl with the appropriate
11752      * dirty rect. This method calls into fast invalidation methods in ViewGroup that
11753      * walk up the hierarchy, transforming the dirty rect as necessary.
11754      *
11755      * The method also handles normal invalidation logic if display list properties are not
11756      * being used in this view. The invalidateParent and forceRedraw flags are used by that
11757      * backup approach, to handle these cases used in the various property-setting methods.
11758      *
11759      * @param invalidateParent Force a call to invalidateParentCaches() if display list properties
11760      * are not being used in this view
11761      * @param forceRedraw Mark the view as DRAWN to force the invalidation to propagate, if display
11762      * list properties are not being used in this view
11763      */
11764     void invalidateViewProperty(boolean invalidateParent, boolean forceRedraw) {
11765         if (!isHardwareAccelerated()
11766                 || !mRenderNode.isValid()
11767                 || (mPrivateFlags & PFLAG_DRAW_ANIMATION) != 0) {
11768             if (invalidateParent) {
11769                 invalidateParentCaches();
11770             }
11771             if (forceRedraw) {
11772                 mPrivateFlags |= PFLAG_DRAWN; // force another invalidation with the new orientation
11773             }
11774             invalidate(false);
11775         } else {
11776             damageInParent();
11777         }
11778         if (isHardwareAccelerated() && invalidateParent && getZ() != 0) {
11779             damageShadowReceiver();
11780         }
11781     }
11782
11783     /**
11784      * Tells the parent view to damage this view's bounds.
11785      *
11786      * @hide
11787      */
11788     protected void damageInParent() {
11789         final AttachInfo ai = mAttachInfo;
11790         final ViewParent p = mParent;
11791         if (p != null && ai != null) {
11792             final Rect r = ai.mTmpInvalRect;
11793             r.set(0, 0, mRight - mLeft, mBottom - mTop);
11794             if (mParent instanceof ViewGroup) {
11795                 ((ViewGroup) mParent).damageChild(this, r);
11796             } else {
11797                 mParent.invalidateChild(this, r);
11798             }
11799         }
11800     }
11801
11802     /**
11803      * Utility method to transform a given Rect by the current matrix of this view.
11804      */
11805     void transformRect(final Rect rect) {
11806         if (!getMatrix().isIdentity()) {
11807             RectF boundingRect = mAttachInfo.mTmpTransformRect;
11808             boundingRect.set(rect);
11809             getMatrix().mapRect(boundingRect);
11810             rect.set((int) Math.floor(boundingRect.left),
11811                     (int) Math.floor(boundingRect.top),
11812                     (int) Math.ceil(boundingRect.right),
11813                     (int) Math.ceil(boundingRect.bottom));
11814         }
11815     }
11816
11817     /**
11818      * Used to indicate that the parent of this view should clear its caches. This functionality
11819      * is used to force the parent to rebuild its display list (when hardware-accelerated),
11820      * which is necessary when various parent-managed properties of the view change, such as
11821      * alpha, translationX/Y, scrollX/Y, scaleX/Y, and rotation/X/Y. This method only
11822      * clears the parent caches and does not causes an invalidate event.
11823      *
11824      * @hide
11825      */
11826     protected void invalidateParentCaches() {
11827         if (mParent instanceof View) {
11828             ((View) mParent).mPrivateFlags |= PFLAG_INVALIDATED;
11829         }
11830     }
11831
11832     /**
11833      * Used to indicate that the parent of this view should be invalidated. This functionality
11834      * is used to force the parent to rebuild its display list (when hardware-accelerated),
11835      * which is necessary when various parent-managed properties of the view change, such as
11836      * alpha, translationX/Y, scrollX/Y, scaleX/Y, and rotation/X/Y. This method will propagate
11837      * an invalidation event to the parent.
11838      *
11839      * @hide
11840      */
11841     protected void invalidateParentIfNeeded() {
11842         if (isHardwareAccelerated() && mParent instanceof View) {
11843             ((View) mParent).invalidate(true);
11844         }
11845     }
11846
11847     /**
11848      * @hide
11849      */
11850     protected void invalidateParentIfNeededAndWasQuickRejected() {
11851         if ((mPrivateFlags2 & PFLAG2_VIEW_QUICK_REJECTED) != 0) {
11852             // View was rejected last time it was drawn by its parent; this may have changed
11853             invalidateParentIfNeeded();
11854         }
11855     }
11856
11857     /**
11858      * Indicates whether this View is opaque. An opaque View guarantees that it will
11859      * draw all the pixels overlapping its bounds using a fully opaque color.
11860      *
11861      * Subclasses of View should override this method whenever possible to indicate
11862      * whether an instance is opaque. Opaque Views are treated in a special way by
11863      * the View hierarchy, possibly allowing it to perform optimizations during
11864      * invalidate/draw passes.
11865      *
11866      * @return True if this View is guaranteed to be fully opaque, false otherwise.
11867      */
11868     @ViewDebug.ExportedProperty(category = "drawing")
11869     public boolean isOpaque() {
11870         return (mPrivateFlags & PFLAG_OPAQUE_MASK) == PFLAG_OPAQUE_MASK &&
11871                 getFinalAlpha() >= 1.0f;
11872     }
11873
11874     /**
11875      * @hide
11876      */
11877     protected void computeOpaqueFlags() {
11878         // Opaque if:
11879         //   - Has a background
11880         //   - Background is opaque
11881         //   - Doesn't have scrollbars or scrollbars overlay
11882
11883         if (mBackground != null && mBackground.getOpacity() == PixelFormat.OPAQUE) {
11884             mPrivateFlags |= PFLAG_OPAQUE_BACKGROUND;
11885         } else {
11886             mPrivateFlags &= ~PFLAG_OPAQUE_BACKGROUND;
11887         }
11888
11889         final int flags = mViewFlags;
11890         if (((flags & SCROLLBARS_VERTICAL) == 0 && (flags & SCROLLBARS_HORIZONTAL) == 0) ||
11891                 (flags & SCROLLBARS_STYLE_MASK) == SCROLLBARS_INSIDE_OVERLAY ||
11892                 (flags & SCROLLBARS_STYLE_MASK) == SCROLLBARS_OUTSIDE_OVERLAY) {
11893             mPrivateFlags |= PFLAG_OPAQUE_SCROLLBARS;
11894         } else {
11895             mPrivateFlags &= ~PFLAG_OPAQUE_SCROLLBARS;
11896         }
11897     }
11898
11899     /**
11900      * @hide
11901      */
11902     protected boolean hasOpaqueScrollbars() {
11903         return (mPrivateFlags & PFLAG_OPAQUE_SCROLLBARS) == PFLAG_OPAQUE_SCROLLBARS;
11904     }
11905
11906     /**
11907      * @return A handler associated with the thread running the View. This
11908      * handler can be used to pump events in the UI events queue.
11909      */
11910     public Handler getHandler() {
11911         final AttachInfo attachInfo = mAttachInfo;
11912         if (attachInfo != null) {
11913             return attachInfo.mHandler;
11914         }
11915         return null;
11916     }
11917
11918     /**
11919      * Gets the view root associated with the View.
11920      * @return The view root, or null if none.
11921      * @hide
11922      */
11923     public ViewRootImpl getViewRootImpl() {
11924         if (mAttachInfo != null) {
11925             return mAttachInfo.mViewRootImpl;
11926         }
11927         return null;
11928     }
11929
11930     /**
11931      * @hide
11932      */
11933     public HardwareRenderer getHardwareRenderer() {
11934         return mAttachInfo != null ? mAttachInfo.mHardwareRenderer : null;
11935     }
11936
11937     /**
11938      * <p>Causes the Runnable to be added to the message queue.
11939      * The runnable will be run on the user interface thread.</p>
11940      *
11941      * @param action The Runnable that will be executed.
11942      *
11943      * @return Returns true if the Runnable was successfully placed in to the
11944      *         message queue.  Returns false on failure, usually because the
11945      *         looper processing the message queue is exiting.
11946      *
11947      * @see #postDelayed
11948      * @see #removeCallbacks
11949      */
11950     public boolean post(Runnable action) {
11951         final AttachInfo attachInfo = mAttachInfo;
11952         if (attachInfo != null) {
11953             return attachInfo.mHandler.post(action);
11954         }
11955         // Assume that post will succeed later
11956         ViewRootImpl.getRunQueue().post(action);
11957         return true;
11958     }
11959
11960     /**
11961      * <p>Causes the Runnable to be added to the message queue, to be run
11962      * after the specified amount of time elapses.
11963      * The runnable will be run on the user interface thread.</p>
11964      *
11965      * @param action The Runnable that will be executed.
11966      * @param delayMillis The delay (in milliseconds) until the Runnable
11967      *        will be executed.
11968      *
11969      * @return true if the Runnable was successfully placed in to the
11970      *         message queue.  Returns false on failure, usually because the
11971      *         looper processing the message queue is exiting.  Note that a
11972      *         result of true does not mean the Runnable will be processed --
11973      *         if the looper is quit before the delivery time of the message
11974      *         occurs then the message will be dropped.
11975      *
11976      * @see #post
11977      * @see #removeCallbacks
11978      */
11979     public boolean postDelayed(Runnable action, long delayMillis) {
11980         final AttachInfo attachInfo = mAttachInfo;
11981         if (attachInfo != null) {
11982             return attachInfo.mHandler.postDelayed(action, delayMillis);
11983         }
11984         // Assume that post will succeed later
11985         ViewRootImpl.getRunQueue().postDelayed(action, delayMillis);
11986         return true;
11987     }
11988
11989     /**
11990      * <p>Causes the Runnable to execute on the next animation time step.
11991      * The runnable will be run on the user interface thread.</p>
11992      *
11993      * @param action The Runnable that will be executed.
11994      *
11995      * @see #postOnAnimationDelayed
11996      * @see #removeCallbacks
11997      */
11998     public void postOnAnimation(Runnable action) {
11999         final AttachInfo attachInfo = mAttachInfo;
12000         if (attachInfo != null) {
12001             attachInfo.mViewRootImpl.mChoreographer.postCallback(
12002                     Choreographer.CALLBACK_ANIMATION, action, null);
12003         } else {
12004             // Assume that post will succeed later
12005             ViewRootImpl.getRunQueue().post(action);
12006         }
12007     }
12008
12009     /**
12010      * <p>Causes the Runnable to execute on the next animation time step,
12011      * after the specified amount of time elapses.
12012      * The runnable will be run on the user interface thread.</p>
12013      *
12014      * @param action The Runnable that will be executed.
12015      * @param delayMillis The delay (in milliseconds) until the Runnable
12016      *        will be executed.
12017      *
12018      * @see #postOnAnimation
12019      * @see #removeCallbacks
12020      */
12021     public void postOnAnimationDelayed(Runnable action, long delayMillis) {
12022         final AttachInfo attachInfo = mAttachInfo;
12023         if (attachInfo != null) {
12024             attachInfo.mViewRootImpl.mChoreographer.postCallbackDelayed(
12025                     Choreographer.CALLBACK_ANIMATION, action, null, delayMillis);
12026         } else {
12027             // Assume that post will succeed later
12028             ViewRootImpl.getRunQueue().postDelayed(action, delayMillis);
12029         }
12030     }
12031
12032     /**
12033      * <p>Removes the specified Runnable from the message queue.</p>
12034      *
12035      * @param action The Runnable to remove from the message handling queue
12036      *
12037      * @return true if this view could ask the Handler to remove the Runnable,
12038      *         false otherwise. When the returned value is true, the Runnable
12039      *         may or may not have been actually removed from the message queue
12040      *         (for instance, if the Runnable was not in the queue already.)
12041      *
12042      * @see #post
12043      * @see #postDelayed
12044      * @see #postOnAnimation
12045      * @see #postOnAnimationDelayed
12046      */
12047     public boolean removeCallbacks(Runnable action) {
12048         if (action != null) {
12049             final AttachInfo attachInfo = mAttachInfo;
12050             if (attachInfo != null) {
12051                 attachInfo.mHandler.removeCallbacks(action);
12052                 attachInfo.mViewRootImpl.mChoreographer.removeCallbacks(
12053                         Choreographer.CALLBACK_ANIMATION, action, null);
12054             }
12055             // Assume that post will succeed later
12056             ViewRootImpl.getRunQueue().removeCallbacks(action);
12057         }
12058         return true;
12059     }
12060
12061     /**
12062      * <p>Cause an invalidate to happen on a subsequent cycle through the event loop.
12063      * Use this to invalidate the View from a non-UI thread.</p>
12064      *
12065      * <p>This method can be invoked from outside of the UI thread
12066      * only when this View is attached to a window.</p>
12067      *
12068      * @see #invalidate()
12069      * @see #postInvalidateDelayed(long)
12070      */
12071     public void postInvalidate() {
12072         postInvalidateDelayed(0);
12073     }
12074
12075     /**
12076      * <p>Cause an invalidate of the specified area to happen on a subsequent cycle
12077      * through the event loop. Use this to invalidate the View from a non-UI thread.</p>
12078      *
12079      * <p>This method can be invoked from outside of the UI thread
12080      * only when this View is attached to a window.</p>
12081      *
12082      * @param left The left coordinate of the rectangle to invalidate.
12083      * @param top The top coordinate of the rectangle to invalidate.
12084      * @param right The right coordinate of the rectangle to invalidate.
12085      * @param bottom The bottom coordinate of the rectangle to invalidate.
12086      *
12087      * @see #invalidate(int, int, int, int)
12088      * @see #invalidate(Rect)
12089      * @see #postInvalidateDelayed(long, int, int, int, int)
12090      */
12091     public void postInvalidate(int left, int top, int right, int bottom) {
12092         postInvalidateDelayed(0, left, top, right, bottom);
12093     }
12094
12095     /**
12096      * <p>Cause an invalidate to happen on a subsequent cycle through the event
12097      * loop. Waits for the specified amount of time.</p>
12098      *
12099      * <p>This method can be invoked from outside of the UI thread
12100      * only when this View is attached to a window.</p>
12101      *
12102      * @param delayMilliseconds the duration in milliseconds to delay the
12103      *         invalidation by
12104      *
12105      * @see #invalidate()
12106      * @see #postInvalidate()
12107      */
12108     public void postInvalidateDelayed(long delayMilliseconds) {
12109         // We try only with the AttachInfo because there's no point in invalidating
12110         // if we are not attached to our window
12111         final AttachInfo attachInfo = mAttachInfo;
12112         if (attachInfo != null) {
12113             attachInfo.mViewRootImpl.dispatchInvalidateDelayed(this, delayMilliseconds);
12114         }
12115     }
12116
12117     /**
12118      * <p>Cause an invalidate of the specified area to happen on a subsequent cycle
12119      * through the event loop. Waits for the specified amount of time.</p>
12120      *
12121      * <p>This method can be invoked from outside of the UI thread
12122      * only when this View is attached to a window.</p>
12123      *
12124      * @param delayMilliseconds the duration in milliseconds to delay the
12125      *         invalidation by
12126      * @param left The left coordinate of the rectangle to invalidate.
12127      * @param top The top coordinate of the rectangle to invalidate.
12128      * @param right The right coordinate of the rectangle to invalidate.
12129      * @param bottom The bottom coordinate of the rectangle to invalidate.
12130      *
12131      * @see #invalidate(int, int, int, int)
12132      * @see #invalidate(Rect)
12133      * @see #postInvalidate(int, int, int, int)
12134      */
12135     public void postInvalidateDelayed(long delayMilliseconds, int left, int top,
12136             int right, int bottom) {
12137
12138         // We try only with the AttachInfo because there's no point in invalidating
12139         // if we are not attached to our window
12140         final AttachInfo attachInfo = mAttachInfo;
12141         if (attachInfo != null) {
12142             final AttachInfo.InvalidateInfo info = AttachInfo.InvalidateInfo.obtain();
12143             info.target = this;
12144             info.left = left;
12145             info.top = top;
12146             info.right = right;
12147             info.bottom = bottom;
12148
12149             attachInfo.mViewRootImpl.dispatchInvalidateRectDelayed(info, delayMilliseconds);
12150         }
12151     }
12152
12153     /**
12154      * <p>Cause an invalidate to happen on the next animation time step, typically the
12155      * next display frame.</p>
12156      *
12157      * <p>This method can be invoked from outside of the UI thread
12158      * only when this View is attached to a window.</p>
12159      *
12160      * @see #invalidate()
12161      */
12162     public void postInvalidateOnAnimation() {
12163         // We try only with the AttachInfo because there's no point in invalidating
12164         // if we are not attached to our window
12165         final AttachInfo attachInfo = mAttachInfo;
12166         if (attachInfo != null) {
12167             attachInfo.mViewRootImpl.dispatchInvalidateOnAnimation(this);
12168         }
12169     }
12170
12171     /**
12172      * <p>Cause an invalidate of the specified area to happen on the next animation
12173      * time step, typically the next display frame.</p>
12174      *
12175      * <p>This method can be invoked from outside of the UI thread
12176      * only when this View is attached to a window.</p>
12177      *
12178      * @param left The left coordinate of the rectangle to invalidate.
12179      * @param top The top coordinate of the rectangle to invalidate.
12180      * @param right The right coordinate of the rectangle to invalidate.
12181      * @param bottom The bottom coordinate of the rectangle to invalidate.
12182      *
12183      * @see #invalidate(int, int, int, int)
12184      * @see #invalidate(Rect)
12185      */
12186     public void postInvalidateOnAnimation(int left, int top, int right, int bottom) {
12187         // We try only with the AttachInfo because there's no point in invalidating
12188         // if we are not attached to our window
12189         final AttachInfo attachInfo = mAttachInfo;
12190         if (attachInfo != null) {
12191             final AttachInfo.InvalidateInfo info = AttachInfo.InvalidateInfo.obtain();
12192             info.target = this;
12193             info.left = left;
12194             info.top = top;
12195             info.right = right;
12196             info.bottom = bottom;
12197
12198             attachInfo.mViewRootImpl.dispatchInvalidateRectOnAnimation(info);
12199         }
12200     }
12201
12202     /**
12203      * Post a callback to send a {@link AccessibilityEvent#TYPE_VIEW_SCROLLED} event.
12204      * This event is sent at most once every
12205      * {@link ViewConfiguration#getSendRecurringAccessibilityEventsInterval()}.
12206      */
12207     private void postSendViewScrolledAccessibilityEventCallback() {
12208         if (mSendViewScrolledAccessibilityEvent == null) {
12209             mSendViewScrolledAccessibilityEvent = new SendViewScrolledAccessibilityEvent();
12210         }
12211         if (!mSendViewScrolledAccessibilityEvent.mIsPending) {
12212             mSendViewScrolledAccessibilityEvent.mIsPending = true;
12213             postDelayed(mSendViewScrolledAccessibilityEvent,
12214                     ViewConfiguration.getSendRecurringAccessibilityEventsInterval());
12215         }
12216     }
12217
12218     /**
12219      * Called by a parent to request that a child update its values for mScrollX
12220      * and mScrollY if necessary. This will typically be done if the child is
12221      * animating a scroll using a {@link android.widget.Scroller Scroller}
12222      * object.
12223      */
12224     public void computeScroll() {
12225     }
12226
12227     /**
12228      * <p>Indicate whether the horizontal edges are faded when the view is
12229      * scrolled horizontally.</p>
12230      *
12231      * @return true if the horizontal edges should are faded on scroll, false
12232      *         otherwise
12233      *
12234      * @see #setHorizontalFadingEdgeEnabled(boolean)
12235      *
12236      * @attr ref android.R.styleable#View_requiresFadingEdge
12237      */
12238     public boolean isHorizontalFadingEdgeEnabled() {
12239         return (mViewFlags & FADING_EDGE_HORIZONTAL) == FADING_EDGE_HORIZONTAL;
12240     }
12241
12242     /**
12243      * <p>Define whether the horizontal edges should be faded when this view
12244      * is scrolled horizontally.</p>
12245      *
12246      * @param horizontalFadingEdgeEnabled true if the horizontal edges should
12247      *                                    be faded when the view is scrolled
12248      *                                    horizontally
12249      *
12250      * @see #isHorizontalFadingEdgeEnabled()
12251      *
12252      * @attr ref android.R.styleable#View_requiresFadingEdge
12253      */
12254     public void setHorizontalFadingEdgeEnabled(boolean horizontalFadingEdgeEnabled) {
12255         if (isHorizontalFadingEdgeEnabled() != horizontalFadingEdgeEnabled) {
12256             if (horizontalFadingEdgeEnabled) {
12257                 initScrollCache();
12258             }
12259
12260             mViewFlags ^= FADING_EDGE_HORIZONTAL;
12261         }
12262     }
12263
12264     /**
12265      * <p>Indicate whether the vertical edges are faded when the view is
12266      * scrolled horizontally.</p>
12267      *
12268      * @return true if the vertical edges should are faded on scroll, false
12269      *         otherwise
12270      *
12271      * @see #setVerticalFadingEdgeEnabled(boolean)
12272      *
12273      * @attr ref android.R.styleable#View_requiresFadingEdge
12274      */
12275     public boolean isVerticalFadingEdgeEnabled() {
12276         return (mViewFlags & FADING_EDGE_VERTICAL) == FADING_EDGE_VERTICAL;
12277     }
12278
12279     /**
12280      * <p>Define whether the vertical edges should be faded when this view
12281      * is scrolled vertically.</p>
12282      *
12283      * @param verticalFadingEdgeEnabled true if the vertical edges should
12284      *                                  be faded when the view is scrolled
12285      *                                  vertically
12286      *
12287      * @see #isVerticalFadingEdgeEnabled()
12288      *
12289      * @attr ref android.R.styleable#View_requiresFadingEdge
12290      */
12291     public void setVerticalFadingEdgeEnabled(boolean verticalFadingEdgeEnabled) {
12292         if (isVerticalFadingEdgeEnabled() != verticalFadingEdgeEnabled) {
12293             if (verticalFadingEdgeEnabled) {
12294                 initScrollCache();
12295             }
12296
12297             mViewFlags ^= FADING_EDGE_VERTICAL;
12298         }
12299     }
12300
12301     /**
12302      * Returns the strength, or intensity, of the top faded edge. The strength is
12303      * a value between 0.0 (no fade) and 1.0 (full fade). The default implementation
12304      * returns 0.0 or 1.0 but no value in between.
12305      *
12306      * Subclasses should override this method to provide a smoother fade transition
12307      * when scrolling occurs.
12308      *
12309      * @return the intensity of the top fade as a float between 0.0f and 1.0f
12310      */
12311     protected float getTopFadingEdgeStrength() {
12312         return computeVerticalScrollOffset() > 0 ? 1.0f : 0.0f;
12313     }
12314
12315     /**
12316      * Returns the strength, or intensity, of the bottom faded edge. The strength is
12317      * a value between 0.0 (no fade) and 1.0 (full fade). The default implementation
12318      * returns 0.0 or 1.0 but no value in between.
12319      *
12320      * Subclasses should override this method to provide a smoother fade transition
12321      * when scrolling occurs.
12322      *
12323      * @return the intensity of the bottom fade as a float between 0.0f and 1.0f
12324      */
12325     protected float getBottomFadingEdgeStrength() {
12326         return computeVerticalScrollOffset() + computeVerticalScrollExtent() <
12327                 computeVerticalScrollRange() ? 1.0f : 0.0f;
12328     }
12329
12330     /**
12331      * Returns the strength, or intensity, of the left faded edge. The strength is
12332      * a value between 0.0 (no fade) and 1.0 (full fade). The default implementation
12333      * returns 0.0 or 1.0 but no value in between.
12334      *
12335      * Subclasses should override this method to provide a smoother fade transition
12336      * when scrolling occurs.
12337      *
12338      * @return the intensity of the left fade as a float between 0.0f and 1.0f
12339      */
12340     protected float getLeftFadingEdgeStrength() {
12341         return computeHorizontalScrollOffset() > 0 ? 1.0f : 0.0f;
12342     }
12343
12344     /**
12345      * Returns the strength, or intensity, of the right faded edge. The strength is
12346      * a value between 0.0 (no fade) and 1.0 (full fade). The default implementation
12347      * returns 0.0 or 1.0 but no value in between.
12348      *
12349      * Subclasses should override this method to provide a smoother fade transition
12350      * when scrolling occurs.
12351      *
12352      * @return the intensity of the right fade as a float between 0.0f and 1.0f
12353      */
12354     protected float getRightFadingEdgeStrength() {
12355         return computeHorizontalScrollOffset() + computeHorizontalScrollExtent() <
12356                 computeHorizontalScrollRange() ? 1.0f : 0.0f;
12357     }
12358
12359     /**
12360      * <p>Indicate whether the horizontal scrollbar should be drawn or not. The
12361      * scrollbar is not drawn by default.</p>
12362      *
12363      * @return true if the horizontal scrollbar should be painted, false
12364      *         otherwise
12365      *
12366      * @see #setHorizontalScrollBarEnabled(boolean)
12367      */
12368     public boolean isHorizontalScrollBarEnabled() {
12369         return (mViewFlags & SCROLLBARS_HORIZONTAL) == SCROLLBARS_HORIZONTAL;
12370     }
12371
12372     /**
12373      * <p>Define whether the horizontal scrollbar should be drawn or not. The
12374      * scrollbar is not drawn by default.</p>
12375      *
12376      * @param horizontalScrollBarEnabled true if the horizontal scrollbar should
12377      *                                   be painted
12378      *
12379      * @see #isHorizontalScrollBarEnabled()
12380      */
12381     public void setHorizontalScrollBarEnabled(boolean horizontalScrollBarEnabled) {
12382         if (isHorizontalScrollBarEnabled() != horizontalScrollBarEnabled) {
12383             mViewFlags ^= SCROLLBARS_HORIZONTAL;
12384             computeOpaqueFlags();
12385             resolvePadding();
12386         }
12387     }
12388
12389     /**
12390      * <p>Indicate whether the vertical scrollbar should be drawn or not. The
12391      * scrollbar is not drawn by default.</p>
12392      *
12393      * @return true if the vertical scrollbar should be painted, false
12394      *         otherwise
12395      *
12396      * @see #setVerticalScrollBarEnabled(boolean)
12397      */
12398     public boolean isVerticalScrollBarEnabled() {
12399         return (mViewFlags & SCROLLBARS_VERTICAL) == SCROLLBARS_VERTICAL;
12400     }
12401
12402     /**
12403      * <p>Define whether the vertical scrollbar should be drawn or not. The
12404      * scrollbar is not drawn by default.</p>
12405      *
12406      * @param verticalScrollBarEnabled true if the vertical scrollbar should
12407      *                                 be painted
12408      *
12409      * @see #isVerticalScrollBarEnabled()
12410      */
12411     public void setVerticalScrollBarEnabled(boolean verticalScrollBarEnabled) {
12412         if (isVerticalScrollBarEnabled() != verticalScrollBarEnabled) {
12413             mViewFlags ^= SCROLLBARS_VERTICAL;
12414             computeOpaqueFlags();
12415             resolvePadding();
12416         }
12417     }
12418
12419     /**
12420      * @hide
12421      */
12422     protected void recomputePadding() {
12423         internalSetPadding(mUserPaddingLeft, mPaddingTop, mUserPaddingRight, mUserPaddingBottom);
12424     }
12425
12426     /**
12427      * Define whether scrollbars will fade when the view is not scrolling.
12428      *
12429      * @param fadeScrollbars wheter to enable fading
12430      *
12431      * @attr ref android.R.styleable#View_fadeScrollbars
12432      */
12433     public void setScrollbarFadingEnabled(boolean fadeScrollbars) {
12434         initScrollCache();
12435         final ScrollabilityCache scrollabilityCache = mScrollCache;
12436         scrollabilityCache.fadeScrollBars = fadeScrollbars;
12437         if (fadeScrollbars) {
12438             scrollabilityCache.state = ScrollabilityCache.OFF;
12439         } else {
12440             scrollabilityCache.state = ScrollabilityCache.ON;
12441         }
12442     }
12443
12444     /**
12445      *
12446      * Returns true if scrollbars will fade when this view is not scrolling
12447      *
12448      * @return true if scrollbar fading is enabled
12449      *
12450      * @attr ref android.R.styleable#View_fadeScrollbars
12451      */
12452     public boolean isScrollbarFadingEnabled() {
12453         return mScrollCache != null && mScrollCache.fadeScrollBars;
12454     }
12455
12456     /**
12457      *
12458      * Returns the delay before scrollbars fade.
12459      *
12460      * @return the delay before scrollbars fade
12461      *
12462      * @attr ref android.R.styleable#View_scrollbarDefaultDelayBeforeFade
12463      */
12464     public int getScrollBarDefaultDelayBeforeFade() {
12465         return mScrollCache == null ? ViewConfiguration.getScrollDefaultDelay() :
12466                 mScrollCache.scrollBarDefaultDelayBeforeFade;
12467     }
12468
12469     /**
12470      * Define the delay before scrollbars fade.
12471      *
12472      * @param scrollBarDefaultDelayBeforeFade - the delay before scrollbars fade
12473      *
12474      * @attr ref android.R.styleable#View_scrollbarDefaultDelayBeforeFade
12475      */
12476     public void setScrollBarDefaultDelayBeforeFade(int scrollBarDefaultDelayBeforeFade) {
12477         getScrollCache().scrollBarDefaultDelayBeforeFade = scrollBarDefaultDelayBeforeFade;
12478     }
12479
12480     /**
12481      *
12482      * Returns the scrollbar fade duration.
12483      *
12484      * @return the scrollbar fade duration
12485      *
12486      * @attr ref android.R.styleable#View_scrollbarFadeDuration
12487      */
12488     public int getScrollBarFadeDuration() {
12489         return mScrollCache == null ? ViewConfiguration.getScrollBarFadeDuration() :
12490                 mScrollCache.scrollBarFadeDuration;
12491     }
12492
12493     /**
12494      * Define the scrollbar fade duration.
12495      *
12496      * @param scrollBarFadeDuration - the scrollbar fade duration
12497      *
12498      * @attr ref android.R.styleable#View_scrollbarFadeDuration
12499      */
12500     public void setScrollBarFadeDuration(int scrollBarFadeDuration) {
12501         getScrollCache().scrollBarFadeDuration = scrollBarFadeDuration;
12502     }
12503
12504     /**
12505      *
12506      * Returns the scrollbar size.
12507      *
12508      * @return the scrollbar size
12509      *
12510      * @attr ref android.R.styleable#View_scrollbarSize
12511      */
12512     public int getScrollBarSize() {
12513         return mScrollCache == null ? ViewConfiguration.get(mContext).getScaledScrollBarSize() :
12514                 mScrollCache.scrollBarSize;
12515     }
12516
12517     /**
12518      * Define the scrollbar size.
12519      *
12520      * @param scrollBarSize - the scrollbar size
12521      *
12522      * @attr ref android.R.styleable#View_scrollbarSize
12523      */
12524     public void setScrollBarSize(int scrollBarSize) {
12525         getScrollCache().scrollBarSize = scrollBarSize;
12526     }
12527
12528     /**
12529      * <p>Specify the style of the scrollbars. The scrollbars can be overlaid or
12530      * inset. When inset, they add to the padding of the view. And the scrollbars
12531      * can be drawn inside the padding area or on the edge of the view. For example,
12532      * if a view has a background drawable and you want to draw the scrollbars
12533      * inside the padding specified by the drawable, you can use
12534      * SCROLLBARS_INSIDE_OVERLAY or SCROLLBARS_INSIDE_INSET. If you want them to
12535      * appear at the edge of the view, ignoring the padding, then you can use
12536      * SCROLLBARS_OUTSIDE_OVERLAY or SCROLLBARS_OUTSIDE_INSET.</p>
12537      * @param style the style of the scrollbars. Should be one of
12538      * SCROLLBARS_INSIDE_OVERLAY, SCROLLBARS_INSIDE_INSET,
12539      * SCROLLBARS_OUTSIDE_OVERLAY or SCROLLBARS_OUTSIDE_INSET.
12540      * @see #SCROLLBARS_INSIDE_OVERLAY
12541      * @see #SCROLLBARS_INSIDE_INSET
12542      * @see #SCROLLBARS_OUTSIDE_OVERLAY
12543      * @see #SCROLLBARS_OUTSIDE_INSET
12544      *
12545      * @attr ref android.R.styleable#View_scrollbarStyle
12546      */
12547     public void setScrollBarStyle(@ScrollBarStyle int style) {
12548         if (style != (mViewFlags & SCROLLBARS_STYLE_MASK)) {
12549             mViewFlags = (mViewFlags & ~SCROLLBARS_STYLE_MASK) | (style & SCROLLBARS_STYLE_MASK);
12550             computeOpaqueFlags();
12551             resolvePadding();
12552         }
12553     }
12554
12555     /**
12556      * <p>Returns the current scrollbar style.</p>
12557      * @return the current scrollbar style
12558      * @see #SCROLLBARS_INSIDE_OVERLAY
12559      * @see #SCROLLBARS_INSIDE_INSET
12560      * @see #SCROLLBARS_OUTSIDE_OVERLAY
12561      * @see #SCROLLBARS_OUTSIDE_INSET
12562      *
12563      * @attr ref android.R.styleable#View_scrollbarStyle
12564      */
12565     @ViewDebug.ExportedProperty(mapping = {
12566             @ViewDebug.IntToString(from = SCROLLBARS_INSIDE_OVERLAY, to = "INSIDE_OVERLAY"),
12567             @ViewDebug.IntToString(from = SCROLLBARS_INSIDE_INSET, to = "INSIDE_INSET"),
12568             @ViewDebug.IntToString(from = SCROLLBARS_OUTSIDE_OVERLAY, to = "OUTSIDE_OVERLAY"),
12569             @ViewDebug.IntToString(from = SCROLLBARS_OUTSIDE_INSET, to = "OUTSIDE_INSET")
12570     })
12571     @ScrollBarStyle
12572     public int getScrollBarStyle() {
12573         return mViewFlags & SCROLLBARS_STYLE_MASK;
12574     }
12575
12576     /**
12577      * <p>Compute the horizontal range that the horizontal scrollbar
12578      * represents.</p>
12579      *
12580      * <p>The range is expressed in arbitrary units that must be the same as the
12581      * units used by {@link #computeHorizontalScrollExtent()} and
12582      * {@link #computeHorizontalScrollOffset()}.</p>
12583      *
12584      * <p>The default range is the drawing width of this view.</p>
12585      *
12586      * @return the total horizontal range represented by the horizontal
12587      *         scrollbar
12588      *
12589      * @see #computeHorizontalScrollExtent()
12590      * @see #computeHorizontalScrollOffset()
12591      * @see android.widget.ScrollBarDrawable
12592      */
12593     protected int computeHorizontalScrollRange() {
12594         return getWidth();
12595     }
12596
12597     /**
12598      * <p>Compute the horizontal offset of the horizontal scrollbar's thumb
12599      * within the horizontal range. This value is used to compute the position
12600      * of the thumb within the scrollbar's track.</p>
12601      *
12602      * <p>The range is expressed in arbitrary units that must be the same as the
12603      * units used by {@link #computeHorizontalScrollRange()} and
12604      * {@link #computeHorizontalScrollExtent()}.</p>
12605      *
12606      * <p>The default offset is the scroll offset of this view.</p>
12607      *
12608      * @return the horizontal offset of the scrollbar's thumb
12609      *
12610      * @see #computeHorizontalScrollRange()
12611      * @see #computeHorizontalScrollExtent()
12612      * @see android.widget.ScrollBarDrawable
12613      */
12614     protected int computeHorizontalScrollOffset() {
12615         return mScrollX;
12616     }
12617
12618     /**
12619      * <p>Compute the horizontal extent of the horizontal scrollbar's thumb
12620      * within the horizontal range. This value is used to compute the length
12621      * of the thumb within the scrollbar's track.</p>
12622      *
12623      * <p>The range is expressed in arbitrary units that must be the same as the
12624      * units used by {@link #computeHorizontalScrollRange()} and
12625      * {@link #computeHorizontalScrollOffset()}.</p>
12626      *
12627      * <p>The default extent is the drawing width of this view.</p>
12628      *
12629      * @return the horizontal extent of the scrollbar's thumb
12630      *
12631      * @see #computeHorizontalScrollRange()
12632      * @see #computeHorizontalScrollOffset()
12633      * @see android.widget.ScrollBarDrawable
12634      */
12635     protected int computeHorizontalScrollExtent() {
12636         return getWidth();
12637     }
12638
12639     /**
12640      * <p>Compute the vertical range that the vertical scrollbar represents.</p>
12641      *
12642      * <p>The range is expressed in arbitrary units that must be the same as the
12643      * units used by {@link #computeVerticalScrollExtent()} and
12644      * {@link #computeVerticalScrollOffset()}.</p>
12645      *
12646      * @return the total vertical range represented by the vertical scrollbar
12647      *
12648      * <p>The default range is the drawing height of this view.</p>
12649      *
12650      * @see #computeVerticalScrollExtent()
12651      * @see #computeVerticalScrollOffset()
12652      * @see android.widget.ScrollBarDrawable
12653      */
12654     protected int computeVerticalScrollRange() {
12655         return getHeight();
12656     }
12657
12658     /**
12659      * <p>Compute the vertical offset of the vertical scrollbar's thumb
12660      * within the horizontal range. This value is used to compute the position
12661      * of the thumb within the scrollbar's track.</p>
12662      *
12663      * <p>The range is expressed in arbitrary units that must be the same as the
12664      * units used by {@link #computeVerticalScrollRange()} and
12665      * {@link #computeVerticalScrollExtent()}.</p>
12666      *
12667      * <p>The default offset is the scroll offset of this view.</p>
12668      *
12669      * @return the vertical offset of the scrollbar's thumb
12670      *
12671      * @see #computeVerticalScrollRange()
12672      * @see #computeVerticalScrollExtent()
12673      * @see android.widget.ScrollBarDrawable
12674      */
12675     protected int computeVerticalScrollOffset() {
12676         return mScrollY;
12677     }
12678
12679     /**
12680      * <p>Compute the vertical extent of the vertical scrollbar's thumb
12681      * within the vertical range. This value is used to compute the length
12682      * of the thumb within the scrollbar's track.</p>
12683      *
12684      * <p>The range is expressed in arbitrary units that must be the same as the
12685      * units used by {@link #computeVerticalScrollRange()} and
12686      * {@link #computeVerticalScrollOffset()}.</p>
12687      *
12688      * <p>The default extent is the drawing height of this view.</p>
12689      *
12690      * @return the vertical extent of the scrollbar's thumb
12691      *
12692      * @see #computeVerticalScrollRange()
12693      * @see #computeVerticalScrollOffset()
12694      * @see android.widget.ScrollBarDrawable
12695      */
12696     protected int computeVerticalScrollExtent() {
12697         return getHeight();
12698     }
12699
12700     /**
12701      * Check if this view can be scrolled horizontally in a certain direction.
12702      *
12703      * @param direction Negative to check scrolling left, positive to check scrolling right.
12704      * @return true if this view can be scrolled in the specified direction, false otherwise.
12705      */
12706     public boolean canScrollHorizontally(int direction) {
12707         final int offset = computeHorizontalScrollOffset();
12708         final int range = computeHorizontalScrollRange() - computeHorizontalScrollExtent();
12709         if (range == 0) return false;
12710         if (direction < 0) {
12711             return offset > 0;
12712         } else {
12713             return offset < range - 1;
12714         }
12715     }
12716
12717     /**
12718      * Check if this view can be scrolled vertically in a certain direction.
12719      *
12720      * @param direction Negative to check scrolling up, positive to check scrolling down.
12721      * @return true if this view can be scrolled in the specified direction, false otherwise.
12722      */
12723     public boolean canScrollVertically(int direction) {
12724         final int offset = computeVerticalScrollOffset();
12725         final int range = computeVerticalScrollRange() - computeVerticalScrollExtent();
12726         if (range == 0) return false;
12727         if (direction < 0) {
12728             return offset > 0;
12729         } else {
12730             return offset < range - 1;
12731         }
12732     }
12733
12734     /**
12735      * <p>Request the drawing of the horizontal and the vertical scrollbar. The
12736      * scrollbars are painted only if they have been awakened first.</p>
12737      *
12738      * @param canvas the canvas on which to draw the scrollbars
12739      *
12740      * @see #awakenScrollBars(int)
12741      */
12742     protected final void onDrawScrollBars(Canvas canvas) {
12743         // scrollbars are drawn only when the animation is running
12744         final ScrollabilityCache cache = mScrollCache;
12745         if (cache != null) {
12746
12747             int state = cache.state;
12748
12749             if (state == ScrollabilityCache.OFF) {
12750                 return;
12751             }
12752
12753             boolean invalidate = false;
12754
12755             if (state == ScrollabilityCache.FADING) {
12756                 // We're fading -- get our fade interpolation
12757                 if (cache.interpolatorValues == null) {
12758                     cache.interpolatorValues = new float[1];
12759                 }
12760
12761                 float[] values = cache.interpolatorValues;
12762
12763                 // Stops the animation if we're done
12764                 if (cache.scrollBarInterpolator.timeToValues(values) ==
12765                         Interpolator.Result.FREEZE_END) {
12766                     cache.state = ScrollabilityCache.OFF;
12767                 } else {
12768                     cache.scrollBar.setAlpha(Math.round(values[0]));
12769                 }
12770
12771                 // This will make the scroll bars inval themselves after
12772                 // drawing. We only want this when we're fading so that
12773                 // we prevent excessive redraws
12774                 invalidate = true;
12775             } else {
12776                 // We're just on -- but we may have been fading before so
12777                 // reset alpha
12778                 cache.scrollBar.setAlpha(255);
12779             }
12780
12781
12782             final int viewFlags = mViewFlags;
12783
12784             final boolean drawHorizontalScrollBar =
12785                 (viewFlags & SCROLLBARS_HORIZONTAL) == SCROLLBARS_HORIZONTAL;
12786             final boolean drawVerticalScrollBar =
12787                 (viewFlags & SCROLLBARS_VERTICAL) == SCROLLBARS_VERTICAL
12788                 && !isVerticalScrollBarHidden();
12789
12790             if (drawVerticalScrollBar || drawHorizontalScrollBar) {
12791                 final int width = mRight - mLeft;
12792                 final int height = mBottom - mTop;
12793
12794                 final ScrollBarDrawable scrollBar = cache.scrollBar;
12795
12796                 final int scrollX = mScrollX;
12797                 final int scrollY = mScrollY;
12798                 final int inside = (viewFlags & SCROLLBARS_OUTSIDE_MASK) == 0 ? ~0 : 0;
12799
12800                 int left;
12801                 int top;
12802                 int right;
12803                 int bottom;
12804
12805                 if (drawHorizontalScrollBar) {
12806                     int size = scrollBar.getSize(false);
12807                     if (size <= 0) {
12808                         size = cache.scrollBarSize;
12809                     }
12810
12811                     scrollBar.setParameters(computeHorizontalScrollRange(),
12812                                             computeHorizontalScrollOffset(),
12813                                             computeHorizontalScrollExtent(), false);
12814                     final int verticalScrollBarGap = drawVerticalScrollBar ?
12815                             getVerticalScrollbarWidth() : 0;
12816                     top = scrollY + height - size - (mUserPaddingBottom & inside);
12817                     left = scrollX + (mPaddingLeft & inside);
12818                     right = scrollX + width - (mUserPaddingRight & inside) - verticalScrollBarGap;
12819                     bottom = top + size;
12820                     onDrawHorizontalScrollBar(canvas, scrollBar, left, top, right, bottom);
12821                     if (invalidate) {
12822                         invalidate(left, top, right, bottom);
12823                     }
12824                 }
12825
12826                 if (drawVerticalScrollBar) {
12827                     int size = scrollBar.getSize(true);
12828                     if (size <= 0) {
12829                         size = cache.scrollBarSize;
12830                     }
12831
12832                     scrollBar.setParameters(computeVerticalScrollRange(),
12833                                             computeVerticalScrollOffset(),
12834                                             computeVerticalScrollExtent(), true);
12835                     int verticalScrollbarPosition = mVerticalScrollbarPosition;
12836                     if (verticalScrollbarPosition == SCROLLBAR_POSITION_DEFAULT) {
12837                         verticalScrollbarPosition = isLayoutRtl() ?
12838                                 SCROLLBAR_POSITION_LEFT : SCROLLBAR_POSITION_RIGHT;
12839                     }
12840                     switch (verticalScrollbarPosition) {
12841                         default:
12842                         case SCROLLBAR_POSITION_RIGHT:
12843                             left = scrollX + width - size - (mUserPaddingRight & inside);
12844                             break;
12845                         case SCROLLBAR_POSITION_LEFT:
12846                             left = scrollX + (mUserPaddingLeft & inside);
12847                             break;
12848                     }
12849                     top = scrollY + (mPaddingTop & inside);
12850                     right = left + size;
12851                     bottom = scrollY + height - (mUserPaddingBottom & inside);
12852                     onDrawVerticalScrollBar(canvas, scrollBar, left, top, right, bottom);
12853                     if (invalidate) {
12854                         invalidate(left, top, right, bottom);
12855                     }
12856                 }
12857             }
12858         }
12859     }
12860
12861     /**
12862      * Override this if the vertical scrollbar needs to be hidden in a subclass, like when
12863      * FastScroller is visible.
12864      * @return whether to temporarily hide the vertical scrollbar
12865      * @hide
12866      */
12867     protected boolean isVerticalScrollBarHidden() {
12868         return false;
12869     }
12870
12871     /**
12872      * <p>Draw the horizontal scrollbar if
12873      * {@link #isHorizontalScrollBarEnabled()} returns true.</p>
12874      *
12875      * @param canvas the canvas on which to draw the scrollbar
12876      * @param scrollBar the scrollbar's drawable
12877      *
12878      * @see #isHorizontalScrollBarEnabled()
12879      * @see #computeHorizontalScrollRange()
12880      * @see #computeHorizontalScrollExtent()
12881      * @see #computeHorizontalScrollOffset()
12882      * @see android.widget.ScrollBarDrawable
12883      * @hide
12884      */
12885     protected void onDrawHorizontalScrollBar(Canvas canvas, Drawable scrollBar,
12886             int l, int t, int r, int b) {
12887         scrollBar.setBounds(l, t, r, b);
12888         scrollBar.draw(canvas);
12889     }
12890
12891     /**
12892      * <p>Draw the vertical scrollbar if {@link #isVerticalScrollBarEnabled()}
12893      * returns true.</p>
12894      *
12895      * @param canvas the canvas on which to draw the scrollbar
12896      * @param scrollBar the scrollbar's drawable
12897      *
12898      * @see #isVerticalScrollBarEnabled()
12899      * @see #computeVerticalScrollRange()
12900      * @see #computeVerticalScrollExtent()
12901      * @see #computeVerticalScrollOffset()
12902      * @see android.widget.ScrollBarDrawable
12903      * @hide
12904      */
12905     protected void onDrawVerticalScrollBar(Canvas canvas, Drawable scrollBar,
12906             int l, int t, int r, int b) {
12907         scrollBar.setBounds(l, t, r, b);
12908         scrollBar.draw(canvas);
12909     }
12910
12911     /**
12912      * Implement this to do your drawing.
12913      *
12914      * @param canvas the canvas on which the background will be drawn
12915      */
12916     protected void onDraw(Canvas canvas) {
12917     }
12918
12919     /*
12920      * Caller is responsible for calling requestLayout if necessary.
12921      * (This allows addViewInLayout to not request a new layout.)
12922      */
12923     void assignParent(ViewParent parent) {
12924         if (mParent == null) {
12925             mParent = parent;
12926         } else if (parent == null) {
12927             mParent = null;
12928         } else {
12929             throw new RuntimeException("view " + this + " being added, but"
12930                     + " it already has a parent");
12931         }
12932     }
12933
12934     /**
12935      * This is called when the view is attached to a window.  At this point it
12936      * has a Surface and will start drawing.  Note that this function is
12937      * guaranteed to be called before {@link #onDraw(android.graphics.Canvas)},
12938      * however it may be called any time before the first onDraw -- including
12939      * before or after {@link #onMeasure(int, int)}.
12940      *
12941      * @see #onDetachedFromWindow()
12942      */
12943     protected void onAttachedToWindow() {
12944         if ((mPrivateFlags & PFLAG_REQUEST_TRANSPARENT_REGIONS) != 0) {
12945             mParent.requestTransparentRegion(this);
12946         }
12947
12948         if ((mPrivateFlags & PFLAG_AWAKEN_SCROLL_BARS_ON_ATTACH) != 0) {
12949             initialAwakenScrollBars();
12950             mPrivateFlags &= ~PFLAG_AWAKEN_SCROLL_BARS_ON_ATTACH;
12951         }
12952
12953         mPrivateFlags3 &= ~PFLAG3_IS_LAID_OUT;
12954
12955         jumpDrawablesToCurrentState();
12956
12957         resetSubtreeAccessibilityStateChanged();
12958
12959         // rebuild, since Outline not maintained while View is detached
12960         rebuildOutline();
12961
12962         if (isFocused()) {
12963             InputMethodManager imm = InputMethodManager.peekInstance();
12964             imm.focusIn(this);
12965         }
12966     }
12967
12968     /**
12969      * Resolve all RTL related properties.
12970      *
12971      * @return true if resolution of RTL properties has been done
12972      *
12973      * @hide
12974      */
12975     public boolean resolveRtlPropertiesIfNeeded() {
12976         if (!needRtlPropertiesResolution()) return false;
12977
12978         // Order is important here: LayoutDirection MUST be resolved first
12979         if (!isLayoutDirectionResolved()) {
12980             resolveLayoutDirection();
12981             resolveLayoutParams();
12982         }
12983         // ... then we can resolve the others properties depending on the resolved LayoutDirection.
12984         if (!isTextDirectionResolved()) {
12985             resolveTextDirection();
12986         }
12987         if (!isTextAlignmentResolved()) {
12988             resolveTextAlignment();
12989         }
12990         // Should resolve Drawables before Padding because we need the layout direction of the
12991         // Drawable to correctly resolve Padding.
12992         if (!isDrawablesResolved()) {
12993             resolveDrawables();
12994         }
12995         if (!isPaddingResolved()) {
12996             resolvePadding();
12997         }
12998         onRtlPropertiesChanged(getLayoutDirection());
12999         return true;
13000     }
13001
13002     /**
13003      * Reset resolution of all RTL related properties.
13004      *
13005      * @hide
13006      */
13007     public void resetRtlProperties() {
13008         resetResolvedLayoutDirection();
13009         resetResolvedTextDirection();
13010         resetResolvedTextAlignment();
13011         resetResolvedPadding();
13012         resetResolvedDrawables();
13013     }
13014
13015     /**
13016      * @see #onScreenStateChanged(int)
13017      */
13018     void dispatchScreenStateChanged(int screenState) {
13019         onScreenStateChanged(screenState);
13020     }
13021
13022     /**
13023      * This method is called whenever the state of the screen this view is
13024      * attached to changes. A state change will usually occurs when the screen
13025      * turns on or off (whether it happens automatically or the user does it
13026      * manually.)
13027      *
13028      * @param screenState The new state of the screen. Can be either
13029      *                    {@link #SCREEN_STATE_ON} or {@link #SCREEN_STATE_OFF}
13030      */
13031     public void onScreenStateChanged(int screenState) {
13032     }
13033
13034     /**
13035      * Return true if the application tag in the AndroidManifest has set "supportRtl" to true
13036      */
13037     private boolean hasRtlSupport() {
13038         return mContext.getApplicationInfo().hasRtlSupport();
13039     }
13040
13041     /**
13042      * Return true if we are in RTL compatibility mode (either before Jelly Bean MR1 or
13043      * RTL not supported)
13044      */
13045     private boolean isRtlCompatibilityMode() {
13046         final int targetSdkVersion = getContext().getApplicationInfo().targetSdkVersion;
13047         return targetSdkVersion < JELLY_BEAN_MR1 || !hasRtlSupport();
13048     }
13049
13050     /**
13051      * @return true if RTL properties need resolution.
13052      *
13053      */
13054     private boolean needRtlPropertiesResolution() {
13055         return (mPrivateFlags2 & ALL_RTL_PROPERTIES_RESOLVED) != ALL_RTL_PROPERTIES_RESOLVED;
13056     }
13057
13058     /**
13059      * Called when any RTL property (layout direction or text direction or text alignment) has
13060      * been changed.
13061      *
13062      * Subclasses need to override this method to take care of cached information that depends on the
13063      * resolved layout direction, or to inform child views that inherit their layout direction.
13064      *
13065      * The default implementation does nothing.
13066      *
13067      * @param layoutDirection the direction of the layout
13068      *
13069      * @see #LAYOUT_DIRECTION_LTR
13070      * @see #LAYOUT_DIRECTION_RTL
13071      */
13072     public void onRtlPropertiesChanged(@ResolvedLayoutDir int layoutDirection) {
13073     }
13074
13075     /**
13076      * Resolve and cache the layout direction. LTR is set initially. This is implicitly supposing
13077      * that the parent directionality can and will be resolved before its children.
13078      *
13079      * @return true if resolution has been done, false otherwise.
13080      *
13081      * @hide
13082      */
13083     public boolean resolveLayoutDirection() {
13084         // Clear any previous layout direction resolution
13085         mPrivateFlags2 &= ~PFLAG2_LAYOUT_DIRECTION_RESOLVED_MASK;
13086
13087         if (hasRtlSupport()) {
13088             // Set resolved depending on layout direction
13089             switch ((mPrivateFlags2 & PFLAG2_LAYOUT_DIRECTION_MASK) >>
13090                     PFLAG2_LAYOUT_DIRECTION_MASK_SHIFT) {
13091                 case LAYOUT_DIRECTION_INHERIT:
13092                     // We cannot resolve yet. LTR is by default and let the resolution happen again
13093                     // later to get the correct resolved value
13094                     if (!canResolveLayoutDirection()) return false;
13095
13096                     // Parent has not yet resolved, LTR is still the default
13097                     try {
13098                         if (!mParent.isLayoutDirectionResolved()) return false;
13099
13100                         if (mParent.getLayoutDirection() == LAYOUT_DIRECTION_RTL) {
13101                             mPrivateFlags2 |= PFLAG2_LAYOUT_DIRECTION_RESOLVED_RTL;
13102                         }
13103                     } catch (AbstractMethodError e) {
13104                         Log.e(VIEW_LOG_TAG, mParent.getClass().getSimpleName() +
13105                                 " does not fully implement ViewParent", e);
13106                     }
13107                     break;
13108                 case LAYOUT_DIRECTION_RTL:
13109                     mPrivateFlags2 |= PFLAG2_LAYOUT_DIRECTION_RESOLVED_RTL;
13110                     break;
13111                 case LAYOUT_DIRECTION_LOCALE:
13112                     if((LAYOUT_DIRECTION_RTL ==
13113                             TextUtils.getLayoutDirectionFromLocale(Locale.getDefault()))) {
13114                         mPrivateFlags2 |= PFLAG2_LAYOUT_DIRECTION_RESOLVED_RTL;
13115                     }
13116                     break;
13117                 default:
13118                     // Nothing to do, LTR by default
13119             }
13120         }
13121
13122         // Set to resolved
13123         mPrivateFlags2 |= PFLAG2_LAYOUT_DIRECTION_RESOLVED;
13124         return true;
13125     }
13126
13127     /**
13128      * Check if layout direction resolution can be done.
13129      *
13130      * @return true if layout direction resolution can be done otherwise return false.
13131      */
13132     public boolean canResolveLayoutDirection() {
13133         switch (getRawLayoutDirection()) {
13134             case LAYOUT_DIRECTION_INHERIT:
13135                 if (mParent != null) {
13136                     try {
13137                         return mParent.canResolveLayoutDirection();
13138                     } catch (AbstractMethodError e) {
13139                         Log.e(VIEW_LOG_TAG, mParent.getClass().getSimpleName() +
13140                                 " does not fully implement ViewParent", e);
13141                     }
13142                 }
13143                 return false;
13144
13145             default:
13146                 return true;
13147         }
13148     }
13149
13150     /**
13151      * Reset the resolved layout direction. Layout direction will be resolved during a call to
13152      * {@link #onMeasure(int, int)}.
13153      *
13154      * @hide
13155      */
13156     public void resetResolvedLayoutDirection() {
13157         // Reset the current resolved bits
13158         mPrivateFlags2 &= ~PFLAG2_LAYOUT_DIRECTION_RESOLVED_MASK;
13159     }
13160
13161     /**
13162      * @return true if the layout direction is inherited.
13163      *
13164      * @hide
13165      */
13166     public boolean isLayoutDirectionInherited() {
13167         return (getRawLayoutDirection() == LAYOUT_DIRECTION_INHERIT);
13168     }
13169
13170     /**
13171      * @return true if layout direction has been resolved.
13172      */
13173     public boolean isLayoutDirectionResolved() {
13174         return (mPrivateFlags2 & PFLAG2_LAYOUT_DIRECTION_RESOLVED) == PFLAG2_LAYOUT_DIRECTION_RESOLVED;
13175     }
13176
13177     /**
13178      * Return if padding has been resolved
13179      *
13180      * @hide
13181      */
13182     boolean isPaddingResolved() {
13183         return (mPrivateFlags2 & PFLAG2_PADDING_RESOLVED) == PFLAG2_PADDING_RESOLVED;
13184     }
13185
13186     /**
13187      * Resolves padding depending on layout direction, if applicable, and
13188      * recomputes internal padding values to adjust for scroll bars.
13189      *
13190      * @hide
13191      */
13192     public void resolvePadding() {
13193         final int resolvedLayoutDirection = getLayoutDirection();
13194
13195         if (!isRtlCompatibilityMode()) {
13196             // Post Jelly Bean MR1 case: we need to take the resolved layout direction into account.
13197             // If start / end padding are defined, they will be resolved (hence overriding) to
13198             // left / right or right / left depending on the resolved layout direction.
13199             // If start / end padding are not defined, use the left / right ones.
13200             if (mBackground != null && (!mLeftPaddingDefined || !mRightPaddingDefined)) {
13201                 Rect padding = sThreadLocal.get();
13202                 if (padding == null) {
13203                     padding = new Rect();
13204                     sThreadLocal.set(padding);
13205                 }
13206                 mBackground.getPadding(padding);
13207                 if (!mLeftPaddingDefined) {
13208                     mUserPaddingLeftInitial = padding.left;
13209                 }
13210                 if (!mRightPaddingDefined) {
13211                     mUserPaddingRightInitial = padding.right;
13212                 }
13213             }
13214             switch (resolvedLayoutDirection) {
13215                 case LAYOUT_DIRECTION_RTL:
13216                     if (mUserPaddingStart != UNDEFINED_PADDING) {
13217                         mUserPaddingRight = mUserPaddingStart;
13218                     } else {
13219                         mUserPaddingRight = mUserPaddingRightInitial;
13220                     }
13221                     if (mUserPaddingEnd != UNDEFINED_PADDING) {
13222                         mUserPaddingLeft = mUserPaddingEnd;
13223                     } else {
13224                         mUserPaddingLeft = mUserPaddingLeftInitial;
13225                     }
13226                     break;
13227                 case LAYOUT_DIRECTION_LTR:
13228                 default:
13229                     if (mUserPaddingStart != UNDEFINED_PADDING) {
13230                         mUserPaddingLeft = mUserPaddingStart;
13231                     } else {
13232                         mUserPaddingLeft = mUserPaddingLeftInitial;
13233                     }
13234                     if (mUserPaddingEnd != UNDEFINED_PADDING) {
13235                         mUserPaddingRight = mUserPaddingEnd;
13236                     } else {
13237                         mUserPaddingRight = mUserPaddingRightInitial;
13238                     }
13239             }
13240
13241             mUserPaddingBottom = (mUserPaddingBottom >= 0) ? mUserPaddingBottom : mPaddingBottom;
13242         }
13243
13244         internalSetPadding(mUserPaddingLeft, mPaddingTop, mUserPaddingRight, mUserPaddingBottom);
13245         onRtlPropertiesChanged(resolvedLayoutDirection);
13246
13247         mPrivateFlags2 |= PFLAG2_PADDING_RESOLVED;
13248     }
13249
13250     /**
13251      * Reset the resolved layout direction.
13252      *
13253      * @hide
13254      */
13255     public void resetResolvedPadding() {
13256         mPrivateFlags2 &= ~PFLAG2_PADDING_RESOLVED;
13257     }
13258
13259     /**
13260      * This is called when the view is detached from a window.  At this point it
13261      * no longer has a surface for drawing.
13262      *
13263      * @see #onAttachedToWindow()
13264      */
13265     protected void onDetachedFromWindow() {
13266     }
13267
13268     /**
13269      * This is a framework-internal mirror of onDetachedFromWindow() that's called
13270      * after onDetachedFromWindow().
13271      *
13272      * If you override this you *MUST* call super.onDetachedFromWindowInternal()!
13273      * The super method should be called at the end of the overriden method to ensure
13274      * subclasses are destroyed first
13275      *
13276      * @hide
13277      */
13278     protected void onDetachedFromWindowInternal() {
13279         mPrivateFlags &= ~PFLAG_CANCEL_NEXT_UP_EVENT;
13280         mPrivateFlags3 &= ~PFLAG3_IS_LAID_OUT;
13281
13282         removeUnsetPressCallback();
13283         removeLongPressCallback();
13284         removePerformClickCallback();
13285         removeSendViewScrolledAccessibilityEventCallback();
13286         stopNestedScroll();
13287
13288         // Anything that started animating right before detach should already
13289         // be in its final state when re-attached.
13290         jumpDrawablesToCurrentState();
13291
13292         destroyDrawingCache();
13293
13294         cleanupDraw();
13295         mCurrentAnimation = null;
13296     }
13297
13298     private void cleanupDraw() {
13299         resetDisplayList();
13300         if (mAttachInfo != null) {
13301             mAttachInfo.mViewRootImpl.cancelInvalidate(this);
13302         }
13303     }
13304
13305     void invalidateInheritedLayoutMode(int layoutModeOfRoot) {
13306     }
13307
13308     /**
13309      * @return The number of times this view has been attached to a window
13310      */
13311     protected int getWindowAttachCount() {
13312         return mWindowAttachCount;
13313     }
13314
13315     /**
13316      * Retrieve a unique token identifying the window this view is attached to.
13317      * @return Return the window's token for use in
13318      * {@link WindowManager.LayoutParams#token WindowManager.LayoutParams.token}.
13319      */
13320     public IBinder getWindowToken() {
13321         return mAttachInfo != null ? mAttachInfo.mWindowToken : null;
13322     }
13323
13324     /**
13325      * Retrieve the {@link WindowId} for the window this view is
13326      * currently attached to.
13327      */
13328     public WindowId getWindowId() {
13329         if (mAttachInfo == null) {
13330             return null;
13331         }
13332         if (mAttachInfo.mWindowId == null) {
13333             try {
13334                 mAttachInfo.mIWindowId = mAttachInfo.mSession.getWindowId(
13335                         mAttachInfo.mWindowToken);
13336                 mAttachInfo.mWindowId = new WindowId(
13337                         mAttachInfo.mIWindowId);
13338             } catch (RemoteException e) {
13339             }
13340         }
13341         return mAttachInfo.mWindowId;
13342     }
13343
13344     /**
13345      * Retrieve a unique token identifying the top-level "real" window of
13346      * the window that this view is attached to.  That is, this is like
13347      * {@link #getWindowToken}, except if the window this view in is a panel
13348      * window (attached to another containing window), then the token of
13349      * the containing window is returned instead.
13350      *
13351      * @return Returns the associated window token, either
13352      * {@link #getWindowToken()} or the containing window's token.
13353      */
13354     public IBinder getApplicationWindowToken() {
13355         AttachInfo ai = mAttachInfo;
13356         if (ai != null) {
13357             IBinder appWindowToken = ai.mPanelParentWindowToken;
13358             if (appWindowToken == null) {
13359                 appWindowToken = ai.mWindowToken;
13360             }
13361             return appWindowToken;
13362         }
13363         return null;
13364     }
13365
13366     /**
13367      * Gets the logical display to which the view's window has been attached.
13368      *
13369      * @return The logical display, or null if the view is not currently attached to a window.
13370      */
13371     public Display getDisplay() {
13372         return mAttachInfo != null ? mAttachInfo.mDisplay : null;
13373     }
13374
13375     /**
13376      * Retrieve private session object this view hierarchy is using to
13377      * communicate with the window manager.
13378      * @return the session object to communicate with the window manager
13379      */
13380     /*package*/ IWindowSession getWindowSession() {
13381         return mAttachInfo != null ? mAttachInfo.mSession : null;
13382     }
13383
13384     /**
13385      * @param info the {@link android.view.View.AttachInfo} to associated with
13386      *        this view
13387      */
13388     void dispatchAttachedToWindow(AttachInfo info, int visibility) {
13389         //System.out.println("Attached! " + this);
13390         mAttachInfo = info;
13391         if (mOverlay != null) {
13392             mOverlay.getOverlayView().dispatchAttachedToWindow(info, visibility);
13393         }
13394         mWindowAttachCount++;
13395         // We will need to evaluate the drawable state at least once.
13396         mPrivateFlags |= PFLAG_DRAWABLE_STATE_DIRTY;
13397         if (mFloatingTreeObserver != null) {
13398             info.mTreeObserver.merge(mFloatingTreeObserver);
13399             mFloatingTreeObserver = null;
13400         }
13401         if ((mPrivateFlags&PFLAG_SCROLL_CONTAINER) != 0) {
13402             mAttachInfo.mScrollContainers.add(this);
13403             mPrivateFlags |= PFLAG_SCROLL_CONTAINER_ADDED;
13404         }
13405         performCollectViewAttributes(mAttachInfo, visibility);
13406         onAttachedToWindow();
13407
13408         ListenerInfo li = mListenerInfo;
13409         final CopyOnWriteArrayList<OnAttachStateChangeListener> listeners =
13410                 li != null ? li.mOnAttachStateChangeListeners : null;
13411         if (listeners != null && listeners.size() > 0) {
13412             // NOTE: because of the use of CopyOnWriteArrayList, we *must* use an iterator to
13413             // perform the dispatching. The iterator is a safe guard against listeners that
13414             // could mutate the list by calling the various add/remove methods. This prevents
13415             // the array from being modified while we iterate it.
13416             for (OnAttachStateChangeListener listener : listeners) {
13417                 listener.onViewAttachedToWindow(this);
13418             }
13419         }
13420
13421         int vis = info.mWindowVisibility;
13422         if (vis != GONE) {
13423             onWindowVisibilityChanged(vis);
13424         }
13425         if ((mPrivateFlags&PFLAG_DRAWABLE_STATE_DIRTY) != 0) {
13426             // If nobody has evaluated the drawable state yet, then do it now.
13427             refreshDrawableState();
13428         }
13429         needGlobalAttributesUpdate(false);
13430     }
13431
13432     void dispatchDetachedFromWindow() {
13433         AttachInfo info = mAttachInfo;
13434         if (info != null) {
13435             int vis = info.mWindowVisibility;
13436             if (vis != GONE) {
13437                 onWindowVisibilityChanged(GONE);
13438             }
13439         }
13440
13441         onDetachedFromWindow();
13442         onDetachedFromWindowInternal();
13443
13444         ListenerInfo li = mListenerInfo;
13445         final CopyOnWriteArrayList<OnAttachStateChangeListener> listeners =
13446                 li != null ? li.mOnAttachStateChangeListeners : null;
13447         if (listeners != null && listeners.size() > 0) {
13448             // NOTE: because of the use of CopyOnWriteArrayList, we *must* use an iterator to
13449             // perform the dispatching. The iterator is a safe guard against listeners that
13450             // could mutate the list by calling the various add/remove methods. This prevents
13451             // the array from being modified while we iterate it.
13452             for (OnAttachStateChangeListener listener : listeners) {
13453                 listener.onViewDetachedFromWindow(this);
13454             }
13455         }
13456
13457         if ((mPrivateFlags & PFLAG_SCROLL_CONTAINER_ADDED) != 0) {
13458             mAttachInfo.mScrollContainers.remove(this);
13459             mPrivateFlags &= ~PFLAG_SCROLL_CONTAINER_ADDED;
13460         }
13461
13462         mAttachInfo = null;
13463         if (mOverlay != null) {
13464             mOverlay.getOverlayView().dispatchDetachedFromWindow();
13465         }
13466     }
13467
13468     /**
13469      * Cancel any deferred high-level input events that were previously posted to the event queue.
13470      *
13471      * <p>Many views post high-level events such as click handlers to the event queue
13472      * to run deferred in order to preserve a desired user experience - clearing visible
13473      * pressed states before executing, etc. This method will abort any events of this nature
13474      * that are currently in flight.</p>
13475      *
13476      * <p>Custom views that generate their own high-level deferred input events should override
13477      * {@link #onCancelPendingInputEvents()} and remove those pending events from the queue.</p>
13478      *
13479      * <p>This will also cancel pending input events for any child views.</p>
13480      *
13481      * <p>Note that this may not be sufficient as a debouncing strategy for clicks in all cases.
13482      * This will not impact newer events posted after this call that may occur as a result of
13483      * lower-level input events still waiting in the queue. If you are trying to prevent
13484      * double-submitted  events for the duration of some sort of asynchronous transaction
13485      * you should also take other steps to protect against unexpected double inputs e.g. calling
13486      * {@link #setEnabled(boolean) setEnabled(false)} and re-enabling the view when
13487      * the transaction completes, tracking already submitted transaction IDs, etc.</p>
13488      */
13489     public final void cancelPendingInputEvents() {
13490         dispatchCancelPendingInputEvents();
13491     }
13492
13493     /**
13494      * Called by {@link #cancelPendingInputEvents()} to cancel input events in flight.
13495      * Overridden by ViewGroup to dispatch. Package scoped to prevent app-side meddling.
13496      */
13497     void dispatchCancelPendingInputEvents() {
13498         mPrivateFlags3 &= ~PFLAG3_CALLED_SUPER;
13499         onCancelPendingInputEvents();
13500         if ((mPrivateFlags3 & PFLAG3_CALLED_SUPER) != PFLAG3_CALLED_SUPER) {
13501             throw new SuperNotCalledException("View " + getClass().getSimpleName() +
13502                     " did not call through to super.onCancelPendingInputEvents()");
13503         }
13504     }
13505
13506     /**
13507      * Called as the result of a call to {@link #cancelPendingInputEvents()} on this view or
13508      * a parent view.
13509      *
13510      * <p>This method is responsible for removing any pending high-level input events that were
13511      * posted to the event queue to run later. Custom view classes that post their own deferred
13512      * high-level events via {@link #post(Runnable)}, {@link #postDelayed(Runnable, long)} or
13513      * {@link android.os.Handler} should override this method, call
13514      * <code>super.onCancelPendingInputEvents()</code> and remove those callbacks as appropriate.
13515      * </p>
13516      */
13517     public void onCancelPendingInputEvents() {
13518         removePerformClickCallback();
13519         cancelLongPress();
13520         mPrivateFlags3 |= PFLAG3_CALLED_SUPER;
13521     }
13522
13523     /**
13524      * Store this view hierarchy's frozen state into the given container.
13525      *
13526      * @param container The SparseArray in which to save the view's state.
13527      *
13528      * @see #restoreHierarchyState(android.util.SparseArray)
13529      * @see #dispatchSaveInstanceState(android.util.SparseArray)
13530      * @see #onSaveInstanceState()
13531      */
13532     public void saveHierarchyState(SparseArray<Parcelable> container) {
13533         dispatchSaveInstanceState(container);
13534     }
13535
13536     /**
13537      * Called by {@link #saveHierarchyState(android.util.SparseArray)} to store the state for
13538      * this view and its children. May be overridden to modify how freezing happens to a
13539      * view's children; for example, some views may want to not store state for their children.
13540      *
13541      * @param container The SparseArray in which to save the view's state.
13542      *
13543      * @see #dispatchRestoreInstanceState(android.util.SparseArray)
13544      * @see #saveHierarchyState(android.util.SparseArray)
13545      * @see #onSaveInstanceState()
13546      */
13547     protected void dispatchSaveInstanceState(SparseArray<Parcelable> container) {
13548         if (mID != NO_ID && (mViewFlags & SAVE_DISABLED_MASK) == 0) {
13549             mPrivateFlags &= ~PFLAG_SAVE_STATE_CALLED;
13550             Parcelable state = onSaveInstanceState();
13551             if ((mPrivateFlags & PFLAG_SAVE_STATE_CALLED) == 0) {
13552                 throw new IllegalStateException(
13553                         "Derived class did not call super.onSaveInstanceState()");
13554             }
13555             if (state != null) {
13556                 // Log.i("View", "Freezing #" + Integer.toHexString(mID)
13557                 // + ": " + state);
13558                 container.put(mID, state);
13559             }
13560         }
13561     }
13562
13563     /**
13564      * Hook allowing a view to generate a representation of its internal state
13565      * that can later be used to create a new instance with that same state.
13566      * This state should only contain information that is not persistent or can
13567      * not be reconstructed later. For example, you will never store your
13568      * current position on screen because that will be computed again when a
13569      * new instance of the view is placed in its view hierarchy.
13570      * <p>
13571      * Some examples of things you may store here: the current cursor position
13572      * in a text view (but usually not the text itself since that is stored in a
13573      * content provider or other persistent storage), the currently selected
13574      * item in a list view.
13575      *
13576      * @return Returns a Parcelable object containing the view's current dynamic
13577      *         state, or null if there is nothing interesting to save. The
13578      *         default implementation returns null.
13579      * @see #onRestoreInstanceState(android.os.Parcelable)
13580      * @see #saveHierarchyState(android.util.SparseArray)
13581      * @see #dispatchSaveInstanceState(android.util.SparseArray)
13582      * @see #setSaveEnabled(boolean)
13583      */
13584     protected Parcelable onSaveInstanceState() {
13585         mPrivateFlags |= PFLAG_SAVE_STATE_CALLED;
13586         return BaseSavedState.EMPTY_STATE;
13587     }
13588
13589     /**
13590      * Restore this view hierarchy's frozen state from the given container.
13591      *
13592      * @param container The SparseArray which holds previously frozen states.
13593      *
13594      * @see #saveHierarchyState(android.util.SparseArray)
13595      * @see #dispatchRestoreInstanceState(android.util.SparseArray)
13596      * @see #onRestoreInstanceState(android.os.Parcelable)
13597      */
13598     public void restoreHierarchyState(SparseArray<Parcelable> container) {
13599         dispatchRestoreInstanceState(container);
13600     }
13601
13602     /**
13603      * Called by {@link #restoreHierarchyState(android.util.SparseArray)} to retrieve the
13604      * state for this view and its children. May be overridden to modify how restoring
13605      * happens to a view's children; for example, some views may want to not store state
13606      * for their children.
13607      *
13608      * @param container The SparseArray which holds previously saved state.
13609      *
13610      * @see #dispatchSaveInstanceState(android.util.SparseArray)
13611      * @see #restoreHierarchyState(android.util.SparseArray)
13612      * @see #onRestoreInstanceState(android.os.Parcelable)
13613      */
13614     protected void dispatchRestoreInstanceState(SparseArray<Parcelable> container) {
13615         if (mID != NO_ID) {
13616             Parcelable state = container.get(mID);
13617             if (state != null) {
13618                 // Log.i("View", "Restoreing #" + Integer.toHexString(mID)
13619                 // + ": " + state);
13620                 mPrivateFlags &= ~PFLAG_SAVE_STATE_CALLED;
13621                 onRestoreInstanceState(state);
13622                 if ((mPrivateFlags & PFLAG_SAVE_STATE_CALLED) == 0) {
13623                     throw new IllegalStateException(
13624                             "Derived class did not call super.onRestoreInstanceState()");
13625                 }
13626             }
13627         }
13628     }
13629
13630     /**
13631      * Hook allowing a view to re-apply a representation of its internal state that had previously
13632      * been generated by {@link #onSaveInstanceState}. This function will never be called with a
13633      * null state.
13634      *
13635      * @param state The frozen state that had previously been returned by
13636      *        {@link #onSaveInstanceState}.
13637      *
13638      * @see #onSaveInstanceState()
13639      * @see #restoreHierarchyState(android.util.SparseArray)
13640      * @see #dispatchRestoreInstanceState(android.util.SparseArray)
13641      */
13642     protected void onRestoreInstanceState(Parcelable state) {
13643         mPrivateFlags |= PFLAG_SAVE_STATE_CALLED;
13644         if (state != BaseSavedState.EMPTY_STATE && state != null) {
13645             throw new IllegalArgumentException("Wrong state class, expecting View State but "
13646                     + "received " + state.getClass().toString() + " instead. This usually happens "
13647                     + "when two views of different type have the same id in the same hierarchy. "
13648                     + "This view's id is " + ViewDebug.resolveId(mContext, getId()) + ". Make sure "
13649                     + "other views do not use the same id.");
13650         }
13651     }
13652
13653     /**
13654      * <p>Return the time at which the drawing of the view hierarchy started.</p>
13655      *
13656      * @return the drawing start time in milliseconds
13657      */
13658     public long getDrawingTime() {
13659         return mAttachInfo != null ? mAttachInfo.mDrawingTime : 0;
13660     }
13661
13662     /**
13663      * <p>Enables or disables the duplication of the parent's state into this view. When
13664      * duplication is enabled, this view gets its drawable state from its parent rather
13665      * than from its own internal properties.</p>
13666      *
13667      * <p>Note: in the current implementation, setting this property to true after the
13668      * view was added to a ViewGroup might have no effect at all. This property should
13669      * always be used from XML or set to true before adding this view to a ViewGroup.</p>
13670      *
13671      * <p>Note: if this view's parent addStateFromChildren property is enabled and this
13672      * property is enabled, an exception will be thrown.</p>
13673      *
13674      * <p>Note: if the child view uses and updates additionnal states which are unknown to the
13675      * parent, these states should not be affected by this method.</p>
13676      *
13677      * @param enabled True to enable duplication of the parent's drawable state, false
13678      *                to disable it.
13679      *
13680      * @see #getDrawableState()
13681      * @see #isDuplicateParentStateEnabled()
13682      */
13683     public void setDuplicateParentStateEnabled(boolean enabled) {
13684         setFlags(enabled ? DUPLICATE_PARENT_STATE : 0, DUPLICATE_PARENT_STATE);
13685     }
13686
13687     /**
13688      * <p>Indicates whether this duplicates its drawable state from its parent.</p>
13689      *
13690      * @return True if this view's drawable state is duplicated from the parent,
13691      *         false otherwise
13692      *
13693      * @see #getDrawableState()
13694      * @see #setDuplicateParentStateEnabled(boolean)
13695      */
13696     public boolean isDuplicateParentStateEnabled() {
13697         return (mViewFlags & DUPLICATE_PARENT_STATE) == DUPLICATE_PARENT_STATE;
13698     }
13699
13700     /**
13701      * <p>Specifies the type of layer backing this view. The layer can be
13702      * {@link #LAYER_TYPE_NONE}, {@link #LAYER_TYPE_SOFTWARE} or
13703      * {@link #LAYER_TYPE_HARDWARE}.</p>
13704      *
13705      * <p>A layer is associated with an optional {@link android.graphics.Paint}
13706      * instance that controls how the layer is composed on screen. The following
13707      * properties of the paint are taken into account when composing the layer:</p>
13708      * <ul>
13709      * <li>{@link android.graphics.Paint#getAlpha() Translucency (alpha)}</li>
13710      * <li>{@link android.graphics.Paint#getXfermode() Blending mode}</li>
13711      * <li>{@link android.graphics.Paint#getColorFilter() Color filter}</li>
13712      * </ul>
13713      *
13714      * <p>If this view has an alpha value set to < 1.0 by calling
13715      * {@link #setAlpha(float)}, the alpha value of the layer's paint is superceded
13716      * by this view's alpha value.</p>
13717      *
13718      * <p>Refer to the documentation of {@link #LAYER_TYPE_NONE},
13719      * {@link #LAYER_TYPE_SOFTWARE} and {@link #LAYER_TYPE_HARDWARE}
13720      * for more information on when and how to use layers.</p>
13721      *
13722      * @param layerType The type of layer to use with this view, must be one of
13723      *        {@link #LAYER_TYPE_NONE}, {@link #LAYER_TYPE_SOFTWARE} or
13724      *        {@link #LAYER_TYPE_HARDWARE}
13725      * @param paint The paint used to compose the layer. This argument is optional
13726      *        and can be null. It is ignored when the layer type is
13727      *        {@link #LAYER_TYPE_NONE}
13728      *
13729      * @see #getLayerType()
13730      * @see #LAYER_TYPE_NONE
13731      * @see #LAYER_TYPE_SOFTWARE
13732      * @see #LAYER_TYPE_HARDWARE
13733      * @see #setAlpha(float)
13734      *
13735      * @attr ref android.R.styleable#View_layerType
13736      */
13737     public void setLayerType(int layerType, Paint paint) {
13738         if (layerType < LAYER_TYPE_NONE || layerType > LAYER_TYPE_HARDWARE) {
13739             throw new IllegalArgumentException("Layer type can only be one of: LAYER_TYPE_NONE, "
13740                     + "LAYER_TYPE_SOFTWARE or LAYER_TYPE_HARDWARE");
13741         }
13742
13743         boolean typeChanged = mRenderNode.setLayerType(layerType);
13744
13745         if (!typeChanged) {
13746             setLayerPaint(paint);
13747             return;
13748         }
13749
13750         // Destroy any previous software drawing cache if needed
13751         if (mLayerType == LAYER_TYPE_SOFTWARE) {
13752             destroyDrawingCache();
13753         }
13754
13755         mLayerType = layerType;
13756         final boolean layerDisabled = (mLayerType == LAYER_TYPE_NONE);
13757         mLayerPaint = layerDisabled ? null : (paint == null ? new Paint() : paint);
13758         mRenderNode.setLayerPaint(mLayerPaint);
13759
13760         // draw() behaves differently if we are on a layer, so we need to
13761         // invalidate() here
13762         invalidateParentCaches();
13763         invalidate(true);
13764     }
13765
13766     /**
13767      * Updates the {@link Paint} object used with the current layer (used only if the current
13768      * layer type is not set to {@link #LAYER_TYPE_NONE}). Changed properties of the Paint
13769      * provided to {@link #setLayerType(int, android.graphics.Paint)} will be used the next time
13770      * the View is redrawn, but {@link #setLayerPaint(android.graphics.Paint)} must be called to
13771      * ensure that the view gets redrawn immediately.
13772      *
13773      * <p>A layer is associated with an optional {@link android.graphics.Paint}
13774      * instance that controls how the layer is composed on screen. The following
13775      * properties of the paint are taken into account when composing the layer:</p>
13776      * <ul>
13777      * <li>{@link android.graphics.Paint#getAlpha() Translucency (alpha)}</li>
13778      * <li>{@link android.graphics.Paint#getXfermode() Blending mode}</li>
13779      * <li>{@link android.graphics.Paint#getColorFilter() Color filter}</li>
13780      * </ul>
13781      *
13782      * <p>If this view has an alpha value set to < 1.0 by calling {@link #setAlpha(float)}, the
13783      * alpha value of the layer's paint is superceded by this view's alpha value.</p>
13784      *
13785      * @param paint The paint used to compose the layer. This argument is optional
13786      *        and can be null. It is ignored when the layer type is
13787      *        {@link #LAYER_TYPE_NONE}
13788      *
13789      * @see #setLayerType(int, android.graphics.Paint)
13790      */
13791     public void setLayerPaint(Paint paint) {
13792         int layerType = getLayerType();
13793         if (layerType != LAYER_TYPE_NONE) {
13794             mLayerPaint = paint == null ? new Paint() : paint;
13795             if (layerType == LAYER_TYPE_HARDWARE) {
13796                 if (mRenderNode.setLayerPaint(mLayerPaint)) {
13797                     invalidateViewProperty(false, false);
13798                 }
13799             } else {
13800                 invalidate();
13801             }
13802         }
13803     }
13804
13805     /**
13806      * Indicates whether this view has a static layer. A view with layer type
13807      * {@link #LAYER_TYPE_NONE} is a static layer. Other types of layers are
13808      * dynamic.
13809      */
13810     boolean hasStaticLayer() {
13811         return true;
13812     }
13813
13814     /**
13815      * Indicates what type of layer is currently associated with this view. By default
13816      * a view does not have a layer, and the layer type is {@link #LAYER_TYPE_NONE}.
13817      * Refer to the documentation of {@link #setLayerType(int, android.graphics.Paint)}
13818      * for more information on the different types of layers.
13819      *
13820      * @return {@link #LAYER_TYPE_NONE}, {@link #LAYER_TYPE_SOFTWARE} or
13821      *         {@link #LAYER_TYPE_HARDWARE}
13822      *
13823      * @see #setLayerType(int, android.graphics.Paint)
13824      * @see #buildLayer()
13825      * @see #LAYER_TYPE_NONE
13826      * @see #LAYER_TYPE_SOFTWARE
13827      * @see #LAYER_TYPE_HARDWARE
13828      */
13829     public int getLayerType() {
13830         return mLayerType;
13831     }
13832
13833     /**
13834      * Forces this view's layer to be created and this view to be rendered
13835      * into its layer. If this view's layer type is set to {@link #LAYER_TYPE_NONE},
13836      * invoking this method will have no effect.
13837      *
13838      * This method can for instance be used to render a view into its layer before
13839      * starting an animation. If this view is complex, rendering into the layer
13840      * before starting the animation will avoid skipping frames.
13841      *
13842      * @throws IllegalStateException If this view is not attached to a window
13843      *
13844      * @see #setLayerType(int, android.graphics.Paint)
13845      */
13846     public void buildLayer() {
13847         if (mLayerType == LAYER_TYPE_NONE) return;
13848
13849         final AttachInfo attachInfo = mAttachInfo;
13850         if (attachInfo == null) {
13851             throw new IllegalStateException("This view must be attached to a window first");
13852         }
13853
13854         if (getWidth() == 0 || getHeight() == 0) {
13855             return;
13856         }
13857
13858         switch (mLayerType) {
13859             case LAYER_TYPE_HARDWARE:
13860                 updateDisplayListIfDirty();
13861                 if (attachInfo.mHardwareRenderer != null && mRenderNode.isValid()) {
13862                     attachInfo.mHardwareRenderer.buildLayer(mRenderNode);
13863                 }
13864                 break;
13865             case LAYER_TYPE_SOFTWARE:
13866                 buildDrawingCache(true);
13867                 break;
13868         }
13869     }
13870
13871     /**
13872      * If this View draws with a HardwareLayer, returns it.
13873      * Otherwise returns null
13874      *
13875      * TODO: Only TextureView uses this, can we eliminate it?
13876      */
13877     HardwareLayer getHardwareLayer() {
13878         return null;
13879     }
13880
13881     /**
13882      * Destroys all hardware rendering resources. This method is invoked
13883      * when the system needs to reclaim resources. Upon execution of this
13884      * method, you should free any OpenGL resources created by the view.
13885      *
13886      * Note: you <strong>must</strong> call
13887      * <code>super.destroyHardwareResources()</code> when overriding
13888      * this method.
13889      *
13890      * @hide
13891      */
13892     protected void destroyHardwareResources() {
13893         // Although the Layer will be destroyed by RenderNode, we want to release
13894         // the staging display list, which is also a signal to RenderNode that it's
13895         // safe to free its copy of the display list as it knows that we will
13896         // push an updated DisplayList if we try to draw again
13897         resetDisplayList();
13898     }
13899
13900     /**
13901      * <p>Enables or disables the drawing cache. When the drawing cache is enabled, the next call
13902      * to {@link #getDrawingCache()} or {@link #buildDrawingCache()} will draw the view in a
13903      * bitmap. Calling {@link #draw(android.graphics.Canvas)} will not draw from the cache when
13904      * the cache is enabled. To benefit from the cache, you must request the drawing cache by
13905      * calling {@link #getDrawingCache()} and draw it on screen if the returned bitmap is not
13906      * null.</p>
13907      *
13908      * <p>Enabling the drawing cache is similar to
13909      * {@link #setLayerType(int, android.graphics.Paint) setting a layer} when hardware
13910      * acceleration is turned off. When hardware acceleration is turned on, enabling the
13911      * drawing cache has no effect on rendering because the system uses a different mechanism
13912      * for acceleration which ignores the flag. If you want to use a Bitmap for the view, even
13913      * when hardware acceleration is enabled, see {@link #setLayerType(int, android.graphics.Paint)}
13914      * for information on how to enable software and hardware layers.</p>
13915      *
13916      * <p>This API can be used to manually generate
13917      * a bitmap copy of this view, by setting the flag to <code>true</code> and calling
13918      * {@link #getDrawingCache()}.</p>
13919      *
13920      * @param enabled true to enable the drawing cache, false otherwise
13921      *
13922      * @see #isDrawingCacheEnabled()
13923      * @see #getDrawingCache()
13924      * @see #buildDrawingCache()
13925      * @see #setLayerType(int, android.graphics.Paint)
13926      */
13927     public void setDrawingCacheEnabled(boolean enabled) {
13928         mCachingFailed = false;
13929         setFlags(enabled ? DRAWING_CACHE_ENABLED : 0, DRAWING_CACHE_ENABLED);
13930     }
13931
13932     /**
13933      * <p>Indicates whether the drawing cache is enabled for this view.</p>
13934      *
13935      * @return true if the drawing cache is enabled
13936      *
13937      * @see #setDrawingCacheEnabled(boolean)
13938      * @see #getDrawingCache()
13939      */
13940     @ViewDebug.ExportedProperty(category = "drawing")
13941     public boolean isDrawingCacheEnabled() {
13942         return (mViewFlags & DRAWING_CACHE_ENABLED) == DRAWING_CACHE_ENABLED;
13943     }
13944
13945     /**
13946      * Debugging utility which recursively outputs the dirty state of a view and its
13947      * descendants.
13948      *
13949      * @hide
13950      */
13951     @SuppressWarnings({"UnusedDeclaration"})
13952     public void outputDirtyFlags(String indent, boolean clear, int clearMask) {
13953         Log.d("View", indent + this + "             DIRTY(" + (mPrivateFlags & View.PFLAG_DIRTY_MASK) +
13954                 ") DRAWN(" + (mPrivateFlags & PFLAG_DRAWN) + ")" + " CACHE_VALID(" +
13955                 (mPrivateFlags & View.PFLAG_DRAWING_CACHE_VALID) +
13956                 ") INVALIDATED(" + (mPrivateFlags & PFLAG_INVALIDATED) + ")");
13957         if (clear) {
13958             mPrivateFlags &= clearMask;
13959         }
13960         if (this instanceof ViewGroup) {
13961             ViewGroup parent = (ViewGroup) this;
13962             final int count = parent.getChildCount();
13963             for (int i = 0; i < count; i++) {
13964                 final View child = parent.getChildAt(i);
13965                 child.outputDirtyFlags(indent + "  ", clear, clearMask);
13966             }
13967         }
13968     }
13969
13970     /**
13971      * This method is used by ViewGroup to cause its children to restore or recreate their
13972      * display lists. It is called by getDisplayList() when the parent ViewGroup does not need
13973      * to recreate its own display list, which would happen if it went through the normal
13974      * draw/dispatchDraw mechanisms.
13975      *
13976      * @hide
13977      */
13978     protected void dispatchGetDisplayList() {}
13979
13980     /**
13981      * A view that is not attached or hardware accelerated cannot create a display list.
13982      * This method checks these conditions and returns the appropriate result.
13983      *
13984      * @return true if view has the ability to create a display list, false otherwise.
13985      *
13986      * @hide
13987      */
13988     public boolean canHaveDisplayList() {
13989         return !(mAttachInfo == null || mAttachInfo.mHardwareRenderer == null);
13990     }
13991
13992     private void updateDisplayListIfDirty() {
13993         final RenderNode renderNode = mRenderNode;
13994         if (!canHaveDisplayList()) {
13995             // can't populate RenderNode, don't try
13996             return;
13997         }
13998
13999         if ((mPrivateFlags & PFLAG_DRAWING_CACHE_VALID) == 0
14000                 || !renderNode.isValid()
14001                 || (mRecreateDisplayList)) {
14002             // Don't need to recreate the display list, just need to tell our
14003             // children to restore/recreate theirs
14004             if (renderNode.isValid()
14005                     && !mRecreateDisplayList) {
14006                 mPrivateFlags |= PFLAG_DRAWN | PFLAG_DRAWING_CACHE_VALID;
14007                 mPrivateFlags &= ~PFLAG_DIRTY_MASK;
14008                 dispatchGetDisplayList();
14009
14010                 return; // no work needed
14011             }
14012
14013             // If we got here, we're recreating it. Mark it as such to ensure that
14014             // we copy in child display lists into ours in drawChild()
14015             mRecreateDisplayList = true;
14016
14017             int width = mRight - mLeft;
14018             int height = mBottom - mTop;
14019             int layerType = getLayerType();
14020
14021             final HardwareCanvas canvas = renderNode.start(width, height);
14022             canvas.setHighContrastText(mAttachInfo.mHighContrastText);
14023
14024             try {
14025                 final HardwareLayer layer = getHardwareLayer();
14026                 if (layer != null && layer.isValid()) {
14027                     canvas.drawHardwareLayer(layer, 0, 0, mLayerPaint);
14028                 } else if (layerType == LAYER_TYPE_SOFTWARE) {
14029                     buildDrawingCache(true);
14030                     Bitmap cache = getDrawingCache(true);
14031                     if (cache != null) {
14032                         canvas.drawBitmap(cache, 0, 0, mLayerPaint);
14033                     }
14034                 } else {
14035                     computeScroll();
14036
14037                     canvas.translate(-mScrollX, -mScrollY);
14038                     mPrivateFlags |= PFLAG_DRAWN | PFLAG_DRAWING_CACHE_VALID;
14039                     mPrivateFlags &= ~PFLAG_DIRTY_MASK;
14040
14041                     // Fast path for layouts with no backgrounds
14042                     if ((mPrivateFlags & PFLAG_SKIP_DRAW) == PFLAG_SKIP_DRAW) {
14043                         dispatchDraw(canvas);
14044                         if (mOverlay != null && !mOverlay.isEmpty()) {
14045                             mOverlay.getOverlayView().draw(canvas);
14046                         }
14047                     } else {
14048                         draw(canvas);
14049                     }
14050                     drawAccessibilityFocus(canvas);
14051                 }
14052             } finally {
14053                 renderNode.end(canvas);
14054                 setDisplayListProperties(renderNode);
14055             }
14056         } else {
14057             mPrivateFlags |= PFLAG_DRAWN | PFLAG_DRAWING_CACHE_VALID;
14058             mPrivateFlags &= ~PFLAG_DIRTY_MASK;
14059         }
14060     }
14061
14062     /**
14063      * Returns a RenderNode with View draw content recorded, which can be
14064      * used to draw this view again without executing its draw method.
14065      *
14066      * @return A RenderNode ready to replay, or null if caching is not enabled.
14067      *
14068      * @hide
14069      */
14070     public RenderNode getDisplayList() {
14071         updateDisplayListIfDirty();
14072         return mRenderNode;
14073     }
14074
14075     private void resetDisplayList() {
14076         if (mRenderNode.isValid()) {
14077             mRenderNode.destroyDisplayListData();
14078         }
14079
14080         if (mBackgroundRenderNode != null && mBackgroundRenderNode.isValid()) {
14081             mBackgroundRenderNode.destroyDisplayListData();
14082         }
14083     }
14084
14085     /**
14086      * <p>Calling this method is equivalent to calling <code>getDrawingCache(false)</code>.</p>
14087      *
14088      * @return A non-scaled bitmap representing this view or null if cache is disabled.
14089      *
14090      * @see #getDrawingCache(boolean)
14091      */
14092     public Bitmap getDrawingCache() {
14093         return getDrawingCache(false);
14094     }
14095
14096     /**
14097      * <p>Returns the bitmap in which this view drawing is cached. The returned bitmap
14098      * is null when caching is disabled. If caching is enabled and the cache is not ready,
14099      * this method will create it. Calling {@link #draw(android.graphics.Canvas)} will not
14100      * draw from the cache when the cache is enabled. To benefit from the cache, you must
14101      * request the drawing cache by calling this method and draw it on screen if the
14102      * returned bitmap is not null.</p>
14103      *
14104      * <p>Note about auto scaling in compatibility mode: When auto scaling is not enabled,
14105      * this method will create a bitmap of the same size as this view. Because this bitmap
14106      * will be drawn scaled by the parent ViewGroup, the result on screen might show
14107      * scaling artifacts. To avoid such artifacts, you should call this method by setting
14108      * the auto scaling to true. Doing so, however, will generate a bitmap of a different
14109      * size than the view. This implies that your application must be able to handle this
14110      * size.</p>
14111      *
14112      * @param autoScale Indicates whether the generated bitmap should be scaled based on
14113      *        the current density of the screen when the application is in compatibility
14114      *        mode.
14115      *
14116      * @return A bitmap representing this view or null if cache is disabled.
14117      *
14118      * @see #setDrawingCacheEnabled(boolean)
14119      * @see #isDrawingCacheEnabled()
14120      * @see #buildDrawingCache(boolean)
14121      * @see #destroyDrawingCache()
14122      */
14123     public Bitmap getDrawingCache(boolean autoScale) {
14124         if ((mViewFlags & WILL_NOT_CACHE_DRAWING) == WILL_NOT_CACHE_DRAWING) {
14125             return null;
14126         }
14127         if ((mViewFlags & DRAWING_CACHE_ENABLED) == DRAWING_CACHE_ENABLED) {
14128             buildDrawingCache(autoScale);
14129         }
14130         return autoScale ? mDrawingCache : mUnscaledDrawingCache;
14131     }
14132
14133     /**
14134      * <p>Frees the resources used by the drawing cache. If you call
14135      * {@link #buildDrawingCache()} manually without calling
14136      * {@link #setDrawingCacheEnabled(boolean) setDrawingCacheEnabled(true)}, you
14137      * should cleanup the cache with this method afterwards.</p>
14138      *
14139      * @see #setDrawingCacheEnabled(boolean)
14140      * @see #buildDrawingCache()
14141      * @see #getDrawingCache()
14142      */
14143     public void destroyDrawingCache() {
14144         if (mDrawingCache != null) {
14145             mDrawingCache.recycle();
14146             mDrawingCache = null;
14147         }
14148         if (mUnscaledDrawingCache != null) {
14149             mUnscaledDrawingCache.recycle();
14150             mUnscaledDrawingCache = null;
14151         }
14152     }
14153
14154     /**
14155      * Setting a solid background color for the drawing cache's bitmaps will improve
14156      * performance and memory usage. Note, though that this should only be used if this
14157      * view will always be drawn on top of a solid color.
14158      *
14159      * @param color The background color to use for the drawing cache's bitmap
14160      *
14161      * @see #setDrawingCacheEnabled(boolean)
14162      * @see #buildDrawingCache()
14163      * @see #getDrawingCache()
14164      */
14165     public void setDrawingCacheBackgroundColor(int color) {
14166         if (color != mDrawingCacheBackgroundColor) {
14167             mDrawingCacheBackgroundColor = color;
14168             mPrivateFlags &= ~PFLAG_DRAWING_CACHE_VALID;
14169         }
14170     }
14171
14172     /**
14173      * @see #setDrawingCacheBackgroundColor(int)
14174      *
14175      * @return The background color to used for the drawing cache's bitmap
14176      */
14177     public int getDrawingCacheBackgroundColor() {
14178         return mDrawingCacheBackgroundColor;
14179     }
14180
14181     /**
14182      * <p>Calling this method is equivalent to calling <code>buildDrawingCache(false)</code>.</p>
14183      *
14184      * @see #buildDrawingCache(boolean)
14185      */
14186     public void buildDrawingCache() {
14187         buildDrawingCache(false);
14188     }
14189
14190     /**
14191      * <p>Forces the drawing cache to be built if the drawing cache is invalid.</p>
14192      *
14193      * <p>If you call {@link #buildDrawingCache()} manually without calling
14194      * {@link #setDrawingCacheEnabled(boolean) setDrawingCacheEnabled(true)}, you
14195      * should cleanup the cache by calling {@link #destroyDrawingCache()} afterwards.</p>
14196      *
14197      * <p>Note about auto scaling in compatibility mode: When auto scaling is not enabled,
14198      * this method will create a bitmap of the same size as this view. Because this bitmap
14199      * will be drawn scaled by the parent ViewGroup, the result on screen might show
14200      * scaling artifacts. To avoid such artifacts, you should call this method by setting
14201      * the auto scaling to true. Doing so, however, will generate a bitmap of a different
14202      * size than the view. This implies that your application must be able to handle this
14203      * size.</p>
14204      *
14205      * <p>You should avoid calling this method when hardware acceleration is enabled. If
14206      * you do not need the drawing cache bitmap, calling this method will increase memory
14207      * usage and cause the view to be rendered in software once, thus negatively impacting
14208      * performance.</p>
14209      *
14210      * @see #getDrawingCache()
14211      * @see #destroyDrawingCache()
14212      */
14213     public void buildDrawingCache(boolean autoScale) {
14214         if ((mPrivateFlags & PFLAG_DRAWING_CACHE_VALID) == 0 || (autoScale ?
14215                 mDrawingCache == null : mUnscaledDrawingCache == null)) {
14216             mCachingFailed = false;
14217
14218             int width = mRight - mLeft;
14219             int height = mBottom - mTop;
14220
14221             final AttachInfo attachInfo = mAttachInfo;
14222             final boolean scalingRequired = attachInfo != null && attachInfo.mScalingRequired;
14223
14224             if (autoScale && scalingRequired) {
14225                 width = (int) ((width * attachInfo.mApplicationScale) + 0.5f);
14226                 height = (int) ((height * attachInfo.mApplicationScale) + 0.5f);
14227             }
14228
14229             final int drawingCacheBackgroundColor = mDrawingCacheBackgroundColor;
14230             final boolean opaque = drawingCacheBackgroundColor != 0 || isOpaque();
14231             final boolean use32BitCache = attachInfo != null && attachInfo.mUse32BitDrawingCache;
14232
14233             final long projectedBitmapSize = width * height * (opaque && !use32BitCache ? 2 : 4);
14234             final long drawingCacheSize =
14235                     ViewConfiguration.get(mContext).getScaledMaximumDrawingCacheSize();
14236             if (width <= 0 || height <= 0 || projectedBitmapSize > drawingCacheSize) {
14237                 if (width > 0 && height > 0) {
14238                     Log.w(VIEW_LOG_TAG, "View too large to fit into drawing cache, needs "
14239                             + projectedBitmapSize + " bytes, only "
14240                             + drawingCacheSize + " available");
14241                 }
14242                 destroyDrawingCache();
14243                 mCachingFailed = true;
14244                 return;
14245             }
14246
14247             boolean clear = true;
14248             Bitmap bitmap = autoScale ? mDrawingCache : mUnscaledDrawingCache;
14249
14250             if (bitmap == null || bitmap.getWidth() != width || bitmap.getHeight() != height) {
14251                 Bitmap.Config quality;
14252                 if (!opaque) {
14253                     // Never pick ARGB_4444 because it looks awful
14254                     // Keep the DRAWING_CACHE_QUALITY_LOW flag just in case
14255                     switch (mViewFlags & DRAWING_CACHE_QUALITY_MASK) {
14256                         case DRAWING_CACHE_QUALITY_AUTO:
14257                         case DRAWING_CACHE_QUALITY_LOW:
14258                         case DRAWING_CACHE_QUALITY_HIGH:
14259                         default:
14260                             quality = Bitmap.Config.ARGB_8888;
14261                             break;
14262                     }
14263                 } else {
14264                     // Optimization for translucent windows
14265                     // If the window is translucent, use a 32 bits bitmap to benefit from memcpy()
14266                     quality = use32BitCache ? Bitmap.Config.ARGB_8888 : Bitmap.Config.RGB_565;
14267                 }
14268
14269                 // Try to cleanup memory
14270                 if (bitmap != null) bitmap.recycle();
14271
14272                 try {
14273                     bitmap = Bitmap.createBitmap(mResources.getDisplayMetrics(),
14274                             width, height, quality);
14275                     bitmap.setDensity(getResources().getDisplayMetrics().densityDpi);
14276                     if (autoScale) {
14277                         mDrawingCache = bitmap;
14278                     } else {
14279                         mUnscaledDrawingCache = bitmap;
14280                     }
14281                     if (opaque && use32BitCache) bitmap.setHasAlpha(false);
14282                 } catch (OutOfMemoryError e) {
14283                     // If there is not enough memory to create the bitmap cache, just
14284                     // ignore the issue as bitmap caches are not required to draw the
14285                     // view hierarchy
14286                     if (autoScale) {
14287                         mDrawingCache = null;
14288                     } else {
14289                         mUnscaledDrawingCache = null;
14290                     }
14291                     mCachingFailed = true;
14292                     return;
14293                 }
14294
14295                 clear = drawingCacheBackgroundColor != 0;
14296             }
14297
14298             Canvas canvas;
14299             if (attachInfo != null) {
14300                 canvas = attachInfo.mCanvas;
14301                 if (canvas == null) {
14302                     canvas = new Canvas();
14303                 }
14304                 canvas.setBitmap(bitmap);
14305                 // Temporarily clobber the cached Canvas in case one of our children
14306                 // is also using a drawing cache. Without this, the children would
14307                 // steal the canvas by attaching their own bitmap to it and bad, bad
14308                 // thing would happen (invisible views, corrupted drawings, etc.)
14309                 attachInfo.mCanvas = null;
14310             } else {
14311                 // This case should hopefully never or seldom happen
14312                 canvas = new Canvas(bitmap);
14313             }
14314
14315             if (clear) {
14316                 bitmap.eraseColor(drawingCacheBackgroundColor);
14317             }
14318
14319             computeScroll();
14320             final int restoreCount = canvas.save();
14321
14322             if (autoScale && scalingRequired) {
14323                 final float scale = attachInfo.mApplicationScale;
14324                 canvas.scale(scale, scale);
14325             }
14326
14327             canvas.translate(-mScrollX, -mScrollY);
14328
14329             mPrivateFlags |= PFLAG_DRAWN;
14330             if (mAttachInfo == null || !mAttachInfo.mHardwareAccelerated ||
14331                     mLayerType != LAYER_TYPE_NONE) {
14332                 mPrivateFlags |= PFLAG_DRAWING_CACHE_VALID;
14333             }
14334
14335             // Fast path for layouts with no backgrounds
14336             if ((mPrivateFlags & PFLAG_SKIP_DRAW) == PFLAG_SKIP_DRAW) {
14337                 mPrivateFlags &= ~PFLAG_DIRTY_MASK;
14338                 dispatchDraw(canvas);
14339                 if (mOverlay != null && !mOverlay.isEmpty()) {
14340                     mOverlay.getOverlayView().draw(canvas);
14341                 }
14342             } else {
14343                 draw(canvas);
14344             }
14345             drawAccessibilityFocus(canvas);
14346
14347             canvas.restoreToCount(restoreCount);
14348             canvas.setBitmap(null);
14349
14350             if (attachInfo != null) {
14351                 // Restore the cached Canvas for our siblings
14352                 attachInfo.mCanvas = canvas;
14353             }
14354         }
14355     }
14356
14357     /**
14358      * Create a snapshot of the view into a bitmap.  We should probably make
14359      * some form of this public, but should think about the API.
14360      */
14361     Bitmap createSnapshot(Bitmap.Config quality, int backgroundColor, boolean skipChildren) {
14362         int width = mRight - mLeft;
14363         int height = mBottom - mTop;
14364
14365         final AttachInfo attachInfo = mAttachInfo;
14366         final float scale = attachInfo != null ? attachInfo.mApplicationScale : 1.0f;
14367         width = (int) ((width * scale) + 0.5f);
14368         height = (int) ((height * scale) + 0.5f);
14369
14370         Bitmap bitmap = Bitmap.createBitmap(mResources.getDisplayMetrics(),
14371                 width > 0 ? width : 1, height > 0 ? height : 1, quality);
14372         if (bitmap == null) {
14373             throw new OutOfMemoryError();
14374         }
14375
14376         Resources resources = getResources();
14377         if (resources != null) {
14378             bitmap.setDensity(resources.getDisplayMetrics().densityDpi);
14379         }
14380
14381         Canvas canvas;
14382         if (attachInfo != null) {
14383             canvas = attachInfo.mCanvas;
14384             if (canvas == null) {
14385                 canvas = new Canvas();
14386             }
14387             canvas.setBitmap(bitmap);
14388             // Temporarily clobber the cached Canvas in case one of our children
14389             // is also using a drawing cache. Without this, the children would
14390             // steal the canvas by attaching their own bitmap to it and bad, bad
14391             // things would happen (invisible views, corrupted drawings, etc.)
14392             attachInfo.mCanvas = null;
14393         } else {
14394             // This case should hopefully never or seldom happen
14395             canvas = new Canvas(bitmap);
14396         }
14397
14398         if ((backgroundColor & 0xff000000) != 0) {
14399             bitmap.eraseColor(backgroundColor);
14400         }
14401
14402         computeScroll();
14403         final int restoreCount = canvas.save();
14404         canvas.scale(scale, scale);
14405         canvas.translate(-mScrollX, -mScrollY);
14406
14407         // Temporarily remove the dirty mask
14408         int flags = mPrivateFlags;
14409         mPrivateFlags &= ~PFLAG_DIRTY_MASK;
14410
14411         // Fast path for layouts with no backgrounds
14412         if ((mPrivateFlags & PFLAG_SKIP_DRAW) == PFLAG_SKIP_DRAW) {
14413             dispatchDraw(canvas);
14414             if (mOverlay != null && !mOverlay.isEmpty()) {
14415                 mOverlay.getOverlayView().draw(canvas);
14416             }
14417         } else {
14418             draw(canvas);
14419         }
14420         drawAccessibilityFocus(canvas);
14421
14422         mPrivateFlags = flags;
14423
14424         canvas.restoreToCount(restoreCount);
14425         canvas.setBitmap(null);
14426
14427         if (attachInfo != null) {
14428             // Restore the cached Canvas for our siblings
14429             attachInfo.mCanvas = canvas;
14430         }
14431
14432         return bitmap;
14433     }
14434
14435     /**
14436      * Indicates whether this View is currently in edit mode. A View is usually
14437      * in edit mode when displayed within a developer tool. For instance, if
14438      * this View is being drawn by a visual user interface builder, this method
14439      * should return true.
14440      *
14441      * Subclasses should check the return value of this method to provide
14442      * different behaviors if their normal behavior might interfere with the
14443      * host environment. For instance: the class spawns a thread in its
14444      * constructor, the drawing code relies on device-specific features, etc.
14445      *
14446      * This method is usually checked in the drawing code of custom widgets.
14447      *
14448      * @return True if this View is in edit mode, false otherwise.
14449      */
14450     public boolean isInEditMode() {
14451         return false;
14452     }
14453
14454     /**
14455      * If the View draws content inside its padding and enables fading edges,
14456      * it needs to support padding offsets. Padding offsets are added to the
14457      * fading edges to extend the length of the fade so that it covers pixels
14458      * drawn inside the padding.
14459      *
14460      * Subclasses of this class should override this method if they need
14461      * to draw content inside the padding.
14462      *
14463      * @return True if padding offset must be applied, false otherwise.
14464      *
14465      * @see #getLeftPaddingOffset()
14466      * @see #getRightPaddingOffset()
14467      * @see #getTopPaddingOffset()
14468      * @see #getBottomPaddingOffset()
14469      *
14470      * @since CURRENT
14471      */
14472     protected boolean isPaddingOffsetRequired() {
14473         return false;
14474     }
14475
14476     /**
14477      * Amount by which to extend the left fading region. Called only when
14478      * {@link #isPaddingOffsetRequired()} returns true.
14479      *
14480      * @return The left padding offset in pixels.
14481      *
14482      * @see #isPaddingOffsetRequired()
14483      *
14484      * @since CURRENT
14485      */
14486     protected int getLeftPaddingOffset() {
14487         return 0;
14488     }
14489
14490     /**
14491      * Amount by which to extend the right fading region. Called only when
14492      * {@link #isPaddingOffsetRequired()} returns true.
14493      *
14494      * @return The right padding offset in pixels.
14495      *
14496      * @see #isPaddingOffsetRequired()
14497      *
14498      * @since CURRENT
14499      */
14500     protected int getRightPaddingOffset() {
14501         return 0;
14502     }
14503
14504     /**
14505      * Amount by which to extend the top fading region. Called only when
14506      * {@link #isPaddingOffsetRequired()} returns true.
14507      *
14508      * @return The top padding offset in pixels.
14509      *
14510      * @see #isPaddingOffsetRequired()
14511      *
14512      * @since CURRENT
14513      */
14514     protected int getTopPaddingOffset() {
14515         return 0;
14516     }
14517
14518     /**
14519      * Amount by which to extend the bottom fading region. Called only when
14520      * {@link #isPaddingOffsetRequired()} returns true.
14521      *
14522      * @return The bottom padding offset in pixels.
14523      *
14524      * @see #isPaddingOffsetRequired()
14525      *
14526      * @since CURRENT
14527      */
14528     protected int getBottomPaddingOffset() {
14529         return 0;
14530     }
14531
14532     /**
14533      * @hide
14534      * @param offsetRequired
14535      */
14536     protected int getFadeTop(boolean offsetRequired) {
14537         int top = mPaddingTop;
14538         if (offsetRequired) top += getTopPaddingOffset();
14539         return top;
14540     }
14541
14542     /**
14543      * @hide
14544      * @param offsetRequired
14545      */
14546     protected int getFadeHeight(boolean offsetRequired) {
14547         int padding = mPaddingTop;
14548         if (offsetRequired) padding += getTopPaddingOffset();
14549         return mBottom - mTop - mPaddingBottom - padding;
14550     }
14551
14552     /**
14553      * <p>Indicates whether this view is attached to a hardware accelerated
14554      * window or not.</p>
14555      *
14556      * <p>Even if this method returns true, it does not mean that every call
14557      * to {@link #draw(android.graphics.Canvas)} will be made with an hardware
14558      * accelerated {@link android.graphics.Canvas}. For instance, if this view
14559      * is drawn onto an offscreen {@link android.graphics.Bitmap} and its
14560      * window is hardware accelerated,
14561      * {@link android.graphics.Canvas#isHardwareAccelerated()} will likely
14562      * return false, and this method will return true.</p>
14563      *
14564      * @return True if the view is attached to a window and the window is
14565      *         hardware accelerated; false in any other case.
14566      */
14567     @ViewDebug.ExportedProperty(category = "drawing")
14568     public boolean isHardwareAccelerated() {
14569         return mAttachInfo != null && mAttachInfo.mHardwareAccelerated;
14570     }
14571
14572     /**
14573      * Sets a rectangular area on this view to which the view will be clipped
14574      * when it is drawn. Setting the value to null will remove the clip bounds
14575      * and the view will draw normally, using its full bounds.
14576      *
14577      * @param clipBounds The rectangular area, in the local coordinates of
14578      * this view, to which future drawing operations will be clipped.
14579      */
14580     public void setClipBounds(Rect clipBounds) {
14581         if (clipBounds != null) {
14582             if (clipBounds.equals(mClipBounds)) {
14583                 return;
14584             }
14585             if (mClipBounds == null) {
14586                 invalidate();
14587                 mClipBounds = new Rect(clipBounds);
14588             } else {
14589                 invalidate(Math.min(mClipBounds.left, clipBounds.left),
14590                         Math.min(mClipBounds.top, clipBounds.top),
14591                         Math.max(mClipBounds.right, clipBounds.right),
14592                         Math.max(mClipBounds.bottom, clipBounds.bottom));
14593                 mClipBounds.set(clipBounds);
14594             }
14595         } else {
14596             if (mClipBounds != null) {
14597                 invalidate();
14598                 mClipBounds = null;
14599             }
14600         }
14601         mRenderNode.setClipBounds(mClipBounds);
14602     }
14603
14604     /**
14605      * Returns a copy of the current {@link #setClipBounds(Rect) clipBounds}.
14606      *
14607      * @return A copy of the current clip bounds if clip bounds are set,
14608      * otherwise null.
14609      */
14610     public Rect getClipBounds() {
14611         return (mClipBounds != null) ? new Rect(mClipBounds) : null;
14612     }
14613
14614     /**
14615      * Utility function, called by draw(canvas, parent, drawingTime) to handle the less common
14616      * case of an active Animation being run on the view.
14617      */
14618     private boolean drawAnimation(ViewGroup parent, long drawingTime,
14619             Animation a, boolean scalingRequired) {
14620         Transformation invalidationTransform;
14621         final int flags = parent.mGroupFlags;
14622         final boolean initialized = a.isInitialized();
14623         if (!initialized) {
14624             a.initialize(mRight - mLeft, mBottom - mTop, parent.getWidth(), parent.getHeight());
14625             a.initializeInvalidateRegion(0, 0, mRight - mLeft, mBottom - mTop);
14626             if (mAttachInfo != null) a.setListenerHandler(mAttachInfo.mHandler);
14627             onAnimationStart();
14628         }
14629
14630         final Transformation t = parent.getChildTransformation();
14631         boolean more = a.getTransformation(drawingTime, t, 1f);
14632         if (scalingRequired && mAttachInfo.mApplicationScale != 1f) {
14633             if (parent.mInvalidationTransformation == null) {
14634                 parent.mInvalidationTransformation = new Transformation();
14635             }
14636             invalidationTransform = parent.mInvalidationTransformation;
14637             a.getTransformation(drawingTime, invalidationTransform, 1f);
14638         } else {
14639             invalidationTransform = t;
14640         }
14641
14642         if (more) {
14643             if (!a.willChangeBounds()) {
14644                 if ((flags & (ViewGroup.FLAG_OPTIMIZE_INVALIDATE | ViewGroup.FLAG_ANIMATION_DONE)) ==
14645                         ViewGroup.FLAG_OPTIMIZE_INVALIDATE) {
14646                     parent.mGroupFlags |= ViewGroup.FLAG_INVALIDATE_REQUIRED;
14647                 } else if ((flags & ViewGroup.FLAG_INVALIDATE_REQUIRED) == 0) {
14648                     // The child need to draw an animation, potentially offscreen, so
14649                     // make sure we do not cancel invalidate requests
14650                     parent.mPrivateFlags |= PFLAG_DRAW_ANIMATION;
14651                     parent.invalidate(mLeft, mTop, mRight, mBottom);
14652                 }
14653             } else {
14654                 if (parent.mInvalidateRegion == null) {
14655                     parent.mInvalidateRegion = new RectF();
14656                 }
14657                 final RectF region = parent.mInvalidateRegion;
14658                 a.getInvalidateRegion(0, 0, mRight - mLeft, mBottom - mTop, region,
14659                         invalidationTransform);
14660
14661                 // The child need to draw an animation, potentially offscreen, so
14662                 // make sure we do not cancel invalidate requests
14663                 parent.mPrivateFlags |= PFLAG_DRAW_ANIMATION;
14664
14665                 final int left = mLeft + (int) region.left;
14666                 final int top = mTop + (int) region.top;
14667                 parent.invalidate(left, top, left + (int) (region.width() + .5f),
14668                         top + (int) (region.height() + .5f));
14669             }
14670         }
14671         return more;
14672     }
14673
14674     /**
14675      * This method is called by getDisplayList() when a display list is recorded for a View.
14676      * It pushes any properties to the RenderNode that aren't managed by the RenderNode.
14677      */
14678     void setDisplayListProperties(RenderNode renderNode) {
14679         if (renderNode != null) {
14680             if ((mPrivateFlags3 & PFLAG3_OUTLINE_INVALID) != 0) {
14681                 rebuildOutline();
14682                 mPrivateFlags3 &= ~PFLAG3_OUTLINE_INVALID;
14683             }
14684             renderNode.setHasOverlappingRendering(hasOverlappingRendering());
14685             if (mParent instanceof ViewGroup) {
14686                 renderNode.setClipToBounds(
14687                         (((ViewGroup) mParent).mGroupFlags & ViewGroup.FLAG_CLIP_CHILDREN) != 0);
14688             }
14689             float alpha = 1;
14690             if (mParent instanceof ViewGroup && (((ViewGroup) mParent).mGroupFlags &
14691                     ViewGroup.FLAG_SUPPORT_STATIC_TRANSFORMATIONS) != 0) {
14692                 ViewGroup parentVG = (ViewGroup) mParent;
14693                 final Transformation t = parentVG.getChildTransformation();
14694                 if (parentVG.getChildStaticTransformation(this, t)) {
14695                     final int transformType = t.getTransformationType();
14696                     if (transformType != Transformation.TYPE_IDENTITY) {
14697                         if ((transformType & Transformation.TYPE_ALPHA) != 0) {
14698                             alpha = t.getAlpha();
14699                         }
14700                         if ((transformType & Transformation.TYPE_MATRIX) != 0) {
14701                             renderNode.setStaticMatrix(t.getMatrix());
14702                         }
14703                     }
14704                 }
14705             }
14706             if (mTransformationInfo != null) {
14707                 alpha *= getFinalAlpha();
14708                 if (alpha < 1) {
14709                     final int multipliedAlpha = (int) (255 * alpha);
14710                     if (onSetAlpha(multipliedAlpha)) {
14711                         alpha = 1;
14712                     }
14713                 }
14714                 renderNode.setAlpha(alpha);
14715             } else if (alpha < 1) {
14716                 renderNode.setAlpha(alpha);
14717             }
14718         }
14719     }
14720
14721     /**
14722      * This method is called by ViewGroup.drawChild() to have each child view draw itself.
14723      * This draw() method is an implementation detail and is not intended to be overridden or
14724      * to be called from anywhere else other than ViewGroup.drawChild().
14725      */
14726     boolean draw(Canvas canvas, ViewGroup parent, long drawingTime) {
14727         boolean usingRenderNodeProperties = mAttachInfo != null && mAttachInfo.mHardwareAccelerated;
14728         boolean more = false;
14729         final boolean childHasIdentityMatrix = hasIdentityMatrix();
14730         final int flags = parent.mGroupFlags;
14731
14732         if ((flags & ViewGroup.FLAG_CLEAR_TRANSFORMATION) == ViewGroup.FLAG_CLEAR_TRANSFORMATION) {
14733             parent.getChildTransformation().clear();
14734             parent.mGroupFlags &= ~ViewGroup.FLAG_CLEAR_TRANSFORMATION;
14735         }
14736
14737         Transformation transformToApply = null;
14738         boolean concatMatrix = false;
14739
14740         boolean scalingRequired = false;
14741         boolean caching;
14742         int layerType = getLayerType();
14743
14744         final boolean hardwareAccelerated = canvas.isHardwareAccelerated();
14745         if ((flags & ViewGroup.FLAG_CHILDREN_DRAWN_WITH_CACHE) != 0 ||
14746                 (flags & ViewGroup.FLAG_ALWAYS_DRAWN_WITH_CACHE) != 0) {
14747             caching = true;
14748             // Auto-scaled apps are not hw-accelerated, no need to set scaling flag on DisplayList
14749             if (mAttachInfo != null) scalingRequired = mAttachInfo.mScalingRequired;
14750         } else {
14751             caching = (layerType != LAYER_TYPE_NONE) || hardwareAccelerated;
14752         }
14753
14754         final Animation a = getAnimation();
14755         if (a != null) {
14756             more = drawAnimation(parent, drawingTime, a, scalingRequired);
14757             concatMatrix = a.willChangeTransformationMatrix();
14758             if (concatMatrix) {
14759                 mPrivateFlags3 |= PFLAG3_VIEW_IS_ANIMATING_TRANSFORM;
14760             }
14761             transformToApply = parent.getChildTransformation();
14762         } else {
14763             if ((mPrivateFlags3 & PFLAG3_VIEW_IS_ANIMATING_TRANSFORM) != 0) {
14764                 // No longer animating: clear out old animation matrix
14765                 mRenderNode.setAnimationMatrix(null);
14766                 mPrivateFlags3 &= ~PFLAG3_VIEW_IS_ANIMATING_TRANSFORM;
14767             }
14768             if (!usingRenderNodeProperties &&
14769                     (flags & ViewGroup.FLAG_SUPPORT_STATIC_TRANSFORMATIONS) != 0) {
14770                 final Transformation t = parent.getChildTransformation();
14771                 final boolean hasTransform = parent.getChildStaticTransformation(this, t);
14772                 if (hasTransform) {
14773                     final int transformType = t.getTransformationType();
14774                     transformToApply = transformType != Transformation.TYPE_IDENTITY ? t : null;
14775                     concatMatrix = (transformType & Transformation.TYPE_MATRIX) != 0;
14776                 }
14777             }
14778         }
14779
14780         concatMatrix |= !childHasIdentityMatrix;
14781
14782         // Sets the flag as early as possible to allow draw() implementations
14783         // to call invalidate() successfully when doing animations
14784         mPrivateFlags |= PFLAG_DRAWN;
14785
14786         if (!concatMatrix &&
14787                 (flags & (ViewGroup.FLAG_SUPPORT_STATIC_TRANSFORMATIONS |
14788                         ViewGroup.FLAG_CLIP_CHILDREN)) == ViewGroup.FLAG_CLIP_CHILDREN &&
14789                 canvas.quickReject(mLeft, mTop, mRight, mBottom, Canvas.EdgeType.BW) &&
14790                 (mPrivateFlags & PFLAG_DRAW_ANIMATION) == 0) {
14791             mPrivateFlags2 |= PFLAG2_VIEW_QUICK_REJECTED;
14792             return more;
14793         }
14794         mPrivateFlags2 &= ~PFLAG2_VIEW_QUICK_REJECTED;
14795
14796         if (hardwareAccelerated) {
14797             // Clear INVALIDATED flag to allow invalidation to occur during rendering, but
14798             // retain the flag's value temporarily in the mRecreateDisplayList flag
14799             mRecreateDisplayList = (mPrivateFlags & PFLAG_INVALIDATED) == PFLAG_INVALIDATED;
14800             mPrivateFlags &= ~PFLAG_INVALIDATED;
14801         }
14802
14803         RenderNode renderNode = null;
14804         Bitmap cache = null;
14805         boolean hasDisplayList = false;
14806         if (caching) {
14807             if (!hardwareAccelerated) {
14808                 if (layerType != LAYER_TYPE_NONE) {
14809                     layerType = LAYER_TYPE_SOFTWARE;
14810                     buildDrawingCache(true);
14811                 }
14812                 cache = getDrawingCache(true);
14813             } else {
14814                 switch (layerType) {
14815                     case LAYER_TYPE_SOFTWARE:
14816                         if (usingRenderNodeProperties) {
14817                             hasDisplayList = canHaveDisplayList();
14818                         } else {
14819                             buildDrawingCache(true);
14820                             cache = getDrawingCache(true);
14821                         }
14822                         break;
14823                     case LAYER_TYPE_HARDWARE:
14824                         if (usingRenderNodeProperties) {
14825                             hasDisplayList = canHaveDisplayList();
14826                         }
14827                         break;
14828                     case LAYER_TYPE_NONE:
14829                         // Delay getting the display list until animation-driven alpha values are
14830                         // set up and possibly passed on to the view
14831                         hasDisplayList = canHaveDisplayList();
14832                         break;
14833                 }
14834             }
14835         }
14836         usingRenderNodeProperties &= hasDisplayList;
14837         if (usingRenderNodeProperties) {
14838             renderNode = getDisplayList();
14839             if (!renderNode.isValid()) {
14840                 // Uncommon, but possible. If a view is removed from the hierarchy during the call
14841                 // to getDisplayList(), the display list will be marked invalid and we should not
14842                 // try to use it again.
14843                 renderNode = null;
14844                 hasDisplayList = false;
14845                 usingRenderNodeProperties = false;
14846             }
14847         }
14848
14849         int sx = 0;
14850         int sy = 0;
14851         if (!hasDisplayList) {
14852             computeScroll();
14853             sx = mScrollX;
14854             sy = mScrollY;
14855         }
14856
14857         final boolean hasNoCache = cache == null || hasDisplayList;
14858         final boolean offsetForScroll = cache == null && !hasDisplayList &&
14859                 layerType != LAYER_TYPE_HARDWARE;
14860
14861         int restoreTo = -1;
14862         if (!usingRenderNodeProperties || transformToApply != null) {
14863             restoreTo = canvas.save();
14864         }
14865         if (offsetForScroll) {
14866             canvas.translate(mLeft - sx, mTop - sy);
14867         } else {
14868             if (!usingRenderNodeProperties) {
14869                 canvas.translate(mLeft, mTop);
14870             }
14871             if (scalingRequired) {
14872                 if (usingRenderNodeProperties) {
14873                     // TODO: Might not need this if we put everything inside the DL
14874                     restoreTo = canvas.save();
14875                 }
14876                 // mAttachInfo cannot be null, otherwise scalingRequired == false
14877                 final float scale = 1.0f / mAttachInfo.mApplicationScale;
14878                 canvas.scale(scale, scale);
14879             }
14880         }
14881
14882         float alpha = usingRenderNodeProperties ? 1 : (getAlpha() * getTransitionAlpha());
14883         if (transformToApply != null || alpha < 1 ||  !hasIdentityMatrix() ||
14884                 (mPrivateFlags3 & PFLAG3_VIEW_IS_ANIMATING_ALPHA) == PFLAG3_VIEW_IS_ANIMATING_ALPHA) {
14885             if (transformToApply != null || !childHasIdentityMatrix) {
14886                 int transX = 0;
14887                 int transY = 0;
14888
14889                 if (offsetForScroll) {
14890                     transX = -sx;
14891                     transY = -sy;
14892                 }
14893
14894                 if (transformToApply != null) {
14895                     if (concatMatrix) {
14896                         if (usingRenderNodeProperties) {
14897                             renderNode.setAnimationMatrix(transformToApply.getMatrix());
14898                         } else {
14899                             // Undo the scroll translation, apply the transformation matrix,
14900                             // then redo the scroll translate to get the correct result.
14901                             canvas.translate(-transX, -transY);
14902                             canvas.concat(transformToApply.getMatrix());
14903                             canvas.translate(transX, transY);
14904                         }
14905                         parent.mGroupFlags |= ViewGroup.FLAG_CLEAR_TRANSFORMATION;
14906                     }
14907
14908                     float transformAlpha = transformToApply.getAlpha();
14909                     if (transformAlpha < 1) {
14910                         alpha *= transformAlpha;
14911                         parent.mGroupFlags |= ViewGroup.FLAG_CLEAR_TRANSFORMATION;
14912                     }
14913                 }
14914
14915                 if (!childHasIdentityMatrix && !usingRenderNodeProperties) {
14916                     canvas.translate(-transX, -transY);
14917                     canvas.concat(getMatrix());
14918                     canvas.translate(transX, transY);
14919                 }
14920             }
14921
14922             // Deal with alpha if it is or used to be <1
14923             if (alpha < 1 ||
14924                     (mPrivateFlags3 & PFLAG3_VIEW_IS_ANIMATING_ALPHA) == PFLAG3_VIEW_IS_ANIMATING_ALPHA) {
14925                 if (alpha < 1) {
14926                     mPrivateFlags3 |= PFLAG3_VIEW_IS_ANIMATING_ALPHA;
14927                 } else {
14928                     mPrivateFlags3 &= ~PFLAG3_VIEW_IS_ANIMATING_ALPHA;
14929                 }
14930                 parent.mGroupFlags |= ViewGroup.FLAG_CLEAR_TRANSFORMATION;
14931                 if (hasNoCache) {
14932                     final int multipliedAlpha = (int) (255 * alpha);
14933                     if (!onSetAlpha(multipliedAlpha)) {
14934                         int layerFlags = Canvas.HAS_ALPHA_LAYER_SAVE_FLAG;
14935                         if ((flags & ViewGroup.FLAG_CLIP_CHILDREN) != 0 ||
14936                                 layerType != LAYER_TYPE_NONE) {
14937                             layerFlags |= Canvas.CLIP_TO_LAYER_SAVE_FLAG;
14938                         }
14939                         if (usingRenderNodeProperties) {
14940                             renderNode.setAlpha(alpha * getAlpha() * getTransitionAlpha());
14941                         } else  if (layerType == LAYER_TYPE_NONE) {
14942                             final int scrollX = hasDisplayList ? 0 : sx;
14943                             final int scrollY = hasDisplayList ? 0 : sy;
14944                             canvas.saveLayerAlpha(scrollX, scrollY,
14945                                     scrollX + (mRight - mLeft), scrollY + (mBottom - mTop),
14946                                     multipliedAlpha, layerFlags);
14947                         }
14948                     } else {
14949                         // Alpha is handled by the child directly, clobber the layer's alpha
14950                         mPrivateFlags |= PFLAG_ALPHA_SET;
14951                     }
14952                 }
14953             }
14954         } else if ((mPrivateFlags & PFLAG_ALPHA_SET) == PFLAG_ALPHA_SET) {
14955             onSetAlpha(255);
14956             mPrivateFlags &= ~PFLAG_ALPHA_SET;
14957         }
14958
14959         if (!usingRenderNodeProperties) {
14960             // apply clips directly, since RenderNode won't do it for this draw
14961             if ((flags & ViewGroup.FLAG_CLIP_CHILDREN) == ViewGroup.FLAG_CLIP_CHILDREN
14962                     && cache == null) {
14963                 if (offsetForScroll) {
14964                     canvas.clipRect(sx, sy, sx + (mRight - mLeft), sy + (mBottom - mTop));
14965                 } else {
14966                     if (!scalingRequired || cache == null) {
14967                         canvas.clipRect(0, 0, mRight - mLeft, mBottom - mTop);
14968                     } else {
14969                         canvas.clipRect(0, 0, cache.getWidth(), cache.getHeight());
14970                     }
14971                 }
14972             }
14973
14974             if (mClipBounds != null) {
14975                 // clip bounds ignore scroll
14976                 canvas.clipRect(mClipBounds);
14977             }
14978         }
14979
14980
14981
14982         if (!usingRenderNodeProperties && hasDisplayList) {
14983             renderNode = getDisplayList();
14984             if (!renderNode.isValid()) {
14985                 // Uncommon, but possible. If a view is removed from the hierarchy during the call
14986                 // to getDisplayList(), the display list will be marked invalid and we should not
14987                 // try to use it again.
14988                 renderNode = null;
14989                 hasDisplayList = false;
14990             }
14991         }
14992
14993         if (hasNoCache) {
14994             boolean layerRendered = false;
14995             if (layerType == LAYER_TYPE_HARDWARE && !usingRenderNodeProperties) {
14996                 final HardwareLayer layer = getHardwareLayer();
14997                 if (layer != null && layer.isValid()) {
14998                     int restoreAlpha = mLayerPaint.getAlpha();
14999                     mLayerPaint.setAlpha((int) (alpha * 255));
15000                     ((HardwareCanvas) canvas).drawHardwareLayer(layer, 0, 0, mLayerPaint);
15001                     mLayerPaint.setAlpha(restoreAlpha);
15002                     layerRendered = true;
15003                 } else {
15004                     final int scrollX = hasDisplayList ? 0 : sx;
15005                     final int scrollY = hasDisplayList ? 0 : sy;
15006                     canvas.saveLayer(scrollX, scrollY,
15007                             scrollX + mRight - mLeft, scrollY + mBottom - mTop, mLayerPaint,
15008                             Canvas.HAS_ALPHA_LAYER_SAVE_FLAG | Canvas.CLIP_TO_LAYER_SAVE_FLAG);
15009                 }
15010             }
15011
15012             if (!layerRendered) {
15013                 if (!hasDisplayList) {
15014                     // Fast path for layouts with no backgrounds
15015                     if ((mPrivateFlags & PFLAG_SKIP_DRAW) == PFLAG_SKIP_DRAW) {
15016                         mPrivateFlags &= ~PFLAG_DIRTY_MASK;
15017                         dispatchDraw(canvas);
15018                         if (mOverlay != null && !mOverlay.isEmpty()) {
15019                             mOverlay.getOverlayView().draw(canvas);
15020                         }
15021                     } else {
15022                         draw(canvas);
15023                     }
15024                     drawAccessibilityFocus(canvas);
15025                 } else {
15026                     mPrivateFlags &= ~PFLAG_DIRTY_MASK;
15027                     ((HardwareCanvas) canvas).drawRenderNode(renderNode, null, flags);
15028                 }
15029             }
15030         } else if (cache != null) {
15031             mPrivateFlags &= ~PFLAG_DIRTY_MASK;
15032             Paint cachePaint;
15033             int restoreAlpha = 0;
15034
15035             if (layerType == LAYER_TYPE_NONE) {
15036                 cachePaint = parent.mCachePaint;
15037                 if (cachePaint == null) {
15038                     cachePaint = new Paint();
15039                     cachePaint.setDither(false);
15040                     parent.mCachePaint = cachePaint;
15041                 }
15042             } else {
15043                 cachePaint = mLayerPaint;
15044                 restoreAlpha = mLayerPaint.getAlpha();
15045             }
15046             cachePaint.setAlpha((int) (alpha * 255));
15047             canvas.drawBitmap(cache, 0.0f, 0.0f, cachePaint);
15048             cachePaint.setAlpha(restoreAlpha);
15049         }
15050
15051         if (restoreTo >= 0) {
15052             canvas.restoreToCount(restoreTo);
15053         }
15054
15055         if (a != null && !more) {
15056             if (!hardwareAccelerated && !a.getFillAfter()) {
15057                 onSetAlpha(255);
15058             }
15059             parent.finishAnimatingView(this, a);
15060         }
15061
15062         if (more && hardwareAccelerated) {
15063             if (a.hasAlpha() && (mPrivateFlags & PFLAG_ALPHA_SET) == PFLAG_ALPHA_SET) {
15064                 // alpha animations should cause the child to recreate its display list
15065                 invalidate(true);
15066             }
15067         }
15068
15069         mRecreateDisplayList = false;
15070
15071         return more;
15072     }
15073
15074     /**
15075      * Manually render this view (and all of its children) to the given Canvas.
15076      * The view must have already done a full layout before this function is
15077      * called.  When implementing a view, implement
15078      * {@link #onDraw(android.graphics.Canvas)} instead of overriding this method.
15079      * If you do need to override this method, call the superclass version.
15080      *
15081      * @param canvas The Canvas to which the View is rendered.
15082      */
15083     public void draw(Canvas canvas) {
15084         final int privateFlags = mPrivateFlags;
15085         final boolean dirtyOpaque = (privateFlags & PFLAG_DIRTY_MASK) == PFLAG_DIRTY_OPAQUE &&
15086                 (mAttachInfo == null || !mAttachInfo.mIgnoreDirtyState);
15087         mPrivateFlags = (privateFlags & ~PFLAG_DIRTY_MASK) | PFLAG_DRAWN;
15088
15089         /*
15090          * Draw traversal performs several drawing steps which must be executed
15091          * in the appropriate order:
15092          *
15093          *      1. Draw the background
15094          *      2. If necessary, save the canvas' layers to prepare for fading
15095          *      3. Draw view's content
15096          *      4. Draw children
15097          *      5. If necessary, draw the fading edges and restore layers
15098          *      6. Draw decorations (scrollbars for instance)
15099          */
15100
15101         // Step 1, draw the background, if needed
15102         int saveCount;
15103
15104         if (!dirtyOpaque) {
15105             drawBackground(canvas);
15106         }
15107
15108         // skip step 2 & 5 if possible (common case)
15109         final int viewFlags = mViewFlags;
15110         boolean horizontalEdges = (viewFlags & FADING_EDGE_HORIZONTAL) != 0;
15111         boolean verticalEdges = (viewFlags & FADING_EDGE_VERTICAL) != 0;
15112         if (!verticalEdges && !horizontalEdges) {
15113             // Step 3, draw the content
15114             if (!dirtyOpaque) onDraw(canvas);
15115
15116             // Step 4, draw the children
15117             dispatchDraw(canvas);
15118
15119             // Step 6, draw decorations (scrollbars)
15120             onDrawScrollBars(canvas);
15121
15122             if (mOverlay != null && !mOverlay.isEmpty()) {
15123                 mOverlay.getOverlayView().dispatchDraw(canvas);
15124             }
15125
15126             // we're done...
15127             return;
15128         }
15129
15130         /*
15131          * Here we do the full fledged routine...
15132          * (this is an uncommon case where speed matters less,
15133          * this is why we repeat some of the tests that have been
15134          * done above)
15135          */
15136
15137         boolean drawTop = false;
15138         boolean drawBottom = false;
15139         boolean drawLeft = false;
15140         boolean drawRight = false;
15141
15142         float topFadeStrength = 0.0f;
15143         float bottomFadeStrength = 0.0f;
15144         float leftFadeStrength = 0.0f;
15145         float rightFadeStrength = 0.0f;
15146
15147         // Step 2, save the canvas' layers
15148         int paddingLeft = mPaddingLeft;
15149
15150         final boolean offsetRequired = isPaddingOffsetRequired();
15151         if (offsetRequired) {
15152             paddingLeft += getLeftPaddingOffset();
15153         }
15154
15155         int left = mScrollX + paddingLeft;
15156         int right = left + mRight - mLeft - mPaddingRight - paddingLeft;
15157         int top = mScrollY + getFadeTop(offsetRequired);
15158         int bottom = top + getFadeHeight(offsetRequired);
15159
15160         if (offsetRequired) {
15161             right += getRightPaddingOffset();
15162             bottom += getBottomPaddingOffset();
15163         }
15164
15165         final ScrollabilityCache scrollabilityCache = mScrollCache;
15166         final float fadeHeight = scrollabilityCache.fadingEdgeLength;
15167         int length = (int) fadeHeight;
15168
15169         // clip the fade length if top and bottom fades overlap
15170         // overlapping fades produce odd-looking artifacts
15171         if (verticalEdges && (top + length > bottom - length)) {
15172             length = (bottom - top) / 2;
15173         }
15174
15175         // also clip horizontal fades if necessary
15176         if (horizontalEdges && (left + length > right - length)) {
15177             length = (right - left) / 2;
15178         }
15179
15180         if (verticalEdges) {
15181             topFadeStrength = Math.max(0.0f, Math.min(1.0f, getTopFadingEdgeStrength()));
15182             drawTop = topFadeStrength * fadeHeight > 1.0f;
15183             bottomFadeStrength = Math.max(0.0f, Math.min(1.0f, getBottomFadingEdgeStrength()));
15184             drawBottom = bottomFadeStrength * fadeHeight > 1.0f;
15185         }
15186
15187         if (horizontalEdges) {
15188             leftFadeStrength = Math.max(0.0f, Math.min(1.0f, getLeftFadingEdgeStrength()));
15189             drawLeft = leftFadeStrength * fadeHeight > 1.0f;
15190             rightFadeStrength = Math.max(0.0f, Math.min(1.0f, getRightFadingEdgeStrength()));
15191             drawRight = rightFadeStrength * fadeHeight > 1.0f;
15192         }
15193
15194         saveCount = canvas.getSaveCount();
15195
15196         int solidColor = getSolidColor();
15197         if (solidColor == 0) {
15198             final int flags = Canvas.HAS_ALPHA_LAYER_SAVE_FLAG;
15199
15200             if (drawTop) {
15201                 canvas.saveLayer(left, top, right, top + length, null, flags);
15202             }
15203
15204             if (drawBottom) {
15205                 canvas.saveLayer(left, bottom - length, right, bottom, null, flags);
15206             }
15207
15208             if (drawLeft) {
15209                 canvas.saveLayer(left, top, left + length, bottom, null, flags);
15210             }
15211
15212             if (drawRight) {
15213                 canvas.saveLayer(right - length, top, right, bottom, null, flags);
15214             }
15215         } else {
15216             scrollabilityCache.setFadeColor(solidColor);
15217         }
15218
15219         // Step 3, draw the content
15220         if (!dirtyOpaque) onDraw(canvas);
15221
15222         // Step 4, draw the children
15223         dispatchDraw(canvas);
15224
15225         // Step 5, draw the fade effect and restore layers
15226         final Paint p = scrollabilityCache.paint;
15227         final Matrix matrix = scrollabilityCache.matrix;
15228         final Shader fade = scrollabilityCache.shader;
15229
15230         if (drawTop) {
15231             matrix.setScale(1, fadeHeight * topFadeStrength);
15232             matrix.postTranslate(left, top);
15233             fade.setLocalMatrix(matrix);
15234             p.setShader(fade);
15235             canvas.drawRect(left, top, right, top + length, p);
15236         }
15237
15238         if (drawBottom) {
15239             matrix.setScale(1, fadeHeight * bottomFadeStrength);
15240             matrix.postRotate(180);
15241             matrix.postTranslate(left, bottom);
15242             fade.setLocalMatrix(matrix);
15243             p.setShader(fade);
15244             canvas.drawRect(left, bottom - length, right, bottom, p);
15245         }
15246
15247         if (drawLeft) {
15248             matrix.setScale(1, fadeHeight * leftFadeStrength);
15249             matrix.postRotate(-90);
15250             matrix.postTranslate(left, top);
15251             fade.setLocalMatrix(matrix);
15252             p.setShader(fade);
15253             canvas.drawRect(left, top, left + length, bottom, p);
15254         }
15255
15256         if (drawRight) {
15257             matrix.setScale(1, fadeHeight * rightFadeStrength);
15258             matrix.postRotate(90);
15259             matrix.postTranslate(right, top);
15260             fade.setLocalMatrix(matrix);
15261             p.setShader(fade);
15262             canvas.drawRect(right - length, top, right, bottom, p);
15263         }
15264
15265         canvas.restoreToCount(saveCount);
15266
15267         // Step 6, draw decorations (scrollbars)
15268         onDrawScrollBars(canvas);
15269
15270         if (mOverlay != null && !mOverlay.isEmpty()) {
15271             mOverlay.getOverlayView().dispatchDraw(canvas);
15272         }
15273     }
15274
15275     /**
15276      * Draws the accessibility focus rect onto the specified canvas.
15277      *
15278      * @param canvas Canvas on which to draw the focus rect
15279      */
15280     private void drawAccessibilityFocus(Canvas canvas) {
15281         if (mAttachInfo == null) {
15282             return;
15283         }
15284
15285         final Rect bounds = mAttachInfo.mTmpInvalRect;
15286         final ViewRootImpl viewRoot = getViewRootImpl();
15287         if (viewRoot == null || viewRoot.getAccessibilityFocusedHost() != this) {
15288             return;
15289         }
15290
15291         final AccessibilityManager manager = AccessibilityManager.getInstance(mContext);
15292         if (!manager.isEnabled() || !manager.isTouchExplorationEnabled()) {
15293             return;
15294         }
15295
15296         final Drawable drawable = viewRoot.getAccessibilityFocusedDrawable();
15297         if (drawable == null) {
15298             return;
15299         }
15300
15301         final AccessibilityNodeInfo virtualView = viewRoot.getAccessibilityFocusedVirtualView();
15302         if (virtualView != null) {
15303             virtualView.getBoundsInScreen(bounds);
15304             final int[] offset = mAttachInfo.mTmpLocation;
15305             getLocationOnScreen(offset);
15306             bounds.offset(-offset[0], -offset[1]);
15307         } else {
15308             bounds.set(0, 0, mRight - mLeft, mBottom - mTop);
15309         }
15310
15311         canvas.save();
15312         canvas.translate(mScrollX, mScrollY);
15313         canvas.clipRect(bounds, Region.Op.REPLACE);
15314         drawable.setBounds(bounds);
15315         drawable.draw(canvas);
15316         canvas.restore();
15317     }
15318
15319     /**
15320      * Draws the background onto the specified canvas.
15321      *
15322      * @param canvas Canvas on which to draw the background
15323      */
15324     private void drawBackground(Canvas canvas) {
15325         final Drawable background = mBackground;
15326         if (background == null) {
15327             return;
15328         }
15329
15330         if (mBackgroundSizeChanged) {
15331             background.setBounds(0, 0,  mRight - mLeft, mBottom - mTop);
15332             mBackgroundSizeChanged = false;
15333             mPrivateFlags3 |= PFLAG3_OUTLINE_INVALID;
15334         }
15335
15336         // Attempt to use a display list if requested.
15337         if (canvas.isHardwareAccelerated() && mAttachInfo != null
15338                 && mAttachInfo.mHardwareRenderer != null) {
15339             mBackgroundRenderNode = getDrawableRenderNode(background, mBackgroundRenderNode);
15340
15341             final RenderNode displayList = mBackgroundRenderNode;
15342             if (displayList != null && displayList.isValid()) {
15343                 setBackgroundDisplayListProperties(displayList);
15344                 ((HardwareCanvas) canvas).drawRenderNode(displayList);
15345                 return;
15346             }
15347         }
15348
15349         final int scrollX = mScrollX;
15350         final int scrollY = mScrollY;
15351         if ((scrollX | scrollY) == 0) {
15352             background.draw(canvas);
15353         } else {
15354             canvas.translate(scrollX, scrollY);
15355             background.draw(canvas);
15356             canvas.translate(-scrollX, -scrollY);
15357         }
15358     }
15359
15360     /**
15361      * Set up background drawable display list properties.
15362      *
15363      * @param displayList Valid display list for the background drawable
15364      */
15365     private void setBackgroundDisplayListProperties(RenderNode displayList) {
15366         displayList.setTranslationX(mScrollX);
15367         displayList.setTranslationY(mScrollY);
15368     }
15369
15370     /**
15371      * Creates a new display list or updates the existing display list for the
15372      * specified Drawable.
15373      *
15374      * @param drawable Drawable for which to create a display list
15375      * @param renderNode Existing RenderNode, or {@code null}
15376      * @return A valid display list for the specified drawable
15377      */
15378     private RenderNode getDrawableRenderNode(Drawable drawable, RenderNode renderNode) {
15379         if (renderNode == null) {
15380             renderNode = RenderNode.create(drawable.getClass().getName(), this);
15381         }
15382
15383         final Rect bounds = drawable.getBounds();
15384         final int width = bounds.width();
15385         final int height = bounds.height();
15386         final HardwareCanvas canvas = renderNode.start(width, height);
15387         try {
15388             drawable.draw(canvas);
15389         } finally {
15390             renderNode.end(canvas);
15391         }
15392
15393         // Set up drawable properties that are view-independent.
15394         renderNode.setLeftTopRightBottom(bounds.left, bounds.top, bounds.right, bounds.bottom);
15395         renderNode.setProjectBackwards(drawable.isProjected());
15396         renderNode.setProjectionReceiver(true);
15397         renderNode.setClipToBounds(false);
15398         return renderNode;
15399     }
15400
15401     /**
15402      * Returns the overlay for this view, creating it if it does not yet exist.
15403      * Adding drawables to the overlay will cause them to be displayed whenever
15404      * the view itself is redrawn. Objects in the overlay should be actively
15405      * managed: remove them when they should not be displayed anymore. The
15406      * overlay will always have the same size as its host view.
15407      *
15408      * <p>Note: Overlays do not currently work correctly with {@link
15409      * SurfaceView} or {@link TextureView}; contents in overlays for these
15410      * types of views may not display correctly.</p>
15411      *
15412      * @return The ViewOverlay object for this view.
15413      * @see ViewOverlay
15414      */
15415     public ViewOverlay getOverlay() {
15416         if (mOverlay == null) {
15417             mOverlay = new ViewOverlay(mContext, this);
15418         }
15419         return mOverlay;
15420     }
15421
15422     /**
15423      * Override this if your view is known to always be drawn on top of a solid color background,
15424      * and needs to draw fading edges. Returning a non-zero color enables the view system to
15425      * optimize the drawing of the fading edges. If you do return a non-zero color, the alpha
15426      * should be set to 0xFF.
15427      *
15428      * @see #setVerticalFadingEdgeEnabled(boolean)
15429      * @see #setHorizontalFadingEdgeEnabled(boolean)
15430      *
15431      * @return The known solid color background for this view, or 0 if the color may vary
15432      */
15433     @ViewDebug.ExportedProperty(category = "drawing")
15434     public int getSolidColor() {
15435         return 0;
15436     }
15437
15438     /**
15439      * Build a human readable string representation of the specified view flags.
15440      *
15441      * @param flags the view flags to convert to a string
15442      * @return a String representing the supplied flags
15443      */
15444     private static String printFlags(int flags) {
15445         String output = "";
15446         int numFlags = 0;
15447         if ((flags & FOCUSABLE_MASK) == FOCUSABLE) {
15448             output += "TAKES_FOCUS";
15449             numFlags++;
15450         }
15451
15452         switch (flags & VISIBILITY_MASK) {
15453         case INVISIBLE:
15454             if (numFlags > 0) {
15455                 output += " ";
15456             }
15457             output += "INVISIBLE";
15458             // USELESS HERE numFlags++;
15459             break;
15460         case GONE:
15461             if (numFlags > 0) {
15462                 output += " ";
15463             }
15464             output += "GONE";
15465             // USELESS HERE numFlags++;
15466             break;
15467         default:
15468             break;
15469         }
15470         return output;
15471     }
15472
15473     /**
15474      * Build a human readable string representation of the specified private
15475      * view flags.
15476      *
15477      * @param privateFlags the private view flags to convert to a string
15478      * @return a String representing the supplied flags
15479      */
15480     private static String printPrivateFlags(int privateFlags) {
15481         String output = "";
15482         int numFlags = 0;
15483
15484         if ((privateFlags & PFLAG_WANTS_FOCUS) == PFLAG_WANTS_FOCUS) {
15485             output += "WANTS_FOCUS";
15486             numFlags++;
15487         }
15488
15489         if ((privateFlags & PFLAG_FOCUSED) == PFLAG_FOCUSED) {
15490             if (numFlags > 0) {
15491                 output += " ";
15492             }
15493             output += "FOCUSED";
15494             numFlags++;
15495         }
15496
15497         if ((privateFlags & PFLAG_SELECTED) == PFLAG_SELECTED) {
15498             if (numFlags > 0) {
15499                 output += " ";
15500             }
15501             output += "SELECTED";
15502             numFlags++;
15503         }
15504
15505         if ((privateFlags & PFLAG_IS_ROOT_NAMESPACE) == PFLAG_IS_ROOT_NAMESPACE) {
15506             if (numFlags > 0) {
15507                 output += " ";
15508             }
15509             output += "IS_ROOT_NAMESPACE";
15510             numFlags++;
15511         }
15512
15513         if ((privateFlags & PFLAG_HAS_BOUNDS) == PFLAG_HAS_BOUNDS) {
15514             if (numFlags > 0) {
15515                 output += " ";
15516             }
15517             output += "HAS_BOUNDS";
15518             numFlags++;
15519         }
15520
15521         if ((privateFlags & PFLAG_DRAWN) == PFLAG_DRAWN) {
15522             if (numFlags > 0) {
15523                 output += " ";
15524             }
15525             output += "DRAWN";
15526             // USELESS HERE numFlags++;
15527         }
15528         return output;
15529     }
15530
15531     /**
15532      * <p>Indicates whether or not this view's layout will be requested during
15533      * the next hierarchy layout pass.</p>
15534      *
15535      * @return true if the layout will be forced during next layout pass
15536      */
15537     public boolean isLayoutRequested() {
15538         return (mPrivateFlags & PFLAG_FORCE_LAYOUT) == PFLAG_FORCE_LAYOUT;
15539     }
15540
15541     /**
15542      * Return true if o is a ViewGroup that is laying out using optical bounds.
15543      * @hide
15544      */
15545     public static boolean isLayoutModeOptical(Object o) {
15546         return o instanceof ViewGroup && ((ViewGroup) o).isLayoutModeOptical();
15547     }
15548
15549     private boolean setOpticalFrame(int left, int top, int right, int bottom) {
15550         Insets parentInsets = mParent instanceof View ?
15551                 ((View) mParent).getOpticalInsets() : Insets.NONE;
15552         Insets childInsets = getOpticalInsets();
15553         return setFrame(
15554                 left   + parentInsets.left - childInsets.left,
15555                 top    + parentInsets.top  - childInsets.top,
15556                 right  + parentInsets.left + childInsets.right,
15557                 bottom + parentInsets.top  + childInsets.bottom);
15558     }
15559
15560     /**
15561      * Assign a size and position to a view and all of its
15562      * descendants
15563      *
15564      * <p>This is the second phase of the layout mechanism.
15565      * (The first is measuring). In this phase, each parent calls
15566      * layout on all of its children to position them.
15567      * This is typically done using the child measurements
15568      * that were stored in the measure pass().</p>
15569      *
15570      * <p>Derived classes should not override this method.
15571      * Derived classes with children should override
15572      * onLayout. In that method, they should
15573      * call layout on each of their children.</p>
15574      *
15575      * @param l Left position, relative to parent
15576      * @param t Top position, relative to parent
15577      * @param r Right position, relative to parent
15578      * @param b Bottom position, relative to parent
15579      */
15580     @SuppressWarnings({"unchecked"})
15581     public void layout(int l, int t, int r, int b) {
15582         if ((mPrivateFlags3 & PFLAG3_MEASURE_NEEDED_BEFORE_LAYOUT) != 0) {
15583             onMeasure(mOldWidthMeasureSpec, mOldHeightMeasureSpec);
15584             mPrivateFlags3 &= ~PFLAG3_MEASURE_NEEDED_BEFORE_LAYOUT;
15585         }
15586
15587         int oldL = mLeft;
15588         int oldT = mTop;
15589         int oldB = mBottom;
15590         int oldR = mRight;
15591
15592         boolean changed = isLayoutModeOptical(mParent) ?
15593                 setOpticalFrame(l, t, r, b) : setFrame(l, t, r, b);
15594
15595         if (changed || (mPrivateFlags & PFLAG_LAYOUT_REQUIRED) == PFLAG_LAYOUT_REQUIRED) {
15596             onLayout(changed, l, t, r, b);
15597             mPrivateFlags &= ~PFLAG_LAYOUT_REQUIRED;
15598
15599             ListenerInfo li = mListenerInfo;
15600             if (li != null && li.mOnLayoutChangeListeners != null) {
15601                 ArrayList<OnLayoutChangeListener> listenersCopy =
15602                         (ArrayList<OnLayoutChangeListener>)li.mOnLayoutChangeListeners.clone();
15603                 int numListeners = listenersCopy.size();
15604                 for (int i = 0; i < numListeners; ++i) {
15605                     listenersCopy.get(i).onLayoutChange(this, l, t, r, b, oldL, oldT, oldR, oldB);
15606                 }
15607             }
15608         }
15609
15610         mPrivateFlags &= ~PFLAG_FORCE_LAYOUT;
15611         mPrivateFlags3 |= PFLAG3_IS_LAID_OUT;
15612     }
15613
15614     /**
15615      * Called from layout when this view should
15616      * assign a size and position to each of its children.
15617      *
15618      * Derived classes with children should override
15619      * this method and call layout on each of
15620      * their children.
15621      * @param changed This is a new size or position for this view
15622      * @param left Left position, relative to parent
15623      * @param top Top position, relative to parent
15624      * @param right Right position, relative to parent
15625      * @param bottom Bottom position, relative to parent
15626      */
15627     protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
15628     }
15629
15630     /**
15631      * Assign a size and position to this view.
15632      *
15633      * This is called from layout.
15634      *
15635      * @param left Left position, relative to parent
15636      * @param top Top position, relative to parent
15637      * @param right Right position, relative to parent
15638      * @param bottom Bottom position, relative to parent
15639      * @return true if the new size and position are different than the
15640      *         previous ones
15641      * {@hide}
15642      */
15643     protected boolean setFrame(int left, int top, int right, int bottom) {
15644         boolean changed = false;
15645
15646         if (DBG) {
15647             Log.d("View", this + " View.setFrame(" + left + "," + top + ","
15648                     + right + "," + bottom + ")");
15649         }
15650
15651         if (mLeft != left || mRight != right || mTop != top || mBottom != bottom) {
15652             changed = true;
15653
15654             // Remember our drawn bit
15655             int drawn = mPrivateFlags & PFLAG_DRAWN;
15656
15657             int oldWidth = mRight - mLeft;
15658             int oldHeight = mBottom - mTop;
15659             int newWidth = right - left;
15660             int newHeight = bottom - top;
15661             boolean sizeChanged = (newWidth != oldWidth) || (newHeight != oldHeight);
15662
15663             // Invalidate our old position
15664             invalidate(sizeChanged);
15665
15666             mLeft = left;
15667             mTop = top;
15668             mRight = right;
15669             mBottom = bottom;
15670             mRenderNode.setLeftTopRightBottom(mLeft, mTop, mRight, mBottom);
15671
15672             mPrivateFlags |= PFLAG_HAS_BOUNDS;
15673
15674
15675             if (sizeChanged) {
15676                 sizeChange(newWidth, newHeight, oldWidth, oldHeight);
15677             }
15678
15679             if ((mViewFlags & VISIBILITY_MASK) == VISIBLE) {
15680                 // If we are visible, force the DRAWN bit to on so that
15681                 // this invalidate will go through (at least to our parent).
15682                 // This is because someone may have invalidated this view
15683                 // before this call to setFrame came in, thereby clearing
15684                 // the DRAWN bit.
15685                 mPrivateFlags |= PFLAG_DRAWN;
15686                 invalidate(sizeChanged);
15687                 // parent display list may need to be recreated based on a change in the bounds
15688                 // of any child
15689                 invalidateParentCaches();
15690             }
15691
15692             // Reset drawn bit to original value (invalidate turns it off)
15693             mPrivateFlags |= drawn;
15694
15695             mBackgroundSizeChanged = true;
15696
15697             notifySubtreeAccessibilityStateChangedIfNeeded();
15698         }
15699         return changed;
15700     }
15701
15702     /**
15703      * Same as setFrame, but public and hidden. For use in {@link android.transition.ChangeBounds}.
15704      * @hide
15705      */
15706     public void setLeftTopRightBottom(int left, int top, int right, int bottom) {
15707         setFrame(left, top, right, bottom);
15708     }
15709
15710     private void sizeChange(int newWidth, int newHeight, int oldWidth, int oldHeight) {
15711         onSizeChanged(newWidth, newHeight, oldWidth, oldHeight);
15712         if (mOverlay != null) {
15713             mOverlay.getOverlayView().setRight(newWidth);
15714             mOverlay.getOverlayView().setBottom(newHeight);
15715         }
15716         mPrivateFlags3 |= PFLAG3_OUTLINE_INVALID;
15717     }
15718
15719     /**
15720      * Finalize inflating a view from XML.  This is called as the last phase
15721      * of inflation, after all child views have been added.
15722      *
15723      * <p>Even if the subclass overrides onFinishInflate, they should always be
15724      * sure to call the super method, so that we get called.
15725      */
15726     protected void onFinishInflate() {
15727     }
15728
15729     /**
15730      * Returns the resources associated with this view.
15731      *
15732      * @return Resources object.
15733      */
15734     public Resources getResources() {
15735         return mResources;
15736     }
15737
15738     /**
15739      * Invalidates the specified Drawable.
15740      *
15741      * @param drawable the drawable to invalidate
15742      */
15743     @Override
15744     public void invalidateDrawable(@NonNull Drawable drawable) {
15745         if (verifyDrawable(drawable)) {
15746             final Rect dirty = drawable.getDirtyBounds();
15747             final int scrollX = mScrollX;
15748             final int scrollY = mScrollY;
15749
15750             invalidate(dirty.left + scrollX, dirty.top + scrollY,
15751                     dirty.right + scrollX, dirty.bottom + scrollY);
15752
15753             mPrivateFlags3 |= PFLAG3_OUTLINE_INVALID;
15754         }
15755     }
15756
15757     /**
15758      * Schedules an action on a drawable to occur at a specified time.
15759      *
15760      * @param who the recipient of the action
15761      * @param what the action to run on the drawable
15762      * @param when the time at which the action must occur. Uses the
15763      *        {@link SystemClock#uptimeMillis} timebase.
15764      */
15765     @Override
15766     public void scheduleDrawable(Drawable who, Runnable what, long when) {
15767         if (verifyDrawable(who) && what != null) {
15768             final long delay = when - SystemClock.uptimeMillis();
15769             if (mAttachInfo != null) {
15770                 mAttachInfo.mViewRootImpl.mChoreographer.postCallbackDelayed(
15771                         Choreographer.CALLBACK_ANIMATION, what, who,
15772                         Choreographer.subtractFrameDelay(delay));
15773             } else {
15774                 ViewRootImpl.getRunQueue().postDelayed(what, delay);
15775             }
15776         }
15777     }
15778
15779     /**
15780      * Cancels a scheduled action on a drawable.
15781      *
15782      * @param who the recipient of the action
15783      * @param what the action to cancel
15784      */
15785     @Override
15786     public void unscheduleDrawable(Drawable who, Runnable what) {
15787         if (verifyDrawable(who) && what != null) {
15788             if (mAttachInfo != null) {
15789                 mAttachInfo.mViewRootImpl.mChoreographer.removeCallbacks(
15790                         Choreographer.CALLBACK_ANIMATION, what, who);
15791             }
15792             ViewRootImpl.getRunQueue().removeCallbacks(what);
15793         }
15794     }
15795
15796     /**
15797      * Unschedule any events associated with the given Drawable.  This can be
15798      * used when selecting a new Drawable into a view, so that the previous
15799      * one is completely unscheduled.
15800      *
15801      * @param who The Drawable to unschedule.
15802      *
15803      * @see #drawableStateChanged
15804      */
15805     public void unscheduleDrawable(Drawable who) {
15806         if (mAttachInfo != null && who != null) {
15807             mAttachInfo.mViewRootImpl.mChoreographer.removeCallbacks(
15808                     Choreographer.CALLBACK_ANIMATION, null, who);
15809         }
15810     }
15811
15812     /**
15813      * Resolve the Drawables depending on the layout direction. This is implicitly supposing
15814      * that the View directionality can and will be resolved before its Drawables.
15815      *
15816      * Will call {@link View#onResolveDrawables} when resolution is done.
15817      *
15818      * @hide
15819      */
15820     protected void resolveDrawables() {
15821         // Drawables resolution may need to happen before resolving the layout direction (which is
15822         // done only during the measure() call).
15823         // If the layout direction is not resolved yet, we cannot resolve the Drawables except in
15824         // one case: when the raw layout direction has not been defined as LAYOUT_DIRECTION_INHERIT.
15825         // So, if the raw layout direction is LAYOUT_DIRECTION_LTR or LAYOUT_DIRECTION_RTL or
15826         // LAYOUT_DIRECTION_LOCALE, we can "cheat" and we don't need to wait for the layout
15827         // direction to be resolved as its resolved value will be the same as its raw value.
15828         if (!isLayoutDirectionResolved() &&
15829                 getRawLayoutDirection() == View.LAYOUT_DIRECTION_INHERIT) {
15830             return;
15831         }
15832
15833         final int layoutDirection = isLayoutDirectionResolved() ?
15834                 getLayoutDirection() : getRawLayoutDirection();
15835
15836         if (mBackground != null) {
15837             mBackground.setLayoutDirection(layoutDirection);
15838         }
15839         mPrivateFlags2 |= PFLAG2_DRAWABLE_RESOLVED;
15840         onResolveDrawables(layoutDirection);
15841     }
15842
15843     /**
15844      * Called when layout direction has been resolved.
15845      *
15846      * The default implementation does nothing.
15847      *
15848      * @param layoutDirection The resolved layout direction.
15849      *
15850      * @see #LAYOUT_DIRECTION_LTR
15851      * @see #LAYOUT_DIRECTION_RTL
15852      *
15853      * @hide
15854      */
15855     public void onResolveDrawables(@ResolvedLayoutDir int layoutDirection) {
15856     }
15857
15858     /**
15859      * @hide
15860      */
15861     protected void resetResolvedDrawables() {
15862         mPrivateFlags2 &= ~PFLAG2_DRAWABLE_RESOLVED;
15863     }
15864
15865     private boolean isDrawablesResolved() {
15866         return (mPrivateFlags2 & PFLAG2_DRAWABLE_RESOLVED) == PFLAG2_DRAWABLE_RESOLVED;
15867     }
15868
15869     /**
15870      * If your view subclass is displaying its own Drawable objects, it should
15871      * override this function and return true for any Drawable it is
15872      * displaying.  This allows animations for those drawables to be
15873      * scheduled.
15874      *
15875      * <p>Be sure to call through to the super class when overriding this
15876      * function.
15877      *
15878      * @param who The Drawable to verify.  Return true if it is one you are
15879      *            displaying, else return the result of calling through to the
15880      *            super class.
15881      *
15882      * @return boolean If true than the Drawable is being displayed in the
15883      *         view; else false and it is not allowed to animate.
15884      *
15885      * @see #unscheduleDrawable(android.graphics.drawable.Drawable)
15886      * @see #drawableStateChanged()
15887      */
15888     protected boolean verifyDrawable(Drawable who) {
15889         return who == mBackground;
15890     }
15891
15892     /**
15893      * This function is called whenever the state of the view changes in such
15894      * a way that it impacts the state of drawables being shown.
15895      * <p>
15896      * If the View has a StateListAnimator, it will also be called to run necessary state
15897      * change animations.
15898      * <p>
15899      * Be sure to call through to the superclass when overriding this function.
15900      *
15901      * @see Drawable#setState(int[])
15902      */
15903     protected void drawableStateChanged() {
15904         final Drawable d = mBackground;
15905         if (d != null && d.isStateful()) {
15906             d.setState(getDrawableState());
15907         }
15908
15909         if (mStateListAnimator != null) {
15910             mStateListAnimator.setState(getDrawableState());
15911         }
15912     }
15913
15914     /**
15915      * This function is called whenever the view hotspot changes and needs to
15916      * be propagated to drawables managed by the view.
15917      * <p>
15918      * Be sure to call through to the superclass when overriding this function.
15919      *
15920      * @param x hotspot x coordinate
15921      * @param y hotspot y coordinate
15922      */
15923     public void drawableHotspotChanged(float x, float y) {
15924         if (mBackground != null) {
15925             mBackground.setHotspot(x, y);
15926         }
15927     }
15928
15929     /**
15930      * Call this to force a view to update its drawable state. This will cause
15931      * drawableStateChanged to be called on this view. Views that are interested
15932      * in the new state should call getDrawableState.
15933      *
15934      * @see #drawableStateChanged
15935      * @see #getDrawableState
15936      */
15937     public void refreshDrawableState() {
15938         mPrivateFlags |= PFLAG_DRAWABLE_STATE_DIRTY;
15939         drawableStateChanged();
15940
15941         ViewParent parent = mParent;
15942         if (parent != null) {
15943             parent.childDrawableStateChanged(this);
15944         }
15945     }
15946
15947     /**
15948      * Return an array of resource IDs of the drawable states representing the
15949      * current state of the view.
15950      *
15951      * @return The current drawable state
15952      *
15953      * @see Drawable#setState(int[])
15954      * @see #drawableStateChanged()
15955      * @see #onCreateDrawableState(int)
15956      */
15957     public final int[] getDrawableState() {
15958         if ((mDrawableState != null) && ((mPrivateFlags & PFLAG_DRAWABLE_STATE_DIRTY) == 0)) {
15959             return mDrawableState;
15960         } else {
15961             mDrawableState = onCreateDrawableState(0);
15962             mPrivateFlags &= ~PFLAG_DRAWABLE_STATE_DIRTY;
15963             return mDrawableState;
15964         }
15965     }
15966
15967     /**
15968      * Generate the new {@link android.graphics.drawable.Drawable} state for
15969      * this view. This is called by the view
15970      * system when the cached Drawable state is determined to be invalid.  To
15971      * retrieve the current state, you should use {@link #getDrawableState}.
15972      *
15973      * @param extraSpace if non-zero, this is the number of extra entries you
15974      * would like in the returned array in which you can place your own
15975      * states.
15976      *
15977      * @return Returns an array holding the current {@link Drawable} state of
15978      * the view.
15979      *
15980      * @see #mergeDrawableStates(int[], int[])
15981      */
15982     protected int[] onCreateDrawableState(int extraSpace) {
15983         if ((mViewFlags & DUPLICATE_PARENT_STATE) == DUPLICATE_PARENT_STATE &&
15984                 mParent instanceof View) {
15985             return ((View) mParent).onCreateDrawableState(extraSpace);
15986         }
15987
15988         int[] drawableState;
15989
15990         int privateFlags = mPrivateFlags;
15991
15992         int viewStateIndex = 0;
15993         if ((privateFlags & PFLAG_PRESSED) != 0) viewStateIndex |= VIEW_STATE_PRESSED;
15994         if ((mViewFlags & ENABLED_MASK) == ENABLED) viewStateIndex |= VIEW_STATE_ENABLED;
15995         if (isFocused()) viewStateIndex |= VIEW_STATE_FOCUSED;
15996         if ((privateFlags & PFLAG_SELECTED) != 0) viewStateIndex |= VIEW_STATE_SELECTED;
15997         if (hasWindowFocus()) viewStateIndex |= VIEW_STATE_WINDOW_FOCUSED;
15998         if ((privateFlags & PFLAG_ACTIVATED) != 0) viewStateIndex |= VIEW_STATE_ACTIVATED;
15999         if (mAttachInfo != null && mAttachInfo.mHardwareAccelerationRequested &&
16000                 HardwareRenderer.isAvailable()) {
16001             // This is set if HW acceleration is requested, even if the current
16002             // process doesn't allow it.  This is just to allow app preview
16003             // windows to better match their app.
16004             viewStateIndex |= VIEW_STATE_ACCELERATED;
16005         }
16006         if ((privateFlags & PFLAG_HOVERED) != 0) viewStateIndex |= VIEW_STATE_HOVERED;
16007
16008         final int privateFlags2 = mPrivateFlags2;
16009         if ((privateFlags2 & PFLAG2_DRAG_CAN_ACCEPT) != 0) viewStateIndex |= VIEW_STATE_DRAG_CAN_ACCEPT;
16010         if ((privateFlags2 & PFLAG2_DRAG_HOVERED) != 0) viewStateIndex |= VIEW_STATE_DRAG_HOVERED;
16011
16012         drawableState = VIEW_STATE_SETS[viewStateIndex];
16013
16014         //noinspection ConstantIfStatement
16015         if (false) {
16016             Log.i("View", "drawableStateIndex=" + viewStateIndex);
16017             Log.i("View", toString()
16018                     + " pressed=" + ((privateFlags & PFLAG_PRESSED) != 0)
16019                     + " en=" + ((mViewFlags & ENABLED_MASK) == ENABLED)
16020                     + " fo=" + hasFocus()
16021                     + " sl=" + ((privateFlags & PFLAG_SELECTED) != 0)
16022                     + " wf=" + hasWindowFocus()
16023                     + ": " + Arrays.toString(drawableState));
16024         }
16025
16026         if (extraSpace == 0) {
16027             return drawableState;
16028         }
16029
16030         final int[] fullState;
16031         if (drawableState != null) {
16032             fullState = new int[drawableState.length + extraSpace];
16033             System.arraycopy(drawableState, 0, fullState, 0, drawableState.length);
16034         } else {
16035             fullState = new int[extraSpace];
16036         }
16037
16038         return fullState;
16039     }
16040
16041     /**
16042      * Merge your own state values in <var>additionalState</var> into the base
16043      * state values <var>baseState</var> that were returned by
16044      * {@link #onCreateDrawableState(int)}.
16045      *
16046      * @param baseState The base state values returned by
16047      * {@link #onCreateDrawableState(int)}, which will be modified to also hold your
16048      * own additional state values.
16049      *
16050      * @param additionalState The additional state values you would like
16051      * added to <var>baseState</var>; this array is not modified.
16052      *
16053      * @return As a convenience, the <var>baseState</var> array you originally
16054      * passed into the function is returned.
16055      *
16056      * @see #onCreateDrawableState(int)
16057      */
16058     protected static int[] mergeDrawableStates(int[] baseState, int[] additionalState) {
16059         final int N = baseState.length;
16060         int i = N - 1;
16061         while (i >= 0 && baseState[i] == 0) {
16062             i--;
16063         }
16064         System.arraycopy(additionalState, 0, baseState, i + 1, additionalState.length);
16065         return baseState;
16066     }
16067
16068     /**
16069      * Call {@link Drawable#jumpToCurrentState() Drawable.jumpToCurrentState()}
16070      * on all Drawable objects associated with this view.
16071      * <p>
16072      * Also calls {@link StateListAnimator#jumpToCurrentState()} if there is a StateListAnimator
16073      * attached to this view.
16074      */
16075     public void jumpDrawablesToCurrentState() {
16076         if (mBackground != null) {
16077             mBackground.jumpToCurrentState();
16078         }
16079         if (mStateListAnimator != null) {
16080             mStateListAnimator.jumpToCurrentState();
16081         }
16082     }
16083
16084     /**
16085      * Sets the background color for this view.
16086      * @param color the color of the background
16087      */
16088     @RemotableViewMethod
16089     public void setBackgroundColor(int color) {
16090         if (mBackground instanceof ColorDrawable) {
16091             ((ColorDrawable) mBackground.mutate()).setColor(color);
16092             computeOpaqueFlags();
16093             mBackgroundResource = 0;
16094         } else {
16095             setBackground(new ColorDrawable(color));
16096         }
16097     }
16098
16099     /**
16100      * Set the background to a given resource. The resource should refer to
16101      * a Drawable object or 0 to remove the background.
16102      * @param resid The identifier of the resource.
16103      *
16104      * @attr ref android.R.styleable#View_background
16105      */
16106     @RemotableViewMethod
16107     public void setBackgroundResource(int resid) {
16108         if (resid != 0 && resid == mBackgroundResource) {
16109             return;
16110         }
16111
16112         Drawable d = null;
16113         if (resid != 0) {
16114             d = mContext.getDrawable(resid);
16115         }
16116         setBackground(d);
16117
16118         mBackgroundResource = resid;
16119     }
16120
16121     /**
16122      * Set the background to a given Drawable, or remove the background. If the
16123      * background has padding, this View's padding is set to the background's
16124      * padding. However, when a background is removed, this View's padding isn't
16125      * touched. If setting the padding is desired, please use
16126      * {@link #setPadding(int, int, int, int)}.
16127      *
16128      * @param background The Drawable to use as the background, or null to remove the
16129      *        background
16130      */
16131     public void setBackground(Drawable background) {
16132         //noinspection deprecation
16133         setBackgroundDrawable(background);
16134     }
16135
16136     /**
16137      * @deprecated use {@link #setBackground(Drawable)} instead
16138      */
16139     @Deprecated
16140     public void setBackgroundDrawable(Drawable background) {
16141         computeOpaqueFlags();
16142
16143         if (background == mBackground) {
16144             return;
16145         }
16146
16147         boolean requestLayout = false;
16148
16149         mBackgroundResource = 0;
16150
16151         /*
16152          * Regardless of whether we're setting a new background or not, we want
16153          * to clear the previous drawable.
16154          */
16155         if (mBackground != null) {
16156             mBackground.setCallback(null);
16157             unscheduleDrawable(mBackground);
16158         }
16159
16160         if (background != null) {
16161             Rect padding = sThreadLocal.get();
16162             if (padding == null) {
16163                 padding = new Rect();
16164                 sThreadLocal.set(padding);
16165             }
16166             resetResolvedDrawables();
16167             background.setLayoutDirection(getLayoutDirection());
16168             if (background.getPadding(padding)) {
16169                 resetResolvedPadding();
16170                 switch (background.getLayoutDirection()) {
16171                     case LAYOUT_DIRECTION_RTL:
16172                         mUserPaddingLeftInitial = padding.right;
16173                         mUserPaddingRightInitial = padding.left;
16174                         internalSetPadding(padding.right, padding.top, padding.left, padding.bottom);
16175                         break;
16176                     case LAYOUT_DIRECTION_LTR:
16177                     default:
16178                         mUserPaddingLeftInitial = padding.left;
16179                         mUserPaddingRightInitial = padding.right;
16180                         internalSetPadding(padding.left, padding.top, padding.right, padding.bottom);
16181                 }
16182                 mLeftPaddingDefined = false;
16183                 mRightPaddingDefined = false;
16184             }
16185
16186             // Compare the minimum sizes of the old Drawable and the new.  If there isn't an old or
16187             // if it has a different minimum size, we should layout again
16188             if (mBackground == null
16189                     || mBackground.getMinimumHeight() != background.getMinimumHeight()
16190                     || mBackground.getMinimumWidth() != background.getMinimumWidth()) {
16191                 requestLayout = true;
16192             }
16193
16194             background.setCallback(this);
16195             if (background.isStateful()) {
16196                 background.setState(getDrawableState());
16197             }
16198             background.setVisible(getVisibility() == VISIBLE, false);
16199             mBackground = background;
16200
16201             applyBackgroundTint();
16202
16203             if ((mPrivateFlags & PFLAG_SKIP_DRAW) != 0) {
16204                 mPrivateFlags &= ~PFLAG_SKIP_DRAW;
16205                 mPrivateFlags |= PFLAG_ONLY_DRAWS_BACKGROUND;
16206                 requestLayout = true;
16207             }
16208         } else {
16209             /* Remove the background */
16210             mBackground = null;
16211
16212             if ((mPrivateFlags & PFLAG_ONLY_DRAWS_BACKGROUND) != 0) {
16213                 /*
16214                  * This view ONLY drew the background before and we're removing
16215                  * the background, so now it won't draw anything
16216                  * (hence we SKIP_DRAW)
16217                  */
16218                 mPrivateFlags &= ~PFLAG_ONLY_DRAWS_BACKGROUND;
16219                 mPrivateFlags |= PFLAG_SKIP_DRAW;
16220             }
16221
16222             /*
16223              * When the background is set, we try to apply its padding to this
16224              * View. When the background is removed, we don't touch this View's
16225              * padding. This is noted in the Javadocs. Hence, we don't need to
16226              * requestLayout(), the invalidate() below is sufficient.
16227              */
16228
16229             // The old background's minimum size could have affected this
16230             // View's layout, so let's requestLayout
16231             requestLayout = true;
16232         }
16233
16234         computeOpaqueFlags();
16235
16236         if (requestLayout) {
16237             requestLayout();
16238         }
16239
16240         mBackgroundSizeChanged = true;
16241         invalidate(true);
16242     }
16243
16244     /**
16245      * Gets the background drawable
16246      *
16247      * @return The drawable used as the background for this view, if any.
16248      *
16249      * @see #setBackground(Drawable)
16250      *
16251      * @attr ref android.R.styleable#View_background
16252      */
16253     public Drawable getBackground() {
16254         return mBackground;
16255     }
16256
16257     /**
16258      * Applies a tint to the background drawable. Does not modify the current tint
16259      * mode, which is {@link PorterDuff.Mode#SRC_IN} by default.
16260      * <p>
16261      * Subsequent calls to {@link #setBackground(Drawable)} will automatically
16262      * mutate the drawable and apply the specified tint and tint mode using
16263      * {@link Drawable#setTintList(ColorStateList)}.
16264      *
16265      * @param tint the tint to apply, may be {@code null} to clear tint
16266      *
16267      * @attr ref android.R.styleable#View_backgroundTint
16268      * @see #getBackgroundTintList()
16269      * @see Drawable#setTintList(ColorStateList)
16270      */
16271     public void setBackgroundTintList(@Nullable ColorStateList tint) {
16272         if (mBackgroundTint == null) {
16273             mBackgroundTint = new TintInfo();
16274         }
16275         mBackgroundTint.mTintList = tint;
16276         mBackgroundTint.mHasTintList = true;
16277
16278         applyBackgroundTint();
16279     }
16280
16281     /**
16282      * Return the tint applied to the background drawable, if specified.
16283      *
16284      * @return the tint applied to the background drawable
16285      * @attr ref android.R.styleable#View_backgroundTint
16286      * @see #setBackgroundTintList(ColorStateList)
16287      */
16288     @Nullable
16289     public ColorStateList getBackgroundTintList() {
16290         return mBackgroundTint != null ? mBackgroundTint.mTintList : null;
16291     }
16292
16293     /**
16294      * Specifies the blending mode used to apply the tint specified by
16295      * {@link #setBackgroundTintList(ColorStateList)}} to the background
16296      * drawable. The default mode is {@link PorterDuff.Mode#SRC_IN}.
16297      *
16298      * @param tintMode the blending mode used to apply the tint, may be
16299      *                 {@code null} to clear tint
16300      * @attr ref android.R.styleable#View_backgroundTintMode
16301      * @see #getBackgroundTintMode()
16302      * @see Drawable#setTintMode(PorterDuff.Mode)
16303      */
16304     public void setBackgroundTintMode(@Nullable PorterDuff.Mode tintMode) {
16305         if (mBackgroundTint == null) {
16306             mBackgroundTint = new TintInfo();
16307         }
16308         mBackgroundTint.mTintMode = tintMode;
16309         mBackgroundTint.mHasTintMode = true;
16310
16311         applyBackgroundTint();
16312     }
16313
16314     /**
16315      * Return the blending mode used to apply the tint to the background
16316      * drawable, if specified.
16317      *
16318      * @return the blending mode used to apply the tint to the background
16319      *         drawable
16320      * @attr ref android.R.styleable#View_backgroundTintMode
16321      * @see #setBackgroundTintMode(PorterDuff.Mode)
16322      */
16323     @Nullable
16324     public PorterDuff.Mode getBackgroundTintMode() {
16325         return mBackgroundTint != null ? mBackgroundTint.mTintMode : null;
16326     }
16327
16328     private void applyBackgroundTint() {
16329         if (mBackground != null && mBackgroundTint != null) {
16330             final TintInfo tintInfo = mBackgroundTint;
16331             if (tintInfo.mHasTintList || tintInfo.mHasTintMode) {
16332                 mBackground = mBackground.mutate();
16333
16334                 if (tintInfo.mHasTintList) {
16335                     mBackground.setTintList(tintInfo.mTintList);
16336                 }
16337
16338                 if (tintInfo.mHasTintMode) {
16339                     mBackground.setTintMode(tintInfo.mTintMode);
16340                 }
16341             }
16342         }
16343     }
16344
16345     /**
16346      * Sets the padding. The view may add on the space required to display
16347      * the scrollbars, depending on the style and visibility of the scrollbars.
16348      * So the values returned from {@link #getPaddingLeft}, {@link #getPaddingTop},
16349      * {@link #getPaddingRight} and {@link #getPaddingBottom} may be different
16350      * from the values set in this call.
16351      *
16352      * @attr ref android.R.styleable#View_padding
16353      * @attr ref android.R.styleable#View_paddingBottom
16354      * @attr ref android.R.styleable#View_paddingLeft
16355      * @attr ref android.R.styleable#View_paddingRight
16356      * @attr ref android.R.styleable#View_paddingTop
16357      * @param left the left padding in pixels
16358      * @param top the top padding in pixels
16359      * @param right the right padding in pixels
16360      * @param bottom the bottom padding in pixels
16361      */
16362     public void setPadding(int left, int top, int right, int bottom) {
16363         resetResolvedPadding();
16364
16365         mUserPaddingStart = UNDEFINED_PADDING;
16366         mUserPaddingEnd = UNDEFINED_PADDING;
16367
16368         mUserPaddingLeftInitial = left;
16369         mUserPaddingRightInitial = right;
16370
16371         mLeftPaddingDefined = true;
16372         mRightPaddingDefined = true;
16373
16374         internalSetPadding(left, top, right, bottom);
16375     }
16376
16377     /**
16378      * @hide
16379      */
16380     protected void internalSetPadding(int left, int top, int right, int bottom) {
16381         mUserPaddingLeft = left;
16382         mUserPaddingRight = right;
16383         mUserPaddingBottom = bottom;
16384
16385         final int viewFlags = mViewFlags;
16386         boolean changed = false;
16387
16388         // Common case is there are no scroll bars.
16389         if ((viewFlags & (SCROLLBARS_VERTICAL|SCROLLBARS_HORIZONTAL)) != 0) {
16390             if ((viewFlags & SCROLLBARS_VERTICAL) != 0) {
16391                 final int offset = (viewFlags & SCROLLBARS_INSET_MASK) == 0
16392                         ? 0 : getVerticalScrollbarWidth();
16393                 switch (mVerticalScrollbarPosition) {
16394                     case SCROLLBAR_POSITION_DEFAULT:
16395                         if (isLayoutRtl()) {
16396                             left += offset;
16397                         } else {
16398                             right += offset;
16399                         }
16400                         break;
16401                     case SCROLLBAR_POSITION_RIGHT:
16402                         right += offset;
16403                         break;
16404                     case SCROLLBAR_POSITION_LEFT:
16405                         left += offset;
16406                         break;
16407                 }
16408             }
16409             if ((viewFlags & SCROLLBARS_HORIZONTAL) != 0) {
16410                 bottom += (viewFlags & SCROLLBARS_INSET_MASK) == 0
16411                         ? 0 : getHorizontalScrollbarHeight();
16412             }
16413         }
16414
16415         if (mPaddingLeft != left) {
16416             changed = true;
16417             mPaddingLeft = left;
16418         }
16419         if (mPaddingTop != top) {
16420             changed = true;
16421             mPaddingTop = top;
16422         }
16423         if (mPaddingRight != right) {
16424             changed = true;
16425             mPaddingRight = right;
16426         }
16427         if (mPaddingBottom != bottom) {
16428             changed = true;
16429             mPaddingBottom = bottom;
16430         }
16431
16432         if (changed) {
16433             requestLayout();
16434         }
16435     }
16436
16437     /**
16438      * Sets the relative padding. The view may add on the space required to display
16439      * the scrollbars, depending on the style and visibility of the scrollbars.
16440      * So the values returned from {@link #getPaddingStart}, {@link #getPaddingTop},
16441      * {@link #getPaddingEnd} and {@link #getPaddingBottom} may be different
16442      * from the values set in this call.
16443      *
16444      * @attr ref android.R.styleable#View_padding
16445      * @attr ref android.R.styleable#View_paddingBottom
16446      * @attr ref android.R.styleable#View_paddingStart
16447      * @attr ref android.R.styleable#View_paddingEnd
16448      * @attr ref android.R.styleable#View_paddingTop
16449      * @param start the start padding in pixels
16450      * @param top the top padding in pixels
16451      * @param end the end padding in pixels
16452      * @param bottom the bottom padding in pixels
16453      */
16454     public void setPaddingRelative(int start, int top, int end, int bottom) {
16455         resetResolvedPadding();
16456
16457         mUserPaddingStart = start;
16458         mUserPaddingEnd = end;
16459         mLeftPaddingDefined = true;
16460         mRightPaddingDefined = true;
16461
16462         switch(getLayoutDirection()) {
16463             case LAYOUT_DIRECTION_RTL:
16464                 mUserPaddingLeftInitial = end;
16465                 mUserPaddingRightInitial = start;
16466                 internalSetPadding(end, top, start, bottom);
16467                 break;
16468             case LAYOUT_DIRECTION_LTR:
16469             default:
16470                 mUserPaddingLeftInitial = start;
16471                 mUserPaddingRightInitial = end;
16472                 internalSetPadding(start, top, end, bottom);
16473         }
16474     }
16475
16476     /**
16477      * Returns the top padding of this view.
16478      *
16479      * @return the top padding in pixels
16480      */
16481     public int getPaddingTop() {
16482         return mPaddingTop;
16483     }
16484
16485     /**
16486      * Returns the bottom padding of this view. If there are inset and enabled
16487      * scrollbars, this value may include the space required to display the
16488      * scrollbars as well.
16489      *
16490      * @return the bottom padding in pixels
16491      */
16492     public int getPaddingBottom() {
16493         return mPaddingBottom;
16494     }
16495
16496     /**
16497      * Returns the left padding of this view. If there are inset and enabled
16498      * scrollbars, this value may include the space required to display the
16499      * scrollbars as well.
16500      *
16501      * @return the left padding in pixels
16502      */
16503     public int getPaddingLeft() {
16504         if (!isPaddingResolved()) {
16505             resolvePadding();
16506         }
16507         return mPaddingLeft;
16508     }
16509
16510     /**
16511      * Returns the start padding of this view depending on its resolved layout direction.
16512      * If there are inset and enabled scrollbars, this value may include the space
16513      * required to display the scrollbars as well.
16514      *
16515      * @return the start padding in pixels
16516      */
16517     public int getPaddingStart() {
16518         if (!isPaddingResolved()) {
16519             resolvePadding();
16520         }
16521         return (getLayoutDirection() == LAYOUT_DIRECTION_RTL) ?
16522                 mPaddingRight : mPaddingLeft;
16523     }
16524
16525     /**
16526      * Returns the right padding of this view. If there are inset and enabled
16527      * scrollbars, this value may include the space required to display the
16528      * scrollbars as well.
16529      *
16530      * @return the right padding in pixels
16531      */
16532     public int getPaddingRight() {
16533         if (!isPaddingResolved()) {
16534             resolvePadding();
16535         }
16536         return mPaddingRight;
16537     }
16538
16539     /**
16540      * Returns the end padding of this view depending on its resolved layout direction.
16541      * If there are inset and enabled scrollbars, this value may include the space
16542      * required to display the scrollbars as well.
16543      *
16544      * @return the end padding in pixels
16545      */
16546     public int getPaddingEnd() {
16547         if (!isPaddingResolved()) {
16548             resolvePadding();
16549         }
16550         return (getLayoutDirection() == LAYOUT_DIRECTION_RTL) ?
16551                 mPaddingLeft : mPaddingRight;
16552     }
16553
16554     /**
16555      * Return if the padding as been set thru relative values
16556      * {@link #setPaddingRelative(int, int, int, int)} or thru
16557      * @attr ref android.R.styleable#View_paddingStart or
16558      * @attr ref android.R.styleable#View_paddingEnd
16559      *
16560      * @return true if the padding is relative or false if it is not.
16561      */
16562     public boolean isPaddingRelative() {
16563         return (mUserPaddingStart != UNDEFINED_PADDING || mUserPaddingEnd != UNDEFINED_PADDING);
16564     }
16565
16566     Insets computeOpticalInsets() {
16567         return (mBackground == null) ? Insets.NONE : mBackground.getOpticalInsets();
16568     }
16569
16570     /**
16571      * @hide
16572      */
16573     public void resetPaddingToInitialValues() {
16574         if (isRtlCompatibilityMode()) {
16575             mPaddingLeft = mUserPaddingLeftInitial;
16576             mPaddingRight = mUserPaddingRightInitial;
16577             return;
16578         }
16579         if (isLayoutRtl()) {
16580             mPaddingLeft = (mUserPaddingEnd >= 0) ? mUserPaddingEnd : mUserPaddingLeftInitial;
16581             mPaddingRight = (mUserPaddingStart >= 0) ? mUserPaddingStart : mUserPaddingRightInitial;
16582         } else {
16583             mPaddingLeft = (mUserPaddingStart >= 0) ? mUserPaddingStart : mUserPaddingLeftInitial;
16584             mPaddingRight = (mUserPaddingEnd >= 0) ? mUserPaddingEnd : mUserPaddingRightInitial;
16585         }
16586     }
16587
16588     /**
16589      * @hide
16590      */
16591     public Insets getOpticalInsets() {
16592         if (mLayoutInsets == null) {
16593             mLayoutInsets = computeOpticalInsets();
16594         }
16595         return mLayoutInsets;
16596     }
16597
16598     /**
16599      * Set this view's optical insets.
16600      *
16601      * <p>This method should be treated similarly to setMeasuredDimension and not as a general
16602      * property. Views that compute their own optical insets should call it as part of measurement.
16603      * This method does not request layout. If you are setting optical insets outside of
16604      * measure/layout itself you will want to call requestLayout() yourself.
16605      * </p>
16606      * @hide
16607      */
16608     public void setOpticalInsets(Insets insets) {
16609         mLayoutInsets = insets;
16610     }
16611
16612     /**
16613      * Changes the selection state of this view. A view can be selected or not.
16614      * Note that selection is not the same as focus. Views are typically
16615      * selected in the context of an AdapterView like ListView or GridView;
16616      * the selected view is the view that is highlighted.
16617      *
16618      * @param selected true if the view must be selected, false otherwise
16619      */
16620     public void setSelected(boolean selected) {
16621         //noinspection DoubleNegation
16622         if (((mPrivateFlags & PFLAG_SELECTED) != 0) != selected) {
16623             mPrivateFlags = (mPrivateFlags & ~PFLAG_SELECTED) | (selected ? PFLAG_SELECTED : 0);
16624             if (!selected) resetPressedState();
16625             invalidate(true);
16626             refreshDrawableState();
16627             dispatchSetSelected(selected);
16628             if (selected) {
16629                 sendAccessibilityEvent(AccessibilityEvent.TYPE_VIEW_SELECTED);
16630             } else {
16631                 notifyViewAccessibilityStateChangedIfNeeded(
16632                         AccessibilityEvent.CONTENT_CHANGE_TYPE_UNDEFINED);
16633             }
16634         }
16635     }
16636
16637     /**
16638      * Dispatch setSelected to all of this View's children.
16639      *
16640      * @see #setSelected(boolean)
16641      *
16642      * @param selected The new selected state
16643      */
16644     protected void dispatchSetSelected(boolean selected) {
16645     }
16646
16647     /**
16648      * Indicates the selection state of this view.
16649      *
16650      * @return true if the view is selected, false otherwise
16651      */
16652     @ViewDebug.ExportedProperty
16653     public boolean isSelected() {
16654         return (mPrivateFlags & PFLAG_SELECTED) != 0;
16655     }
16656
16657     /**
16658      * Changes the activated state of this view. A view can be activated or not.
16659      * Note that activation is not the same as selection.  Selection is
16660      * a transient property, representing the view (hierarchy) the user is
16661      * currently interacting with.  Activation is a longer-term state that the
16662      * user can move views in and out of.  For example, in a list view with
16663      * single or multiple selection enabled, the views in the current selection
16664      * set are activated.  (Um, yeah, we are deeply sorry about the terminology
16665      * here.)  The activated state is propagated down to children of the view it
16666      * is set on.
16667      *
16668      * @param activated true if the view must be activated, false otherwise
16669      */
16670     public void setActivated(boolean activated) {
16671         //noinspection DoubleNegation
16672         if (((mPrivateFlags & PFLAG_ACTIVATED) != 0) != activated) {
16673             mPrivateFlags = (mPrivateFlags & ~PFLAG_ACTIVATED) | (activated ? PFLAG_ACTIVATED : 0);
16674             invalidate(true);
16675             refreshDrawableState();
16676             dispatchSetActivated(activated);
16677         }
16678     }
16679
16680     /**
16681      * Dispatch setActivated to all of this View's children.
16682      *
16683      * @see #setActivated(boolean)
16684      *
16685      * @param activated The new activated state
16686      */
16687     protected void dispatchSetActivated(boolean activated) {
16688     }
16689
16690     /**
16691      * Indicates the activation state of this view.
16692      *
16693      * @return true if the view is activated, false otherwise
16694      */
16695     @ViewDebug.ExportedProperty
16696     public boolean isActivated() {
16697         return (mPrivateFlags & PFLAG_ACTIVATED) != 0;
16698     }
16699
16700     /**
16701      * Returns the ViewTreeObserver for this view's hierarchy. The view tree
16702      * observer can be used to get notifications when global events, like
16703      * layout, happen.
16704      *
16705      * The returned ViewTreeObserver observer is not guaranteed to remain
16706      * valid for the lifetime of this View. If the caller of this method keeps
16707      * a long-lived reference to ViewTreeObserver, it should always check for
16708      * the return value of {@link ViewTreeObserver#isAlive()}.
16709      *
16710      * @return The ViewTreeObserver for this view's hierarchy.
16711      */
16712     public ViewTreeObserver getViewTreeObserver() {
16713         if (mAttachInfo != null) {
16714             return mAttachInfo.mTreeObserver;
16715         }
16716         if (mFloatingTreeObserver == null) {
16717             mFloatingTreeObserver = new ViewTreeObserver();
16718         }
16719         return mFloatingTreeObserver;
16720     }
16721
16722     /**
16723      * <p>Finds the topmost view in the current view hierarchy.</p>
16724      *
16725      * @return the topmost view containing this view
16726      */
16727     public View getRootView() {
16728         if (mAttachInfo != null) {
16729             final View v = mAttachInfo.mRootView;
16730             if (v != null) {
16731                 return v;
16732             }
16733         }
16734
16735         View parent = this;
16736
16737         while (parent.mParent != null && parent.mParent instanceof View) {
16738             parent = (View) parent.mParent;
16739         }
16740
16741         return parent;
16742     }
16743
16744     /**
16745      * Transforms a motion event from view-local coordinates to on-screen
16746      * coordinates.
16747      *
16748      * @param ev the view-local motion event
16749      * @return false if the transformation could not be applied
16750      * @hide
16751      */
16752     public boolean toGlobalMotionEvent(MotionEvent ev) {
16753         final AttachInfo info = mAttachInfo;
16754         if (info == null) {
16755             return false;
16756         }
16757
16758         final Matrix m = info.mTmpMatrix;
16759         m.set(Matrix.IDENTITY_MATRIX);
16760         transformMatrixToGlobal(m);
16761         ev.transform(m);
16762         return true;
16763     }
16764
16765     /**
16766      * Transforms a motion event from on-screen coordinates to view-local
16767      * coordinates.
16768      *
16769      * @param ev the on-screen motion event
16770      * @return false if the transformation could not be applied
16771      * @hide
16772      */
16773     public boolean toLocalMotionEvent(MotionEvent ev) {
16774         final AttachInfo info = mAttachInfo;
16775         if (info == null) {
16776             return false;
16777         }
16778
16779         final Matrix m = info.mTmpMatrix;
16780         m.set(Matrix.IDENTITY_MATRIX);
16781         transformMatrixToLocal(m);
16782         ev.transform(m);
16783         return true;
16784     }
16785
16786     /**
16787      * Modifies the input matrix such that it maps view-local coordinates to
16788      * on-screen coordinates.
16789      *
16790      * @param m input matrix to modify
16791      * @hide
16792      */
16793     public void transformMatrixToGlobal(Matrix m) {
16794         final ViewParent parent = mParent;
16795         if (parent instanceof View) {
16796             final View vp = (View) parent;
16797             vp.transformMatrixToGlobal(m);
16798             m.preTranslate(-vp.mScrollX, -vp.mScrollY);
16799         } else if (parent instanceof ViewRootImpl) {
16800             final ViewRootImpl vr = (ViewRootImpl) parent;
16801             vr.transformMatrixToGlobal(m);
16802             m.preTranslate(0, -vr.mCurScrollY);
16803         }
16804
16805         m.preTranslate(mLeft, mTop);
16806
16807         if (!hasIdentityMatrix()) {
16808             m.preConcat(getMatrix());
16809         }
16810     }
16811
16812     /**
16813      * Modifies the input matrix such that it maps on-screen coordinates to
16814      * view-local coordinates.
16815      *
16816      * @param m input matrix to modify
16817      * @hide
16818      */
16819     public void transformMatrixToLocal(Matrix m) {
16820         final ViewParent parent = mParent;
16821         if (parent instanceof View) {
16822             final View vp = (View) parent;
16823             vp.transformMatrixToLocal(m);
16824             m.postTranslate(vp.mScrollX, vp.mScrollY);
16825         } else if (parent instanceof ViewRootImpl) {
16826             final ViewRootImpl vr = (ViewRootImpl) parent;
16827             vr.transformMatrixToLocal(m);
16828             m.postTranslate(0, vr.mCurScrollY);
16829         }
16830
16831         m.postTranslate(-mLeft, -mTop);
16832
16833         if (!hasIdentityMatrix()) {
16834             m.postConcat(getInverseMatrix());
16835         }
16836     }
16837
16838     /**
16839      * @hide
16840      */
16841     @ViewDebug.ExportedProperty(category = "layout", indexMapping = {
16842             @ViewDebug.IntToString(from = 0, to = "x"),
16843             @ViewDebug.IntToString(from = 1, to = "y")
16844     })
16845     public int[] getLocationOnScreen() {
16846         int[] location = new int[2];
16847         getLocationOnScreen(location);
16848         return location;
16849     }
16850
16851     /**
16852      * <p>Computes the coordinates of this view on the screen. The argument
16853      * must be an array of two integers. After the method returns, the array
16854      * contains the x and y location in that order.</p>
16855      *
16856      * @param location an array of two integers in which to hold the coordinates
16857      */
16858     public void getLocationOnScreen(int[] location) {
16859         getLocationInWindow(location);
16860
16861         final AttachInfo info = mAttachInfo;
16862         if (info != null) {
16863             location[0] += info.mWindowLeft;
16864             location[1] += info.mWindowTop;
16865         }
16866     }
16867
16868     /**
16869      * <p>Computes the coordinates of this view in its window. The argument
16870      * must be an array of two integers. After the method returns, the array
16871      * contains the x and y location in that order.</p>
16872      *
16873      * @param location an array of two integers in which to hold the coordinates
16874      */
16875     public void getLocationInWindow(int[] location) {
16876         if (location == null || location.length < 2) {
16877             throw new IllegalArgumentException("location must be an array of two integers");
16878         }
16879
16880         if (mAttachInfo == null) {
16881             // When the view is not attached to a window, this method does not make sense
16882             location[0] = location[1] = 0;
16883             return;
16884         }
16885
16886         float[] position = mAttachInfo.mTmpTransformLocation;
16887         position[0] = position[1] = 0.0f;
16888
16889         if (!hasIdentityMatrix()) {
16890             getMatrix().mapPoints(position);
16891         }
16892
16893         position[0] += mLeft;
16894         position[1] += mTop;
16895
16896         ViewParent viewParent = mParent;
16897         while (viewParent instanceof View) {
16898             final View view = (View) viewParent;
16899
16900             position[0] -= view.mScrollX;
16901             position[1] -= view.mScrollY;
16902
16903             if (!view.hasIdentityMatrix()) {
16904                 view.getMatrix().mapPoints(position);
16905             }
16906
16907             position[0] += view.mLeft;
16908             position[1] += view.mTop;
16909
16910             viewParent = view.mParent;
16911          }
16912
16913         if (viewParent instanceof ViewRootImpl) {
16914             // *cough*
16915             final ViewRootImpl vr = (ViewRootImpl) viewParent;
16916             position[1] -= vr.mCurScrollY;
16917         }
16918
16919         location[0] = (int) (position[0] + 0.5f);
16920         location[1] = (int) (position[1] + 0.5f);
16921     }
16922
16923     /**
16924      * {@hide}
16925      * @param id the id of the view to be found
16926      * @return the view of the specified id, null if cannot be found
16927      */
16928     protected View findViewTraversal(int id) {
16929         if (id == mID) {
16930             return this;
16931         }
16932         return null;
16933     }
16934
16935     /**
16936      * {@hide}
16937      * @param tag the tag of the view to be found
16938      * @return the view of specified tag, null if cannot be found
16939      */
16940     protected View findViewWithTagTraversal(Object tag) {
16941         if (tag != null && tag.equals(mTag)) {
16942             return this;
16943         }
16944         return null;
16945     }
16946
16947     /**
16948      * {@hide}
16949      * @param predicate The predicate to evaluate.
16950      * @param childToSkip If not null, ignores this child during the recursive traversal.
16951      * @return The first view that matches the predicate or null.
16952      */
16953     protected View findViewByPredicateTraversal(Predicate<View> predicate, View childToSkip) {
16954         if (predicate.apply(this)) {
16955             return this;
16956         }
16957         return null;
16958     }
16959
16960     /**
16961      * Look for a child view with the given id.  If this view has the given
16962      * id, return this view.
16963      *
16964      * @param id The id to search for.
16965      * @return The view that has the given id in the hierarchy or null
16966      */
16967     public final View findViewById(int id) {
16968         if (id < 0) {
16969             return null;
16970         }
16971         return findViewTraversal(id);
16972     }
16973
16974     /**
16975      * Finds a view by its unuque and stable accessibility id.
16976      *
16977      * @param accessibilityId The searched accessibility id.
16978      * @return The found view.
16979      */
16980     final View findViewByAccessibilityId(int accessibilityId) {
16981         if (accessibilityId < 0) {
16982             return null;
16983         }
16984         return findViewByAccessibilityIdTraversal(accessibilityId);
16985     }
16986
16987     /**
16988      * Performs the traversal to find a view by its unuque and stable accessibility id.
16989      *
16990      * <strong>Note:</strong>This method does not stop at the root namespace
16991      * boundary since the user can touch the screen at an arbitrary location
16992      * potentially crossing the root namespace bounday which will send an
16993      * accessibility event to accessibility services and they should be able
16994      * to obtain the event source. Also accessibility ids are guaranteed to be
16995      * unique in the window.
16996      *
16997      * @param accessibilityId The accessibility id.
16998      * @return The found view.
16999      *
17000      * @hide
17001      */
17002     public View findViewByAccessibilityIdTraversal(int accessibilityId) {
17003         if (getAccessibilityViewId() == accessibilityId) {
17004             return this;
17005         }
17006         return null;
17007     }
17008
17009     /**
17010      * Look for a child view with the given tag.  If this view has the given
17011      * tag, return this view.
17012      *
17013      * @param tag The tag to search for, using "tag.equals(getTag())".
17014      * @return The View that has the given tag in the hierarchy or null
17015      */
17016     public final View findViewWithTag(Object tag) {
17017         if (tag == null) {
17018             return null;
17019         }
17020         return findViewWithTagTraversal(tag);
17021     }
17022
17023     /**
17024      * {@hide}
17025      * Look for a child view that matches the specified predicate.
17026      * If this view matches the predicate, return this view.
17027      *
17028      * @param predicate The predicate to evaluate.
17029      * @return The first view that matches the predicate or null.
17030      */
17031     public final View findViewByPredicate(Predicate<View> predicate) {
17032         return findViewByPredicateTraversal(predicate, null);
17033     }
17034
17035     /**
17036      * {@hide}
17037      * Look for a child view that matches the specified predicate,
17038      * starting with the specified view and its descendents and then
17039      * recusively searching the ancestors and siblings of that view
17040      * until this view is reached.
17041      *
17042      * This method is useful in cases where the predicate does not match
17043      * a single unique view (perhaps multiple views use the same id)
17044      * and we are trying to find the view that is "closest" in scope to the
17045      * starting view.
17046      *
17047      * @param start The view to start from.
17048      * @param predicate The predicate to evaluate.
17049      * @return The first view that matches the predicate or null.
17050      */
17051     public final View findViewByPredicateInsideOut(View start, Predicate<View> predicate) {
17052         View childToSkip = null;
17053         for (;;) {
17054             View view = start.findViewByPredicateTraversal(predicate, childToSkip);
17055             if (view != null || start == this) {
17056                 return view;
17057             }
17058
17059             ViewParent parent = start.getParent();
17060             if (parent == null || !(parent instanceof View)) {
17061                 return null;
17062             }
17063
17064             childToSkip = start;
17065             start = (View) parent;
17066         }
17067     }
17068
17069     /**
17070      * Sets the identifier for this view. The identifier does not have to be
17071      * unique in this view's hierarchy. The identifier should be a positive
17072      * number.
17073      *
17074      * @see #NO_ID
17075      * @see #getId()
17076      * @see #findViewById(int)
17077      *
17078      * @param id a number used to identify the view
17079      *
17080      * @attr ref android.R.styleable#View_id
17081      */
17082     public void setId(int id) {
17083         mID = id;
17084         if (mID == View.NO_ID && mLabelForId != View.NO_ID) {
17085             mID = generateViewId();
17086         }
17087     }
17088
17089     /**
17090      * {@hide}
17091      *
17092      * @param isRoot true if the view belongs to the root namespace, false
17093      *        otherwise
17094      */
17095     public void setIsRootNamespace(boolean isRoot) {
17096         if (isRoot) {
17097             mPrivateFlags |= PFLAG_IS_ROOT_NAMESPACE;
17098         } else {
17099             mPrivateFlags &= ~PFLAG_IS_ROOT_NAMESPACE;
17100         }
17101     }
17102
17103     /**
17104      * {@hide}
17105      *
17106      * @return true if the view belongs to the root namespace, false otherwise
17107      */
17108     public boolean isRootNamespace() {
17109         return (mPrivateFlags&PFLAG_IS_ROOT_NAMESPACE) != 0;
17110     }
17111
17112     /**
17113      * Returns this view's identifier.
17114      *
17115      * @return a positive integer used to identify the view or {@link #NO_ID}
17116      *         if the view has no ID
17117      *
17118      * @see #setId(int)
17119      * @see #findViewById(int)
17120      * @attr ref android.R.styleable#View_id
17121      */
17122     @ViewDebug.CapturedViewProperty
17123     public int getId() {
17124         return mID;
17125     }
17126
17127     /**
17128      * Returns this view's tag.
17129      *
17130      * @return the Object stored in this view as a tag, or {@code null} if not
17131      *         set
17132      *
17133      * @see #setTag(Object)
17134      * @see #getTag(int)
17135      */
17136     @ViewDebug.ExportedProperty
17137     public Object getTag() {
17138         return mTag;
17139     }
17140
17141     /**
17142      * Sets the tag associated with this view. A tag can be used to mark
17143      * a view in its hierarchy and does not have to be unique within the
17144      * hierarchy. Tags can also be used to store data within a view without
17145      * resorting to another data structure.
17146      *
17147      * @param tag an Object to tag the view with
17148      *
17149      * @see #getTag()
17150      * @see #setTag(int, Object)
17151      */
17152     public void setTag(final Object tag) {
17153         mTag = tag;
17154     }
17155
17156     /**
17157      * Returns the tag associated with this view and the specified key.
17158      *
17159      * @param key The key identifying the tag
17160      *
17161      * @return the Object stored in this view as a tag, or {@code null} if not
17162      *         set
17163      *
17164      * @see #setTag(int, Object)
17165      * @see #getTag()
17166      */
17167     public Object getTag(int key) {
17168         if (mKeyedTags != null) return mKeyedTags.get(key);
17169         return null;
17170     }
17171
17172     /**
17173      * Sets a tag associated with this view and a key. A tag can be used
17174      * to mark a view in its hierarchy and does not have to be unique within
17175      * the hierarchy. Tags can also be used to store data within a view
17176      * without resorting to another data structure.
17177      *
17178      * The specified key should be an id declared in the resources of the
17179      * application to ensure it is unique (see the <a
17180      * href={@docRoot}guide/topics/resources/more-resources.html#Id">ID resource type</a>).
17181      * Keys identified as belonging to
17182      * the Android framework or not associated with any package will cause
17183      * an {@link IllegalArgumentException} to be thrown.
17184      *
17185      * @param key The key identifying the tag
17186      * @param tag An Object to tag the view with
17187      *
17188      * @throws IllegalArgumentException If they specified key is not valid
17189      *
17190      * @see #setTag(Object)
17191      * @see #getTag(int)
17192      */
17193     public void setTag(int key, final Object tag) {
17194         // If the package id is 0x00 or 0x01, it's either an undefined package
17195         // or a framework id
17196         if ((key >>> 24) < 2) {
17197             throw new IllegalArgumentException("The key must be an application-specific "
17198                     + "resource id.");
17199         }
17200
17201         setKeyedTag(key, tag);
17202     }
17203
17204     /**
17205      * Variation of {@link #setTag(int, Object)} that enforces the key to be a
17206      * framework id.
17207      *
17208      * @hide
17209      */
17210     public void setTagInternal(int key, Object tag) {
17211         if ((key >>> 24) != 0x1) {
17212             throw new IllegalArgumentException("The key must be a framework-specific "
17213                     + "resource id.");
17214         }
17215
17216         setKeyedTag(key, tag);
17217     }
17218
17219     private void setKeyedTag(int key, Object tag) {
17220         if (mKeyedTags == null) {
17221             mKeyedTags = new SparseArray<Object>(2);
17222         }
17223
17224         mKeyedTags.put(key, tag);
17225     }
17226
17227     /**
17228      * Prints information about this view in the log output, with the tag
17229      * {@link #VIEW_LOG_TAG}.
17230      *
17231      * @hide
17232      */
17233     public void debug() {
17234         debug(0);
17235     }
17236
17237     /**
17238      * Prints information about this view in the log output, with the tag
17239      * {@link #VIEW_LOG_TAG}. Each line in the output is preceded with an
17240      * indentation defined by the <code>depth</code>.
17241      *
17242      * @param depth the indentation level
17243      *
17244      * @hide
17245      */
17246     protected void debug(int depth) {
17247         String output = debugIndent(depth - 1);
17248
17249         output += "+ " + this;
17250         int id = getId();
17251         if (id != -1) {
17252             output += " (id=" + id + ")";
17253         }
17254         Object tag = getTag();
17255         if (tag != null) {
17256             output += " (tag=" + tag + ")";
17257         }
17258         Log.d(VIEW_LOG_TAG, output);
17259
17260         if ((mPrivateFlags & PFLAG_FOCUSED) != 0) {
17261             output = debugIndent(depth) + " FOCUSED";
17262             Log.d(VIEW_LOG_TAG, output);
17263         }
17264
17265         output = debugIndent(depth);
17266         output += "frame={" + mLeft + ", " + mTop + ", " + mRight
17267                 + ", " + mBottom + "} scroll={" + mScrollX + ", " + mScrollY
17268                 + "} ";
17269         Log.d(VIEW_LOG_TAG, output);
17270
17271         if (mPaddingLeft != 0 || mPaddingTop != 0 || mPaddingRight != 0
17272                 || mPaddingBottom != 0) {
17273             output = debugIndent(depth);
17274             output += "padding={" + mPaddingLeft + ", " + mPaddingTop
17275                     + ", " + mPaddingRight + ", " + mPaddingBottom + "}";
17276             Log.d(VIEW_LOG_TAG, output);
17277         }
17278
17279         output = debugIndent(depth);
17280         output += "mMeasureWidth=" + mMeasuredWidth +
17281                 " mMeasureHeight=" + mMeasuredHeight;
17282         Log.d(VIEW_LOG_TAG, output);
17283
17284         output = debugIndent(depth);
17285         if (mLayoutParams == null) {
17286             output += "BAD! no layout params";
17287         } else {
17288             output = mLayoutParams.debug(output);
17289         }
17290         Log.d(VIEW_LOG_TAG, output);
17291
17292         output = debugIndent(depth);
17293         output += "flags={";
17294         output += View.printFlags(mViewFlags);
17295         output += "}";
17296         Log.d(VIEW_LOG_TAG, output);
17297
17298         output = debugIndent(depth);
17299         output += "privateFlags={";
17300         output += View.printPrivateFlags(mPrivateFlags);
17301         output += "}";
17302         Log.d(VIEW_LOG_TAG, output);
17303     }
17304
17305     /**
17306      * Creates a string of whitespaces used for indentation.
17307      *
17308      * @param depth the indentation level
17309      * @return a String containing (depth * 2 + 3) * 2 white spaces
17310      *
17311      * @hide
17312      */
17313     protected static String debugIndent(int depth) {
17314         StringBuilder spaces = new StringBuilder((depth * 2 + 3) * 2);
17315         for (int i = 0; i < (depth * 2) + 3; i++) {
17316             spaces.append(' ').append(' ');
17317         }
17318         return spaces.toString();
17319     }
17320
17321     /**
17322      * <p>Return the offset of the widget's text baseline from the widget's top
17323      * boundary. If this widget does not support baseline alignment, this
17324      * method returns -1. </p>
17325      *
17326      * @return the offset of the baseline within the widget's bounds or -1
17327      *         if baseline alignment is not supported
17328      */
17329     @ViewDebug.ExportedProperty(category = "layout")
17330     public int getBaseline() {
17331         return -1;
17332     }
17333
17334     /**
17335      * Returns whether the view hierarchy is currently undergoing a layout pass. This
17336      * information is useful to avoid situations such as calling {@link #requestLayout()} during
17337      * a layout pass.
17338      *
17339      * @return whether the view hierarchy is currently undergoing a layout pass
17340      */
17341     public boolean isInLayout() {
17342         ViewRootImpl viewRoot = getViewRootImpl();
17343         return (viewRoot != null && viewRoot.isInLayout());
17344     }
17345
17346     /**
17347      * Call this when something has changed which has invalidated the
17348      * layout of this view. This will schedule a layout pass of the view
17349      * tree. This should not be called while the view hierarchy is currently in a layout
17350      * pass ({@link #isInLayout()}. If layout is happening, the request may be honored at the
17351      * end of the current layout pass (and then layout will run again) or after the current
17352      * frame is drawn and the next layout occurs.
17353      *
17354      * <p>Subclasses which override this method should call the superclass method to
17355      * handle possible request-during-layout errors correctly.</p>
17356      */
17357     public void requestLayout() {
17358         if (mMeasureCache != null) mMeasureCache.clear();
17359
17360         if (mAttachInfo != null && mAttachInfo.mViewRequestingLayout == null) {
17361             // Only trigger request-during-layout logic if this is the view requesting it,
17362             // not the views in its parent hierarchy
17363             ViewRootImpl viewRoot = getViewRootImpl();
17364             if (viewRoot != null && viewRoot.isInLayout()) {
17365                 if (!viewRoot.requestLayoutDuringLayout(this)) {
17366                     return;
17367                 }
17368             }
17369             mAttachInfo.mViewRequestingLayout = this;
17370         }
17371
17372         mPrivateFlags |= PFLAG_FORCE_LAYOUT;
17373         mPrivateFlags |= PFLAG_INVALIDATED;
17374
17375         if (mParent != null && !mParent.isLayoutRequested()) {
17376             mParent.requestLayout();
17377         }
17378         if (mAttachInfo != null && mAttachInfo.mViewRequestingLayout == this) {
17379             mAttachInfo.mViewRequestingLayout = null;
17380         }
17381     }
17382
17383     /**
17384      * Forces this view to be laid out during the next layout pass.
17385      * This method does not call requestLayout() or forceLayout()
17386      * on the parent.
17387      */
17388     public void forceLayout() {
17389         if (mMeasureCache != null) mMeasureCache.clear();
17390
17391         mPrivateFlags |= PFLAG_FORCE_LAYOUT;
17392         mPrivateFlags |= PFLAG_INVALIDATED;
17393     }
17394
17395     /**
17396      * <p>
17397      * This is called to find out how big a view should be. The parent
17398      * supplies constraint information in the width and height parameters.
17399      * </p>
17400      *
17401      * <p>
17402      * The actual measurement work of a view is performed in
17403      * {@link #onMeasure(int, int)}, called by this method. Therefore, only
17404      * {@link #onMeasure(int, int)} can and must be overridden by subclasses.
17405      * </p>
17406      *
17407      *
17408      * @param widthMeasureSpec Horizontal space requirements as imposed by the
17409      *        parent
17410      * @param heightMeasureSpec Vertical space requirements as imposed by the
17411      *        parent
17412      *
17413      * @see #onMeasure(int, int)
17414      */
17415     public final void measure(int widthMeasureSpec, int heightMeasureSpec) {
17416         boolean optical = isLayoutModeOptical(this);
17417         if (optical != isLayoutModeOptical(mParent)) {
17418             Insets insets = getOpticalInsets();
17419             int oWidth  = insets.left + insets.right;
17420             int oHeight = insets.top  + insets.bottom;
17421             widthMeasureSpec  = MeasureSpec.adjust(widthMeasureSpec,  optical ? -oWidth  : oWidth);
17422             heightMeasureSpec = MeasureSpec.adjust(heightMeasureSpec, optical ? -oHeight : oHeight);
17423         }
17424
17425         // Suppress sign extension for the low bytes
17426         long key = (long) widthMeasureSpec << 32 | (long) heightMeasureSpec & 0xffffffffL;
17427         if (mMeasureCache == null) mMeasureCache = new LongSparseLongArray(2);
17428
17429         final boolean forceLayout = (mPrivateFlags & PFLAG_FORCE_LAYOUT) == PFLAG_FORCE_LAYOUT;
17430         final boolean isExactly = MeasureSpec.getMode(widthMeasureSpec) == MeasureSpec.EXACTLY &&
17431                 MeasureSpec.getMode(heightMeasureSpec) == MeasureSpec.EXACTLY;
17432         final boolean matchingSize = isExactly &&
17433                 getMeasuredWidth() == MeasureSpec.getSize(widthMeasureSpec) &&
17434                 getMeasuredHeight() == MeasureSpec.getSize(heightMeasureSpec);
17435         if (forceLayout || !matchingSize &&
17436                 (widthMeasureSpec != mOldWidthMeasureSpec ||
17437                         heightMeasureSpec != mOldHeightMeasureSpec)) {
17438
17439             // first clears the measured dimension flag
17440             mPrivateFlags &= ~PFLAG_MEASURED_DIMENSION_SET;
17441
17442             resolveRtlPropertiesIfNeeded();
17443
17444             int cacheIndex = forceLayout ? -1 : mMeasureCache.indexOfKey(key);
17445             if (cacheIndex < 0 || sIgnoreMeasureCache) {
17446                 // measure ourselves, this should set the measured dimension flag back
17447                 onMeasure(widthMeasureSpec, heightMeasureSpec);
17448                 mPrivateFlags3 &= ~PFLAG3_MEASURE_NEEDED_BEFORE_LAYOUT;
17449             } else {
17450                 long value = mMeasureCache.valueAt(cacheIndex);
17451                 // Casting a long to int drops the high 32 bits, no mask needed
17452                 setMeasuredDimensionRaw((int) (value >> 32), (int) value);
17453                 mPrivateFlags3 |= PFLAG3_MEASURE_NEEDED_BEFORE_LAYOUT;
17454             }
17455
17456             // flag not set, setMeasuredDimension() was not invoked, we raise
17457             // an exception to warn the developer
17458             if ((mPrivateFlags & PFLAG_MEASURED_DIMENSION_SET) != PFLAG_MEASURED_DIMENSION_SET) {
17459                 throw new IllegalStateException("onMeasure() did not set the"
17460                         + " measured dimension by calling"
17461                         + " setMeasuredDimension()");
17462             }
17463
17464             mPrivateFlags |= PFLAG_LAYOUT_REQUIRED;
17465         }
17466
17467         mOldWidthMeasureSpec = widthMeasureSpec;
17468         mOldHeightMeasureSpec = heightMeasureSpec;
17469
17470         mMeasureCache.put(key, ((long) mMeasuredWidth) << 32 |
17471                 (long) mMeasuredHeight & 0xffffffffL); // suppress sign extension
17472     }
17473
17474     /**
17475      * <p>
17476      * Measure the view and its content to determine the measured width and the
17477      * measured height. This method is invoked by {@link #measure(int, int)} and
17478      * should be overriden by subclasses to provide accurate and efficient
17479      * measurement of their contents.
17480      * </p>
17481      *
17482      * <p>
17483      * <strong>CONTRACT:</strong> When overriding this method, you
17484      * <em>must</em> call {@link #setMeasuredDimension(int, int)} to store the
17485      * measured width and height of this view. Failure to do so will trigger an
17486      * <code>IllegalStateException</code>, thrown by
17487      * {@link #measure(int, int)}. Calling the superclass'
17488      * {@link #onMeasure(int, int)} is a valid use.
17489      * </p>
17490      *
17491      * <p>
17492      * The base class implementation of measure defaults to the background size,
17493      * unless a larger size is allowed by the MeasureSpec. Subclasses should
17494      * override {@link #onMeasure(int, int)} to provide better measurements of
17495      * their content.
17496      * </p>
17497      *
17498      * <p>
17499      * If this method is overridden, it is the subclass's responsibility to make
17500      * sure the measured height and width are at least the view's minimum height
17501      * and width ({@link #getSuggestedMinimumHeight()} and
17502      * {@link #getSuggestedMinimumWidth()}).
17503      * </p>
17504      *
17505      * @param widthMeasureSpec horizontal space requirements as imposed by the parent.
17506      *                         The requirements are encoded with
17507      *                         {@link android.view.View.MeasureSpec}.
17508      * @param heightMeasureSpec vertical space requirements as imposed by the parent.
17509      *                         The requirements are encoded with
17510      *                         {@link android.view.View.MeasureSpec}.
17511      *
17512      * @see #getMeasuredWidth()
17513      * @see #getMeasuredHeight()
17514      * @see #setMeasuredDimension(int, int)
17515      * @see #getSuggestedMinimumHeight()
17516      * @see #getSuggestedMinimumWidth()
17517      * @see android.view.View.MeasureSpec#getMode(int)
17518      * @see android.view.View.MeasureSpec#getSize(int)
17519      */
17520     protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
17521         setMeasuredDimension(getDefaultSize(getSuggestedMinimumWidth(), widthMeasureSpec),
17522                 getDefaultSize(getSuggestedMinimumHeight(), heightMeasureSpec));
17523     }
17524
17525     /**
17526      * <p>This method must be called by {@link #onMeasure(int, int)} to store the
17527      * measured width and measured height. Failing to do so will trigger an
17528      * exception at measurement time.</p>
17529      *
17530      * @param measuredWidth The measured width of this view.  May be a complex
17531      * bit mask as defined by {@link #MEASURED_SIZE_MASK} and
17532      * {@link #MEASURED_STATE_TOO_SMALL}.
17533      * @param measuredHeight The measured height of this view.  May be a complex
17534      * bit mask as defined by {@link #MEASURED_SIZE_MASK} and
17535      * {@link #MEASURED_STATE_TOO_SMALL}.
17536      */
17537     protected final void setMeasuredDimension(int measuredWidth, int measuredHeight) {
17538         boolean optical = isLayoutModeOptical(this);
17539         if (optical != isLayoutModeOptical(mParent)) {
17540             Insets insets = getOpticalInsets();
17541             int opticalWidth  = insets.left + insets.right;
17542             int opticalHeight = insets.top  + insets.bottom;
17543
17544             measuredWidth  += optical ? opticalWidth  : -opticalWidth;
17545             measuredHeight += optical ? opticalHeight : -opticalHeight;
17546         }
17547         setMeasuredDimensionRaw(measuredWidth, measuredHeight);
17548     }
17549
17550     /**
17551      * Sets the measured dimension without extra processing for things like optical bounds.
17552      * Useful for reapplying consistent values that have already been cooked with adjustments
17553      * for optical bounds, etc. such as those from the measurement cache.
17554      *
17555      * @param measuredWidth The measured width of this view.  May be a complex
17556      * bit mask as defined by {@link #MEASURED_SIZE_MASK} and
17557      * {@link #MEASURED_STATE_TOO_SMALL}.
17558      * @param measuredHeight The measured height of this view.  May be a complex
17559      * bit mask as defined by {@link #MEASURED_SIZE_MASK} and
17560      * {@link #MEASURED_STATE_TOO_SMALL}.
17561      */
17562     private void setMeasuredDimensionRaw(int measuredWidth, int measuredHeight) {
17563         mMeasuredWidth = measuredWidth;
17564         mMeasuredHeight = measuredHeight;
17565
17566         mPrivateFlags |= PFLAG_MEASURED_DIMENSION_SET;
17567     }
17568
17569     /**
17570      * Merge two states as returned by {@link #getMeasuredState()}.
17571      * @param curState The current state as returned from a view or the result
17572      * of combining multiple views.
17573      * @param newState The new view state to combine.
17574      * @return Returns a new integer reflecting the combination of the two
17575      * states.
17576      */
17577     public static int combineMeasuredStates(int curState, int newState) {
17578         return curState | newState;
17579     }
17580
17581     /**
17582      * Version of {@link #resolveSizeAndState(int, int, int)}
17583      * returning only the {@link #MEASURED_SIZE_MASK} bits of the result.
17584      */
17585     public static int resolveSize(int size, int measureSpec) {
17586         return resolveSizeAndState(size, measureSpec, 0) & MEASURED_SIZE_MASK;
17587     }
17588
17589     /**
17590      * Utility to reconcile a desired size and state, with constraints imposed
17591      * by a MeasureSpec.  Will take the desired size, unless a different size
17592      * is imposed by the constraints.  The returned value is a compound integer,
17593      * with the resolved size in the {@link #MEASURED_SIZE_MASK} bits and
17594      * optionally the bit {@link #MEASURED_STATE_TOO_SMALL} set if the resulting
17595      * size is smaller than the size the view wants to be.
17596      *
17597      * @param size How big the view wants to be
17598      * @param measureSpec Constraints imposed by the parent
17599      * @return Size information bit mask as defined by
17600      * {@link #MEASURED_SIZE_MASK} and {@link #MEASURED_STATE_TOO_SMALL}.
17601      */
17602     public static int resolveSizeAndState(int size, int measureSpec, int childMeasuredState) {
17603         int result = size;
17604         int specMode = MeasureSpec.getMode(measureSpec);
17605         int specSize =  MeasureSpec.getSize(measureSpec);
17606         switch (specMode) {
17607         case MeasureSpec.UNSPECIFIED:
17608             result = size;
17609             break;
17610         case MeasureSpec.AT_MOST:
17611             if (specSize < size) {
17612                 result = specSize | MEASURED_STATE_TOO_SMALL;
17613             } else {
17614                 result = size;
17615             }
17616             break;
17617         case MeasureSpec.EXACTLY:
17618             result = specSize;
17619             break;
17620         }
17621         return result | (childMeasuredState&MEASURED_STATE_MASK);
17622     }
17623
17624     /**
17625      * Utility to return a default size. Uses the supplied size if the
17626      * MeasureSpec imposed no constraints. Will get larger if allowed
17627      * by the MeasureSpec.
17628      *
17629      * @param size Default size for this view
17630      * @param measureSpec Constraints imposed by the parent
17631      * @return The size this view should be.
17632      */
17633     public static int getDefaultSize(int size, int measureSpec) {
17634         int result = size;
17635         int specMode = MeasureSpec.getMode(measureSpec);
17636         int specSize = MeasureSpec.getSize(measureSpec);
17637
17638         switch (specMode) {
17639         case MeasureSpec.UNSPECIFIED:
17640             result = size;
17641             break;
17642         case MeasureSpec.AT_MOST:
17643         case MeasureSpec.EXACTLY:
17644             result = specSize;
17645             break;
17646         }
17647         return result;
17648     }
17649
17650     /**
17651      * Returns the suggested minimum height that the view should use. This
17652      * returns the maximum of the view's minimum height
17653      * and the background's minimum height
17654      * ({@link android.graphics.drawable.Drawable#getMinimumHeight()}).
17655      * <p>
17656      * When being used in {@link #onMeasure(int, int)}, the caller should still
17657      * ensure the returned height is within the requirements of the parent.
17658      *
17659      * @return The suggested minimum height of the view.
17660      */
17661     protected int getSuggestedMinimumHeight() {
17662         return (mBackground == null) ? mMinHeight : max(mMinHeight, mBackground.getMinimumHeight());
17663
17664     }
17665
17666     /**
17667      * Returns the suggested minimum width that the view should use. This
17668      * returns the maximum of the view's minimum width)
17669      * and the background's minimum width
17670      *  ({@link android.graphics.drawable.Drawable#getMinimumWidth()}).
17671      * <p>
17672      * When being used in {@link #onMeasure(int, int)}, the caller should still
17673      * ensure the returned width is within the requirements of the parent.
17674      *
17675      * @return The suggested minimum width of the view.
17676      */
17677     protected int getSuggestedMinimumWidth() {
17678         return (mBackground == null) ? mMinWidth : max(mMinWidth, mBackground.getMinimumWidth());
17679     }
17680
17681     /**
17682      * Returns the minimum height of the view.
17683      *
17684      * @return the minimum height the view will try to be.
17685      *
17686      * @see #setMinimumHeight(int)
17687      *
17688      * @attr ref android.R.styleable#View_minHeight
17689      */
17690     public int getMinimumHeight() {
17691         return mMinHeight;
17692     }
17693
17694     /**
17695      * Sets the minimum height of the view. It is not guaranteed the view will
17696      * be able to achieve this minimum height (for example, if its parent layout
17697      * constrains it with less available height).
17698      *
17699      * @param minHeight The minimum height the view will try to be.
17700      *
17701      * @see #getMinimumHeight()
17702      *
17703      * @attr ref android.R.styleable#View_minHeight
17704      */
17705     public void setMinimumHeight(int minHeight) {
17706         mMinHeight = minHeight;
17707         requestLayout();
17708     }
17709
17710     /**
17711      * Returns the minimum width of the view.
17712      *
17713      * @return the minimum width the view will try to be.
17714      *
17715      * @see #setMinimumWidth(int)
17716      *
17717      * @attr ref android.R.styleable#View_minWidth
17718      */
17719     public int getMinimumWidth() {
17720         return mMinWidth;
17721     }
17722
17723     /**
17724      * Sets the minimum width of the view. It is not guaranteed the view will
17725      * be able to achieve this minimum width (for example, if its parent layout
17726      * constrains it with less available width).
17727      *
17728      * @param minWidth The minimum width the view will try to be.
17729      *
17730      * @see #getMinimumWidth()
17731      *
17732      * @attr ref android.R.styleable#View_minWidth
17733      */
17734     public void setMinimumWidth(int minWidth) {
17735         mMinWidth = minWidth;
17736         requestLayout();
17737
17738     }
17739
17740     /**
17741      * Get the animation currently associated with this view.
17742      *
17743      * @return The animation that is currently playing or
17744      *         scheduled to play for this view.
17745      */
17746     public Animation getAnimation() {
17747         return mCurrentAnimation;
17748     }
17749
17750     /**
17751      * Start the specified animation now.
17752      *
17753      * @param animation the animation to start now
17754      */
17755     public void startAnimation(Animation animation) {
17756         animation.setStartTime(Animation.START_ON_FIRST_FRAME);
17757         setAnimation(animation);
17758         invalidateParentCaches();
17759         invalidate(true);
17760     }
17761
17762     /**
17763      * Cancels any animations for this view.
17764      */
17765     public void clearAnimation() {
17766         if (mCurrentAnimation != null) {
17767             mCurrentAnimation.detach();
17768         }
17769         mCurrentAnimation = null;
17770         invalidateParentIfNeeded();
17771     }
17772
17773     /**
17774      * Sets the next animation to play for this view.
17775      * If you want the animation to play immediately, use
17776      * {@link #startAnimation(android.view.animation.Animation)} instead.
17777      * This method provides allows fine-grained
17778      * control over the start time and invalidation, but you
17779      * must make sure that 1) the animation has a start time set, and
17780      * 2) the view's parent (which controls animations on its children)
17781      * will be invalidated when the animation is supposed to
17782      * start.
17783      *
17784      * @param animation The next animation, or null.
17785      */
17786     public void setAnimation(Animation animation) {
17787         mCurrentAnimation = animation;
17788
17789         if (animation != null) {
17790             // If the screen is off assume the animation start time is now instead of
17791             // the next frame we draw. Keeping the START_ON_FIRST_FRAME start time
17792             // would cause the animation to start when the screen turns back on
17793             if (mAttachInfo != null && mAttachInfo.mDisplayState == Display.STATE_OFF
17794                     && animation.getStartTime() == Animation.START_ON_FIRST_FRAME) {
17795                 animation.setStartTime(AnimationUtils.currentAnimationTimeMillis());
17796             }
17797             animation.reset();
17798         }
17799     }
17800
17801     /**
17802      * Invoked by a parent ViewGroup to notify the start of the animation
17803      * currently associated with this view. If you override this method,
17804      * always call super.onAnimationStart();
17805      *
17806      * @see #setAnimation(android.view.animation.Animation)
17807      * @see #getAnimation()
17808      */
17809     protected void onAnimationStart() {
17810         mPrivateFlags |= PFLAG_ANIMATION_STARTED;
17811     }
17812
17813     /**
17814      * Invoked by a parent ViewGroup to notify the end of the animation
17815      * currently associated with this view. If you override this method,
17816      * always call super.onAnimationEnd();
17817      *
17818      * @see #setAnimation(android.view.animation.Animation)
17819      * @see #getAnimation()
17820      */
17821     protected void onAnimationEnd() {
17822         mPrivateFlags &= ~PFLAG_ANIMATION_STARTED;
17823     }
17824
17825     /**
17826      * Invoked if there is a Transform that involves alpha. Subclass that can
17827      * draw themselves with the specified alpha should return true, and then
17828      * respect that alpha when their onDraw() is called. If this returns false
17829      * then the view may be redirected to draw into an offscreen buffer to
17830      * fulfill the request, which will look fine, but may be slower than if the
17831      * subclass handles it internally. The default implementation returns false.
17832      *
17833      * @param alpha The alpha (0..255) to apply to the view's drawing
17834      * @return true if the view can draw with the specified alpha.
17835      */
17836     protected boolean onSetAlpha(int alpha) {
17837         return false;
17838     }
17839
17840     /**
17841      * This is used by the RootView to perform an optimization when
17842      * the view hierarchy contains one or several SurfaceView.
17843      * SurfaceView is always considered transparent, but its children are not,
17844      * therefore all View objects remove themselves from the global transparent
17845      * region (passed as a parameter to this function).
17846      *
17847      * @param region The transparent region for this ViewAncestor (window).
17848      *
17849      * @return Returns true if the effective visibility of the view at this
17850      * point is opaque, regardless of the transparent region; returns false
17851      * if it is possible for underlying windows to be seen behind the view.
17852      *
17853      * {@hide}
17854      */
17855     public boolean gatherTransparentRegion(Region region) {
17856         final AttachInfo attachInfo = mAttachInfo;
17857         if (region != null && attachInfo != null) {
17858             final int pflags = mPrivateFlags;
17859             if ((pflags & PFLAG_SKIP_DRAW) == 0) {
17860                 // The SKIP_DRAW flag IS NOT set, so this view draws. We need to
17861                 // remove it from the transparent region.
17862                 final int[] location = attachInfo.mTransparentLocation;
17863                 getLocationInWindow(location);
17864                 region.op(location[0], location[1], location[0] + mRight - mLeft,
17865                         location[1] + mBottom - mTop, Region.Op.DIFFERENCE);
17866             } else if ((pflags & PFLAG_ONLY_DRAWS_BACKGROUND) != 0 && mBackground != null &&
17867                     mBackground.getOpacity() != PixelFormat.TRANSPARENT) {
17868                 // The ONLY_DRAWS_BACKGROUND flag IS set and the background drawable
17869                 // exists, so we remove the background drawable's non-transparent
17870                 // parts from this transparent region.
17871                 applyDrawableToTransparentRegion(mBackground, region);
17872             }
17873         }
17874         return true;
17875     }
17876
17877     /**
17878      * Play a sound effect for this view.
17879      *
17880      * <p>The framework will play sound effects for some built in actions, such as
17881      * clicking, but you may wish to play these effects in your widget,
17882      * for instance, for internal navigation.
17883      *
17884      * <p>The sound effect will only be played if sound effects are enabled by the user, and
17885      * {@link #isSoundEffectsEnabled()} is true.
17886      *
17887      * @param soundConstant One of the constants defined in {@link SoundEffectConstants}
17888      */
17889     public void playSoundEffect(int soundConstant) {
17890         if (mAttachInfo == null || mAttachInfo.mRootCallbacks == null || !isSoundEffectsEnabled()) {
17891             return;
17892         }
17893         mAttachInfo.mRootCallbacks.playSoundEffect(soundConstant);
17894     }
17895
17896     /**
17897      * BZZZTT!!1!
17898      *
17899      * <p>Provide haptic feedback to the user for this view.
17900      *
17901      * <p>The framework will provide haptic feedback for some built in actions,
17902      * such as long presses, but you may wish to provide feedback for your
17903      * own widget.
17904      *
17905      * <p>The feedback will only be performed if
17906      * {@link #isHapticFeedbackEnabled()} is true.
17907      *
17908      * @param feedbackConstant One of the constants defined in
17909      * {@link HapticFeedbackConstants}
17910      */
17911     public boolean performHapticFeedback(int feedbackConstant) {
17912         return performHapticFeedback(feedbackConstant, 0);
17913     }
17914
17915     /**
17916      * BZZZTT!!1!
17917      *
17918      * <p>Like {@link #performHapticFeedback(int)}, with additional options.
17919      *
17920      * @param feedbackConstant One of the constants defined in
17921      * {@link HapticFeedbackConstants}
17922      * @param flags Additional flags as per {@link HapticFeedbackConstants}.
17923      */
17924     public boolean performHapticFeedback(int feedbackConstant, int flags) {
17925         if (mAttachInfo == null) {
17926             return false;
17927         }
17928         //noinspection SimplifiableIfStatement
17929         if ((flags & HapticFeedbackConstants.FLAG_IGNORE_VIEW_SETTING) == 0
17930                 && !isHapticFeedbackEnabled()) {
17931             return false;
17932         }
17933         return mAttachInfo.mRootCallbacks.performHapticFeedback(feedbackConstant,
17934                 (flags & HapticFeedbackConstants.FLAG_IGNORE_GLOBAL_SETTING) != 0);
17935     }
17936
17937     /**
17938      * Request that the visibility of the status bar or other screen/window
17939      * decorations be changed.
17940      *
17941      * <p>This method is used to put the over device UI into temporary modes
17942      * where the user's attention is focused more on the application content,
17943      * by dimming or hiding surrounding system affordances.  This is typically
17944      * used in conjunction with {@link Window#FEATURE_ACTION_BAR_OVERLAY
17945      * Window.FEATURE_ACTION_BAR_OVERLAY}, allowing the applications content
17946      * to be placed behind the action bar (and with these flags other system
17947      * affordances) so that smooth transitions between hiding and showing them
17948      * can be done.
17949      *
17950      * <p>Two representative examples of the use of system UI visibility is
17951      * implementing a content browsing application (like a magazine reader)
17952      * and a video playing application.
17953      *
17954      * <p>The first code shows a typical implementation of a View in a content
17955      * browsing application.  In this implementation, the application goes
17956      * into a content-oriented mode by hiding the status bar and action bar,
17957      * and putting the navigation elements into lights out mode.  The user can
17958      * then interact with content while in this mode.  Such an application should
17959      * provide an easy way for the user to toggle out of the mode (such as to
17960      * check information in the status bar or access notifications).  In the
17961      * implementation here, this is done simply by tapping on the content.
17962      *
17963      * {@sample development/samples/ApiDemos/src/com/example/android/apis/view/ContentBrowserActivity.java
17964      *      content}
17965      *
17966      * <p>This second code sample shows a typical implementation of a View
17967      * in a video playing application.  In this situation, while the video is
17968      * playing the application would like to go into a complete full-screen mode,
17969      * to use as much of the display as possible for the video.  When in this state
17970      * the user can not interact with the application; the system intercepts
17971      * touching on the screen to pop the UI out of full screen mode.  See
17972      * {@link #fitSystemWindows(Rect)} for a sample layout that goes with this code.
17973      *
17974      * {@sample development/samples/ApiDemos/src/com/example/android/apis/view/VideoPlayerActivity.java
17975      *      content}
17976      *
17977      * @param visibility  Bitwise-or of flags {@link #SYSTEM_UI_FLAG_LOW_PROFILE},
17978      * {@link #SYSTEM_UI_FLAG_HIDE_NAVIGATION}, {@link #SYSTEM_UI_FLAG_FULLSCREEN},
17979      * {@link #SYSTEM_UI_FLAG_LAYOUT_STABLE}, {@link #SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION},
17980      * {@link #SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN}, {@link #SYSTEM_UI_FLAG_IMMERSIVE},
17981      * and {@link #SYSTEM_UI_FLAG_IMMERSIVE_STICKY}.
17982      */
17983     public void setSystemUiVisibility(int visibility) {
17984         if (visibility != mSystemUiVisibility) {
17985             mSystemUiVisibility = visibility;
17986             if (mParent != null && mAttachInfo != null && !mAttachInfo.mRecomputeGlobalAttributes) {
17987                 mParent.recomputeViewAttributes(this);
17988             }
17989         }
17990     }
17991
17992     /**
17993      * Returns the last {@link #setSystemUiVisibility(int)} that this view has requested.
17994      * @return  Bitwise-or of flags {@link #SYSTEM_UI_FLAG_LOW_PROFILE},
17995      * {@link #SYSTEM_UI_FLAG_HIDE_NAVIGATION}, {@link #SYSTEM_UI_FLAG_FULLSCREEN},
17996      * {@link #SYSTEM_UI_FLAG_LAYOUT_STABLE}, {@link #SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION},
17997      * {@link #SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN}, {@link #SYSTEM_UI_FLAG_IMMERSIVE},
17998      * and {@link #SYSTEM_UI_FLAG_IMMERSIVE_STICKY}.
17999      */
18000     public int getSystemUiVisibility() {
18001         return mSystemUiVisibility;
18002     }
18003
18004     /**
18005      * Returns the current system UI visibility that is currently set for
18006      * the entire window.  This is the combination of the
18007      * {@link #setSystemUiVisibility(int)} values supplied by all of the
18008      * views in the window.
18009      */
18010     public int getWindowSystemUiVisibility() {
18011         return mAttachInfo != null ? mAttachInfo.mSystemUiVisibility : 0;
18012     }
18013
18014     /**
18015      * Override to find out when the window's requested system UI visibility
18016      * has changed, that is the value returned by {@link #getWindowSystemUiVisibility()}.
18017      * This is different from the callbacks received through
18018      * {@link #setOnSystemUiVisibilityChangeListener(OnSystemUiVisibilityChangeListener)}
18019      * in that this is only telling you about the local request of the window,
18020      * not the actual values applied by the system.
18021      */
18022     public void onWindowSystemUiVisibilityChanged(int visible) {
18023     }
18024
18025     /**
18026      * Dispatch callbacks to {@link #onWindowSystemUiVisibilityChanged(int)} down
18027      * the view hierarchy.
18028      */
18029     public void dispatchWindowSystemUiVisiblityChanged(int visible) {
18030         onWindowSystemUiVisibilityChanged(visible);
18031     }
18032
18033     /**
18034      * Set a listener to receive callbacks when the visibility of the system bar changes.
18035      * @param l  The {@link OnSystemUiVisibilityChangeListener} to receive callbacks.
18036      */
18037     public void setOnSystemUiVisibilityChangeListener(OnSystemUiVisibilityChangeListener l) {
18038         getListenerInfo().mOnSystemUiVisibilityChangeListener = l;
18039         if (mParent != null && mAttachInfo != null && !mAttachInfo.mRecomputeGlobalAttributes) {
18040             mParent.recomputeViewAttributes(this);
18041         }
18042     }
18043
18044     /**
18045      * Dispatch callbacks to {@link #setOnSystemUiVisibilityChangeListener} down
18046      * the view hierarchy.
18047      */
18048     public void dispatchSystemUiVisibilityChanged(int visibility) {
18049         ListenerInfo li = mListenerInfo;
18050         if (li != null && li.mOnSystemUiVisibilityChangeListener != null) {
18051             li.mOnSystemUiVisibilityChangeListener.onSystemUiVisibilityChange(
18052                     visibility & PUBLIC_STATUS_BAR_VISIBILITY_MASK);
18053         }
18054     }
18055
18056     boolean updateLocalSystemUiVisibility(int localValue, int localChanges) {
18057         int val = (mSystemUiVisibility&~localChanges) | (localValue&localChanges);
18058         if (val != mSystemUiVisibility) {
18059             setSystemUiVisibility(val);
18060             return true;
18061         }
18062         return false;
18063     }
18064
18065     /** @hide */
18066     public void setDisabledSystemUiVisibility(int flags) {
18067         if (mAttachInfo != null) {
18068             if (mAttachInfo.mDisabledSystemUiVisibility != flags) {
18069                 mAttachInfo.mDisabledSystemUiVisibility = flags;
18070                 if (mParent != null) {
18071                     mParent.recomputeViewAttributes(this);
18072                 }
18073             }
18074         }
18075     }
18076
18077     /**
18078      * Creates an image that the system displays during the drag and drop
18079      * operation. This is called a &quot;drag shadow&quot;. The default implementation
18080      * for a DragShadowBuilder based on a View returns an image that has exactly the same
18081      * appearance as the given View. The default also positions the center of the drag shadow
18082      * directly under the touch point. If no View is provided (the constructor with no parameters
18083      * is used), and {@link #onProvideShadowMetrics(Point,Point) onProvideShadowMetrics()} and
18084      * {@link #onDrawShadow(Canvas) onDrawShadow()} are not overriden, then the
18085      * default is an invisible drag shadow.
18086      * <p>
18087      * You are not required to use the View you provide to the constructor as the basis of the
18088      * drag shadow. The {@link #onDrawShadow(Canvas) onDrawShadow()} method allows you to draw
18089      * anything you want as the drag shadow.
18090      * </p>
18091      * <p>
18092      *  You pass a DragShadowBuilder object to the system when you start the drag. The system
18093      *  calls {@link #onProvideShadowMetrics(Point,Point) onProvideShadowMetrics()} to get the
18094      *  size and position of the drag shadow. It uses this data to construct a
18095      *  {@link android.graphics.Canvas} object, then it calls {@link #onDrawShadow(Canvas) onDrawShadow()}
18096      *  so that your application can draw the shadow image in the Canvas.
18097      * </p>
18098      *
18099      * <div class="special reference">
18100      * <h3>Developer Guides</h3>
18101      * <p>For a guide to implementing drag and drop features, read the
18102      * <a href="{@docRoot}guide/topics/ui/drag-drop.html">Drag and Drop</a> developer guide.</p>
18103      * </div>
18104      */
18105     public static class DragShadowBuilder {
18106         private final WeakReference<View> mView;
18107
18108         /**
18109          * Constructs a shadow image builder based on a View. By default, the resulting drag
18110          * shadow will have the same appearance and dimensions as the View, with the touch point
18111          * over the center of the View.
18112          * @param view A View. Any View in scope can be used.
18113          */
18114         public DragShadowBuilder(View view) {
18115             mView = new WeakReference<View>(view);
18116         }
18117
18118         /**
18119          * Construct a shadow builder object with no associated View.  This
18120          * constructor variant is only useful when the {@link #onProvideShadowMetrics(Point, Point)}
18121          * and {@link #onDrawShadow(Canvas)} methods are also overridden in order
18122          * to supply the drag shadow's dimensions and appearance without
18123          * reference to any View object. If they are not overridden, then the result is an
18124          * invisible drag shadow.
18125          */
18126         public DragShadowBuilder() {
18127             mView = new WeakReference<View>(null);
18128         }
18129
18130         /**
18131          * Returns the View object that had been passed to the
18132          * {@link #View.DragShadowBuilder(View)}
18133          * constructor.  If that View parameter was {@code null} or if the
18134          * {@link #View.DragShadowBuilder()}
18135          * constructor was used to instantiate the builder object, this method will return
18136          * null.
18137          *
18138          * @return The View object associate with this builder object.
18139          */
18140         @SuppressWarnings({"JavadocReference"})
18141         final public View getView() {
18142             return mView.get();
18143         }
18144
18145         /**
18146          * Provides the metrics for the shadow image. These include the dimensions of
18147          * the shadow image, and the point within that shadow that should
18148          * be centered under the touch location while dragging.
18149          * <p>
18150          * The default implementation sets the dimensions of the shadow to be the
18151          * same as the dimensions of the View itself and centers the shadow under
18152          * the touch point.
18153          * </p>
18154          *
18155          * @param shadowSize A {@link android.graphics.Point} containing the width and height
18156          * of the shadow image. Your application must set {@link android.graphics.Point#x} to the
18157          * desired width and must set {@link android.graphics.Point#y} to the desired height of the
18158          * image.
18159          *
18160          * @param shadowTouchPoint A {@link android.graphics.Point} for the position within the
18161          * shadow image that should be underneath the touch point during the drag and drop
18162          * operation. Your application must set {@link android.graphics.Point#x} to the
18163          * X coordinate and {@link android.graphics.Point#y} to the Y coordinate of this position.
18164          */
18165         public void onProvideShadowMetrics(Point shadowSize, Point shadowTouchPoint) {
18166             final View view = mView.get();
18167             if (view != null) {
18168                 shadowSize.set(view.getWidth(), view.getHeight());
18169                 shadowTouchPoint.set(shadowSize.x / 2, shadowSize.y / 2);
18170             } else {
18171                 Log.e(View.VIEW_LOG_TAG, "Asked for drag thumb metrics but no view");
18172             }
18173         }
18174
18175         /**
18176          * Draws the shadow image. The system creates the {@link android.graphics.Canvas} object
18177          * based on the dimensions it received from the
18178          * {@link #onProvideShadowMetrics(Point, Point)} callback.
18179          *
18180          * @param canvas A {@link android.graphics.Canvas} object in which to draw the shadow image.
18181          */
18182         public void onDrawShadow(Canvas canvas) {
18183             final View view = mView.get();
18184             if (view != null) {
18185                 view.draw(canvas);
18186             } else {
18187                 Log.e(View.VIEW_LOG_TAG, "Asked to draw drag shadow but no view");
18188             }
18189         }
18190     }
18191
18192     /**
18193      * Starts a drag and drop operation. When your application calls this method, it passes a
18194      * {@link android.view.View.DragShadowBuilder} object to the system. The
18195      * system calls this object's {@link DragShadowBuilder#onProvideShadowMetrics(Point, Point)}
18196      * to get metrics for the drag shadow, and then calls the object's
18197      * {@link DragShadowBuilder#onDrawShadow(Canvas)} to draw the drag shadow itself.
18198      * <p>
18199      *  Once the system has the drag shadow, it begins the drag and drop operation by sending
18200      *  drag events to all the View objects in your application that are currently visible. It does
18201      *  this either by calling the View object's drag listener (an implementation of
18202      *  {@link android.view.View.OnDragListener#onDrag(View,DragEvent) onDrag()} or by calling the
18203      *  View object's {@link android.view.View#onDragEvent(DragEvent) onDragEvent()} method.
18204      *  Both are passed a {@link android.view.DragEvent} object that has a
18205      *  {@link android.view.DragEvent#getAction()} value of
18206      *  {@link android.view.DragEvent#ACTION_DRAG_STARTED}.
18207      * </p>
18208      * <p>
18209      * Your application can invoke startDrag() on any attached View object. The View object does not
18210      * need to be the one used in {@link android.view.View.DragShadowBuilder}, nor does it need to
18211      * be related to the View the user selected for dragging.
18212      * </p>
18213      * @param data A {@link android.content.ClipData} object pointing to the data to be
18214      * transferred by the drag and drop operation.
18215      * @param shadowBuilder A {@link android.view.View.DragShadowBuilder} object for building the
18216      * drag shadow.
18217      * @param myLocalState An {@link java.lang.Object} containing local data about the drag and
18218      * drop operation. This Object is put into every DragEvent object sent by the system during the
18219      * current drag.
18220      * <p>
18221      * myLocalState is a lightweight mechanism for the sending information from the dragged View
18222      * to the target Views. For example, it can contain flags that differentiate between a
18223      * a copy operation and a move operation.
18224      * </p>
18225      * @param flags Flags that control the drag and drop operation. No flags are currently defined,
18226      * so the parameter should be set to 0.
18227      * @return {@code true} if the method completes successfully, or
18228      * {@code false} if it fails anywhere. Returning {@code false} means the system was unable to
18229      * do a drag, and so no drag operation is in progress.
18230      */
18231     public final boolean startDrag(ClipData data, DragShadowBuilder shadowBuilder,
18232             Object myLocalState, int flags) {
18233         if (ViewDebug.DEBUG_DRAG) {
18234             Log.d(VIEW_LOG_TAG, "startDrag: data=" + data + " flags=" + flags);
18235         }
18236         boolean okay = false;
18237
18238         Point shadowSize = new Point();
18239         Point shadowTouchPoint = new Point();
18240         shadowBuilder.onProvideShadowMetrics(shadowSize, shadowTouchPoint);
18241
18242         if ((shadowSize.x < 0) || (shadowSize.y < 0) ||
18243                 (shadowTouchPoint.x < 0) || (shadowTouchPoint.y < 0)) {
18244             throw new IllegalStateException("Drag shadow dimensions must not be negative");
18245         }
18246
18247         if (ViewDebug.DEBUG_DRAG) {
18248             Log.d(VIEW_LOG_TAG, "drag shadow: width=" + shadowSize.x + " height=" + shadowSize.y
18249                     + " shadowX=" + shadowTouchPoint.x + " shadowY=" + shadowTouchPoint.y);
18250         }
18251         Surface surface = new Surface();
18252         try {
18253             IBinder token = mAttachInfo.mSession.prepareDrag(mAttachInfo.mWindow,
18254                     flags, shadowSize.x, shadowSize.y, surface);
18255             if (ViewDebug.DEBUG_DRAG) Log.d(VIEW_LOG_TAG, "prepareDrag returned token=" + token
18256                     + " surface=" + surface);
18257             if (token != null) {
18258                 Canvas canvas = surface.lockCanvas(null);
18259                 try {
18260                     canvas.drawColor(0, PorterDuff.Mode.CLEAR);
18261                     shadowBuilder.onDrawShadow(canvas);
18262                 } finally {
18263                     surface.unlockCanvasAndPost(canvas);
18264                 }
18265
18266                 final ViewRootImpl root = getViewRootImpl();
18267
18268                 // Cache the local state object for delivery with DragEvents
18269                 root.setLocalDragState(myLocalState);
18270
18271                 // repurpose 'shadowSize' for the last touch point
18272                 root.getLastTouchPoint(shadowSize);
18273
18274                 okay = mAttachInfo.mSession.performDrag(mAttachInfo.mWindow, token,
18275                         shadowSize.x, shadowSize.y,
18276                         shadowTouchPoint.x, shadowTouchPoint.y, data);
18277                 if (ViewDebug.DEBUG_DRAG) Log.d(VIEW_LOG_TAG, "performDrag returned " + okay);
18278
18279                 // Off and running!  Release our local surface instance; the drag
18280                 // shadow surface is now managed by the system process.
18281                 surface.release();
18282             }
18283         } catch (Exception e) {
18284             Log.e(VIEW_LOG_TAG, "Unable to initiate drag", e);
18285             surface.destroy();
18286         }
18287
18288         return okay;
18289     }
18290
18291     /**
18292      * Handles drag events sent by the system following a call to
18293      * {@link android.view.View#startDrag(ClipData,DragShadowBuilder,Object,int) startDrag()}.
18294      *<p>
18295      * When the system calls this method, it passes a
18296      * {@link android.view.DragEvent} object. A call to
18297      * {@link android.view.DragEvent#getAction()} returns one of the action type constants defined
18298      * in DragEvent. The method uses these to determine what is happening in the drag and drop
18299      * operation.
18300      * @param event The {@link android.view.DragEvent} sent by the system.
18301      * The {@link android.view.DragEvent#getAction()} method returns an action type constant defined
18302      * in DragEvent, indicating the type of drag event represented by this object.
18303      * @return {@code true} if the method was successful, otherwise {@code false}.
18304      * <p>
18305      *  The method should return {@code true} in response to an action type of
18306      *  {@link android.view.DragEvent#ACTION_DRAG_STARTED} to receive drag events for the current
18307      *  operation.
18308      * </p>
18309      * <p>
18310      *  The method should also return {@code true} in response to an action type of
18311      *  {@link android.view.DragEvent#ACTION_DROP} if it consumed the drop, or
18312      *  {@code false} if it didn't.
18313      * </p>
18314      */
18315     public boolean onDragEvent(DragEvent event) {
18316         return false;
18317     }
18318
18319     /**
18320      * Detects if this View is enabled and has a drag event listener.
18321      * If both are true, then it calls the drag event listener with the
18322      * {@link android.view.DragEvent} it received. If the drag event listener returns
18323      * {@code true}, then dispatchDragEvent() returns {@code true}.
18324      * <p>
18325      * For all other cases, the method calls the
18326      * {@link android.view.View#onDragEvent(DragEvent) onDragEvent()} drag event handler
18327      * method and returns its result.
18328      * </p>
18329      * <p>
18330      * This ensures that a drag event is always consumed, even if the View does not have a drag
18331      * event listener. However, if the View has a listener and the listener returns true, then
18332      * onDragEvent() is not called.
18333      * </p>
18334      */
18335     public boolean dispatchDragEvent(DragEvent event) {
18336         ListenerInfo li = mListenerInfo;
18337         //noinspection SimplifiableIfStatement
18338         if (li != null && li.mOnDragListener != null && (mViewFlags & ENABLED_MASK) == ENABLED
18339                 && li.mOnDragListener.onDrag(this, event)) {
18340             return true;
18341         }
18342         return onDragEvent(event);
18343     }
18344
18345     boolean canAcceptDrag() {
18346         return (mPrivateFlags2 & PFLAG2_DRAG_CAN_ACCEPT) != 0;
18347     }
18348
18349     /**
18350      * This needs to be a better API (NOT ON VIEW) before it is exposed.  If
18351      * it is ever exposed at all.
18352      * @hide
18353      */
18354     public void onCloseSystemDialogs(String reason) {
18355     }
18356
18357     /**
18358      * Given a Drawable whose bounds have been set to draw into this view,
18359      * update a Region being computed for
18360      * {@link #gatherTransparentRegion(android.graphics.Region)} so
18361      * that any non-transparent parts of the Drawable are removed from the
18362      * given transparent region.
18363      *
18364      * @param dr The Drawable whose transparency is to be applied to the region.
18365      * @param region A Region holding the current transparency information,
18366      * where any parts of the region that are set are considered to be
18367      * transparent.  On return, this region will be modified to have the
18368      * transparency information reduced by the corresponding parts of the
18369      * Drawable that are not transparent.
18370      * {@hide}
18371      */
18372     public void applyDrawableToTransparentRegion(Drawable dr, Region region) {
18373         if (DBG) {
18374             Log.i("View", "Getting transparent region for: " + this);
18375         }
18376         final Region r = dr.getTransparentRegion();
18377         final Rect db = dr.getBounds();
18378         final AttachInfo attachInfo = mAttachInfo;
18379         if (r != null && attachInfo != null) {
18380             final int w = getRight()-getLeft();
18381             final int h = getBottom()-getTop();
18382             if (db.left > 0) {
18383                 //Log.i("VIEW", "Drawable left " + db.left + " > view 0");
18384                 r.op(0, 0, db.left, h, Region.Op.UNION);
18385             }
18386             if (db.right < w) {
18387                 //Log.i("VIEW", "Drawable right " + db.right + " < view " + w);
18388                 r.op(db.right, 0, w, h, Region.Op.UNION);
18389             }
18390             if (db.top > 0) {
18391                 //Log.i("VIEW", "Drawable top " + db.top + " > view 0");
18392                 r.op(0, 0, w, db.top, Region.Op.UNION);
18393             }
18394             if (db.bottom < h) {
18395                 //Log.i("VIEW", "Drawable bottom " + db.bottom + " < view " + h);
18396                 r.op(0, db.bottom, w, h, Region.Op.UNION);
18397             }
18398             final int[] location = attachInfo.mTransparentLocation;
18399             getLocationInWindow(location);
18400             r.translate(location[0], location[1]);
18401             region.op(r, Region.Op.INTERSECT);
18402         } else {
18403             region.op(db, Region.Op.DIFFERENCE);
18404         }
18405     }
18406
18407     private void checkForLongClick(int delayOffset) {
18408         if ((mViewFlags & LONG_CLICKABLE) == LONG_CLICKABLE) {
18409             mHasPerformedLongPress = false;
18410
18411             if (mPendingCheckForLongPress == null) {
18412                 mPendingCheckForLongPress = new CheckForLongPress();
18413             }
18414             mPendingCheckForLongPress.rememberWindowAttachCount();
18415             postDelayed(mPendingCheckForLongPress,
18416                     ViewConfiguration.getLongPressTimeout() - delayOffset);
18417         }
18418     }
18419
18420     /**
18421      * Inflate a view from an XML resource.  This convenience method wraps the {@link
18422      * LayoutInflater} class, which provides a full range of options for view inflation.
18423      *
18424      * @param context The Context object for your activity or application.
18425      * @param resource The resource ID to inflate
18426      * @param root A view group that will be the parent.  Used to properly inflate the
18427      * layout_* parameters.
18428      * @see LayoutInflater
18429      */
18430     public static View inflate(Context context, int resource, ViewGroup root) {
18431         LayoutInflater factory = LayoutInflater.from(context);
18432         return factory.inflate(resource, root);
18433     }
18434
18435     /**
18436      * Scroll the view with standard behavior for scrolling beyond the normal
18437      * content boundaries. Views that call this method should override
18438      * {@link #onOverScrolled(int, int, boolean, boolean)} to respond to the
18439      * results of an over-scroll operation.
18440      *
18441      * Views can use this method to handle any touch or fling-based scrolling.
18442      *
18443      * @param deltaX Change in X in pixels
18444      * @param deltaY Change in Y in pixels
18445      * @param scrollX Current X scroll value in pixels before applying deltaX
18446      * @param scrollY Current Y scroll value in pixels before applying deltaY
18447      * @param scrollRangeX Maximum content scroll range along the X axis
18448      * @param scrollRangeY Maximum content scroll range along the Y axis
18449      * @param maxOverScrollX Number of pixels to overscroll by in either direction
18450      *          along the X axis.
18451      * @param maxOverScrollY Number of pixels to overscroll by in either direction
18452      *          along the Y axis.
18453      * @param isTouchEvent true if this scroll operation is the result of a touch event.
18454      * @return true if scrolling was clamped to an over-scroll boundary along either
18455      *          axis, false otherwise.
18456      */
18457     @SuppressWarnings({"UnusedParameters"})
18458     protected boolean overScrollBy(int deltaX, int deltaY,
18459             int scrollX, int scrollY,
18460             int scrollRangeX, int scrollRangeY,
18461             int maxOverScrollX, int maxOverScrollY,
18462             boolean isTouchEvent) {
18463         final int overScrollMode = mOverScrollMode;
18464         final boolean canScrollHorizontal =
18465                 computeHorizontalScrollRange() > computeHorizontalScrollExtent();
18466         final boolean canScrollVertical =
18467                 computeVerticalScrollRange() > computeVerticalScrollExtent();
18468         final boolean overScrollHorizontal = overScrollMode == OVER_SCROLL_ALWAYS ||
18469                 (overScrollMode == OVER_SCROLL_IF_CONTENT_SCROLLS && canScrollHorizontal);
18470         final boolean overScrollVertical = overScrollMode == OVER_SCROLL_ALWAYS ||
18471                 (overScrollMode == OVER_SCROLL_IF_CONTENT_SCROLLS && canScrollVertical);
18472
18473         int newScrollX = scrollX + deltaX;
18474         if (!overScrollHorizontal) {
18475             maxOverScrollX = 0;
18476         }
18477
18478         int newScrollY = scrollY + deltaY;
18479         if (!overScrollVertical) {
18480             maxOverScrollY = 0;
18481         }
18482
18483         // Clamp values if at the limits and record
18484         final int left = -maxOverScrollX;
18485         final int right = maxOverScrollX + scrollRangeX;
18486         final int top = -maxOverScrollY;
18487         final int bottom = maxOverScrollY + scrollRangeY;
18488
18489         boolean clampedX = false;
18490         if (newScrollX > right) {
18491             newScrollX = right;
18492             clampedX = true;
18493         } else if (newScrollX < left) {
18494             newScrollX = left;
18495             clampedX = true;
18496         }
18497
18498         boolean clampedY = false;
18499         if (newScrollY > bottom) {
18500             newScrollY = bottom;
18501             clampedY = true;
18502         } else if (newScrollY < top) {
18503             newScrollY = top;
18504             clampedY = true;
18505         }
18506
18507         onOverScrolled(newScrollX, newScrollY, clampedX, clampedY);
18508
18509         return clampedX || clampedY;
18510     }
18511
18512     /**
18513      * Called by {@link #overScrollBy(int, int, int, int, int, int, int, int, boolean)} to
18514      * respond to the results of an over-scroll operation.
18515      *
18516      * @param scrollX New X scroll value in pixels
18517      * @param scrollY New Y scroll value in pixels
18518      * @param clampedX True if scrollX was clamped to an over-scroll boundary
18519      * @param clampedY True if scrollY was clamped to an over-scroll boundary
18520      */
18521     protected void onOverScrolled(int scrollX, int scrollY,
18522             boolean clampedX, boolean clampedY) {
18523         // Intentionally empty.
18524     }
18525
18526     /**
18527      * Returns the over-scroll mode for this view. The result will be
18528      * one of {@link #OVER_SCROLL_ALWAYS} (default), {@link #OVER_SCROLL_IF_CONTENT_SCROLLS}
18529      * (allow over-scrolling only if the view content is larger than the container),
18530      * or {@link #OVER_SCROLL_NEVER}.
18531      *
18532      * @return This view's over-scroll mode.
18533      */
18534     public int getOverScrollMode() {
18535         return mOverScrollMode;
18536     }
18537
18538     /**
18539      * Set the over-scroll mode for this view. Valid over-scroll modes are
18540      * {@link #OVER_SCROLL_ALWAYS} (default), {@link #OVER_SCROLL_IF_CONTENT_SCROLLS}
18541      * (allow over-scrolling only if the view content is larger than the container),
18542      * or {@link #OVER_SCROLL_NEVER}.
18543      *
18544      * Setting the over-scroll mode of a view will have an effect only if the
18545      * view is capable of scrolling.
18546      *
18547      * @param overScrollMode The new over-scroll mode for this view.
18548      */
18549     public void setOverScrollMode(int overScrollMode) {
18550         if (overScrollMode != OVER_SCROLL_ALWAYS &&
18551                 overScrollMode != OVER_SCROLL_IF_CONTENT_SCROLLS &&
18552                 overScrollMode != OVER_SCROLL_NEVER) {
18553             throw new IllegalArgumentException("Invalid overscroll mode " + overScrollMode);
18554         }
18555         mOverScrollMode = overScrollMode;
18556     }
18557
18558     /**
18559      * Enable or disable nested scrolling for this view.
18560      *
18561      * <p>If this property is set to true the view will be permitted to initiate nested
18562      * scrolling operations with a compatible parent view in the current hierarchy. If this
18563      * view does not implement nested scrolling this will have no effect. Disabling nested scrolling
18564      * while a nested scroll is in progress has the effect of {@link #stopNestedScroll() stopping}
18565      * the nested scroll.</p>
18566      *
18567      * @param enabled true to enable nested scrolling, false to disable
18568      *
18569      * @see #isNestedScrollingEnabled()
18570      */
18571     public void setNestedScrollingEnabled(boolean enabled) {
18572         if (enabled) {
18573             mPrivateFlags3 |= PFLAG3_NESTED_SCROLLING_ENABLED;
18574         } else {
18575             stopNestedScroll();
18576             mPrivateFlags3 &= ~PFLAG3_NESTED_SCROLLING_ENABLED;
18577         }
18578     }
18579
18580     /**
18581      * Returns true if nested scrolling is enabled for this view.
18582      *
18583      * <p>If nested scrolling is enabled and this View class implementation supports it,
18584      * this view will act as a nested scrolling child view when applicable, forwarding data
18585      * about the scroll operation in progress to a compatible and cooperating nested scrolling
18586      * parent.</p>
18587      *
18588      * @return true if nested scrolling is enabled
18589      *
18590      * @see #setNestedScrollingEnabled(boolean)
18591      */
18592     public boolean isNestedScrollingEnabled() {
18593         return (mPrivateFlags3 & PFLAG3_NESTED_SCROLLING_ENABLED) ==
18594                 PFLAG3_NESTED_SCROLLING_ENABLED;
18595     }
18596
18597     /**
18598      * Begin a nestable scroll operation along the given axes.
18599      *
18600      * <p>A view starting a nested scroll promises to abide by the following contract:</p>
18601      *
18602      * <p>The view will call startNestedScroll upon initiating a scroll operation. In the case
18603      * of a touch scroll this corresponds to the initial {@link MotionEvent#ACTION_DOWN}.
18604      * In the case of touch scrolling the nested scroll will be terminated automatically in
18605      * the same manner as {@link ViewParent#requestDisallowInterceptTouchEvent(boolean)}.
18606      * In the event of programmatic scrolling the caller must explicitly call
18607      * {@link #stopNestedScroll()} to indicate the end of the nested scroll.</p>
18608      *
18609      * <p>If <code>startNestedScroll</code> returns true, a cooperative parent was found.
18610      * If it returns false the caller may ignore the rest of this contract until the next scroll.
18611      * Calling startNestedScroll while a nested scroll is already in progress will return true.</p>
18612      *
18613      * <p>At each incremental step of the scroll the caller should invoke
18614      * {@link #dispatchNestedPreScroll(int, int, int[], int[]) dispatchNestedPreScroll}
18615      * once it has calculated the requested scrolling delta. If it returns true the nested scrolling
18616      * parent at least partially consumed the scroll and the caller should adjust the amount it
18617      * scrolls by.</p>
18618      *
18619      * <p>After applying the remainder of the scroll delta the caller should invoke
18620      * {@link #dispatchNestedScroll(int, int, int, int, int[]) dispatchNestedScroll}, passing
18621      * both the delta consumed and the delta unconsumed. A nested scrolling parent may treat
18622      * these values differently. See {@link ViewParent#onNestedScroll(View, int, int, int, int)}.
18623      * </p>
18624      *
18625      * @param axes Flags consisting of a combination of {@link #SCROLL_AXIS_HORIZONTAL} and/or
18626      *             {@link #SCROLL_AXIS_VERTICAL}.
18627      * @return true if a cooperative parent was found and nested scrolling has been enabled for
18628      *         the current gesture.
18629      *
18630      * @see #stopNestedScroll()
18631      * @see #dispatchNestedPreScroll(int, int, int[], int[])
18632      * @see #dispatchNestedScroll(int, int, int, int, int[])
18633      */
18634     public boolean startNestedScroll(int axes) {
18635         if (hasNestedScrollingParent()) {
18636             // Already in progress
18637             return true;
18638         }
18639         if (isNestedScrollingEnabled()) {
18640             ViewParent p = getParent();
18641             View child = this;
18642             while (p != null) {
18643                 try {
18644                     if (p.onStartNestedScroll(child, this, axes)) {
18645                         mNestedScrollingParent = p;
18646                         p.onNestedScrollAccepted(child, this, axes);
18647                         return true;
18648                     }
18649                 } catch (AbstractMethodError e) {
18650                     Log.e(VIEW_LOG_TAG, "ViewParent " + p + " does not implement interface " +
18651                             "method onStartNestedScroll", e);
18652                     // Allow the search upward to continue
18653                 }
18654                 if (p instanceof View) {
18655                     child = (View) p;
18656                 }
18657                 p = p.getParent();
18658             }
18659         }
18660         return false;
18661     }
18662
18663     /**
18664      * Stop a nested scroll in progress.
18665      *
18666      * <p>Calling this method when a nested scroll is not currently in progress is harmless.</p>
18667      *
18668      * @see #startNestedScroll(int)
18669      */
18670     public void stopNestedScroll() {
18671         if (mNestedScrollingParent != null) {
18672             mNestedScrollingParent.onStopNestedScroll(this);
18673             mNestedScrollingParent = null;
18674         }
18675     }
18676
18677     /**
18678      * Returns true if this view has a nested scrolling parent.
18679      *
18680      * <p>The presence of a nested scrolling parent indicates that this view has initiated
18681      * a nested scroll and it was accepted by an ancestor view further up the view hierarchy.</p>
18682      *
18683      * @return whether this view has a nested scrolling parent
18684      */
18685     public boolean hasNestedScrollingParent() {
18686         return mNestedScrollingParent != null;
18687     }
18688
18689     /**
18690      * Dispatch one step of a nested scroll in progress.
18691      *
18692      * <p>Implementations of views that support nested scrolling should call this to report
18693      * info about a scroll in progress to the current nested scrolling parent. If a nested scroll
18694      * is not currently in progress or nested scrolling is not
18695      * {@link #isNestedScrollingEnabled() enabled} for this view this method does nothing.</p>
18696      *
18697      * <p>Compatible View implementations should also call
18698      * {@link #dispatchNestedPreScroll(int, int, int[], int[]) dispatchNestedPreScroll} before
18699      * consuming a component of the scroll event themselves.</p>
18700      *
18701      * @param dxConsumed Horizontal distance in pixels consumed by this view during this scroll step
18702      * @param dyConsumed Vertical distance in pixels consumed by this view during this scroll step
18703      * @param dxUnconsumed Horizontal scroll distance in pixels not consumed by this view
18704      * @param dyUnconsumed Horizontal scroll distance in pixels not consumed by this view
18705      * @param offsetInWindow Optional. If not null, on return this will contain the offset
18706      *                       in local view coordinates of this view from before this operation
18707      *                       to after it completes. View implementations may use this to adjust
18708      *                       expected input coordinate tracking.
18709      * @return true if the event was dispatched, false if it could not be dispatched.
18710      * @see #dispatchNestedPreScroll(int, int, int[], int[])
18711      */
18712     public boolean dispatchNestedScroll(int dxConsumed, int dyConsumed,
18713             int dxUnconsumed, int dyUnconsumed, int[] offsetInWindow) {
18714         if (isNestedScrollingEnabled() && mNestedScrollingParent != null) {
18715             if (dxConsumed != 0 || dyConsumed != 0 || dxUnconsumed != 0 || dyUnconsumed != 0) {
18716                 int startX = 0;
18717                 int startY = 0;
18718                 if (offsetInWindow != null) {
18719                     getLocationInWindow(offsetInWindow);
18720                     startX = offsetInWindow[0];
18721                     startY = offsetInWindow[1];
18722                 }
18723
18724                 mNestedScrollingParent.onNestedScroll(this, dxConsumed, dyConsumed,
18725                         dxUnconsumed, dyUnconsumed);
18726
18727                 if (offsetInWindow != null) {
18728                     getLocationInWindow(offsetInWindow);
18729                     offsetInWindow[0] -= startX;
18730                     offsetInWindow[1] -= startY;
18731                 }
18732                 return true;
18733             } else if (offsetInWindow != null) {
18734                 // No motion, no dispatch. Keep offsetInWindow up to date.
18735                 offsetInWindow[0] = 0;
18736                 offsetInWindow[1] = 0;
18737             }
18738         }
18739         return false;
18740     }
18741
18742     /**
18743      * Dispatch one step of a nested scroll in progress before this view consumes any portion of it.
18744      *
18745      * <p>Nested pre-scroll events are to nested scroll events what touch intercept is to touch.
18746      * <code>dispatchNestedPreScroll</code> offers an opportunity for the parent view in a nested
18747      * scrolling operation to consume some or all of the scroll operation before the child view
18748      * consumes it.</p>
18749      *
18750      * @param dx Horizontal scroll distance in pixels
18751      * @param dy Vertical scroll distance in pixels
18752      * @param consumed Output. If not null, consumed[0] will contain the consumed component of dx
18753      *                 and consumed[1] the consumed dy.
18754      * @param offsetInWindow Optional. If not null, on return this will contain the offset
18755      *                       in local view coordinates of this view from before this operation
18756      *                       to after it completes. View implementations may use this to adjust
18757      *                       expected input coordinate tracking.
18758      * @return true if the parent consumed some or all of the scroll delta
18759      * @see #dispatchNestedScroll(int, int, int, int, int[])
18760      */
18761     public boolean dispatchNestedPreScroll(int dx, int dy, int[] consumed, int[] offsetInWindow) {
18762         if (isNestedScrollingEnabled() && mNestedScrollingParent != null) {
18763             if (dx != 0 || dy != 0) {
18764                 int startX = 0;
18765                 int startY = 0;
18766                 if (offsetInWindow != null) {
18767                     getLocationInWindow(offsetInWindow);
18768                     startX = offsetInWindow[0];
18769                     startY = offsetInWindow[1];
18770                 }
18771
18772                 if (consumed == null) {
18773                     if (mTempNestedScrollConsumed == null) {
18774                         mTempNestedScrollConsumed = new int[2];
18775                     }
18776                     consumed = mTempNestedScrollConsumed;
18777                 }
18778                 consumed[0] = 0;
18779                 consumed[1] = 0;
18780                 mNestedScrollingParent.onNestedPreScroll(this, dx, dy, consumed);
18781
18782                 if (offsetInWindow != null) {
18783                     getLocationInWindow(offsetInWindow);
18784                     offsetInWindow[0] -= startX;
18785                     offsetInWindow[1] -= startY;
18786                 }
18787                 return consumed[0] != 0 || consumed[1] != 0;
18788             } else if (offsetInWindow != null) {
18789                 offsetInWindow[0] = 0;
18790                 offsetInWindow[1] = 0;
18791             }
18792         }
18793         return false;
18794     }
18795
18796     /**
18797      * Dispatch a fling to a nested scrolling parent.
18798      *
18799      * <p>This method should be used to indicate that a nested scrolling child has detected
18800      * suitable conditions for a fling. Generally this means that a touch scroll has ended with a
18801      * {@link VelocityTracker velocity} in the direction of scrolling that meets or exceeds
18802      * the {@link ViewConfiguration#getScaledMinimumFlingVelocity() minimum fling velocity}
18803      * along a scrollable axis.</p>
18804      *
18805      * <p>If a nested scrolling child view would normally fling but it is at the edge of
18806      * its own content, it can use this method to delegate the fling to its nested scrolling
18807      * parent instead. The parent may optionally consume the fling or observe a child fling.</p>
18808      *
18809      * @param velocityX Horizontal fling velocity in pixels per second
18810      * @param velocityY Vertical fling velocity in pixels per second
18811      * @param consumed true if the child consumed the fling, false otherwise
18812      * @return true if the nested scrolling parent consumed or otherwise reacted to the fling
18813      */
18814     public boolean dispatchNestedFling(float velocityX, float velocityY, boolean consumed) {
18815         if (isNestedScrollingEnabled() && mNestedScrollingParent != null) {
18816             return mNestedScrollingParent.onNestedFling(this, velocityX, velocityY, consumed);
18817         }
18818         return false;
18819     }
18820
18821     /**
18822      * Dispatch a fling to a nested scrolling parent before it is processed by this view.
18823      *
18824      * <p>Nested pre-fling events are to nested fling events what touch intercept is to touch
18825      * and what nested pre-scroll is to nested scroll. <code>dispatchNestedPreFling</code>
18826      * offsets an opportunity for the parent view in a nested fling to fully consume the fling
18827      * before the child view consumes it. If this method returns <code>true</code>, a nested
18828      * parent view consumed the fling and this view should not scroll as a result.</p>
18829      *
18830      * <p>For a better user experience, only one view in a nested scrolling chain should consume
18831      * the fling at a time. If a parent view consumed the fling this method will return false.
18832      * Custom view implementations should account for this in two ways:</p>
18833      *
18834      * <ul>
18835      *     <li>If a custom view is paged and needs to settle to a fixed page-point, do not
18836      *     call <code>dispatchNestedPreFling</code>; consume the fling and settle to a valid
18837      *     position regardless.</li>
18838      *     <li>If a nested parent does consume the fling, this view should not scroll at all,
18839      *     even to settle back to a valid idle position.</li>
18840      * </ul>
18841      *
18842      * <p>Views should also not offer fling velocities to nested parent views along an axis
18843      * where scrolling is not currently supported; a {@link android.widget.ScrollView ScrollView}
18844      * should not offer a horizontal fling velocity to its parents since scrolling along that
18845      * axis is not permitted and carrying velocity along that motion does not make sense.</p>
18846      *
18847      * @param velocityX Horizontal fling velocity in pixels per second
18848      * @param velocityY Vertical fling velocity in pixels per second
18849      * @return true if a nested scrolling parent consumed the fling
18850      */
18851     public boolean dispatchNestedPreFling(float velocityX, float velocityY) {
18852         if (isNestedScrollingEnabled() && mNestedScrollingParent != null) {
18853             return mNestedScrollingParent.onNestedPreFling(this, velocityX, velocityY);
18854         }
18855         return false;
18856     }
18857
18858     /**
18859      * Gets a scale factor that determines the distance the view should scroll
18860      * vertically in response to {@link MotionEvent#ACTION_SCROLL}.
18861      * @return The vertical scroll scale factor.
18862      * @hide
18863      */
18864     protected float getVerticalScrollFactor() {
18865         if (mVerticalScrollFactor == 0) {
18866             TypedValue outValue = new TypedValue();
18867             if (!mContext.getTheme().resolveAttribute(
18868                     com.android.internal.R.attr.listPreferredItemHeight, outValue, true)) {
18869                 throw new IllegalStateException(
18870                         "Expected theme to define listPreferredItemHeight.");
18871             }
18872             mVerticalScrollFactor = outValue.getDimension(
18873                     mContext.getResources().getDisplayMetrics());
18874         }
18875         return mVerticalScrollFactor;
18876     }
18877
18878     /**
18879      * Gets a scale factor that determines the distance the view should scroll
18880      * horizontally in response to {@link MotionEvent#ACTION_SCROLL}.
18881      * @return The horizontal scroll scale factor.
18882      * @hide
18883      */
18884     protected float getHorizontalScrollFactor() {
18885         // TODO: Should use something else.
18886         return getVerticalScrollFactor();
18887     }
18888
18889     /**
18890      * Return the value specifying the text direction or policy that was set with
18891      * {@link #setTextDirection(int)}.
18892      *
18893      * @return the defined text direction. It can be one of:
18894      *
18895      * {@link #TEXT_DIRECTION_INHERIT},
18896      * {@link #TEXT_DIRECTION_FIRST_STRONG}
18897      * {@link #TEXT_DIRECTION_ANY_RTL},
18898      * {@link #TEXT_DIRECTION_LTR},
18899      * {@link #TEXT_DIRECTION_RTL},
18900      * {@link #TEXT_DIRECTION_LOCALE}
18901      *
18902      * @attr ref android.R.styleable#View_textDirection
18903      *
18904      * @hide
18905      */
18906     @ViewDebug.ExportedProperty(category = "text", mapping = {
18907             @ViewDebug.IntToString(from = TEXT_DIRECTION_INHERIT, to = "INHERIT"),
18908             @ViewDebug.IntToString(from = TEXT_DIRECTION_FIRST_STRONG, to = "FIRST_STRONG"),
18909             @ViewDebug.IntToString(from = TEXT_DIRECTION_ANY_RTL, to = "ANY_RTL"),
18910             @ViewDebug.IntToString(from = TEXT_DIRECTION_LTR, to = "LTR"),
18911             @ViewDebug.IntToString(from = TEXT_DIRECTION_RTL, to = "RTL"),
18912             @ViewDebug.IntToString(from = TEXT_DIRECTION_LOCALE, to = "LOCALE")
18913     })
18914     public int getRawTextDirection() {
18915         return (mPrivateFlags2 & PFLAG2_TEXT_DIRECTION_MASK) >> PFLAG2_TEXT_DIRECTION_MASK_SHIFT;
18916     }
18917
18918     /**
18919      * Set the text direction.
18920      *
18921      * @param textDirection the direction to set. Should be one of:
18922      *
18923      * {@link #TEXT_DIRECTION_INHERIT},
18924      * {@link #TEXT_DIRECTION_FIRST_STRONG}
18925      * {@link #TEXT_DIRECTION_ANY_RTL},
18926      * {@link #TEXT_DIRECTION_LTR},
18927      * {@link #TEXT_DIRECTION_RTL},
18928      * {@link #TEXT_DIRECTION_LOCALE}
18929      *
18930      * Resolution will be done if the value is set to TEXT_DIRECTION_INHERIT. The resolution
18931      * proceeds up the parent chain of the view to get the value. If there is no parent, then it will
18932      * return the default {@link #TEXT_DIRECTION_FIRST_STRONG}.
18933      *
18934      * @attr ref android.R.styleable#View_textDirection
18935      */
18936     public void setTextDirection(int textDirection) {
18937         if (getRawTextDirection() != textDirection) {
18938             // Reset the current text direction and the resolved one
18939             mPrivateFlags2 &= ~PFLAG2_TEXT_DIRECTION_MASK;
18940             resetResolvedTextDirection();
18941             // Set the new text direction
18942             mPrivateFlags2 |= ((textDirection << PFLAG2_TEXT_DIRECTION_MASK_SHIFT) & PFLAG2_TEXT_DIRECTION_MASK);
18943             // Do resolution
18944             resolveTextDirection();
18945             // Notify change
18946             onRtlPropertiesChanged(getLayoutDirection());
18947             // Refresh
18948             requestLayout();
18949             invalidate(true);
18950         }
18951     }
18952
18953     /**
18954      * Return the resolved text direction.
18955      *
18956      * @return the resolved text direction. Returns one of:
18957      *
18958      * {@link #TEXT_DIRECTION_FIRST_STRONG}
18959      * {@link #TEXT_DIRECTION_ANY_RTL},
18960      * {@link #TEXT_DIRECTION_LTR},
18961      * {@link #TEXT_DIRECTION_RTL},
18962      * {@link #TEXT_DIRECTION_LOCALE}
18963      *
18964      * @attr ref android.R.styleable#View_textDirection
18965      */
18966     @ViewDebug.ExportedProperty(category = "text", mapping = {
18967             @ViewDebug.IntToString(from = TEXT_DIRECTION_INHERIT, to = "INHERIT"),
18968             @ViewDebug.IntToString(from = TEXT_DIRECTION_FIRST_STRONG, to = "FIRST_STRONG"),
18969             @ViewDebug.IntToString(from = TEXT_DIRECTION_ANY_RTL, to = "ANY_RTL"),
18970             @ViewDebug.IntToString(from = TEXT_DIRECTION_LTR, to = "LTR"),
18971             @ViewDebug.IntToString(from = TEXT_DIRECTION_RTL, to = "RTL"),
18972             @ViewDebug.IntToString(from = TEXT_DIRECTION_LOCALE, to = "LOCALE")
18973     })
18974     public int getTextDirection() {
18975         return (mPrivateFlags2 & PFLAG2_TEXT_DIRECTION_RESOLVED_MASK) >> PFLAG2_TEXT_DIRECTION_RESOLVED_MASK_SHIFT;
18976     }
18977
18978     /**
18979      * Resolve the text direction.
18980      *
18981      * @return true if resolution has been done, false otherwise.
18982      *
18983      * @hide
18984      */
18985     public boolean resolveTextDirection() {
18986         // Reset any previous text direction resolution
18987         mPrivateFlags2 &= ~(PFLAG2_TEXT_DIRECTION_RESOLVED | PFLAG2_TEXT_DIRECTION_RESOLVED_MASK);
18988
18989         if (hasRtlSupport()) {
18990             // Set resolved text direction flag depending on text direction flag
18991             final int textDirection = getRawTextDirection();
18992             switch(textDirection) {
18993                 case TEXT_DIRECTION_INHERIT:
18994                     if (!canResolveTextDirection()) {
18995                         // We cannot do the resolution if there is no parent, so use the default one
18996                         mPrivateFlags2 |= PFLAG2_TEXT_DIRECTION_RESOLVED_DEFAULT;
18997                         // Resolution will need to happen again later
18998                         return false;
18999                     }
19000
19001                     // Parent has not yet resolved, so we still return the default
19002                     try {
19003                         if (!mParent.isTextDirectionResolved()) {
19004                             mPrivateFlags2 |= PFLAG2_TEXT_DIRECTION_RESOLVED_DEFAULT;
19005                             // Resolution will need to happen again later
19006                             return false;
19007                         }
19008                     } catch (AbstractMethodError e) {
19009                         Log.e(VIEW_LOG_TAG, mParent.getClass().getSimpleName() +
19010                                 " does not fully implement ViewParent", e);
19011                         mPrivateFlags2 |= PFLAG2_TEXT_DIRECTION_RESOLVED |
19012                                 PFLAG2_TEXT_DIRECTION_RESOLVED_DEFAULT;
19013                         return true;
19014                     }
19015
19016                     // Set current resolved direction to the same value as the parent's one
19017                     int parentResolvedDirection;
19018                     try {
19019                         parentResolvedDirection = mParent.getTextDirection();
19020                     } catch (AbstractMethodError e) {
19021                         Log.e(VIEW_LOG_TAG, mParent.getClass().getSimpleName() +
19022                                 " does not fully implement ViewParent", e);
19023                         parentResolvedDirection = TEXT_DIRECTION_LTR;
19024                     }
19025                     switch (parentResolvedDirection) {
19026                         case TEXT_DIRECTION_FIRST_STRONG:
19027                         case TEXT_DIRECTION_ANY_RTL:
19028                         case TEXT_DIRECTION_LTR:
19029                         case TEXT_DIRECTION_RTL:
19030                         case TEXT_DIRECTION_LOCALE:
19031                             mPrivateFlags2 |=
19032                                     (parentResolvedDirection << PFLAG2_TEXT_DIRECTION_RESOLVED_MASK_SHIFT);
19033                             break;
19034                         default:
19035                             // Default resolved direction is "first strong" heuristic
19036                             mPrivateFlags2 |= PFLAG2_TEXT_DIRECTION_RESOLVED_DEFAULT;
19037                     }
19038                     break;
19039                 case TEXT_DIRECTION_FIRST_STRONG:
19040                 case TEXT_DIRECTION_ANY_RTL:
19041                 case TEXT_DIRECTION_LTR:
19042                 case TEXT_DIRECTION_RTL:
19043                 case TEXT_DIRECTION_LOCALE:
19044                     // Resolved direction is the same as text direction
19045                     mPrivateFlags2 |= (textDirection << PFLAG2_TEXT_DIRECTION_RESOLVED_MASK_SHIFT);
19046                     break;
19047                 default:
19048                     // Default resolved direction is "first strong" heuristic
19049                     mPrivateFlags2 |= PFLAG2_TEXT_DIRECTION_RESOLVED_DEFAULT;
19050             }
19051         } else {
19052             // Default resolved direction is "first strong" heuristic
19053             mPrivateFlags2 |= PFLAG2_TEXT_DIRECTION_RESOLVED_DEFAULT;
19054         }
19055
19056         // Set to resolved
19057         mPrivateFlags2 |= PFLAG2_TEXT_DIRECTION_RESOLVED;
19058         return true;
19059     }
19060
19061     /**
19062      * Check if text direction resolution can be done.
19063      *
19064      * @return true if text direction resolution can be done otherwise return false.
19065      */
19066     public boolean canResolveTextDirection() {
19067         switch (getRawTextDirection()) {
19068             case TEXT_DIRECTION_INHERIT:
19069                 if (mParent != null) {
19070                     try {
19071                         return mParent.canResolveTextDirection();
19072                     } catch (AbstractMethodError e) {
19073                         Log.e(VIEW_LOG_TAG, mParent.getClass().getSimpleName() +
19074                                 " does not fully implement ViewParent", e);
19075                     }
19076                 }
19077                 return false;
19078
19079             default:
19080                 return true;
19081         }
19082     }
19083
19084     /**
19085      * Reset resolved text direction. Text direction will be resolved during a call to
19086      * {@link #onMeasure(int, int)}.
19087      *
19088      * @hide
19089      */
19090     public void resetResolvedTextDirection() {
19091         // Reset any previous text direction resolution
19092         mPrivateFlags2 &= ~(PFLAG2_TEXT_DIRECTION_RESOLVED | PFLAG2_TEXT_DIRECTION_RESOLVED_MASK);
19093         // Set to default value
19094         mPrivateFlags2 |= PFLAG2_TEXT_DIRECTION_RESOLVED_DEFAULT;
19095     }
19096
19097     /**
19098      * @return true if text direction is inherited.
19099      *
19100      * @hide
19101      */
19102     public boolean isTextDirectionInherited() {
19103         return (getRawTextDirection() == TEXT_DIRECTION_INHERIT);
19104     }
19105
19106     /**
19107      * @return true if text direction is resolved.
19108      */
19109     public boolean isTextDirectionResolved() {
19110         return (mPrivateFlags2 & PFLAG2_TEXT_DIRECTION_RESOLVED) == PFLAG2_TEXT_DIRECTION_RESOLVED;
19111     }
19112
19113     /**
19114      * Return the value specifying the text alignment or policy that was set with
19115      * {@link #setTextAlignment(int)}.
19116      *
19117      * @return the defined text alignment. It can be one of:
19118      *
19119      * {@link #TEXT_ALIGNMENT_INHERIT},
19120      * {@link #TEXT_ALIGNMENT_GRAVITY},
19121      * {@link #TEXT_ALIGNMENT_CENTER},
19122      * {@link #TEXT_ALIGNMENT_TEXT_START},
19123      * {@link #TEXT_ALIGNMENT_TEXT_END},
19124      * {@link #TEXT_ALIGNMENT_VIEW_START},
19125      * {@link #TEXT_ALIGNMENT_VIEW_END}
19126      *
19127      * @attr ref android.R.styleable#View_textAlignment
19128      *
19129      * @hide
19130      */
19131     @ViewDebug.ExportedProperty(category = "text", mapping = {
19132             @ViewDebug.IntToString(from = TEXT_ALIGNMENT_INHERIT, to = "INHERIT"),
19133             @ViewDebug.IntToString(from = TEXT_ALIGNMENT_GRAVITY, to = "GRAVITY"),
19134             @ViewDebug.IntToString(from = TEXT_ALIGNMENT_TEXT_START, to = "TEXT_START"),
19135             @ViewDebug.IntToString(from = TEXT_ALIGNMENT_TEXT_END, to = "TEXT_END"),
19136             @ViewDebug.IntToString(from = TEXT_ALIGNMENT_CENTER, to = "CENTER"),
19137             @ViewDebug.IntToString(from = TEXT_ALIGNMENT_VIEW_START, to = "VIEW_START"),
19138             @ViewDebug.IntToString(from = TEXT_ALIGNMENT_VIEW_END, to = "VIEW_END")
19139     })
19140     @TextAlignment
19141     public int getRawTextAlignment() {
19142         return (mPrivateFlags2 & PFLAG2_TEXT_ALIGNMENT_MASK) >> PFLAG2_TEXT_ALIGNMENT_MASK_SHIFT;
19143     }
19144
19145     /**
19146      * Set the text alignment.
19147      *
19148      * @param textAlignment The text alignment to set. Should be one of
19149      *
19150      * {@link #TEXT_ALIGNMENT_INHERIT},
19151      * {@link #TEXT_ALIGNMENT_GRAVITY},
19152      * {@link #TEXT_ALIGNMENT_CENTER},
19153      * {@link #TEXT_ALIGNMENT_TEXT_START},
19154      * {@link #TEXT_ALIGNMENT_TEXT_END},
19155      * {@link #TEXT_ALIGNMENT_VIEW_START},
19156      * {@link #TEXT_ALIGNMENT_VIEW_END}
19157      *
19158      * Resolution will be done if the value is set to TEXT_ALIGNMENT_INHERIT. The resolution
19159      * proceeds up the parent chain of the view to get the value. If there is no parent, then it
19160      * will return the default {@link #TEXT_ALIGNMENT_GRAVITY}.
19161      *
19162      * @attr ref android.R.styleable#View_textAlignment
19163      */
19164     public void setTextAlignment(@TextAlignment int textAlignment) {
19165         if (textAlignment != getRawTextAlignment()) {
19166             // Reset the current and resolved text alignment
19167             mPrivateFlags2 &= ~PFLAG2_TEXT_ALIGNMENT_MASK;
19168             resetResolvedTextAlignment();
19169             // Set the new text alignment
19170             mPrivateFlags2 |=
19171                     ((textAlignment << PFLAG2_TEXT_ALIGNMENT_MASK_SHIFT) & PFLAG2_TEXT_ALIGNMENT_MASK);
19172             // Do resolution
19173             resolveTextAlignment();
19174             // Notify change
19175             onRtlPropertiesChanged(getLayoutDirection());
19176             // Refresh
19177             requestLayout();
19178             invalidate(true);
19179         }
19180     }
19181
19182     /**
19183      * Return the resolved text alignment.
19184      *
19185      * @return the resolved text alignment. Returns one of:
19186      *
19187      * {@link #TEXT_ALIGNMENT_GRAVITY},
19188      * {@link #TEXT_ALIGNMENT_CENTER},
19189      * {@link #TEXT_ALIGNMENT_TEXT_START},
19190      * {@link #TEXT_ALIGNMENT_TEXT_END},
19191      * {@link #TEXT_ALIGNMENT_VIEW_START},
19192      * {@link #TEXT_ALIGNMENT_VIEW_END}
19193      *
19194      * @attr ref android.R.styleable#View_textAlignment
19195      */
19196     @ViewDebug.ExportedProperty(category = "text", mapping = {
19197             @ViewDebug.IntToString(from = TEXT_ALIGNMENT_INHERIT, to = "INHERIT"),
19198             @ViewDebug.IntToString(from = TEXT_ALIGNMENT_GRAVITY, to = "GRAVITY"),
19199             @ViewDebug.IntToString(from = TEXT_ALIGNMENT_TEXT_START, to = "TEXT_START"),
19200             @ViewDebug.IntToString(from = TEXT_ALIGNMENT_TEXT_END, to = "TEXT_END"),
19201             @ViewDebug.IntToString(from = TEXT_ALIGNMENT_CENTER, to = "CENTER"),
19202             @ViewDebug.IntToString(from = TEXT_ALIGNMENT_VIEW_START, to = "VIEW_START"),
19203             @ViewDebug.IntToString(from = TEXT_ALIGNMENT_VIEW_END, to = "VIEW_END")
19204     })
19205     @TextAlignment
19206     public int getTextAlignment() {
19207         return (mPrivateFlags2 & PFLAG2_TEXT_ALIGNMENT_RESOLVED_MASK) >>
19208                 PFLAG2_TEXT_ALIGNMENT_RESOLVED_MASK_SHIFT;
19209     }
19210
19211     /**
19212      * Resolve the text alignment.
19213      *
19214      * @return true if resolution has been done, false otherwise.
19215      *
19216      * @hide
19217      */
19218     public boolean resolveTextAlignment() {
19219         // Reset any previous text alignment resolution
19220         mPrivateFlags2 &= ~(PFLAG2_TEXT_ALIGNMENT_RESOLVED | PFLAG2_TEXT_ALIGNMENT_RESOLVED_MASK);
19221
19222         if (hasRtlSupport()) {
19223             // Set resolved text alignment flag depending on text alignment flag
19224             final int textAlignment = getRawTextAlignment();
19225             switch (textAlignment) {
19226                 case TEXT_ALIGNMENT_INHERIT:
19227                     // Check if we can resolve the text alignment
19228                     if (!canResolveTextAlignment()) {
19229                         // We cannot do the resolution if there is no parent so use the default
19230                         mPrivateFlags2 |= PFLAG2_TEXT_ALIGNMENT_RESOLVED_DEFAULT;
19231                         // Resolution will need to happen again later
19232                         return false;
19233                     }
19234
19235                     // Parent has not yet resolved, so we still return the default
19236                     try {
19237                         if (!mParent.isTextAlignmentResolved()) {
19238                             mPrivateFlags2 |= PFLAG2_TEXT_ALIGNMENT_RESOLVED_DEFAULT;
19239                             // Resolution will need to happen again later
19240                             return false;
19241                         }
19242                     } catch (AbstractMethodError e) {
19243                         Log.e(VIEW_LOG_TAG, mParent.getClass().getSimpleName() +
19244                                 " does not fully implement ViewParent", e);
19245                         mPrivateFlags2 |= PFLAG2_TEXT_ALIGNMENT_RESOLVED |
19246                                 PFLAG2_TEXT_ALIGNMENT_RESOLVED_DEFAULT;
19247                         return true;
19248                     }
19249
19250                     int parentResolvedTextAlignment;
19251                     try {
19252                         parentResolvedTextAlignment = mParent.getTextAlignment();
19253                     } catch (AbstractMethodError e) {
19254                         Log.e(VIEW_LOG_TAG, mParent.getClass().getSimpleName() +
19255                                 " does not fully implement ViewParent", e);
19256                         parentResolvedTextAlignment = TEXT_ALIGNMENT_GRAVITY;
19257                     }
19258                     switch (parentResolvedTextAlignment) {
19259                         case TEXT_ALIGNMENT_GRAVITY:
19260                         case TEXT_ALIGNMENT_TEXT_START:
19261                         case TEXT_ALIGNMENT_TEXT_END:
19262                         case TEXT_ALIGNMENT_CENTER:
19263                         case TEXT_ALIGNMENT_VIEW_START:
19264                         case TEXT_ALIGNMENT_VIEW_END:
19265                             // Resolved text alignment is the same as the parent resolved
19266                             // text alignment
19267                             mPrivateFlags2 |=
19268                                     (parentResolvedTextAlignment << PFLAG2_TEXT_ALIGNMENT_RESOLVED_MASK_SHIFT);
19269                             break;
19270                         default:
19271                             // Use default resolved text alignment
19272                             mPrivateFlags2 |= PFLAG2_TEXT_ALIGNMENT_RESOLVED_DEFAULT;
19273                     }
19274                     break;
19275                 case TEXT_ALIGNMENT_GRAVITY:
19276                 case TEXT_ALIGNMENT_TEXT_START:
19277                 case TEXT_ALIGNMENT_TEXT_END:
19278                 case TEXT_ALIGNMENT_CENTER:
19279                 case TEXT_ALIGNMENT_VIEW_START:
19280                 case TEXT_ALIGNMENT_VIEW_END:
19281                     // Resolved text alignment is the same as text alignment
19282                     mPrivateFlags2 |= (textAlignment << PFLAG2_TEXT_ALIGNMENT_RESOLVED_MASK_SHIFT);
19283                     break;
19284                 default:
19285                     // Use default resolved text alignment
19286                     mPrivateFlags2 |= PFLAG2_TEXT_ALIGNMENT_RESOLVED_DEFAULT;
19287             }
19288         } else {
19289             // Use default resolved text alignment
19290             mPrivateFlags2 |= PFLAG2_TEXT_ALIGNMENT_RESOLVED_DEFAULT;
19291         }
19292
19293         // Set the resolved
19294         mPrivateFlags2 |= PFLAG2_TEXT_ALIGNMENT_RESOLVED;
19295         return true;
19296     }
19297
19298     /**
19299      * Check if text alignment resolution can be done.
19300      *
19301      * @return true if text alignment resolution can be done otherwise return false.
19302      */
19303     public boolean canResolveTextAlignment() {
19304         switch (getRawTextAlignment()) {
19305             case TEXT_DIRECTION_INHERIT:
19306                 if (mParent != null) {
19307                     try {
19308                         return mParent.canResolveTextAlignment();
19309                     } catch (AbstractMethodError e) {
19310                         Log.e(VIEW_LOG_TAG, mParent.getClass().getSimpleName() +
19311                                 " does not fully implement ViewParent", e);
19312                     }
19313                 }
19314                 return false;
19315
19316             default:
19317                 return true;
19318         }
19319     }
19320
19321     /**
19322      * Reset resolved text alignment. Text alignment will be resolved during a call to
19323      * {@link #onMeasure(int, int)}.
19324      *
19325      * @hide
19326      */
19327     public void resetResolvedTextAlignment() {
19328         // Reset any previous text alignment resolution
19329         mPrivateFlags2 &= ~(PFLAG2_TEXT_ALIGNMENT_RESOLVED | PFLAG2_TEXT_ALIGNMENT_RESOLVED_MASK);
19330         // Set to default
19331         mPrivateFlags2 |= PFLAG2_TEXT_ALIGNMENT_RESOLVED_DEFAULT;
19332     }
19333
19334     /**
19335      * @return true if text alignment is inherited.
19336      *
19337      * @hide
19338      */
19339     public boolean isTextAlignmentInherited() {
19340         return (getRawTextAlignment() == TEXT_ALIGNMENT_INHERIT);
19341     }
19342
19343     /**
19344      * @return true if text alignment is resolved.
19345      */
19346     public boolean isTextAlignmentResolved() {
19347         return (mPrivateFlags2 & PFLAG2_TEXT_ALIGNMENT_RESOLVED) == PFLAG2_TEXT_ALIGNMENT_RESOLVED;
19348     }
19349
19350     /**
19351      * Generate a value suitable for use in {@link #setId(int)}.
19352      * This value will not collide with ID values generated at build time by aapt for R.id.
19353      *
19354      * @return a generated ID value
19355      */
19356     public static int generateViewId() {
19357         for (;;) {
19358             final int result = sNextGeneratedId.get();
19359             // aapt-generated IDs have the high byte nonzero; clamp to the range under that.
19360             int newValue = result + 1;
19361             if (newValue > 0x00FFFFFF) newValue = 1; // Roll over to 1, not 0.
19362             if (sNextGeneratedId.compareAndSet(result, newValue)) {
19363                 return result;
19364             }
19365         }
19366     }
19367
19368     /**
19369      * Gets the Views in the hierarchy affected by entering and exiting Activity Scene transitions.
19370      * @param transitioningViews This View will be added to transitioningViews if it is VISIBLE and
19371      *                           a normal View or a ViewGroup with
19372      *                           {@link android.view.ViewGroup#isTransitionGroup()} true.
19373      * @hide
19374      */
19375     public void captureTransitioningViews(List<View> transitioningViews) {
19376         if (getVisibility() == View.VISIBLE) {
19377             transitioningViews.add(this);
19378         }
19379     }
19380
19381     /**
19382      * Adds all Views that have {@link #getTransitionName()} non-null to namedElements.
19383      * @param namedElements Will contain all Views in the hierarchy having a transitionName.
19384      * @hide
19385      */
19386     public void findNamedViews(Map<String, View> namedElements) {
19387         if (getVisibility() == VISIBLE || mGhostView != null) {
19388             String transitionName = getTransitionName();
19389             if (transitionName != null) {
19390                 namedElements.put(transitionName, this);
19391             }
19392         }
19393     }
19394
19395     //
19396     // Properties
19397     //
19398     /**
19399      * A Property wrapper around the <code>alpha</code> functionality handled by the
19400      * {@link View#setAlpha(float)} and {@link View#getAlpha()} methods.
19401      */
19402     public static final Property<View, Float> ALPHA = new FloatProperty<View>("alpha") {
19403         @Override
19404         public void setValue(View object, float value) {
19405             object.setAlpha(value);
19406         }
19407
19408         @Override
19409         public Float get(View object) {
19410             return object.getAlpha();
19411         }
19412     };
19413
19414     /**
19415      * A Property wrapper around the <code>translationX</code> functionality handled by the
19416      * {@link View#setTranslationX(float)} and {@link View#getTranslationX()} methods.
19417      */
19418     public static final Property<View, Float> TRANSLATION_X = new FloatProperty<View>("translationX") {
19419         @Override
19420         public void setValue(View object, float value) {
19421             object.setTranslationX(value);
19422         }
19423
19424                 @Override
19425         public Float get(View object) {
19426             return object.getTranslationX();
19427         }
19428     };
19429
19430     /**
19431      * A Property wrapper around the <code>translationY</code> functionality handled by the
19432      * {@link View#setTranslationY(float)} and {@link View#getTranslationY()} methods.
19433      */
19434     public static final Property<View, Float> TRANSLATION_Y = new FloatProperty<View>("translationY") {
19435         @Override
19436         public void setValue(View object, float value) {
19437             object.setTranslationY(value);
19438         }
19439
19440         @Override
19441         public Float get(View object) {
19442             return object.getTranslationY();
19443         }
19444     };
19445
19446     /**
19447      * A Property wrapper around the <code>translationZ</code> functionality handled by the
19448      * {@link View#setTranslationZ(float)} and {@link View#getTranslationZ()} methods.
19449      */
19450     public static final Property<View, Float> TRANSLATION_Z = new FloatProperty<View>("translationZ") {
19451         @Override
19452         public void setValue(View object, float value) {
19453             object.setTranslationZ(value);
19454         }
19455
19456         @Override
19457         public Float get(View object) {
19458             return object.getTranslationZ();
19459         }
19460     };
19461
19462     /**
19463      * A Property wrapper around the <code>x</code> functionality handled by the
19464      * {@link View#setX(float)} and {@link View#getX()} methods.
19465      */
19466     public static final Property<View, Float> X = new FloatProperty<View>("x") {
19467         @Override
19468         public void setValue(View object, float value) {
19469             object.setX(value);
19470         }
19471
19472         @Override
19473         public Float get(View object) {
19474             return object.getX();
19475         }
19476     };
19477
19478     /**
19479      * A Property wrapper around the <code>y</code> functionality handled by the
19480      * {@link View#setY(float)} and {@link View#getY()} methods.
19481      */
19482     public static final Property<View, Float> Y = new FloatProperty<View>("y") {
19483         @Override
19484         public void setValue(View object, float value) {
19485             object.setY(value);
19486         }
19487
19488         @Override
19489         public Float get(View object) {
19490             return object.getY();
19491         }
19492     };
19493
19494     /**
19495      * A Property wrapper around the <code>z</code> functionality handled by the
19496      * {@link View#setZ(float)} and {@link View#getZ()} methods.
19497      */
19498     public static final Property<View, Float> Z = new FloatProperty<View>("z") {
19499         @Override
19500         public void setValue(View object, float value) {
19501             object.setZ(value);
19502         }
19503
19504         @Override
19505         public Float get(View object) {
19506             return object.getZ();
19507         }
19508     };
19509
19510     /**
19511      * A Property wrapper around the <code>rotation</code> functionality handled by the
19512      * {@link View#setRotation(float)} and {@link View#getRotation()} methods.
19513      */
19514     public static final Property<View, Float> ROTATION = new FloatProperty<View>("rotation") {
19515         @Override
19516         public void setValue(View object, float value) {
19517             object.setRotation(value);
19518         }
19519
19520         @Override
19521         public Float get(View object) {
19522             return object.getRotation();
19523         }
19524     };
19525
19526     /**
19527      * A Property wrapper around the <code>rotationX</code> functionality handled by the
19528      * {@link View#setRotationX(float)} and {@link View#getRotationX()} methods.
19529      */
19530     public static final Property<View, Float> ROTATION_X = new FloatProperty<View>("rotationX") {
19531         @Override
19532         public void setValue(View object, float value) {
19533             object.setRotationX(value);
19534         }
19535
19536         @Override
19537         public Float get(View object) {
19538             return object.getRotationX();
19539         }
19540     };
19541
19542     /**
19543      * A Property wrapper around the <code>rotationY</code> functionality handled by the
19544      * {@link View#setRotationY(float)} and {@link View#getRotationY()} methods.
19545      */
19546     public static final Property<View, Float> ROTATION_Y = new FloatProperty<View>("rotationY") {
19547         @Override
19548         public void setValue(View object, float value) {
19549             object.setRotationY(value);
19550         }
19551
19552         @Override
19553         public Float get(View object) {
19554             return object.getRotationY();
19555         }
19556     };
19557
19558     /**
19559      * A Property wrapper around the <code>scaleX</code> functionality handled by the
19560      * {@link View#setScaleX(float)} and {@link View#getScaleX()} methods.
19561      */
19562     public static final Property<View, Float> SCALE_X = new FloatProperty<View>("scaleX") {
19563         @Override
19564         public void setValue(View object, float value) {
19565             object.setScaleX(value);
19566         }
19567
19568         @Override
19569         public Float get(View object) {
19570             return object.getScaleX();
19571         }
19572     };
19573
19574     /**
19575      * A Property wrapper around the <code>scaleY</code> functionality handled by the
19576      * {@link View#setScaleY(float)} and {@link View#getScaleY()} methods.
19577      */
19578     public static final Property<View, Float> SCALE_Y = new FloatProperty<View>("scaleY") {
19579         @Override
19580         public void setValue(View object, float value) {
19581             object.setScaleY(value);
19582         }
19583
19584         @Override
19585         public Float get(View object) {
19586             return object.getScaleY();
19587         }
19588     };
19589
19590     /**
19591      * A MeasureSpec encapsulates the layout requirements passed from parent to child.
19592      * Each MeasureSpec represents a requirement for either the width or the height.
19593      * A MeasureSpec is comprised of a size and a mode. There are three possible
19594      * modes:
19595      * <dl>
19596      * <dt>UNSPECIFIED</dt>
19597      * <dd>
19598      * The parent has not imposed any constraint on the child. It can be whatever size
19599      * it wants.
19600      * </dd>
19601      *
19602      * <dt>EXACTLY</dt>
19603      * <dd>
19604      * The parent has determined an exact size for the child. The child is going to be
19605      * given those bounds regardless of how big it wants to be.
19606      * </dd>
19607      *
19608      * <dt>AT_MOST</dt>
19609      * <dd>
19610      * The child can be as large as it wants up to the specified size.
19611      * </dd>
19612      * </dl>
19613      *
19614      * MeasureSpecs are implemented as ints to reduce object allocation. This class
19615      * is provided to pack and unpack the &lt;size, mode&gt; tuple into the int.
19616      */
19617     public static class MeasureSpec {
19618         private static final int MODE_SHIFT = 30;
19619         private static final int MODE_MASK  = 0x3 << MODE_SHIFT;
19620
19621         /**
19622          * Measure specification mode: The parent has not imposed any constraint
19623          * on the child. It can be whatever size it wants.
19624          */
19625         public static final int UNSPECIFIED = 0 << MODE_SHIFT;
19626
19627         /**
19628          * Measure specification mode: The parent has determined an exact size
19629          * for the child. The child is going to be given those bounds regardless
19630          * of how big it wants to be.
19631          */
19632         public static final int EXACTLY     = 1 << MODE_SHIFT;
19633
19634         /**
19635          * Measure specification mode: The child can be as large as it wants up
19636          * to the specified size.
19637          */
19638         public static final int AT_MOST     = 2 << MODE_SHIFT;
19639
19640         /**
19641          * Creates a measure specification based on the supplied size and mode.
19642          *
19643          * The mode must always be one of the following:
19644          * <ul>
19645          *  <li>{@link android.view.View.MeasureSpec#UNSPECIFIED}</li>
19646          *  <li>{@link android.view.View.MeasureSpec#EXACTLY}</li>
19647          *  <li>{@link android.view.View.MeasureSpec#AT_MOST}</li>
19648          * </ul>
19649          *
19650          * <p><strong>Note:</strong> On API level 17 and lower, makeMeasureSpec's
19651          * implementation was such that the order of arguments did not matter
19652          * and overflow in either value could impact the resulting MeasureSpec.
19653          * {@link android.widget.RelativeLayout} was affected by this bug.
19654          * Apps targeting API levels greater than 17 will get the fixed, more strict
19655          * behavior.</p>
19656          *
19657          * @param size the size of the measure specification
19658          * @param mode the mode of the measure specification
19659          * @return the measure specification based on size and mode
19660          */
19661         public static int makeMeasureSpec(int size, int mode) {
19662             if (sUseBrokenMakeMeasureSpec) {
19663                 return size + mode;
19664             } else {
19665                 return (size & ~MODE_MASK) | (mode & MODE_MASK);
19666             }
19667         }
19668
19669         /**
19670          * Extracts the mode from the supplied measure specification.
19671          *
19672          * @param measureSpec the measure specification to extract the mode from
19673          * @return {@link android.view.View.MeasureSpec#UNSPECIFIED},
19674          *         {@link android.view.View.MeasureSpec#AT_MOST} or
19675          *         {@link android.view.View.MeasureSpec#EXACTLY}
19676          */
19677         public static int getMode(int measureSpec) {
19678             return (measureSpec & MODE_MASK);
19679         }
19680
19681         /**
19682          * Extracts the size from the supplied measure specification.
19683          *
19684          * @param measureSpec the measure specification to extract the size from
19685          * @return the size in pixels defined in the supplied measure specification
19686          */
19687         public static int getSize(int measureSpec) {
19688             return (measureSpec & ~MODE_MASK);
19689         }
19690
19691         static int adjust(int measureSpec, int delta) {
19692             final int mode = getMode(measureSpec);
19693             if (mode == UNSPECIFIED) {
19694                 // No need to adjust size for UNSPECIFIED mode.
19695                 return makeMeasureSpec(0, UNSPECIFIED);
19696             }
19697             int size = getSize(measureSpec) + delta;
19698             if (size < 0) {
19699                 Log.e(VIEW_LOG_TAG, "MeasureSpec.adjust: new size would be negative! (" + size +
19700                         ") spec: " + toString(measureSpec) + " delta: " + delta);
19701                 size = 0;
19702             }
19703             return makeMeasureSpec(size, mode);
19704         }
19705
19706         /**
19707          * Returns a String representation of the specified measure
19708          * specification.
19709          *
19710          * @param measureSpec the measure specification to convert to a String
19711          * @return a String with the following format: "MeasureSpec: MODE SIZE"
19712          */
19713         public static String toString(int measureSpec) {
19714             int mode = getMode(measureSpec);
19715             int size = getSize(measureSpec);
19716
19717             StringBuilder sb = new StringBuilder("MeasureSpec: ");
19718
19719             if (mode == UNSPECIFIED)
19720                 sb.append("UNSPECIFIED ");
19721             else if (mode == EXACTLY)
19722                 sb.append("EXACTLY ");
19723             else if (mode == AT_MOST)
19724                 sb.append("AT_MOST ");
19725             else
19726                 sb.append(mode).append(" ");
19727
19728             sb.append(size);
19729             return sb.toString();
19730         }
19731     }
19732
19733     private final class CheckForLongPress implements Runnable {
19734         private int mOriginalWindowAttachCount;
19735
19736         @Override
19737         public void run() {
19738             if (isPressed() && (mParent != null)
19739                     && mOriginalWindowAttachCount == mWindowAttachCount) {
19740                 if (performLongClick()) {
19741                     mHasPerformedLongPress = true;
19742                 }
19743             }
19744         }
19745
19746         public void rememberWindowAttachCount() {
19747             mOriginalWindowAttachCount = mWindowAttachCount;
19748         }
19749     }
19750
19751     private final class CheckForTap implements Runnable {
19752         public float x;
19753         public float y;
19754
19755         @Override
19756         public void run() {
19757             mPrivateFlags &= ~PFLAG_PREPRESSED;
19758             setPressed(true, x, y);
19759             checkForLongClick(ViewConfiguration.getTapTimeout());
19760         }
19761     }
19762
19763     private final class PerformClick implements Runnable {
19764         @Override
19765         public void run() {
19766             performClick();
19767         }
19768     }
19769
19770     /** @hide */
19771     public void hackTurnOffWindowResizeAnim(boolean off) {
19772         mAttachInfo.mTurnOffWindowResizeAnim = off;
19773     }
19774
19775     /**
19776      * This method returns a ViewPropertyAnimator object, which can be used to animate
19777      * specific properties on this View.
19778      *
19779      * @return ViewPropertyAnimator The ViewPropertyAnimator associated with this View.
19780      */
19781     public ViewPropertyAnimator animate() {
19782         if (mAnimator == null) {
19783             mAnimator = new ViewPropertyAnimator(this);
19784         }
19785         return mAnimator;
19786     }
19787
19788     /**
19789      * Sets the name of the View to be used to identify Views in Transitions.
19790      * Names should be unique in the View hierarchy.
19791      *
19792      * @param transitionName The name of the View to uniquely identify it for Transitions.
19793      */
19794     public final void setTransitionName(String transitionName) {
19795         mTransitionName = transitionName;
19796     }
19797
19798     /**
19799      * Returns the name of the View to be used to identify Views in Transitions.
19800      * Names should be unique in the View hierarchy.
19801      *
19802      * <p>This returns null if the View has not been given a name.</p>
19803      *
19804      * @return The name used of the View to be used to identify Views in Transitions or null
19805      * if no name has been given.
19806      */
19807     @ViewDebug.ExportedProperty
19808     public String getTransitionName() {
19809         return mTransitionName;
19810     }
19811
19812     /**
19813      * Interface definition for a callback to be invoked when a hardware key event is
19814      * dispatched to this view. The callback will be invoked before the key event is
19815      * given to the view. This is only useful for hardware keyboards; a software input
19816      * method has no obligation to trigger this listener.
19817      */
19818     public interface OnKeyListener {
19819         /**
19820          * Called when a hardware key is dispatched to a view. This allows listeners to
19821          * get a chance to respond before the target view.
19822          * <p>Key presses in software keyboards will generally NOT trigger this method,
19823          * although some may elect to do so in some situations. Do not assume a
19824          * software input method has to be key-based; even if it is, it may use key presses
19825          * in a different way than you expect, so there is no way to reliably catch soft
19826          * input key presses.
19827          *
19828          * @param v The view the key has been dispatched to.
19829          * @param keyCode The code for the physical key that was pressed
19830          * @param event The KeyEvent object containing full information about
19831          *        the event.
19832          * @return True if the listener has consumed the event, false otherwise.
19833          */
19834         boolean onKey(View v, int keyCode, KeyEvent event);
19835     }
19836
19837     /**
19838      * Interface definition for a callback to be invoked when a touch event is
19839      * dispatched to this view. The callback will be invoked before the touch
19840      * event is given to the view.
19841      */
19842     public interface OnTouchListener {
19843         /**
19844          * Called when a touch event is dispatched to a view. This allows listeners to
19845          * get a chance to respond before the target view.
19846          *
19847          * @param v The view the touch event has been dispatched to.
19848          * @param event The MotionEvent object containing full information about
19849          *        the event.
19850          * @return True if the listener has consumed the event, false otherwise.
19851          */
19852         boolean onTouch(View v, MotionEvent event);
19853     }
19854
19855     /**
19856      * Interface definition for a callback to be invoked when a hover event is
19857      * dispatched to this view. The callback will be invoked before the hover
19858      * event is given to the view.
19859      */
19860     public interface OnHoverListener {
19861         /**
19862          * Called when a hover event is dispatched to a view. This allows listeners to
19863          * get a chance to respond before the target view.
19864          *
19865          * @param v The view the hover event has been dispatched to.
19866          * @param event The MotionEvent object containing full information about
19867          *        the event.
19868          * @return True if the listener has consumed the event, false otherwise.
19869          */
19870         boolean onHover(View v, MotionEvent event);
19871     }
19872
19873     /**
19874      * Interface definition for a callback to be invoked when a generic motion event is
19875      * dispatched to this view. The callback will be invoked before the generic motion
19876      * event is given to the view.
19877      */
19878     public interface OnGenericMotionListener {
19879         /**
19880          * Called when a generic motion event is dispatched to a view. This allows listeners to
19881          * get a chance to respond before the target view.
19882          *
19883          * @param v The view the generic motion event has been dispatched to.
19884          * @param event The MotionEvent object containing full information about
19885          *        the event.
19886          * @return True if the listener has consumed the event, false otherwise.
19887          */
19888         boolean onGenericMotion(View v, MotionEvent event);
19889     }
19890
19891     /**
19892      * Interface definition for a callback to be invoked when a view has been clicked and held.
19893      */
19894     public interface OnLongClickListener {
19895         /**
19896          * Called when a view has been clicked and held.
19897          *
19898          * @param v The view that was clicked and held.
19899          *
19900          * @return true if the callback consumed the long click, false otherwise.
19901          */
19902         boolean onLongClick(View v);
19903     }
19904
19905     /**
19906      * Interface definition for a callback to be invoked when a drag is being dispatched
19907      * to this view.  The callback will be invoked before the hosting view's own
19908      * onDrag(event) method.  If the listener wants to fall back to the hosting view's
19909      * onDrag(event) behavior, it should return 'false' from this callback.
19910      *
19911      * <div class="special reference">
19912      * <h3>Developer Guides</h3>
19913      * <p>For a guide to implementing drag and drop features, read the
19914      * <a href="{@docRoot}guide/topics/ui/drag-drop.html">Drag and Drop</a> developer guide.</p>
19915      * </div>
19916      */
19917     public interface OnDragListener {
19918         /**
19919          * Called when a drag event is dispatched to a view. This allows listeners
19920          * to get a chance to override base View behavior.
19921          *
19922          * @param v The View that received the drag event.
19923          * @param event The {@link android.view.DragEvent} object for the drag event.
19924          * @return {@code true} if the drag event was handled successfully, or {@code false}
19925          * if the drag event was not handled. Note that {@code false} will trigger the View
19926          * to call its {@link #onDragEvent(DragEvent) onDragEvent()} handler.
19927          */
19928         boolean onDrag(View v, DragEvent event);
19929     }
19930
19931     /**
19932      * Interface definition for a callback to be invoked when the focus state of
19933      * a view changed.
19934      */
19935     public interface OnFocusChangeListener {
19936         /**
19937          * Called when the focus state of a view has changed.
19938          *
19939          * @param v The view whose state has changed.
19940          * @param hasFocus The new focus state of v.
19941          */
19942         void onFocusChange(View v, boolean hasFocus);
19943     }
19944
19945     /**
19946      * Interface definition for a callback to be invoked when a view is clicked.
19947      */
19948     public interface OnClickListener {
19949         /**
19950          * Called when a view has been clicked.
19951          *
19952          * @param v The view that was clicked.
19953          */
19954         void onClick(View v);
19955     }
19956
19957     /**
19958      * Interface definition for a callback to be invoked when the context menu
19959      * for this view is being built.
19960      */
19961     public interface OnCreateContextMenuListener {
19962         /**
19963          * Called when the context menu for this view is being built. It is not
19964          * safe to hold onto the menu after this method returns.
19965          *
19966          * @param menu The context menu that is being built
19967          * @param v The view for which the context menu is being built
19968          * @param menuInfo Extra information about the item for which the
19969          *            context menu should be shown. This information will vary
19970          *            depending on the class of v.
19971          */
19972         void onCreateContextMenu(ContextMenu menu, View v, ContextMenuInfo menuInfo);
19973     }
19974
19975     /**
19976      * Interface definition for a callback to be invoked when the status bar changes
19977      * visibility.  This reports <strong>global</strong> changes to the system UI
19978      * state, not what the application is requesting.
19979      *
19980      * @see View#setOnSystemUiVisibilityChangeListener(android.view.View.OnSystemUiVisibilityChangeListener)
19981      */
19982     public interface OnSystemUiVisibilityChangeListener {
19983         /**
19984          * Called when the status bar changes visibility because of a call to
19985          * {@link View#setSystemUiVisibility(int)}.
19986          *
19987          * @param visibility  Bitwise-or of flags {@link #SYSTEM_UI_FLAG_LOW_PROFILE},
19988          * {@link #SYSTEM_UI_FLAG_HIDE_NAVIGATION}, and {@link #SYSTEM_UI_FLAG_FULLSCREEN}.
19989          * This tells you the <strong>global</strong> state of these UI visibility
19990          * flags, not what your app is currently applying.
19991          */
19992         public void onSystemUiVisibilityChange(int visibility);
19993     }
19994
19995     /**
19996      * Interface definition for a callback to be invoked when this view is attached
19997      * or detached from its window.
19998      */
19999     public interface OnAttachStateChangeListener {
20000         /**
20001          * Called when the view is attached to a window.
20002          * @param v The view that was attached
20003          */
20004         public void onViewAttachedToWindow(View v);
20005         /**
20006          * Called when the view is detached from a window.
20007          * @param v The view that was detached
20008          */
20009         public void onViewDetachedFromWindow(View v);
20010     }
20011
20012     /**
20013      * Listener for applying window insets on a view in a custom way.
20014      *
20015      * <p>Apps may choose to implement this interface if they want to apply custom policy
20016      * to the way that window insets are treated for a view. If an OnApplyWindowInsetsListener
20017      * is set, its
20018      * {@link OnApplyWindowInsetsListener#onApplyWindowInsets(View, WindowInsets) onApplyWindowInsets}
20019      * method will be called instead of the View's own
20020      * {@link #onApplyWindowInsets(WindowInsets) onApplyWindowInsets} method. The listener
20021      * may optionally call the parameter View's <code>onApplyWindowInsets</code> method to apply
20022      * the View's normal behavior as part of its own.</p>
20023      */
20024     public interface OnApplyWindowInsetsListener {
20025         /**
20026          * When {@link View#setOnApplyWindowInsetsListener(View.OnApplyWindowInsetsListener) set}
20027          * on a View, this listener method will be called instead of the view's own
20028          * {@link View#onApplyWindowInsets(WindowInsets) onApplyWindowInsets} method.
20029          *
20030          * @param v The view applying window insets
20031          * @param insets The insets to apply
20032          * @return The insets supplied, minus any insets that were consumed
20033          */
20034         public WindowInsets onApplyWindowInsets(View v, WindowInsets insets);
20035     }
20036
20037     private final class UnsetPressedState implements Runnable {
20038         @Override
20039         public void run() {
20040             setPressed(false);
20041         }
20042     }
20043
20044     /**
20045      * Base class for derived classes that want to save and restore their own
20046      * state in {@link android.view.View#onSaveInstanceState()}.
20047      */
20048     public static class BaseSavedState extends AbsSavedState {
20049         /**
20050          * Constructor used when reading from a parcel. Reads the state of the superclass.
20051          *
20052          * @param source
20053          */
20054         public BaseSavedState(Parcel source) {
20055             super(source);
20056         }
20057
20058         /**
20059          * Constructor called by derived classes when creating their SavedState objects
20060          *
20061          * @param superState The state of the superclass of this view
20062          */
20063         public BaseSavedState(Parcelable superState) {
20064             super(superState);
20065         }
20066
20067         public static final Parcelable.Creator<BaseSavedState> CREATOR =
20068                 new Parcelable.Creator<BaseSavedState>() {
20069             public BaseSavedState createFromParcel(Parcel in) {
20070                 return new BaseSavedState(in);
20071             }
20072
20073             public BaseSavedState[] newArray(int size) {
20074                 return new BaseSavedState[size];
20075             }
20076         };
20077     }
20078
20079     /**
20080      * A set of information given to a view when it is attached to its parent
20081      * window.
20082      */
20083     final static class AttachInfo {
20084         interface Callbacks {
20085             void playSoundEffect(int effectId);
20086             boolean performHapticFeedback(int effectId, boolean always);
20087         }
20088
20089         /**
20090          * InvalidateInfo is used to post invalidate(int, int, int, int) messages
20091          * to a Handler. This class contains the target (View) to invalidate and
20092          * the coordinates of the dirty rectangle.
20093          *
20094          * For performance purposes, this class also implements a pool of up to
20095          * POOL_LIMIT objects that get reused. This reduces memory allocations
20096          * whenever possible.
20097          */
20098         static class InvalidateInfo {
20099             private static final int POOL_LIMIT = 10;
20100
20101             private static final SynchronizedPool<InvalidateInfo> sPool =
20102                     new SynchronizedPool<InvalidateInfo>(POOL_LIMIT);
20103
20104             View target;
20105
20106             int left;
20107             int top;
20108             int right;
20109             int bottom;
20110
20111             public static InvalidateInfo obtain() {
20112                 InvalidateInfo instance = sPool.acquire();
20113                 return (instance != null) ? instance : new InvalidateInfo();
20114             }
20115
20116             public void recycle() {
20117                 target = null;
20118                 sPool.release(this);
20119             }
20120         }
20121
20122         final IWindowSession mSession;
20123
20124         final IWindow mWindow;
20125
20126         final IBinder mWindowToken;
20127
20128         final Display mDisplay;
20129
20130         final Callbacks mRootCallbacks;
20131
20132         IWindowId mIWindowId;
20133         WindowId mWindowId;
20134
20135         /**
20136          * The top view of the hierarchy.
20137          */
20138         View mRootView;
20139
20140         IBinder mPanelParentWindowToken;
20141
20142         boolean mHardwareAccelerated;
20143         boolean mHardwareAccelerationRequested;
20144         HardwareRenderer mHardwareRenderer;
20145         List<RenderNode> mPendingAnimatingRenderNodes;
20146
20147         /**
20148          * The state of the display to which the window is attached, as reported
20149          * by {@link Display#getState()}.  Note that the display state constants
20150          * declared by {@link Display} do not exactly line up with the screen state
20151          * constants declared by {@link View} (there are more display states than
20152          * screen states).
20153          */
20154         int mDisplayState = Display.STATE_UNKNOWN;
20155
20156         /**
20157          * Scale factor used by the compatibility mode
20158          */
20159         float mApplicationScale;
20160
20161         /**
20162          * Indicates whether the application is in compatibility mode
20163          */
20164         boolean mScalingRequired;
20165
20166         /**
20167          * If set, ViewRootImpl doesn't use its lame animation for when the window resizes.
20168          */
20169         boolean mTurnOffWindowResizeAnim;
20170
20171         /**
20172          * Left position of this view's window
20173          */
20174         int mWindowLeft;
20175
20176         /**
20177          * Top position of this view's window
20178          */
20179         int mWindowTop;
20180
20181         /**
20182          * Indicates whether views need to use 32-bit drawing caches
20183          */
20184         boolean mUse32BitDrawingCache;
20185
20186         /**
20187          * For windows that are full-screen but using insets to layout inside
20188          * of the screen areas, these are the current insets to appear inside
20189          * the overscan area of the display.
20190          */
20191         final Rect mOverscanInsets = new Rect();
20192
20193         /**
20194          * For windows that are full-screen but using insets to layout inside
20195          * of the screen decorations, these are the current insets for the
20196          * content of the window.
20197          */
20198         final Rect mContentInsets = new Rect();
20199
20200         /**
20201          * For windows that are full-screen but using insets to layout inside
20202          * of the screen decorations, these are the current insets for the
20203          * actual visible parts of the window.
20204          */
20205         final Rect mVisibleInsets = new Rect();
20206
20207         /**
20208          * For windows that are full-screen but using insets to layout inside
20209          * of the screen decorations, these are the current insets for the
20210          * stable system windows.
20211          */
20212         final Rect mStableInsets = new Rect();
20213
20214         /**
20215          * The internal insets given by this window.  This value is
20216          * supplied by the client (through
20217          * {@link ViewTreeObserver.OnComputeInternalInsetsListener}) and will
20218          * be given to the window manager when changed to be used in laying
20219          * out windows behind it.
20220          */
20221         final ViewTreeObserver.InternalInsetsInfo mGivenInternalInsets
20222                 = new ViewTreeObserver.InternalInsetsInfo();
20223
20224         /**
20225          * Set to true when mGivenInternalInsets is non-empty.
20226          */
20227         boolean mHasNonEmptyGivenInternalInsets;
20228
20229         /**
20230          * All views in the window's hierarchy that serve as scroll containers,
20231          * used to determine if the window can be resized or must be panned
20232          * to adjust for a soft input area.
20233          */
20234         final ArrayList<View> mScrollContainers = new ArrayList<View>();
20235
20236         final KeyEvent.DispatcherState mKeyDispatchState
20237                 = new KeyEvent.DispatcherState();
20238
20239         /**
20240          * Indicates whether the view's window currently has the focus.
20241          */
20242         boolean mHasWindowFocus;
20243
20244         /**
20245          * The current visibility of the window.
20246          */
20247         int mWindowVisibility;
20248
20249         /**
20250          * Indicates the time at which drawing started to occur.
20251          */
20252         long mDrawingTime;
20253
20254         /**
20255          * Indicates whether or not ignoring the DIRTY_MASK flags.
20256          */
20257         boolean mIgnoreDirtyState;
20258
20259         /**
20260          * This flag tracks when the mIgnoreDirtyState flag is set during draw(),
20261          * to avoid clearing that flag prematurely.
20262          */
20263         boolean mSetIgnoreDirtyState = false;
20264
20265         /**
20266          * Indicates whether the view's window is currently in touch mode.
20267          */
20268         boolean mInTouchMode;
20269
20270         /**
20271          * Indicates whether the view has requested unbuffered input dispatching for the current
20272          * event stream.
20273          */
20274         boolean mUnbufferedDispatchRequested;
20275
20276         /**
20277          * Indicates that ViewAncestor should trigger a global layout change
20278          * the next time it performs a traversal
20279          */
20280         boolean mRecomputeGlobalAttributes;
20281
20282         /**
20283          * Always report new attributes at next traversal.
20284          */
20285         boolean mForceReportNewAttributes;
20286
20287         /**
20288          * Set during a traveral if any views want to keep the screen on.
20289          */
20290         boolean mKeepScreenOn;
20291
20292         /**
20293          * Bitwise-or of all of the values that views have passed to setSystemUiVisibility().
20294          */
20295         int mSystemUiVisibility;
20296
20297         /**
20298          * Hack to force certain system UI visibility flags to be cleared.
20299          */
20300         int mDisabledSystemUiVisibility;
20301
20302         /**
20303          * Last global system UI visibility reported by the window manager.
20304          */
20305         int mGlobalSystemUiVisibility;
20306
20307         /**
20308          * True if a view in this hierarchy has an OnSystemUiVisibilityChangeListener
20309          * attached.
20310          */
20311         boolean mHasSystemUiListeners;
20312
20313         /**
20314          * Set if the window has requested to extend into the overscan region
20315          * via WindowManager.LayoutParams.FLAG_LAYOUT_IN_OVERSCAN.
20316          */
20317         boolean mOverscanRequested;
20318
20319         /**
20320          * Set if the visibility of any views has changed.
20321          */
20322         boolean mViewVisibilityChanged;
20323
20324         /**
20325          * Set to true if a view has been scrolled.
20326          */
20327         boolean mViewScrollChanged;
20328
20329         /**
20330          * Set to true if high contrast mode enabled
20331          */
20332         boolean mHighContrastText;
20333
20334         /**
20335          * Global to the view hierarchy used as a temporary for dealing with
20336          * x/y points in the transparent region computations.
20337          */
20338         final int[] mTransparentLocation = new int[2];
20339
20340         /**
20341          * Global to the view hierarchy used as a temporary for dealing with
20342          * x/y points in the ViewGroup.invalidateChild implementation.
20343          */
20344         final int[] mInvalidateChildLocation = new int[2];
20345
20346         /**
20347          * Global to the view hierarchy used as a temporary for dealng with
20348          * computing absolute on-screen location.
20349          */
20350         final int[] mTmpLocation = new int[2];
20351
20352         /**
20353          * Global to the view hierarchy used as a temporary for dealing with
20354          * x/y location when view is transformed.
20355          */
20356         final float[] mTmpTransformLocation = new float[2];
20357
20358         /**
20359          * The view tree observer used to dispatch global events like
20360          * layout, pre-draw, touch mode change, etc.
20361          */
20362         final ViewTreeObserver mTreeObserver = new ViewTreeObserver();
20363
20364         /**
20365          * A Canvas used by the view hierarchy to perform bitmap caching.
20366          */
20367         Canvas mCanvas;
20368
20369         /**
20370          * The view root impl.
20371          */
20372         final ViewRootImpl mViewRootImpl;
20373
20374         /**
20375          * A Handler supplied by a view's {@link android.view.ViewRootImpl}. This
20376          * handler can be used to pump events in the UI events queue.
20377          */
20378         final Handler mHandler;
20379
20380         /**
20381          * Temporary for use in computing invalidate rectangles while
20382          * calling up the hierarchy.
20383          */
20384         final Rect mTmpInvalRect = new Rect();
20385
20386         /**
20387          * Temporary for use in computing hit areas with transformed views
20388          */
20389         final RectF mTmpTransformRect = new RectF();
20390
20391         /**
20392          * Temporary for use in computing hit areas with transformed views
20393          */
20394         final RectF mTmpTransformRect1 = new RectF();
20395
20396         /**
20397          * Temporary list of rectanges.
20398          */
20399         final List<RectF> mTmpRectList = new ArrayList<>();
20400
20401         /**
20402          * Temporary for use in transforming invalidation rect
20403          */
20404         final Matrix mTmpMatrix = new Matrix();
20405
20406         /**
20407          * Temporary for use in transforming invalidation rect
20408          */
20409         final Transformation mTmpTransformation = new Transformation();
20410
20411         /**
20412          * Temporary for use in querying outlines from OutlineProviders
20413          */
20414         final Outline mTmpOutline = new Outline();
20415
20416         /**
20417          * Temporary list for use in collecting focusable descendents of a view.
20418          */
20419         final ArrayList<View> mTempArrayList = new ArrayList<View>(24);
20420
20421         /**
20422          * The id of the window for accessibility purposes.
20423          */
20424         int mAccessibilityWindowId = AccessibilityNodeInfo.UNDEFINED_ITEM_ID;
20425
20426         /**
20427          * Flags related to accessibility processing.
20428          *
20429          * @see AccessibilityNodeInfo#FLAG_INCLUDE_NOT_IMPORTANT_VIEWS
20430          * @see AccessibilityNodeInfo#FLAG_REPORT_VIEW_IDS
20431          */
20432         int mAccessibilityFetchFlags;
20433
20434         /**
20435          * The drawable for highlighting accessibility focus.
20436          */
20437         Drawable mAccessibilityFocusDrawable;
20438
20439         /**
20440          * Show where the margins, bounds and layout bounds are for each view.
20441          */
20442         boolean mDebugLayout = SystemProperties.getBoolean(DEBUG_LAYOUT_PROPERTY, false);
20443
20444         /**
20445          * Point used to compute visible regions.
20446          */
20447         final Point mPoint = new Point();
20448
20449         /**
20450          * Used to track which View originated a requestLayout() call, used when
20451          * requestLayout() is called during layout.
20452          */
20453         View mViewRequestingLayout;
20454
20455         /**
20456          * Creates a new set of attachment information with the specified
20457          * events handler and thread.
20458          *
20459          * @param handler the events handler the view must use
20460          */
20461         AttachInfo(IWindowSession session, IWindow window, Display display,
20462                 ViewRootImpl viewRootImpl, Handler handler, Callbacks effectPlayer) {
20463             mSession = session;
20464             mWindow = window;
20465             mWindowToken = window.asBinder();
20466             mDisplay = display;
20467             mViewRootImpl = viewRootImpl;
20468             mHandler = handler;
20469             mRootCallbacks = effectPlayer;
20470         }
20471     }
20472
20473     /**
20474      * <p>ScrollabilityCache holds various fields used by a View when scrolling
20475      * is supported. This avoids keeping too many unused fields in most
20476      * instances of View.</p>
20477      */
20478     private static class ScrollabilityCache implements Runnable {
20479
20480         /**
20481          * Scrollbars are not visible
20482          */
20483         public static final int OFF = 0;
20484
20485         /**
20486          * Scrollbars are visible
20487          */
20488         public static final int ON = 1;
20489
20490         /**
20491          * Scrollbars are fading away
20492          */
20493         public static final int FADING = 2;
20494
20495         public boolean fadeScrollBars;
20496
20497         public int fadingEdgeLength;
20498         public int scrollBarDefaultDelayBeforeFade;
20499         public int scrollBarFadeDuration;
20500
20501         public int scrollBarSize;
20502         public ScrollBarDrawable scrollBar;
20503         public float[] interpolatorValues;
20504         public View host;
20505
20506         public final Paint paint;
20507         public final Matrix matrix;
20508         public Shader shader;
20509
20510         public final Interpolator scrollBarInterpolator = new Interpolator(1, 2);
20511
20512         private static final float[] OPAQUE = { 255 };
20513         private static final float[] TRANSPARENT = { 0.0f };
20514
20515         /**
20516          * When fading should start. This time moves into the future every time
20517          * a new scroll happens. Measured based on SystemClock.uptimeMillis()
20518          */
20519         public long fadeStartTime;
20520
20521
20522         /**
20523          * The current state of the scrollbars: ON, OFF, or FADING
20524          */
20525         public int state = OFF;
20526
20527         private int mLastColor;
20528
20529         public ScrollabilityCache(ViewConfiguration configuration, View host) {
20530             fadingEdgeLength = configuration.getScaledFadingEdgeLength();
20531             scrollBarSize = configuration.getScaledScrollBarSize();
20532             scrollBarDefaultDelayBeforeFade = ViewConfiguration.getScrollDefaultDelay();
20533             scrollBarFadeDuration = ViewConfiguration.getScrollBarFadeDuration();
20534
20535             paint = new Paint();
20536             matrix = new Matrix();
20537             // use use a height of 1, and then wack the matrix each time we
20538             // actually use it.
20539             shader = new LinearGradient(0, 0, 0, 1, 0xFF000000, 0, Shader.TileMode.CLAMP);
20540             paint.setShader(shader);
20541             paint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.DST_OUT));
20542
20543             this.host = host;
20544         }
20545
20546         public void setFadeColor(int color) {
20547             if (color != mLastColor) {
20548                 mLastColor = color;
20549
20550                 if (color != 0) {
20551                     shader = new LinearGradient(0, 0, 0, 1, color | 0xFF000000,
20552                             color & 0x00FFFFFF, Shader.TileMode.CLAMP);
20553                     paint.setShader(shader);
20554                     // Restore the default transfer mode (src_over)
20555                     paint.setXfermode(null);
20556                 } else {
20557                     shader = new LinearGradient(0, 0, 0, 1, 0xFF000000, 0, Shader.TileMode.CLAMP);
20558                     paint.setShader(shader);
20559                     paint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.DST_OUT));
20560                 }
20561             }
20562         }
20563
20564         public void run() {
20565             long now = AnimationUtils.currentAnimationTimeMillis();
20566             if (now >= fadeStartTime) {
20567
20568                 // the animation fades the scrollbars out by changing
20569                 // the opacity (alpha) from fully opaque to fully
20570                 // transparent
20571                 int nextFrame = (int) now;
20572                 int framesCount = 0;
20573
20574                 Interpolator interpolator = scrollBarInterpolator;
20575
20576                 // Start opaque
20577                 interpolator.setKeyFrame(framesCount++, nextFrame, OPAQUE);
20578
20579                 // End transparent
20580                 nextFrame += scrollBarFadeDuration;
20581                 interpolator.setKeyFrame(framesCount, nextFrame, TRANSPARENT);
20582
20583                 state = FADING;
20584
20585                 // Kick off the fade animation
20586                 host.invalidate(true);
20587             }
20588         }
20589     }
20590
20591     /**
20592      * Resuable callback for sending
20593      * {@link AccessibilityEvent#TYPE_VIEW_SCROLLED} accessibility event.
20594      */
20595     private class SendViewScrolledAccessibilityEvent implements Runnable {
20596         public volatile boolean mIsPending;
20597
20598         public void run() {
20599             sendAccessibilityEvent(AccessibilityEvent.TYPE_VIEW_SCROLLED);
20600             mIsPending = false;
20601         }
20602     }
20603
20604     /**
20605      * <p>
20606      * This class represents a delegate that can be registered in a {@link View}
20607      * to enhance accessibility support via composition rather via inheritance.
20608      * It is specifically targeted to widget developers that extend basic View
20609      * classes i.e. classes in package android.view, that would like their
20610      * applications to be backwards compatible.
20611      * </p>
20612      * <div class="special reference">
20613      * <h3>Developer Guides</h3>
20614      * <p>For more information about making applications accessible, read the
20615      * <a href="{@docRoot}guide/topics/ui/accessibility/index.html">Accessibility</a>
20616      * developer guide.</p>
20617      * </div>
20618      * <p>
20619      * A scenario in which a developer would like to use an accessibility delegate
20620      * is overriding a method introduced in a later API version then the minimal API
20621      * version supported by the application. For example, the method
20622      * {@link View#onInitializeAccessibilityNodeInfo(AccessibilityNodeInfo)} is not available
20623      * in API version 4 when the accessibility APIs were first introduced. If a
20624      * developer would like his application to run on API version 4 devices (assuming
20625      * all other APIs used by the application are version 4 or lower) and take advantage
20626      * of this method, instead of overriding the method which would break the application's
20627      * backwards compatibility, he can override the corresponding method in this
20628      * delegate and register the delegate in the target View if the API version of
20629      * the system is high enough i.e. the API version is same or higher to the API
20630      * version that introduced
20631      * {@link View#onInitializeAccessibilityNodeInfo(AccessibilityNodeInfo)}.
20632      * </p>
20633      * <p>
20634      * Here is an example implementation:
20635      * </p>
20636      * <code><pre><p>
20637      * if (Build.VERSION.SDK_INT >= 14) {
20638      *     // If the API version is equal of higher than the version in
20639      *     // which onInitializeAccessibilityNodeInfo was introduced we
20640      *     // register a delegate with a customized implementation.
20641      *     View view = findViewById(R.id.view_id);
20642      *     view.setAccessibilityDelegate(new AccessibilityDelegate() {
20643      *         public void onInitializeAccessibilityNodeInfo(View host,
20644      *                 AccessibilityNodeInfo info) {
20645      *             // Let the default implementation populate the info.
20646      *             super.onInitializeAccessibilityNodeInfo(host, info);
20647      *             // Set some other information.
20648      *             info.setEnabled(host.isEnabled());
20649      *         }
20650      *     });
20651      * }
20652      * </code></pre></p>
20653      * <p>
20654      * This delegate contains methods that correspond to the accessibility methods
20655      * in View. If a delegate has been specified the implementation in View hands
20656      * off handling to the corresponding method in this delegate. The default
20657      * implementation the delegate methods behaves exactly as the corresponding
20658      * method in View for the case of no accessibility delegate been set. Hence,
20659      * to customize the behavior of a View method, clients can override only the
20660      * corresponding delegate method without altering the behavior of the rest
20661      * accessibility related methods of the host view.
20662      * </p>
20663      */
20664     public static class AccessibilityDelegate {
20665
20666         /**
20667          * Sends an accessibility event of the given type. If accessibility is not
20668          * enabled this method has no effect.
20669          * <p>
20670          * The default implementation behaves as {@link View#sendAccessibilityEvent(int)
20671          *  View#sendAccessibilityEvent(int)} for the case of no accessibility delegate
20672          * been set.
20673          * </p>
20674          *
20675          * @param host The View hosting the delegate.
20676          * @param eventType The type of the event to send.
20677          *
20678          * @see View#sendAccessibilityEvent(int) View#sendAccessibilityEvent(int)
20679          */
20680         public void sendAccessibilityEvent(View host, int eventType) {
20681             host.sendAccessibilityEventInternal(eventType);
20682         }
20683
20684         /**
20685          * Performs the specified accessibility action on the view. For
20686          * possible accessibility actions look at {@link AccessibilityNodeInfo}.
20687          * <p>
20688          * The default implementation behaves as
20689          * {@link View#performAccessibilityAction(int, Bundle)
20690          *  View#performAccessibilityAction(int, Bundle)} for the case of
20691          *  no accessibility delegate been set.
20692          * </p>
20693          *
20694          * @param action The action to perform.
20695          * @return Whether the action was performed.
20696          *
20697          * @see View#performAccessibilityAction(int, Bundle)
20698          *      View#performAccessibilityAction(int, Bundle)
20699          */
20700         public boolean performAccessibilityAction(View host, int action, Bundle args) {
20701             return host.performAccessibilityActionInternal(action, args);
20702         }
20703
20704         /**
20705          * Sends an accessibility event. This method behaves exactly as
20706          * {@link #sendAccessibilityEvent(View, int)} but takes as an argument an
20707          * empty {@link AccessibilityEvent} and does not perform a check whether
20708          * accessibility is enabled.
20709          * <p>
20710          * The default implementation behaves as
20711          * {@link View#sendAccessibilityEventUnchecked(AccessibilityEvent)
20712          *  View#sendAccessibilityEventUnchecked(AccessibilityEvent)} for
20713          * the case of no accessibility delegate been set.
20714          * </p>
20715          *
20716          * @param host The View hosting the delegate.
20717          * @param event The event to send.
20718          *
20719          * @see View#sendAccessibilityEventUnchecked(AccessibilityEvent)
20720          *      View#sendAccessibilityEventUnchecked(AccessibilityEvent)
20721          */
20722         public void sendAccessibilityEventUnchecked(View host, AccessibilityEvent event) {
20723             host.sendAccessibilityEventUncheckedInternal(event);
20724         }
20725
20726         /**
20727          * Dispatches an {@link AccessibilityEvent} to the host {@link View} first and then
20728          * to its children for adding their text content to the event.
20729          * <p>
20730          * The default implementation behaves as
20731          * {@link View#dispatchPopulateAccessibilityEvent(AccessibilityEvent)
20732          *  View#dispatchPopulateAccessibilityEvent(AccessibilityEvent)} for
20733          * the case of no accessibility delegate been set.
20734          * </p>
20735          *
20736          * @param host The View hosting the delegate.
20737          * @param event The event.
20738          * @return True if the event population was completed.
20739          *
20740          * @see View#dispatchPopulateAccessibilityEvent(AccessibilityEvent)
20741          *      View#dispatchPopulateAccessibilityEvent(AccessibilityEvent)
20742          */
20743         public boolean dispatchPopulateAccessibilityEvent(View host, AccessibilityEvent event) {
20744             return host.dispatchPopulateAccessibilityEventInternal(event);
20745         }
20746
20747         /**
20748          * Gives a chance to the host View to populate the accessibility event with its
20749          * text content.
20750          * <p>
20751          * The default implementation behaves as
20752          * {@link View#onPopulateAccessibilityEvent(AccessibilityEvent)
20753          *  View#onPopulateAccessibilityEvent(AccessibilityEvent)} for
20754          * the case of no accessibility delegate been set.
20755          * </p>
20756          *
20757          * @param host The View hosting the delegate.
20758          * @param event The accessibility event which to populate.
20759          *
20760          * @see View#onPopulateAccessibilityEvent(AccessibilityEvent)
20761          *      View#onPopulateAccessibilityEvent(AccessibilityEvent)
20762          */
20763         public void onPopulateAccessibilityEvent(View host, AccessibilityEvent event) {
20764             host.onPopulateAccessibilityEventInternal(event);
20765         }
20766
20767         /**
20768          * Initializes an {@link AccessibilityEvent} with information about the
20769          * the host View which is the event source.
20770          * <p>
20771          * The default implementation behaves as
20772          * {@link View#onInitializeAccessibilityEvent(AccessibilityEvent)
20773          *  View#onInitializeAccessibilityEvent(AccessibilityEvent)} for
20774          * the case of no accessibility delegate been set.
20775          * </p>
20776          *
20777          * @param host The View hosting the delegate.
20778          * @param event The event to initialize.
20779          *
20780          * @see View#onInitializeAccessibilityEvent(AccessibilityEvent)
20781          *      View#onInitializeAccessibilityEvent(AccessibilityEvent)
20782          */
20783         public void onInitializeAccessibilityEvent(View host, AccessibilityEvent event) {
20784             host.onInitializeAccessibilityEventInternal(event);
20785         }
20786
20787         /**
20788          * Initializes an {@link AccessibilityNodeInfo} with information about the host view.
20789          * <p>
20790          * The default implementation behaves as
20791          * {@link View#onInitializeAccessibilityNodeInfo(AccessibilityNodeInfo)
20792          *  View#onInitializeAccessibilityNodeInfo(AccessibilityNodeInfo)} for
20793          * the case of no accessibility delegate been set.
20794          * </p>
20795          *
20796          * @param host The View hosting the delegate.
20797          * @param info The instance to initialize.
20798          *
20799          * @see View#onInitializeAccessibilityNodeInfo(AccessibilityNodeInfo)
20800          *      View#onInitializeAccessibilityNodeInfo(AccessibilityNodeInfo)
20801          */
20802         public void onInitializeAccessibilityNodeInfo(View host, AccessibilityNodeInfo info) {
20803             host.onInitializeAccessibilityNodeInfoInternal(info);
20804         }
20805
20806         /**
20807          * Called when a child of the host View has requested sending an
20808          * {@link AccessibilityEvent} and gives an opportunity to the parent (the host)
20809          * to augment the event.
20810          * <p>
20811          * The default implementation behaves as
20812          * {@link ViewGroup#onRequestSendAccessibilityEvent(View, AccessibilityEvent)
20813          *  ViewGroup#onRequestSendAccessibilityEvent(View, AccessibilityEvent)} for
20814          * the case of no accessibility delegate been set.
20815          * </p>
20816          *
20817          * @param host The View hosting the delegate.
20818          * @param child The child which requests sending the event.
20819          * @param event The event to be sent.
20820          * @return True if the event should be sent
20821          *
20822          * @see ViewGroup#onRequestSendAccessibilityEvent(View, AccessibilityEvent)
20823          *      ViewGroup#onRequestSendAccessibilityEvent(View, AccessibilityEvent)
20824          */
20825         public boolean onRequestSendAccessibilityEvent(ViewGroup host, View child,
20826                 AccessibilityEvent event) {
20827             return host.onRequestSendAccessibilityEventInternal(child, event);
20828         }
20829
20830         /**
20831          * Gets the provider for managing a virtual view hierarchy rooted at this View
20832          * and reported to {@link android.accessibilityservice.AccessibilityService}s
20833          * that explore the window content.
20834          * <p>
20835          * The default implementation behaves as
20836          * {@link View#getAccessibilityNodeProvider() View#getAccessibilityNodeProvider()} for
20837          * the case of no accessibility delegate been set.
20838          * </p>
20839          *
20840          * @return The provider.
20841          *
20842          * @see AccessibilityNodeProvider
20843          */
20844         public AccessibilityNodeProvider getAccessibilityNodeProvider(View host) {
20845             return null;
20846         }
20847
20848         /**
20849          * Returns an {@link AccessibilityNodeInfo} representing the host view from the
20850          * point of view of an {@link android.accessibilityservice.AccessibilityService}.
20851          * This method is responsible for obtaining an accessibility node info from a
20852          * pool of reusable instances and calling
20853          * {@link #onInitializeAccessibilityNodeInfo(AccessibilityNodeInfo)} on the host
20854          * view to initialize the former.
20855          * <p>
20856          * <strong>Note:</strong> The client is responsible for recycling the obtained
20857          * instance by calling {@link AccessibilityNodeInfo#recycle()} to minimize object
20858          * creation.
20859          * </p>
20860          * <p>
20861          * The default implementation behaves as
20862          * {@link View#createAccessibilityNodeInfo() View#createAccessibilityNodeInfo()} for
20863          * the case of no accessibility delegate been set.
20864          * </p>
20865          * @return A populated {@link AccessibilityNodeInfo}.
20866          *
20867          * @see AccessibilityNodeInfo
20868          *
20869          * @hide
20870          */
20871         public AccessibilityNodeInfo createAccessibilityNodeInfo(View host) {
20872             return host.createAccessibilityNodeInfoInternal();
20873         }
20874     }
20875
20876     private class MatchIdPredicate implements Predicate<View> {
20877         public int mId;
20878
20879         @Override
20880         public boolean apply(View view) {
20881             return (view.mID == mId);
20882         }
20883     }
20884
20885     private class MatchLabelForPredicate implements Predicate<View> {
20886         private int mLabeledId;
20887
20888         @Override
20889         public boolean apply(View view) {
20890             return (view.mLabelForId == mLabeledId);
20891         }
20892     }
20893
20894     private class SendViewStateChangedAccessibilityEvent implements Runnable {
20895         private int mChangeTypes = 0;
20896         private boolean mPosted;
20897         private boolean mPostedWithDelay;
20898         private long mLastEventTimeMillis;
20899
20900         @Override
20901         public void run() {
20902             mPosted = false;
20903             mPostedWithDelay = false;
20904             mLastEventTimeMillis = SystemClock.uptimeMillis();
20905             if (AccessibilityManager.getInstance(mContext).isEnabled()) {
20906                 final AccessibilityEvent event = AccessibilityEvent.obtain();
20907                 event.setEventType(AccessibilityEvent.TYPE_WINDOW_CONTENT_CHANGED);
20908                 event.setContentChangeTypes(mChangeTypes);
20909                 sendAccessibilityEventUnchecked(event);
20910             }
20911             mChangeTypes = 0;
20912         }
20913
20914         public void runOrPost(int changeType) {
20915             mChangeTypes |= changeType;
20916
20917             // If this is a live region or the child of a live region, collect
20918             // all events from this frame and send them on the next frame.
20919             if (inLiveRegion()) {
20920                 // If we're already posted with a delay, remove that.
20921                 if (mPostedWithDelay) {
20922                     removeCallbacks(this);
20923                     mPostedWithDelay = false;
20924                 }
20925                 // Only post if we're not already posted.
20926                 if (!mPosted) {
20927                     post(this);
20928                     mPosted = true;
20929                 }
20930                 return;
20931             }
20932
20933             if (mPosted) {
20934                 return;
20935             }
20936
20937             final long timeSinceLastMillis = SystemClock.uptimeMillis() - mLastEventTimeMillis;
20938             final long minEventIntevalMillis =
20939                     ViewConfiguration.getSendRecurringAccessibilityEventsInterval();
20940             if (timeSinceLastMillis >= minEventIntevalMillis) {
20941                 removeCallbacks(this);
20942                 run();
20943             } else {
20944                 postDelayed(this, minEventIntevalMillis - timeSinceLastMillis);
20945                 mPostedWithDelay = true;
20946             }
20947         }
20948     }
20949
20950     private boolean inLiveRegion() {
20951         if (getAccessibilityLiveRegion() != View.ACCESSIBILITY_LIVE_REGION_NONE) {
20952             return true;
20953         }
20954
20955         ViewParent parent = getParent();
20956         while (parent instanceof View) {
20957             if (((View) parent).getAccessibilityLiveRegion()
20958                     != View.ACCESSIBILITY_LIVE_REGION_NONE) {
20959                 return true;
20960             }
20961             parent = parent.getParent();
20962         }
20963
20964         return false;
20965     }
20966
20967     /**
20968      * Dump all private flags in readable format, useful for documentation and
20969      * sanity checking.
20970      */
20971     private static void dumpFlags() {
20972         final HashMap<String, String> found = Maps.newHashMap();
20973         try {
20974             for (Field field : View.class.getDeclaredFields()) {
20975                 final int modifiers = field.getModifiers();
20976                 if (Modifier.isStatic(modifiers) && Modifier.isFinal(modifiers)) {
20977                     if (field.getType().equals(int.class)) {
20978                         final int value = field.getInt(null);
20979                         dumpFlag(found, field.getName(), value);
20980                     } else if (field.getType().equals(int[].class)) {
20981                         final int[] values = (int[]) field.get(null);
20982                         for (int i = 0; i < values.length; i++) {
20983                             dumpFlag(found, field.getName() + "[" + i + "]", values[i]);
20984                         }
20985                     }
20986                 }
20987             }
20988         } catch (IllegalAccessException e) {
20989             throw new RuntimeException(e);
20990         }
20991
20992         final ArrayList<String> keys = Lists.newArrayList();
20993         keys.addAll(found.keySet());
20994         Collections.sort(keys);
20995         for (String key : keys) {
20996             Log.d(VIEW_LOG_TAG, found.get(key));
20997         }
20998     }
20999
21000     private static void dumpFlag(HashMap<String, String> found, String name, int value) {
21001         // Sort flags by prefix, then by bits, always keeping unique keys
21002         final String bits = String.format("%32s", Integer.toBinaryString(value)).replace('0', ' ');
21003         final int prefix = name.indexOf('_');
21004         final String key = (prefix > 0 ? name.substring(0, prefix) : name) + bits + name;
21005         final String output = bits + " " + name;
21006         found.put(key, output);
21007     }
21008 }