OSDN Git Service

resolve merge conflicts of 56a2b529373b to nyc-dev am: d7dcc3e227
[android-x86/frameworks-base.git] / core / java / android / view / View.java
1 /*
2  * Copyright (C) 2006 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16
17 package android.view;
18
19 import android.animation.AnimatorInflater;
20 import android.animation.StateListAnimator;
21 import android.annotation.CallSuper;
22 import android.annotation.ColorInt;
23 import android.annotation.DrawableRes;
24 import android.annotation.FloatRange;
25 import android.annotation.IdRes;
26 import android.annotation.IntDef;
27 import android.annotation.IntRange;
28 import android.annotation.LayoutRes;
29 import android.annotation.NonNull;
30 import android.annotation.Nullable;
31 import android.annotation.Size;
32 import android.annotation.UiThread;
33 import android.content.ClipData;
34 import android.content.Context;
35 import android.content.ContextWrapper;
36 import android.content.Intent;
37 import android.content.res.ColorStateList;
38 import android.content.res.Configuration;
39 import android.content.res.Resources;
40 import android.content.res.TypedArray;
41 import android.graphics.Bitmap;
42 import android.graphics.Canvas;
43 import android.graphics.Insets;
44 import android.graphics.Interpolator;
45 import android.graphics.LinearGradient;
46 import android.graphics.Matrix;
47 import android.graphics.Outline;
48 import android.graphics.Paint;
49 import android.graphics.PixelFormat;
50 import android.graphics.Point;
51 import android.graphics.PorterDuff;
52 import android.graphics.PorterDuffXfermode;
53 import android.graphics.Rect;
54 import android.graphics.RectF;
55 import android.graphics.Region;
56 import android.graphics.Shader;
57 import android.graphics.drawable.ColorDrawable;
58 import android.graphics.drawable.Drawable;
59 import android.hardware.display.DisplayManagerGlobal;
60 import android.os.Build.VERSION_CODES;
61 import android.os.Bundle;
62 import android.os.Handler;
63 import android.os.IBinder;
64 import android.os.Parcel;
65 import android.os.Parcelable;
66 import android.os.RemoteException;
67 import android.os.SystemClock;
68 import android.os.SystemProperties;
69 import android.os.Trace;
70 import android.text.TextUtils;
71 import android.util.AttributeSet;
72 import android.util.FloatProperty;
73 import android.util.LayoutDirection;
74 import android.util.Log;
75 import android.util.LongSparseLongArray;
76 import android.util.Pools.SynchronizedPool;
77 import android.util.Property;
78 import android.util.SparseArray;
79 import android.util.StateSet;
80 import android.util.SuperNotCalledException;
81 import android.util.TypedValue;
82 import android.view.ContextMenu.ContextMenuInfo;
83 import android.view.AccessibilityIterators.CharacterTextSegmentIterator;
84 import android.view.AccessibilityIterators.ParagraphTextSegmentIterator;
85 import android.view.AccessibilityIterators.TextSegmentIterator;
86 import android.view.AccessibilityIterators.WordTextSegmentIterator;
87 import android.view.accessibility.AccessibilityEvent;
88 import android.view.accessibility.AccessibilityEventSource;
89 import android.view.accessibility.AccessibilityManager;
90 import android.view.accessibility.AccessibilityNodeInfo;
91 import android.view.accessibility.AccessibilityNodeInfo.AccessibilityAction;
92 import android.view.accessibility.AccessibilityNodeProvider;
93 import android.view.animation.Animation;
94 import android.view.animation.AnimationUtils;
95 import android.view.animation.Transformation;
96 import android.view.inputmethod.EditorInfo;
97 import android.view.inputmethod.InputConnection;
98 import android.view.inputmethod.InputMethodManager;
99 import android.widget.Checkable;
100 import android.widget.FrameLayout;
101 import android.widget.ScrollBarDrawable;
102 import static android.os.Build.VERSION_CODES.*;
103 import static java.lang.Math.max;
104
105 import com.android.internal.R;
106 import com.android.internal.util.Predicate;
107 import com.android.internal.view.menu.MenuBuilder;
108 import com.android.internal.widget.ScrollBarUtils;
109 import com.google.android.collect.Lists;
110 import com.google.android.collect.Maps;
111
112 import java.lang.NullPointerException;
113 import java.lang.annotation.Retention;
114 import java.lang.annotation.RetentionPolicy;
115 import java.lang.ref.WeakReference;
116 import java.lang.reflect.Field;
117 import java.lang.reflect.InvocationTargetException;
118 import java.lang.reflect.Method;
119 import java.lang.reflect.Modifier;
120 import java.util.ArrayList;
121 import java.util.Arrays;
122 import java.util.Collections;
123 import java.util.HashMap;
124 import java.util.List;
125 import java.util.Locale;
126 import java.util.Map;
127 import java.util.concurrent.CopyOnWriteArrayList;
128 import java.util.concurrent.atomic.AtomicInteger;
129
130 /**
131  * <p>
132  * This class represents the basic building block for user interface components. A View
133  * occupies a rectangular area on the screen and is responsible for drawing and
134  * event handling. View is the base class for <em>widgets</em>, which are
135  * used to create interactive UI components (buttons, text fields, etc.). The
136  * {@link android.view.ViewGroup} subclass is the base class for <em>layouts</em>, which
137  * are invisible containers that hold other Views (or other ViewGroups) and define
138  * their layout properties.
139  * </p>
140  *
141  * <div class="special reference">
142  * <h3>Developer Guides</h3>
143  * <p>For information about using this class to develop your application's user interface,
144  * read the <a href="{@docRoot}guide/topics/ui/index.html">User Interface</a> developer guide.
145  * </div>
146  *
147  * <a name="Using"></a>
148  * <h3>Using Views</h3>
149  * <p>
150  * All of the views in a window are arranged in a single tree. You can add views
151  * either from code or by specifying a tree of views in one or more XML layout
152  * files. There are many specialized subclasses of views that act as controls or
153  * are capable of displaying text, images, or other content.
154  * </p>
155  * <p>
156  * Once you have created a tree of views, there are typically a few types of
157  * common operations you may wish to perform:
158  * <ul>
159  * <li><strong>Set properties:</strong> for example setting the text of a
160  * {@link android.widget.TextView}. The available properties and the methods
161  * that set them will vary among the different subclasses of views. Note that
162  * properties that are known at build time can be set in the XML layout
163  * files.</li>
164  * <li><strong>Set focus:</strong> The framework will handle moving focus in
165  * response to user input. To force focus to a specific view, call
166  * {@link #requestFocus}.</li>
167  * <li><strong>Set up listeners:</strong> Views allow clients to set listeners
168  * that will be notified when something interesting happens to the view. For
169  * example, all views will let you set a listener to be notified when the view
170  * gains or loses focus. You can register such a listener using
171  * {@link #setOnFocusChangeListener(android.view.View.OnFocusChangeListener)}.
172  * Other view subclasses offer more specialized listeners. For example, a Button
173  * exposes a listener to notify clients when the button is clicked.</li>
174  * <li><strong>Set visibility:</strong> You can hide or show views using
175  * {@link #setVisibility(int)}.</li>
176  * </ul>
177  * </p>
178  * <p><em>
179  * Note: The Android framework is responsible for measuring, laying out and
180  * drawing views. You should not call methods that perform these actions on
181  * views yourself unless you are actually implementing a
182  * {@link android.view.ViewGroup}.
183  * </em></p>
184  *
185  * <a name="Lifecycle"></a>
186  * <h3>Implementing a Custom View</h3>
187  *
188  * <p>
189  * To implement a custom view, you will usually begin by providing overrides for
190  * some of the standard methods that the framework calls on all views. You do
191  * not need to override all of these methods. In fact, you can start by just
192  * overriding {@link #onDraw(android.graphics.Canvas)}.
193  * <table border="2" width="85%" align="center" cellpadding="5">
194  *     <thead>
195  *         <tr><th>Category</th> <th>Methods</th> <th>Description</th></tr>
196  *     </thead>
197  *
198  *     <tbody>
199  *     <tr>
200  *         <td rowspan="2">Creation</td>
201  *         <td>Constructors</td>
202  *         <td>There is a form of the constructor that are called when the view
203  *         is created from code and a form that is called when the view is
204  *         inflated from a layout file. The second form should parse and apply
205  *         any attributes defined in the layout file.
206  *         </td>
207  *     </tr>
208  *     <tr>
209  *         <td><code>{@link #onFinishInflate()}</code></td>
210  *         <td>Called after a view and all of its children has been inflated
211  *         from XML.</td>
212  *     </tr>
213  *
214  *     <tr>
215  *         <td rowspan="3">Layout</td>
216  *         <td><code>{@link #onMeasure(int, int)}</code></td>
217  *         <td>Called to determine the size requirements for this view and all
218  *         of its children.
219  *         </td>
220  *     </tr>
221  *     <tr>
222  *         <td><code>{@link #onLayout(boolean, int, int, int, int)}</code></td>
223  *         <td>Called when this view should assign a size and position to all
224  *         of its children.
225  *         </td>
226  *     </tr>
227  *     <tr>
228  *         <td><code>{@link #onSizeChanged(int, int, int, int)}</code></td>
229  *         <td>Called when the size of this view has changed.
230  *         </td>
231  *     </tr>
232  *
233  *     <tr>
234  *         <td>Drawing</td>
235  *         <td><code>{@link #onDraw(android.graphics.Canvas)}</code></td>
236  *         <td>Called when the view should render its content.
237  *         </td>
238  *     </tr>
239  *
240  *     <tr>
241  *         <td rowspan="4">Event processing</td>
242  *         <td><code>{@link #onKeyDown(int, KeyEvent)}</code></td>
243  *         <td>Called when a new hardware key event occurs.
244  *         </td>
245  *     </tr>
246  *     <tr>
247  *         <td><code>{@link #onKeyUp(int, KeyEvent)}</code></td>
248  *         <td>Called when a hardware key up event occurs.
249  *         </td>
250  *     </tr>
251  *     <tr>
252  *         <td><code>{@link #onTrackballEvent(MotionEvent)}</code></td>
253  *         <td>Called when a trackball motion event occurs.
254  *         </td>
255  *     </tr>
256  *     <tr>
257  *         <td><code>{@link #onTouchEvent(MotionEvent)}</code></td>
258  *         <td>Called when a touch screen motion event occurs.
259  *         </td>
260  *     </tr>
261  *
262  *     <tr>
263  *         <td rowspan="2">Focus</td>
264  *         <td><code>{@link #onFocusChanged(boolean, int, android.graphics.Rect)}</code></td>
265  *         <td>Called when the view gains or loses focus.
266  *         </td>
267  *     </tr>
268  *
269  *     <tr>
270  *         <td><code>{@link #onWindowFocusChanged(boolean)}</code></td>
271  *         <td>Called when the window containing the view gains or loses focus.
272  *         </td>
273  *     </tr>
274  *
275  *     <tr>
276  *         <td rowspan="3">Attaching</td>
277  *         <td><code>{@link #onAttachedToWindow()}</code></td>
278  *         <td>Called when the view is attached to a window.
279  *         </td>
280  *     </tr>
281  *
282  *     <tr>
283  *         <td><code>{@link #onDetachedFromWindow}</code></td>
284  *         <td>Called when the view is detached from its window.
285  *         </td>
286  *     </tr>
287  *
288  *     <tr>
289  *         <td><code>{@link #onWindowVisibilityChanged(int)}</code></td>
290  *         <td>Called when the visibility of the window containing the view
291  *         has changed.
292  *         </td>
293  *     </tr>
294  *     </tbody>
295  *
296  * </table>
297  * </p>
298  *
299  * <a name="IDs"></a>
300  * <h3>IDs</h3>
301  * Views may have an integer id associated with them. These ids are typically
302  * assigned in the layout XML files, and are used to find specific views within
303  * the view tree. A common pattern is to:
304  * <ul>
305  * <li>Define a Button in the layout file and assign it a unique ID.
306  * <pre>
307  * &lt;Button
308  *     android:id="@+id/my_button"
309  *     android:layout_width="wrap_content"
310  *     android:layout_height="wrap_content"
311  *     android:text="@string/my_button_text"/&gt;
312  * </pre></li>
313  * <li>From the onCreate method of an Activity, find the Button
314  * <pre class="prettyprint">
315  *      Button myButton = (Button) findViewById(R.id.my_button);
316  * </pre></li>
317  * </ul>
318  * <p>
319  * View IDs need not be unique throughout the tree, but it is good practice to
320  * ensure that they are at least unique within the part of the tree you are
321  * searching.
322  * </p>
323  *
324  * <a name="Position"></a>
325  * <h3>Position</h3>
326  * <p>
327  * The geometry of a view is that of a rectangle. A view has a location,
328  * expressed as a pair of <em>left</em> and <em>top</em> coordinates, and
329  * two dimensions, expressed as a width and a height. The unit for location
330  * and dimensions is the pixel.
331  * </p>
332  *
333  * <p>
334  * It is possible to retrieve the location of a view by invoking the methods
335  * {@link #getLeft()} and {@link #getTop()}. The former returns the left, or X,
336  * coordinate of the rectangle representing the view. The latter returns the
337  * top, or Y, coordinate of the rectangle representing the view. These methods
338  * both return the location of the view relative to its parent. For instance,
339  * when getLeft() returns 20, that means the view is located 20 pixels to the
340  * right of the left edge of its direct parent.
341  * </p>
342  *
343  * <p>
344  * In addition, several convenience methods are offered to avoid unnecessary
345  * computations, namely {@link #getRight()} and {@link #getBottom()}.
346  * These methods return the coordinates of the right and bottom edges of the
347  * rectangle representing the view. For instance, calling {@link #getRight()}
348  * is similar to the following computation: <code>getLeft() + getWidth()</code>
349  * (see <a href="#SizePaddingMargins">Size</a> for more information about the width.)
350  * </p>
351  *
352  * <a name="SizePaddingMargins"></a>
353  * <h3>Size, padding and margins</h3>
354  * <p>
355  * The size of a view is expressed with a width and a height. A view actually
356  * possess two pairs of width and height values.
357  * </p>
358  *
359  * <p>
360  * The first pair is known as <em>measured width</em> and
361  * <em>measured height</em>. These dimensions define how big a view wants to be
362  * within its parent (see <a href="#Layout">Layout</a> for more details.) The
363  * measured dimensions can be obtained by calling {@link #getMeasuredWidth()}
364  * and {@link #getMeasuredHeight()}.
365  * </p>
366  *
367  * <p>
368  * The second pair is simply known as <em>width</em> and <em>height</em>, or
369  * sometimes <em>drawing width</em> and <em>drawing height</em>. These
370  * dimensions define the actual size of the view on screen, at drawing time and
371  * after layout. These values may, but do not have to, be different from the
372  * measured width and height. The width and height can be obtained by calling
373  * {@link #getWidth()} and {@link #getHeight()}.
374  * </p>
375  *
376  * <p>
377  * To measure its dimensions, a view takes into account its padding. The padding
378  * is expressed in pixels for the left, top, right and bottom parts of the view.
379  * Padding can be used to offset the content of the view by a specific amount of
380  * pixels. For instance, a left padding of 2 will push the view's content by
381  * 2 pixels to the right of the left edge. Padding can be set using the
382  * {@link #setPadding(int, int, int, int)} or {@link #setPaddingRelative(int, int, int, int)}
383  * method and queried by calling {@link #getPaddingLeft()}, {@link #getPaddingTop()},
384  * {@link #getPaddingRight()}, {@link #getPaddingBottom()}, {@link #getPaddingStart()},
385  * {@link #getPaddingEnd()}.
386  * </p>
387  *
388  * <p>
389  * Even though a view can define a padding, it does not provide any support for
390  * margins. However, view groups provide such a support. Refer to
391  * {@link android.view.ViewGroup} and
392  * {@link android.view.ViewGroup.MarginLayoutParams} for further information.
393  * </p>
394  *
395  * <a name="Layout"></a>
396  * <h3>Layout</h3>
397  * <p>
398  * Layout is a two pass process: a measure pass and a layout pass. The measuring
399  * pass is implemented in {@link #measure(int, int)} and is a top-down traversal
400  * of the view tree. Each view pushes dimension specifications down the tree
401  * during the recursion. At the end of the measure pass, every view has stored
402  * its measurements. The second pass happens in
403  * {@link #layout(int,int,int,int)} and is also top-down. During
404  * this pass each parent is responsible for positioning all of its children
405  * using the sizes computed in the measure pass.
406  * </p>
407  *
408  * <p>
409  * When a view's measure() method returns, its {@link #getMeasuredWidth()} and
410  * {@link #getMeasuredHeight()} values must be set, along with those for all of
411  * that view's descendants. A view's measured width and measured height values
412  * must respect the constraints imposed by the view's parents. This guarantees
413  * that at the end of the measure pass, all parents accept all of their
414  * children's measurements. A parent view may call measure() more than once on
415  * its children. For example, the parent may measure each child once with
416  * unspecified dimensions to find out how big they want to be, then call
417  * measure() on them again with actual numbers if the sum of all the children's
418  * unconstrained sizes is too big or too small.
419  * </p>
420  *
421  * <p>
422  * The measure pass uses two classes to communicate dimensions. The
423  * {@link MeasureSpec} class is used by views to tell their parents how they
424  * want to be measured and positioned. The base LayoutParams class just
425  * describes how big the view wants to be for both width and height. For each
426  * dimension, it can specify one of:
427  * <ul>
428  * <li> an exact number
429  * <li>MATCH_PARENT, which means the view wants to be as big as its parent
430  * (minus padding)
431  * <li> WRAP_CONTENT, which means that the view wants to be just big enough to
432  * enclose its content (plus padding).
433  * </ul>
434  * There are subclasses of LayoutParams for different subclasses of ViewGroup.
435  * For example, AbsoluteLayout has its own subclass of LayoutParams which adds
436  * an X and Y value.
437  * </p>
438  *
439  * <p>
440  * MeasureSpecs are used to push requirements down the tree from parent to
441  * child. A MeasureSpec can be in one of three modes:
442  * <ul>
443  * <li>UNSPECIFIED: This is used by a parent to determine the desired dimension
444  * of a child view. For example, a LinearLayout may call measure() on its child
445  * with the height set to UNSPECIFIED and a width of EXACTLY 240 to find out how
446  * tall the child view wants to be given a width of 240 pixels.
447  * <li>EXACTLY: This is used by the parent to impose an exact size on the
448  * child. The child must use this size, and guarantee that all of its
449  * descendants will fit within this size.
450  * <li>AT_MOST: This is used by the parent to impose a maximum size on the
451  * child. The child must guarantee that it and all of its descendants will fit
452  * within this size.
453  * </ul>
454  * </p>
455  *
456  * <p>
457  * To initiate a layout, call {@link #requestLayout}. This method is typically
458  * called by a view on itself when it believes that is can no longer fit within
459  * its current bounds.
460  * </p>
461  *
462  * <a name="Drawing"></a>
463  * <h3>Drawing</h3>
464  * <p>
465  * Drawing is handled by walking the tree and recording the drawing commands of
466  * any View that needs to update. After this, the drawing commands of the
467  * entire tree are issued to screen, clipped to the newly damaged area.
468  * </p>
469  *
470  * <p>
471  * The tree is largely recorded and drawn in order, with parents drawn before
472  * (i.e., behind) their children, with siblings drawn in the order they appear
473  * in the tree. If you set a background drawable for a View, then the View will
474  * draw it before calling back to its <code>onDraw()</code> method. The child
475  * drawing order can be overridden with
476  * {@link ViewGroup#setChildrenDrawingOrderEnabled(boolean) custom child drawing order}
477  * in a ViewGroup, and with {@link #setZ(float)} custom Z values} set on Views.
478  * </p>
479  *
480  * <p>
481  * To force a view to draw, call {@link #invalidate()}.
482  * </p>
483  *
484  * <a name="EventHandlingThreading"></a>
485  * <h3>Event Handling and Threading</h3>
486  * <p>
487  * The basic cycle of a view is as follows:
488  * <ol>
489  * <li>An event comes in and is dispatched to the appropriate view. The view
490  * handles the event and notifies any listeners.</li>
491  * <li>If in the course of processing the event, the view's bounds may need
492  * to be changed, the view will call {@link #requestLayout()}.</li>
493  * <li>Similarly, if in the course of processing the event the view's appearance
494  * may need to be changed, the view will call {@link #invalidate()}.</li>
495  * <li>If either {@link #requestLayout()} or {@link #invalidate()} were called,
496  * the framework will take care of measuring, laying out, and drawing the tree
497  * as appropriate.</li>
498  * </ol>
499  * </p>
500  *
501  * <p><em>Note: The entire view tree is single threaded. You must always be on
502  * the UI thread when calling any method on any view.</em>
503  * If you are doing work on other threads and want to update the state of a view
504  * from that thread, you should use a {@link Handler}.
505  * </p>
506  *
507  * <a name="FocusHandling"></a>
508  * <h3>Focus Handling</h3>
509  * <p>
510  * The framework will handle routine focus movement in response to user input.
511  * This includes changing the focus as views are removed or hidden, or as new
512  * views become available. Views indicate their willingness to take focus
513  * through the {@link #isFocusable} method. To change whether a view can take
514  * focus, call {@link #setFocusable(boolean)}.  When in touch mode (see notes below)
515  * views indicate whether they still would like focus via {@link #isFocusableInTouchMode}
516  * and can change this via {@link #setFocusableInTouchMode(boolean)}.
517  * </p>
518  * <p>
519  * Focus movement is based on an algorithm which finds the nearest neighbor in a
520  * given direction. In rare cases, the default algorithm may not match the
521  * intended behavior of the developer. In these situations, you can provide
522  * explicit overrides by using these XML attributes in the layout file:
523  * <pre>
524  * nextFocusDown
525  * nextFocusLeft
526  * nextFocusRight
527  * nextFocusUp
528  * </pre>
529  * </p>
530  *
531  *
532  * <p>
533  * To get a particular view to take focus, call {@link #requestFocus()}.
534  * </p>
535  *
536  * <a name="TouchMode"></a>
537  * <h3>Touch Mode</h3>
538  * <p>
539  * When a user is navigating a user interface via directional keys such as a D-pad, it is
540  * necessary to give focus to actionable items such as buttons so the user can see
541  * what will take input.  If the device has touch capabilities, however, and the user
542  * begins interacting with the interface by touching it, it is no longer necessary to
543  * always highlight, or give focus to, a particular view.  This motivates a mode
544  * for interaction named 'touch mode'.
545  * </p>
546  * <p>
547  * For a touch capable device, once the user touches the screen, the device
548  * will enter touch mode.  From this point onward, only views for which
549  * {@link #isFocusableInTouchMode} is true will be focusable, such as text editing widgets.
550  * Other views that are touchable, like buttons, will not take focus when touched; they will
551  * only fire the on click listeners.
552  * </p>
553  * <p>
554  * Any time a user hits a directional key, such as a D-pad direction, the view device will
555  * exit touch mode, and find a view to take focus, so that the user may resume interacting
556  * with the user interface without touching the screen again.
557  * </p>
558  * <p>
559  * The touch mode state is maintained across {@link android.app.Activity}s.  Call
560  * {@link #isInTouchMode} to see whether the device is currently in touch mode.
561  * </p>
562  *
563  * <a name="Scrolling"></a>
564  * <h3>Scrolling</h3>
565  * <p>
566  * The framework provides basic support for views that wish to internally
567  * scroll their content. This includes keeping track of the X and Y scroll
568  * offset as well as mechanisms for drawing scrollbars. See
569  * {@link #scrollBy(int, int)}, {@link #scrollTo(int, int)}, and
570  * {@link #awakenScrollBars()} for more details.
571  * </p>
572  *
573  * <a name="Tags"></a>
574  * <h3>Tags</h3>
575  * <p>
576  * Unlike IDs, tags are not used to identify views. Tags are essentially an
577  * extra piece of information that can be associated with a view. They are most
578  * often used as a convenience to store data related to views in the views
579  * themselves rather than by putting them in a separate structure.
580  * </p>
581  * <p>
582  * Tags may be specified with character sequence values in layout XML as either
583  * a single tag using the {@link android.R.styleable#View_tag android:tag}
584  * attribute or multiple tags using the {@code <tag>} child element:
585  * <pre>
586  *     &ltView ...
587  *           android:tag="@string/mytag_value" /&gt;
588  *     &ltView ...&gt;
589  *         &lttag android:id="@+id/mytag"
590  *              android:value="@string/mytag_value" /&gt;
591  *     &lt/View>
592  * </pre>
593  * </p>
594  * <p>
595  * Tags may also be specified with arbitrary objects from code using
596  * {@link #setTag(Object)} or {@link #setTag(int, Object)}.
597  * </p>
598  *
599  * <a name="Themes"></a>
600  * <h3>Themes</h3>
601  * <p>
602  * By default, Views are created using the theme of the Context object supplied
603  * to their constructor; however, a different theme may be specified by using
604  * the {@link android.R.styleable#View_theme android:theme} attribute in layout
605  * XML or by passing a {@link ContextThemeWrapper} to the constructor from
606  * code.
607  * </p>
608  * <p>
609  * When the {@link android.R.styleable#View_theme android:theme} attribute is
610  * used in XML, the specified theme is applied on top of the inflation
611  * context's theme (see {@link LayoutInflater}) and used for the view itself as
612  * well as any child elements.
613  * </p>
614  * <p>
615  * In the following example, both views will be created using the Material dark
616  * color scheme; however, because an overlay theme is used which only defines a
617  * subset of attributes, the value of
618  * {@link android.R.styleable#Theme_colorAccent android:colorAccent} defined on
619  * the inflation context's theme (e.g. the Activity theme) will be preserved.
620  * <pre>
621  *     &ltLinearLayout
622  *             ...
623  *             android:theme="@android:theme/ThemeOverlay.Material.Dark"&gt;
624  *         &ltView ...&gt;
625  *     &lt/LinearLayout&gt;
626  * </pre>
627  * </p>
628  *
629  * <a name="Properties"></a>
630  * <h3>Properties</h3>
631  * <p>
632  * The View class exposes an {@link #ALPHA} property, as well as several transform-related
633  * properties, such as {@link #TRANSLATION_X} and {@link #TRANSLATION_Y}. These properties are
634  * available both in the {@link Property} form as well as in similarly-named setter/getter
635  * methods (such as {@link #setAlpha(float)} for {@link #ALPHA}). These properties can
636  * be used to set persistent state associated with these rendering-related properties on the view.
637  * The properties and methods can also be used in conjunction with
638  * {@link android.animation.Animator Animator}-based animations, described more in the
639  * <a href="#Animation">Animation</a> section.
640  * </p>
641  *
642  * <a name="Animation"></a>
643  * <h3>Animation</h3>
644  * <p>
645  * Starting with Android 3.0, the preferred way of animating views is to use the
646  * {@link android.animation} package APIs. These {@link android.animation.Animator Animator}-based
647  * classes change actual properties of the View object, such as {@link #setAlpha(float) alpha} and
648  * {@link #setTranslationX(float) translationX}. This behavior is contrasted to that of the pre-3.0
649  * {@link android.view.animation.Animation Animation}-based classes, which instead animate only
650  * how the view is drawn on the display. In particular, the {@link ViewPropertyAnimator} class
651  * makes animating these View properties particularly easy and efficient.
652  * </p>
653  * <p>
654  * Alternatively, you can use the pre-3.0 animation classes to animate how Views are rendered.
655  * You can attach an {@link Animation} object to a view using
656  * {@link #setAnimation(Animation)} or
657  * {@link #startAnimation(Animation)}. The animation can alter the scale,
658  * rotation, translation and alpha of a view over time. If the animation is
659  * attached to a view that has children, the animation will affect the entire
660  * subtree rooted by that node. When an animation is started, the framework will
661  * take care of redrawing the appropriate views until the animation completes.
662  * </p>
663  *
664  * <a name="Security"></a>
665  * <h3>Security</h3>
666  * <p>
667  * Sometimes it is essential that an application be able to verify that an action
668  * is being performed with the full knowledge and consent of the user, such as
669  * granting a permission request, making a purchase or clicking on an advertisement.
670  * Unfortunately, a malicious application could try to spoof the user into
671  * performing these actions, unaware, by concealing the intended purpose of the view.
672  * As a remedy, the framework offers a touch filtering mechanism that can be used to
673  * improve the security of views that provide access to sensitive functionality.
674  * </p><p>
675  * To enable touch filtering, call {@link #setFilterTouchesWhenObscured(boolean)} or set the
676  * android:filterTouchesWhenObscured layout attribute to true.  When enabled, the framework
677  * will discard touches that are received whenever the view's window is obscured by
678  * another visible window.  As a result, the view will not receive touches whenever a
679  * toast, dialog or other window appears above the view's window.
680  * </p><p>
681  * For more fine-grained control over security, consider overriding the
682  * {@link #onFilterTouchEventForSecurity(MotionEvent)} method to implement your own
683  * security policy. See also {@link MotionEvent#FLAG_WINDOW_IS_OBSCURED}.
684  * </p>
685  *
686  * @attr ref android.R.styleable#View_alpha
687  * @attr ref android.R.styleable#View_background
688  * @attr ref android.R.styleable#View_clickable
689  * @attr ref android.R.styleable#View_contentDescription
690  * @attr ref android.R.styleable#View_drawingCacheQuality
691  * @attr ref android.R.styleable#View_duplicateParentState
692  * @attr ref android.R.styleable#View_id
693  * @attr ref android.R.styleable#View_requiresFadingEdge
694  * @attr ref android.R.styleable#View_fadeScrollbars
695  * @attr ref android.R.styleable#View_fadingEdgeLength
696  * @attr ref android.R.styleable#View_filterTouchesWhenObscured
697  * @attr ref android.R.styleable#View_fitsSystemWindows
698  * @attr ref android.R.styleable#View_isScrollContainer
699  * @attr ref android.R.styleable#View_focusable
700  * @attr ref android.R.styleable#View_focusableInTouchMode
701  * @attr ref android.R.styleable#View_hapticFeedbackEnabled
702  * @attr ref android.R.styleable#View_keepScreenOn
703  * @attr ref android.R.styleable#View_layerType
704  * @attr ref android.R.styleable#View_layoutDirection
705  * @attr ref android.R.styleable#View_longClickable
706  * @attr ref android.R.styleable#View_minHeight
707  * @attr ref android.R.styleable#View_minWidth
708  * @attr ref android.R.styleable#View_nextFocusDown
709  * @attr ref android.R.styleable#View_nextFocusLeft
710  * @attr ref android.R.styleable#View_nextFocusRight
711  * @attr ref android.R.styleable#View_nextFocusUp
712  * @attr ref android.R.styleable#View_onClick
713  * @attr ref android.R.styleable#View_padding
714  * @attr ref android.R.styleable#View_paddingBottom
715  * @attr ref android.R.styleable#View_paddingLeft
716  * @attr ref android.R.styleable#View_paddingRight
717  * @attr ref android.R.styleable#View_paddingTop
718  * @attr ref android.R.styleable#View_paddingStart
719  * @attr ref android.R.styleable#View_paddingEnd
720  * @attr ref android.R.styleable#View_saveEnabled
721  * @attr ref android.R.styleable#View_rotation
722  * @attr ref android.R.styleable#View_rotationX
723  * @attr ref android.R.styleable#View_rotationY
724  * @attr ref android.R.styleable#View_scaleX
725  * @attr ref android.R.styleable#View_scaleY
726  * @attr ref android.R.styleable#View_scrollX
727  * @attr ref android.R.styleable#View_scrollY
728  * @attr ref android.R.styleable#View_scrollbarSize
729  * @attr ref android.R.styleable#View_scrollbarStyle
730  * @attr ref android.R.styleable#View_scrollbars
731  * @attr ref android.R.styleable#View_scrollbarDefaultDelayBeforeFade
732  * @attr ref android.R.styleable#View_scrollbarFadeDuration
733  * @attr ref android.R.styleable#View_scrollbarTrackHorizontal
734  * @attr ref android.R.styleable#View_scrollbarThumbHorizontal
735  * @attr ref android.R.styleable#View_scrollbarThumbVertical
736  * @attr ref android.R.styleable#View_scrollbarTrackVertical
737  * @attr ref android.R.styleable#View_scrollbarAlwaysDrawHorizontalTrack
738  * @attr ref android.R.styleable#View_scrollbarAlwaysDrawVerticalTrack
739  * @attr ref android.R.styleable#View_stateListAnimator
740  * @attr ref android.R.styleable#View_transitionName
741  * @attr ref android.R.styleable#View_soundEffectsEnabled
742  * @attr ref android.R.styleable#View_tag
743  * @attr ref android.R.styleable#View_textAlignment
744  * @attr ref android.R.styleable#View_textDirection
745  * @attr ref android.R.styleable#View_transformPivotX
746  * @attr ref android.R.styleable#View_transformPivotY
747  * @attr ref android.R.styleable#View_translationX
748  * @attr ref android.R.styleable#View_translationY
749  * @attr ref android.R.styleable#View_translationZ
750  * @attr ref android.R.styleable#View_visibility
751  * @attr ref android.R.styleable#View_theme
752  *
753  * @see android.view.ViewGroup
754  */
755 @UiThread
756 public class View implements Drawable.Callback, KeyEvent.Callback,
757         AccessibilityEventSource {
758     private static final boolean DBG = false;
759
760     /**
761      * The logging tag used by this class with android.util.Log.
762      */
763     protected static final String VIEW_LOG_TAG = "View";
764
765     /**
766      * When set to true, apps will draw debugging information about their layouts.
767      *
768      * @hide
769      */
770     public static final String DEBUG_LAYOUT_PROPERTY = "debug.layout";
771
772     /**
773      * When set to true, this view will save its attribute data.
774      *
775      * @hide
776      */
777     public static boolean mDebugViewAttributes = false;
778
779     /**
780      * Used to mark a View that has no ID.
781      */
782     public static final int NO_ID = -1;
783
784     /**
785      * Signals that compatibility booleans have been initialized according to
786      * target SDK versions.
787      */
788     private static boolean sCompatibilityDone = false;
789
790     /**
791      * Use the old (broken) way of building MeasureSpecs.
792      */
793     private static boolean sUseBrokenMakeMeasureSpec = false;
794
795     /**
796      * Always return a size of 0 for MeasureSpec values with a mode of UNSPECIFIED
797      */
798     static boolean sUseZeroUnspecifiedMeasureSpec = false;
799
800     /**
801      * Ignore any optimizations using the measure cache.
802      */
803     private static boolean sIgnoreMeasureCache = false;
804
805     /**
806      * Ignore an optimization that skips unnecessary EXACTLY layout passes.
807      */
808     private static boolean sAlwaysRemeasureExactly = false;
809
810     /**
811      * Relax constraints around whether setLayoutParams() must be called after
812      * modifying the layout params.
813      */
814     private static boolean sLayoutParamsAlwaysChanged = false;
815
816     /**
817      * Allow setForeground/setBackground to be called (and ignored) on a textureview,
818      * without throwing
819      */
820     static boolean sTextureViewIgnoresDrawableSetters = false;
821
822     /**
823      * Prior to N, some ViewGroups would not convert LayoutParams properly even though both extend
824      * MarginLayoutParams. For instance, converting LinearLayout.LayoutParams to
825      * RelativeLayout.LayoutParams would lose margin information. This is fixed on N but target API
826      * check is implemented for backwards compatibility.
827      *
828      * {@hide}
829      */
830     protected static boolean sPreserveMarginParamsInLayoutParamConversion;
831
832     /**
833      * Prior to N, when drag enters into child of a view that has already received an
834      * ACTION_DRAG_ENTERED event, the parent doesn't get a ACTION_DRAG_EXITED event.
835      * ACTION_DRAG_LOCATION and ACTION_DROP were delivered to the parent of a view that returned
836      * false from its event handler for these events.
837      * Starting from N, the parent will get ACTION_DRAG_EXITED event before the child gets its
838      * ACTION_DRAG_ENTERED. ACTION_DRAG_LOCATION and ACTION_DROP are never propagated to the parent.
839      * sCascadedDragDrop is true for pre-N apps for backwards compatibility implementation.
840      */
841     static boolean sCascadedDragDrop;
842
843     /**
844      * This view does not want keystrokes. Use with TAKES_FOCUS_MASK when
845      * calling setFlags.
846      */
847     private static final int NOT_FOCUSABLE = 0x00000000;
848
849     /**
850      * This view wants keystrokes. Use with TAKES_FOCUS_MASK when calling
851      * setFlags.
852      */
853     private static final int FOCUSABLE = 0x00000001;
854
855     /**
856      * Mask for use with setFlags indicating bits used for focus.
857      */
858     private static final int FOCUSABLE_MASK = 0x00000001;
859
860     /**
861      * This view will adjust its padding to fit sytem windows (e.g. status bar)
862      */
863     private static final int FITS_SYSTEM_WINDOWS = 0x00000002;
864
865     /** @hide */
866     @IntDef({VISIBLE, INVISIBLE, GONE})
867     @Retention(RetentionPolicy.SOURCE)
868     public @interface Visibility {}
869
870     /**
871      * This view is visible.
872      * Use with {@link #setVisibility} and <a href="#attr_android:visibility">{@code
873      * android:visibility}.
874      */
875     public static final int VISIBLE = 0x00000000;
876
877     /**
878      * This view is invisible, but it still takes up space for layout purposes.
879      * Use with {@link #setVisibility} and <a href="#attr_android:visibility">{@code
880      * android:visibility}.
881      */
882     public static final int INVISIBLE = 0x00000004;
883
884     /**
885      * This view is invisible, and it doesn't take any space for layout
886      * purposes. Use with {@link #setVisibility} and <a href="#attr_android:visibility">{@code
887      * android:visibility}.
888      */
889     public static final int GONE = 0x00000008;
890
891     /**
892      * Mask for use with setFlags indicating bits used for visibility.
893      * {@hide}
894      */
895     static final int VISIBILITY_MASK = 0x0000000C;
896
897     private static final int[] VISIBILITY_FLAGS = {VISIBLE, INVISIBLE, GONE};
898
899     /**
900      * This view is enabled. Interpretation varies by subclass.
901      * Use with ENABLED_MASK when calling setFlags.
902      * {@hide}
903      */
904     static final int ENABLED = 0x00000000;
905
906     /**
907      * This view is disabled. Interpretation varies by subclass.
908      * Use with ENABLED_MASK when calling setFlags.
909      * {@hide}
910      */
911     static final int DISABLED = 0x00000020;
912
913    /**
914     * Mask for use with setFlags indicating bits used for indicating whether
915     * this view is enabled
916     * {@hide}
917     */
918     static final int ENABLED_MASK = 0x00000020;
919
920     /**
921      * This view won't draw. {@link #onDraw(android.graphics.Canvas)} won't be
922      * called and further optimizations will be performed. It is okay to have
923      * this flag set and a background. Use with DRAW_MASK when calling setFlags.
924      * {@hide}
925      */
926     static final int WILL_NOT_DRAW = 0x00000080;
927
928     /**
929      * Mask for use with setFlags indicating bits used for indicating whether
930      * this view is will draw
931      * {@hide}
932      */
933     static final int DRAW_MASK = 0x00000080;
934
935     /**
936      * <p>This view doesn't show scrollbars.</p>
937      * {@hide}
938      */
939     static final int SCROLLBARS_NONE = 0x00000000;
940
941     /**
942      * <p>This view shows horizontal scrollbars.</p>
943      * {@hide}
944      */
945     static final int SCROLLBARS_HORIZONTAL = 0x00000100;
946
947     /**
948      * <p>This view shows vertical scrollbars.</p>
949      * {@hide}
950      */
951     static final int SCROLLBARS_VERTICAL = 0x00000200;
952
953     /**
954      * <p>Mask for use with setFlags indicating bits used for indicating which
955      * scrollbars are enabled.</p>
956      * {@hide}
957      */
958     static final int SCROLLBARS_MASK = 0x00000300;
959
960     /**
961      * Indicates that the view should filter touches when its window is obscured.
962      * Refer to the class comments for more information about this security feature.
963      * {@hide}
964      */
965     static final int FILTER_TOUCHES_WHEN_OBSCURED = 0x00000400;
966
967     /**
968      * Set for framework elements that use FITS_SYSTEM_WINDOWS, to indicate
969      * that they are optional and should be skipped if the window has
970      * requested system UI flags that ignore those insets for layout.
971      */
972     static final int OPTIONAL_FITS_SYSTEM_WINDOWS = 0x00000800;
973
974     /**
975      * <p>This view doesn't show fading edges.</p>
976      * {@hide}
977      */
978     static final int FADING_EDGE_NONE = 0x00000000;
979
980     /**
981      * <p>This view shows horizontal fading edges.</p>
982      * {@hide}
983      */
984     static final int FADING_EDGE_HORIZONTAL = 0x00001000;
985
986     /**
987      * <p>This view shows vertical fading edges.</p>
988      * {@hide}
989      */
990     static final int FADING_EDGE_VERTICAL = 0x00002000;
991
992     /**
993      * <p>Mask for use with setFlags indicating bits used for indicating which
994      * fading edges are enabled.</p>
995      * {@hide}
996      */
997     static final int FADING_EDGE_MASK = 0x00003000;
998
999     /**
1000      * <p>Indicates this view can be clicked. When clickable, a View reacts
1001      * to clicks by notifying the OnClickListener.<p>
1002      * {@hide}
1003      */
1004     static final int CLICKABLE = 0x00004000;
1005
1006     /**
1007      * <p>Indicates this view is caching its drawing into a bitmap.</p>
1008      * {@hide}
1009      */
1010     static final int DRAWING_CACHE_ENABLED = 0x00008000;
1011
1012     /**
1013      * <p>Indicates that no icicle should be saved for this view.<p>
1014      * {@hide}
1015      */
1016     static final int SAVE_DISABLED = 0x000010000;
1017
1018     /**
1019      * <p>Mask for use with setFlags indicating bits used for the saveEnabled
1020      * property.</p>
1021      * {@hide}
1022      */
1023     static final int SAVE_DISABLED_MASK = 0x000010000;
1024
1025     /**
1026      * <p>Indicates that no drawing cache should ever be created for this view.<p>
1027      * {@hide}
1028      */
1029     static final int WILL_NOT_CACHE_DRAWING = 0x000020000;
1030
1031     /**
1032      * <p>Indicates this view can take / keep focus when int touch mode.</p>
1033      * {@hide}
1034      */
1035     static final int FOCUSABLE_IN_TOUCH_MODE = 0x00040000;
1036
1037     /** @hide */
1038     @Retention(RetentionPolicy.SOURCE)
1039     @IntDef({DRAWING_CACHE_QUALITY_LOW, DRAWING_CACHE_QUALITY_HIGH, DRAWING_CACHE_QUALITY_AUTO})
1040     public @interface DrawingCacheQuality {}
1041
1042     /**
1043      * <p>Enables low quality mode for the drawing cache.</p>
1044      */
1045     public static final int DRAWING_CACHE_QUALITY_LOW = 0x00080000;
1046
1047     /**
1048      * <p>Enables high quality mode for the drawing cache.</p>
1049      */
1050     public static final int DRAWING_CACHE_QUALITY_HIGH = 0x00100000;
1051
1052     /**
1053      * <p>Enables automatic quality mode for the drawing cache.</p>
1054      */
1055     public static final int DRAWING_CACHE_QUALITY_AUTO = 0x00000000;
1056
1057     private static final int[] DRAWING_CACHE_QUALITY_FLAGS = {
1058             DRAWING_CACHE_QUALITY_AUTO, DRAWING_CACHE_QUALITY_LOW, DRAWING_CACHE_QUALITY_HIGH
1059     };
1060
1061     /**
1062      * <p>Mask for use with setFlags indicating bits used for the cache
1063      * quality property.</p>
1064      * {@hide}
1065      */
1066     static final int DRAWING_CACHE_QUALITY_MASK = 0x00180000;
1067
1068     /**
1069      * <p>
1070      * Indicates this view can be long clicked. When long clickable, a View
1071      * reacts to long clicks by notifying the OnLongClickListener or showing a
1072      * context menu.
1073      * </p>
1074      * {@hide}
1075      */
1076     static final int LONG_CLICKABLE = 0x00200000;
1077
1078     /**
1079      * <p>Indicates that this view gets its drawable states from its direct parent
1080      * and ignores its original internal states.</p>
1081      *
1082      * @hide
1083      */
1084     static final int DUPLICATE_PARENT_STATE = 0x00400000;
1085
1086     /**
1087      * <p>
1088      * Indicates this view can be context clicked. When context clickable, a View reacts to a
1089      * context click (e.g. a primary stylus button press or right mouse click) by notifying the
1090      * OnContextClickListener.
1091      * </p>
1092      * {@hide}
1093      */
1094     static final int CONTEXT_CLICKABLE = 0x00800000;
1095
1096
1097     /** @hide */
1098     @IntDef({
1099         SCROLLBARS_INSIDE_OVERLAY,
1100         SCROLLBARS_INSIDE_INSET,
1101         SCROLLBARS_OUTSIDE_OVERLAY,
1102         SCROLLBARS_OUTSIDE_INSET
1103     })
1104     @Retention(RetentionPolicy.SOURCE)
1105     public @interface ScrollBarStyle {}
1106
1107     /**
1108      * The scrollbar style to display the scrollbars inside the content area,
1109      * without increasing the padding. The scrollbars will be overlaid with
1110      * translucency on the view's content.
1111      */
1112     public static final int SCROLLBARS_INSIDE_OVERLAY = 0;
1113
1114     /**
1115      * The scrollbar style to display the scrollbars inside the padded area,
1116      * increasing the padding of the view. The scrollbars will not overlap the
1117      * content area of the view.
1118      */
1119     public static final int SCROLLBARS_INSIDE_INSET = 0x01000000;
1120
1121     /**
1122      * The scrollbar style to display the scrollbars at the edge of the view,
1123      * without increasing the padding. The scrollbars will be overlaid with
1124      * translucency.
1125      */
1126     public static final int SCROLLBARS_OUTSIDE_OVERLAY = 0x02000000;
1127
1128     /**
1129      * The scrollbar style to display the scrollbars at the edge of the view,
1130      * increasing the padding of the view. The scrollbars will only overlap the
1131      * background, if any.
1132      */
1133     public static final int SCROLLBARS_OUTSIDE_INSET = 0x03000000;
1134
1135     /**
1136      * Mask to check if the scrollbar style is overlay or inset.
1137      * {@hide}
1138      */
1139     static final int SCROLLBARS_INSET_MASK = 0x01000000;
1140
1141     /**
1142      * Mask to check if the scrollbar style is inside or outside.
1143      * {@hide}
1144      */
1145     static final int SCROLLBARS_OUTSIDE_MASK = 0x02000000;
1146
1147     /**
1148      * Mask for scrollbar style.
1149      * {@hide}
1150      */
1151     static final int SCROLLBARS_STYLE_MASK = 0x03000000;
1152
1153     /**
1154      * View flag indicating that the screen should remain on while the
1155      * window containing this view is visible to the user.  This effectively
1156      * takes care of automatically setting the WindowManager's
1157      * {@link WindowManager.LayoutParams#FLAG_KEEP_SCREEN_ON}.
1158      */
1159     public static final int KEEP_SCREEN_ON = 0x04000000;
1160
1161     /**
1162      * View flag indicating whether this view should have sound effects enabled
1163      * for events such as clicking and touching.
1164      */
1165     public static final int SOUND_EFFECTS_ENABLED = 0x08000000;
1166
1167     /**
1168      * View flag indicating whether this view should have haptic feedback
1169      * enabled for events such as long presses.
1170      */
1171     public static final int HAPTIC_FEEDBACK_ENABLED = 0x10000000;
1172
1173     /**
1174      * <p>Indicates that the view hierarchy should stop saving state when
1175      * it reaches this view.  If state saving is initiated immediately at
1176      * the view, it will be allowed.
1177      * {@hide}
1178      */
1179     static final int PARENT_SAVE_DISABLED = 0x20000000;
1180
1181     /**
1182      * <p>Mask for use with setFlags indicating bits used for PARENT_SAVE_DISABLED.</p>
1183      * {@hide}
1184      */
1185     static final int PARENT_SAVE_DISABLED_MASK = 0x20000000;
1186
1187     /** @hide */
1188     @IntDef(flag = true,
1189             value = {
1190                 FOCUSABLES_ALL,
1191                 FOCUSABLES_TOUCH_MODE
1192             })
1193     @Retention(RetentionPolicy.SOURCE)
1194     public @interface FocusableMode {}
1195
1196     /**
1197      * View flag indicating whether {@link #addFocusables(ArrayList, int, int)}
1198      * should add all focusable Views regardless if they are focusable in touch mode.
1199      */
1200     public static final int FOCUSABLES_ALL = 0x00000000;
1201
1202     /**
1203      * View flag indicating whether {@link #addFocusables(ArrayList, int, int)}
1204      * should add only Views focusable in touch mode.
1205      */
1206     public static final int FOCUSABLES_TOUCH_MODE = 0x00000001;
1207
1208     /** @hide */
1209     @IntDef({
1210             FOCUS_BACKWARD,
1211             FOCUS_FORWARD,
1212             FOCUS_LEFT,
1213             FOCUS_UP,
1214             FOCUS_RIGHT,
1215             FOCUS_DOWN
1216     })
1217     @Retention(RetentionPolicy.SOURCE)
1218     public @interface FocusDirection {}
1219
1220     /** @hide */
1221     @IntDef({
1222             FOCUS_LEFT,
1223             FOCUS_UP,
1224             FOCUS_RIGHT,
1225             FOCUS_DOWN
1226     })
1227     @Retention(RetentionPolicy.SOURCE)
1228     public @interface FocusRealDirection {} // Like @FocusDirection, but without forward/backward
1229
1230     /**
1231      * Use with {@link #focusSearch(int)}. Move focus to the previous selectable
1232      * item.
1233      */
1234     public static final int FOCUS_BACKWARD = 0x00000001;
1235
1236     /**
1237      * Use with {@link #focusSearch(int)}. Move focus to the next selectable
1238      * item.
1239      */
1240     public static final int FOCUS_FORWARD = 0x00000002;
1241
1242     /**
1243      * Use with {@link #focusSearch(int)}. Move focus to the left.
1244      */
1245     public static final int FOCUS_LEFT = 0x00000011;
1246
1247     /**
1248      * Use with {@link #focusSearch(int)}. Move focus up.
1249      */
1250     public static final int FOCUS_UP = 0x00000021;
1251
1252     /**
1253      * Use with {@link #focusSearch(int)}. Move focus to the right.
1254      */
1255     public static final int FOCUS_RIGHT = 0x00000042;
1256
1257     /**
1258      * Use with {@link #focusSearch(int)}. Move focus down.
1259      */
1260     public static final int FOCUS_DOWN = 0x00000082;
1261
1262     /**
1263      * Bits of {@link #getMeasuredWidthAndState()} and
1264      * {@link #getMeasuredWidthAndState()} that provide the actual measured size.
1265      */
1266     public static final int MEASURED_SIZE_MASK = 0x00ffffff;
1267
1268     /**
1269      * Bits of {@link #getMeasuredWidthAndState()} and
1270      * {@link #getMeasuredWidthAndState()} that provide the additional state bits.
1271      */
1272     public static final int MEASURED_STATE_MASK = 0xff000000;
1273
1274     /**
1275      * Bit shift of {@link #MEASURED_STATE_MASK} to get to the height bits
1276      * for functions that combine both width and height into a single int,
1277      * such as {@link #getMeasuredState()} and the childState argument of
1278      * {@link #resolveSizeAndState(int, int, int)}.
1279      */
1280     public static final int MEASURED_HEIGHT_STATE_SHIFT = 16;
1281
1282     /**
1283      * Bit of {@link #getMeasuredWidthAndState()} and
1284      * {@link #getMeasuredWidthAndState()} that indicates the measured size
1285      * is smaller that the space the view would like to have.
1286      */
1287     public static final int MEASURED_STATE_TOO_SMALL = 0x01000000;
1288
1289     /**
1290      * Base View state sets
1291      */
1292     // Singles
1293     /**
1294      * Indicates the view has no states set. States are used with
1295      * {@link android.graphics.drawable.Drawable} to change the drawing of the
1296      * view depending on its state.
1297      *
1298      * @see android.graphics.drawable.Drawable
1299      * @see #getDrawableState()
1300      */
1301     protected static final int[] EMPTY_STATE_SET;
1302     /**
1303      * Indicates the view is enabled. States are used with
1304      * {@link android.graphics.drawable.Drawable} to change the drawing of the
1305      * view depending on its state.
1306      *
1307      * @see android.graphics.drawable.Drawable
1308      * @see #getDrawableState()
1309      */
1310     protected static final int[] ENABLED_STATE_SET;
1311     /**
1312      * Indicates the view is focused. States are used with
1313      * {@link android.graphics.drawable.Drawable} to change the drawing of the
1314      * view depending on its state.
1315      *
1316      * @see android.graphics.drawable.Drawable
1317      * @see #getDrawableState()
1318      */
1319     protected static final int[] FOCUSED_STATE_SET;
1320     /**
1321      * Indicates the view is selected. States are used with
1322      * {@link android.graphics.drawable.Drawable} to change the drawing of the
1323      * view depending on its state.
1324      *
1325      * @see android.graphics.drawable.Drawable
1326      * @see #getDrawableState()
1327      */
1328     protected static final int[] SELECTED_STATE_SET;
1329     /**
1330      * Indicates the view is pressed. States are used with
1331      * {@link android.graphics.drawable.Drawable} to change the drawing of the
1332      * view depending on its state.
1333      *
1334      * @see android.graphics.drawable.Drawable
1335      * @see #getDrawableState()
1336      */
1337     protected static final int[] PRESSED_STATE_SET;
1338     /**
1339      * Indicates the view's window has focus. States are used with
1340      * {@link android.graphics.drawable.Drawable} to change the drawing of the
1341      * view depending on its state.
1342      *
1343      * @see android.graphics.drawable.Drawable
1344      * @see #getDrawableState()
1345      */
1346     protected static final int[] WINDOW_FOCUSED_STATE_SET;
1347     // Doubles
1348     /**
1349      * Indicates the view is enabled and has the focus.
1350      *
1351      * @see #ENABLED_STATE_SET
1352      * @see #FOCUSED_STATE_SET
1353      */
1354     protected static final int[] ENABLED_FOCUSED_STATE_SET;
1355     /**
1356      * Indicates the view is enabled and selected.
1357      *
1358      * @see #ENABLED_STATE_SET
1359      * @see #SELECTED_STATE_SET
1360      */
1361     protected static final int[] ENABLED_SELECTED_STATE_SET;
1362     /**
1363      * Indicates the view is enabled and that its window has focus.
1364      *
1365      * @see #ENABLED_STATE_SET
1366      * @see #WINDOW_FOCUSED_STATE_SET
1367      */
1368     protected static final int[] ENABLED_WINDOW_FOCUSED_STATE_SET;
1369     /**
1370      * Indicates the view is focused and selected.
1371      *
1372      * @see #FOCUSED_STATE_SET
1373      * @see #SELECTED_STATE_SET
1374      */
1375     protected static final int[] FOCUSED_SELECTED_STATE_SET;
1376     /**
1377      * Indicates the view has the focus and that its window has the focus.
1378      *
1379      * @see #FOCUSED_STATE_SET
1380      * @see #WINDOW_FOCUSED_STATE_SET
1381      */
1382     protected static final int[] FOCUSED_WINDOW_FOCUSED_STATE_SET;
1383     /**
1384      * Indicates the view is selected and that its window has the focus.
1385      *
1386      * @see #SELECTED_STATE_SET
1387      * @see #WINDOW_FOCUSED_STATE_SET
1388      */
1389     protected static final int[] SELECTED_WINDOW_FOCUSED_STATE_SET;
1390     // Triples
1391     /**
1392      * Indicates the view is enabled, focused and selected.
1393      *
1394      * @see #ENABLED_STATE_SET
1395      * @see #FOCUSED_STATE_SET
1396      * @see #SELECTED_STATE_SET
1397      */
1398     protected static final int[] ENABLED_FOCUSED_SELECTED_STATE_SET;
1399     /**
1400      * Indicates the view is enabled, focused and its window has the focus.
1401      *
1402      * @see #ENABLED_STATE_SET
1403      * @see #FOCUSED_STATE_SET
1404      * @see #WINDOW_FOCUSED_STATE_SET
1405      */
1406     protected static final int[] ENABLED_FOCUSED_WINDOW_FOCUSED_STATE_SET;
1407     /**
1408      * Indicates the view is enabled, selected and its window has the focus.
1409      *
1410      * @see #ENABLED_STATE_SET
1411      * @see #SELECTED_STATE_SET
1412      * @see #WINDOW_FOCUSED_STATE_SET
1413      */
1414     protected static final int[] ENABLED_SELECTED_WINDOW_FOCUSED_STATE_SET;
1415     /**
1416      * Indicates the view is focused, selected and its window has the focus.
1417      *
1418      * @see #FOCUSED_STATE_SET
1419      * @see #SELECTED_STATE_SET
1420      * @see #WINDOW_FOCUSED_STATE_SET
1421      */
1422     protected static final int[] FOCUSED_SELECTED_WINDOW_FOCUSED_STATE_SET;
1423     /**
1424      * Indicates the view is enabled, focused, selected and its window
1425      * has the focus.
1426      *
1427      * @see #ENABLED_STATE_SET
1428      * @see #FOCUSED_STATE_SET
1429      * @see #SELECTED_STATE_SET
1430      * @see #WINDOW_FOCUSED_STATE_SET
1431      */
1432     protected static final int[] ENABLED_FOCUSED_SELECTED_WINDOW_FOCUSED_STATE_SET;
1433     /**
1434      * Indicates the view is pressed and its window has the focus.
1435      *
1436      * @see #PRESSED_STATE_SET
1437      * @see #WINDOW_FOCUSED_STATE_SET
1438      */
1439     protected static final int[] PRESSED_WINDOW_FOCUSED_STATE_SET;
1440     /**
1441      * Indicates the view is pressed and selected.
1442      *
1443      * @see #PRESSED_STATE_SET
1444      * @see #SELECTED_STATE_SET
1445      */
1446     protected static final int[] PRESSED_SELECTED_STATE_SET;
1447     /**
1448      * Indicates the view is pressed, selected and its window has the focus.
1449      *
1450      * @see #PRESSED_STATE_SET
1451      * @see #SELECTED_STATE_SET
1452      * @see #WINDOW_FOCUSED_STATE_SET
1453      */
1454     protected static final int[] PRESSED_SELECTED_WINDOW_FOCUSED_STATE_SET;
1455     /**
1456      * Indicates the view is pressed and focused.
1457      *
1458      * @see #PRESSED_STATE_SET
1459      * @see #FOCUSED_STATE_SET
1460      */
1461     protected static final int[] PRESSED_FOCUSED_STATE_SET;
1462     /**
1463      * Indicates the view is pressed, focused and its window has the focus.
1464      *
1465      * @see #PRESSED_STATE_SET
1466      * @see #FOCUSED_STATE_SET
1467      * @see #WINDOW_FOCUSED_STATE_SET
1468      */
1469     protected static final int[] PRESSED_FOCUSED_WINDOW_FOCUSED_STATE_SET;
1470     /**
1471      * Indicates the view is pressed, focused and selected.
1472      *
1473      * @see #PRESSED_STATE_SET
1474      * @see #SELECTED_STATE_SET
1475      * @see #FOCUSED_STATE_SET
1476      */
1477     protected static final int[] PRESSED_FOCUSED_SELECTED_STATE_SET;
1478     /**
1479      * Indicates the view is pressed, focused, selected and its window has the focus.
1480      *
1481      * @see #PRESSED_STATE_SET
1482      * @see #FOCUSED_STATE_SET
1483      * @see #SELECTED_STATE_SET
1484      * @see #WINDOW_FOCUSED_STATE_SET
1485      */
1486     protected static final int[] PRESSED_FOCUSED_SELECTED_WINDOW_FOCUSED_STATE_SET;
1487     /**
1488      * Indicates the view is pressed and enabled.
1489      *
1490      * @see #PRESSED_STATE_SET
1491      * @see #ENABLED_STATE_SET
1492      */
1493     protected static final int[] PRESSED_ENABLED_STATE_SET;
1494     /**
1495      * Indicates the view is pressed, enabled and its window has the focus.
1496      *
1497      * @see #PRESSED_STATE_SET
1498      * @see #ENABLED_STATE_SET
1499      * @see #WINDOW_FOCUSED_STATE_SET
1500      */
1501     protected static final int[] PRESSED_ENABLED_WINDOW_FOCUSED_STATE_SET;
1502     /**
1503      * Indicates the view is pressed, enabled and selected.
1504      *
1505      * @see #PRESSED_STATE_SET
1506      * @see #ENABLED_STATE_SET
1507      * @see #SELECTED_STATE_SET
1508      */
1509     protected static final int[] PRESSED_ENABLED_SELECTED_STATE_SET;
1510     /**
1511      * Indicates the view is pressed, enabled, selected and its window has the
1512      * focus.
1513      *
1514      * @see #PRESSED_STATE_SET
1515      * @see #ENABLED_STATE_SET
1516      * @see #SELECTED_STATE_SET
1517      * @see #WINDOW_FOCUSED_STATE_SET
1518      */
1519     protected static final int[] PRESSED_ENABLED_SELECTED_WINDOW_FOCUSED_STATE_SET;
1520     /**
1521      * Indicates the view is pressed, enabled and focused.
1522      *
1523      * @see #PRESSED_STATE_SET
1524      * @see #ENABLED_STATE_SET
1525      * @see #FOCUSED_STATE_SET
1526      */
1527     protected static final int[] PRESSED_ENABLED_FOCUSED_STATE_SET;
1528     /**
1529      * Indicates the view is pressed, enabled, focused and its window has the
1530      * focus.
1531      *
1532      * @see #PRESSED_STATE_SET
1533      * @see #ENABLED_STATE_SET
1534      * @see #FOCUSED_STATE_SET
1535      * @see #WINDOW_FOCUSED_STATE_SET
1536      */
1537     protected static final int[] PRESSED_ENABLED_FOCUSED_WINDOW_FOCUSED_STATE_SET;
1538     /**
1539      * Indicates the view is pressed, enabled, focused and selected.
1540      *
1541      * @see #PRESSED_STATE_SET
1542      * @see #ENABLED_STATE_SET
1543      * @see #SELECTED_STATE_SET
1544      * @see #FOCUSED_STATE_SET
1545      */
1546     protected static final int[] PRESSED_ENABLED_FOCUSED_SELECTED_STATE_SET;
1547     /**
1548      * Indicates the view is pressed, enabled, focused, selected and its window
1549      * has the focus.
1550      *
1551      * @see #PRESSED_STATE_SET
1552      * @see #ENABLED_STATE_SET
1553      * @see #SELECTED_STATE_SET
1554      * @see #FOCUSED_STATE_SET
1555      * @see #WINDOW_FOCUSED_STATE_SET
1556      */
1557     protected static final int[] PRESSED_ENABLED_FOCUSED_SELECTED_WINDOW_FOCUSED_STATE_SET;
1558
1559     static {
1560         EMPTY_STATE_SET = StateSet.get(0);
1561
1562         WINDOW_FOCUSED_STATE_SET = StateSet.get(StateSet.VIEW_STATE_WINDOW_FOCUSED);
1563
1564         SELECTED_STATE_SET = StateSet.get(StateSet.VIEW_STATE_SELECTED);
1565         SELECTED_WINDOW_FOCUSED_STATE_SET = StateSet.get(
1566                 StateSet.VIEW_STATE_WINDOW_FOCUSED | StateSet.VIEW_STATE_SELECTED);
1567
1568         FOCUSED_STATE_SET = StateSet.get(StateSet.VIEW_STATE_FOCUSED);
1569         FOCUSED_WINDOW_FOCUSED_STATE_SET = StateSet.get(
1570                 StateSet.VIEW_STATE_WINDOW_FOCUSED | StateSet.VIEW_STATE_FOCUSED);
1571         FOCUSED_SELECTED_STATE_SET = StateSet.get(
1572                 StateSet.VIEW_STATE_SELECTED | StateSet.VIEW_STATE_FOCUSED);
1573         FOCUSED_SELECTED_WINDOW_FOCUSED_STATE_SET = StateSet.get(
1574                 StateSet.VIEW_STATE_WINDOW_FOCUSED | StateSet.VIEW_STATE_SELECTED
1575                         | StateSet.VIEW_STATE_FOCUSED);
1576
1577         ENABLED_STATE_SET = StateSet.get(StateSet.VIEW_STATE_ENABLED);
1578         ENABLED_WINDOW_FOCUSED_STATE_SET = StateSet.get(
1579                 StateSet.VIEW_STATE_WINDOW_FOCUSED | StateSet.VIEW_STATE_ENABLED);
1580         ENABLED_SELECTED_STATE_SET = StateSet.get(
1581                 StateSet.VIEW_STATE_SELECTED | StateSet.VIEW_STATE_ENABLED);
1582         ENABLED_SELECTED_WINDOW_FOCUSED_STATE_SET = StateSet.get(
1583                 StateSet.VIEW_STATE_WINDOW_FOCUSED | StateSet.VIEW_STATE_SELECTED
1584                         | StateSet.VIEW_STATE_ENABLED);
1585         ENABLED_FOCUSED_STATE_SET = StateSet.get(
1586                 StateSet.VIEW_STATE_FOCUSED | StateSet.VIEW_STATE_ENABLED);
1587         ENABLED_FOCUSED_WINDOW_FOCUSED_STATE_SET = StateSet.get(
1588                 StateSet.VIEW_STATE_WINDOW_FOCUSED | StateSet.VIEW_STATE_FOCUSED
1589                         | StateSet.VIEW_STATE_ENABLED);
1590         ENABLED_FOCUSED_SELECTED_STATE_SET = StateSet.get(
1591                 StateSet.VIEW_STATE_SELECTED | StateSet.VIEW_STATE_FOCUSED
1592                         | StateSet.VIEW_STATE_ENABLED);
1593         ENABLED_FOCUSED_SELECTED_WINDOW_FOCUSED_STATE_SET = StateSet.get(
1594                 StateSet.VIEW_STATE_WINDOW_FOCUSED | StateSet.VIEW_STATE_SELECTED
1595                         | StateSet.VIEW_STATE_FOCUSED| StateSet.VIEW_STATE_ENABLED);
1596
1597         PRESSED_STATE_SET = StateSet.get(StateSet.VIEW_STATE_PRESSED);
1598         PRESSED_WINDOW_FOCUSED_STATE_SET = StateSet.get(
1599                 StateSet.VIEW_STATE_WINDOW_FOCUSED | StateSet.VIEW_STATE_PRESSED);
1600         PRESSED_SELECTED_STATE_SET = StateSet.get(
1601                 StateSet.VIEW_STATE_SELECTED | StateSet.VIEW_STATE_PRESSED);
1602         PRESSED_SELECTED_WINDOW_FOCUSED_STATE_SET = StateSet.get(
1603                 StateSet.VIEW_STATE_WINDOW_FOCUSED | StateSet.VIEW_STATE_SELECTED
1604                         | StateSet.VIEW_STATE_PRESSED);
1605         PRESSED_FOCUSED_STATE_SET = StateSet.get(
1606                 StateSet.VIEW_STATE_FOCUSED | StateSet.VIEW_STATE_PRESSED);
1607         PRESSED_FOCUSED_WINDOW_FOCUSED_STATE_SET = StateSet.get(
1608                 StateSet.VIEW_STATE_WINDOW_FOCUSED | StateSet.VIEW_STATE_FOCUSED
1609                         | StateSet.VIEW_STATE_PRESSED);
1610         PRESSED_FOCUSED_SELECTED_STATE_SET = StateSet.get(
1611                 StateSet.VIEW_STATE_SELECTED | StateSet.VIEW_STATE_FOCUSED
1612                         | StateSet.VIEW_STATE_PRESSED);
1613         PRESSED_FOCUSED_SELECTED_WINDOW_FOCUSED_STATE_SET = StateSet.get(
1614                 StateSet.VIEW_STATE_WINDOW_FOCUSED | StateSet.VIEW_STATE_SELECTED
1615                         | StateSet.VIEW_STATE_FOCUSED | StateSet.VIEW_STATE_PRESSED);
1616         PRESSED_ENABLED_STATE_SET = StateSet.get(
1617                 StateSet.VIEW_STATE_ENABLED | StateSet.VIEW_STATE_PRESSED);
1618         PRESSED_ENABLED_WINDOW_FOCUSED_STATE_SET = StateSet.get(
1619                 StateSet.VIEW_STATE_WINDOW_FOCUSED | StateSet.VIEW_STATE_ENABLED
1620                         | StateSet.VIEW_STATE_PRESSED);
1621         PRESSED_ENABLED_SELECTED_STATE_SET = StateSet.get(
1622                 StateSet.VIEW_STATE_SELECTED | StateSet.VIEW_STATE_ENABLED
1623                         | StateSet.VIEW_STATE_PRESSED);
1624         PRESSED_ENABLED_SELECTED_WINDOW_FOCUSED_STATE_SET = StateSet.get(
1625                 StateSet.VIEW_STATE_WINDOW_FOCUSED | StateSet.VIEW_STATE_SELECTED
1626                         | StateSet.VIEW_STATE_ENABLED | StateSet.VIEW_STATE_PRESSED);
1627         PRESSED_ENABLED_FOCUSED_STATE_SET = StateSet.get(
1628                 StateSet.VIEW_STATE_FOCUSED | StateSet.VIEW_STATE_ENABLED
1629                         | StateSet.VIEW_STATE_PRESSED);
1630         PRESSED_ENABLED_FOCUSED_WINDOW_FOCUSED_STATE_SET = StateSet.get(
1631                 StateSet.VIEW_STATE_WINDOW_FOCUSED | StateSet.VIEW_STATE_FOCUSED
1632                         | StateSet.VIEW_STATE_ENABLED | StateSet.VIEW_STATE_PRESSED);
1633         PRESSED_ENABLED_FOCUSED_SELECTED_STATE_SET = StateSet.get(
1634                 StateSet.VIEW_STATE_SELECTED | StateSet.VIEW_STATE_FOCUSED
1635                         | StateSet.VIEW_STATE_ENABLED | StateSet.VIEW_STATE_PRESSED);
1636         PRESSED_ENABLED_FOCUSED_SELECTED_WINDOW_FOCUSED_STATE_SET = StateSet.get(
1637                 StateSet.VIEW_STATE_WINDOW_FOCUSED | StateSet.VIEW_STATE_SELECTED
1638                         | StateSet.VIEW_STATE_FOCUSED| StateSet.VIEW_STATE_ENABLED
1639                         | StateSet.VIEW_STATE_PRESSED);
1640     }
1641
1642     /**
1643      * Accessibility event types that are dispatched for text population.
1644      */
1645     private static final int POPULATING_ACCESSIBILITY_EVENT_TYPES =
1646             AccessibilityEvent.TYPE_VIEW_CLICKED
1647             | AccessibilityEvent.TYPE_VIEW_LONG_CLICKED
1648             | AccessibilityEvent.TYPE_VIEW_SELECTED
1649             | AccessibilityEvent.TYPE_VIEW_FOCUSED
1650             | AccessibilityEvent.TYPE_WINDOW_STATE_CHANGED
1651             | AccessibilityEvent.TYPE_VIEW_HOVER_ENTER
1652             | AccessibilityEvent.TYPE_VIEW_HOVER_EXIT
1653             | AccessibilityEvent.TYPE_VIEW_TEXT_CHANGED
1654             | AccessibilityEvent.TYPE_VIEW_TEXT_SELECTION_CHANGED
1655             | AccessibilityEvent.TYPE_VIEW_ACCESSIBILITY_FOCUSED
1656             | AccessibilityEvent.TYPE_VIEW_TEXT_TRAVERSED_AT_MOVEMENT_GRANULARITY;
1657
1658     /**
1659      * Temporary Rect currently for use in setBackground().  This will probably
1660      * be extended in the future to hold our own class with more than just
1661      * a Rect. :)
1662      */
1663     static final ThreadLocal<Rect> sThreadLocal = new ThreadLocal<Rect>();
1664
1665     /**
1666      * Map used to store views' tags.
1667      */
1668     private SparseArray<Object> mKeyedTags;
1669
1670     /**
1671      * The next available accessibility id.
1672      */
1673     private static int sNextAccessibilityViewId;
1674
1675     /**
1676      * The animation currently associated with this view.
1677      * @hide
1678      */
1679     protected Animation mCurrentAnimation = null;
1680
1681     /**
1682      * Width as measured during measure pass.
1683      * {@hide}
1684      */
1685     @ViewDebug.ExportedProperty(category = "measurement")
1686     int mMeasuredWidth;
1687
1688     /**
1689      * Height as measured during measure pass.
1690      * {@hide}
1691      */
1692     @ViewDebug.ExportedProperty(category = "measurement")
1693     int mMeasuredHeight;
1694
1695     /**
1696      * Flag to indicate that this view was marked INVALIDATED, or had its display list
1697      * invalidated, prior to the current drawing iteration. If true, the view must re-draw
1698      * its display list. This flag, used only when hw accelerated, allows us to clear the
1699      * flag while retaining this information until it's needed (at getDisplayList() time and
1700      * in drawChild(), when we decide to draw a view's children's display lists into our own).
1701      *
1702      * {@hide}
1703      */
1704     boolean mRecreateDisplayList = false;
1705
1706     /**
1707      * The view's identifier.
1708      * {@hide}
1709      *
1710      * @see #setId(int)
1711      * @see #getId()
1712      */
1713     @IdRes
1714     @ViewDebug.ExportedProperty(resolveId = true)
1715     int mID = NO_ID;
1716
1717     /**
1718      * The stable ID of this view for accessibility purposes.
1719      */
1720     int mAccessibilityViewId = NO_ID;
1721
1722     private int mAccessibilityCursorPosition = ACCESSIBILITY_CURSOR_POSITION_UNDEFINED;
1723
1724     SendViewStateChangedAccessibilityEvent mSendViewStateChangedAccessibilityEvent;
1725
1726     /**
1727      * The view's tag.
1728      * {@hide}
1729      *
1730      * @see #setTag(Object)
1731      * @see #getTag()
1732      */
1733     protected Object mTag = null;
1734
1735     // for mPrivateFlags:
1736     /** {@hide} */
1737     static final int PFLAG_WANTS_FOCUS                 = 0x00000001;
1738     /** {@hide} */
1739     static final int PFLAG_FOCUSED                     = 0x00000002;
1740     /** {@hide} */
1741     static final int PFLAG_SELECTED                    = 0x00000004;
1742     /** {@hide} */
1743     static final int PFLAG_IS_ROOT_NAMESPACE           = 0x00000008;
1744     /** {@hide} */
1745     static final int PFLAG_HAS_BOUNDS                  = 0x00000010;
1746     /** {@hide} */
1747     static final int PFLAG_DRAWN                       = 0x00000020;
1748     /**
1749      * When this flag is set, this view is running an animation on behalf of its
1750      * children and should therefore not cancel invalidate requests, even if they
1751      * lie outside of this view's bounds.
1752      *
1753      * {@hide}
1754      */
1755     static final int PFLAG_DRAW_ANIMATION              = 0x00000040;
1756     /** {@hide} */
1757     static final int PFLAG_SKIP_DRAW                   = 0x00000080;
1758     /** {@hide} */
1759     static final int PFLAG_REQUEST_TRANSPARENT_REGIONS = 0x00000200;
1760     /** {@hide} */
1761     static final int PFLAG_DRAWABLE_STATE_DIRTY        = 0x00000400;
1762     /** {@hide} */
1763     static final int PFLAG_MEASURED_DIMENSION_SET      = 0x00000800;
1764     /** {@hide} */
1765     static final int PFLAG_FORCE_LAYOUT                = 0x00001000;
1766     /** {@hide} */
1767     static final int PFLAG_LAYOUT_REQUIRED             = 0x00002000;
1768
1769     private static final int PFLAG_PRESSED             = 0x00004000;
1770
1771     /** {@hide} */
1772     static final int PFLAG_DRAWING_CACHE_VALID         = 0x00008000;
1773     /**
1774      * Flag used to indicate that this view should be drawn once more (and only once
1775      * more) after its animation has completed.
1776      * {@hide}
1777      */
1778     static final int PFLAG_ANIMATION_STARTED           = 0x00010000;
1779
1780     private static final int PFLAG_SAVE_STATE_CALLED   = 0x00020000;
1781
1782     /**
1783      * Indicates that the View returned true when onSetAlpha() was called and that
1784      * the alpha must be restored.
1785      * {@hide}
1786      */
1787     static final int PFLAG_ALPHA_SET                   = 0x00040000;
1788
1789     /**
1790      * Set by {@link #setScrollContainer(boolean)}.
1791      */
1792     static final int PFLAG_SCROLL_CONTAINER            = 0x00080000;
1793
1794     /**
1795      * Set by {@link #setScrollContainer(boolean)}.
1796      */
1797     static final int PFLAG_SCROLL_CONTAINER_ADDED      = 0x00100000;
1798
1799     /**
1800      * View flag indicating whether this view was invalidated (fully or partially.)
1801      *
1802      * @hide
1803      */
1804     static final int PFLAG_DIRTY                       = 0x00200000;
1805
1806     /**
1807      * View flag indicating whether this view was invalidated by an opaque
1808      * invalidate request.
1809      *
1810      * @hide
1811      */
1812     static final int PFLAG_DIRTY_OPAQUE                = 0x00400000;
1813
1814     /**
1815      * Mask for {@link #PFLAG_DIRTY} and {@link #PFLAG_DIRTY_OPAQUE}.
1816      *
1817      * @hide
1818      */
1819     static final int PFLAG_DIRTY_MASK                  = 0x00600000;
1820
1821     /**
1822      * Indicates whether the background is opaque.
1823      *
1824      * @hide
1825      */
1826     static final int PFLAG_OPAQUE_BACKGROUND           = 0x00800000;
1827
1828     /**
1829      * Indicates whether the scrollbars are opaque.
1830      *
1831      * @hide
1832      */
1833     static final int PFLAG_OPAQUE_SCROLLBARS           = 0x01000000;
1834
1835     /**
1836      * Indicates whether the view is opaque.
1837      *
1838      * @hide
1839      */
1840     static final int PFLAG_OPAQUE_MASK                 = 0x01800000;
1841
1842     /**
1843      * Indicates a prepressed state;
1844      * the short time between ACTION_DOWN and recognizing
1845      * a 'real' press. Prepressed is used to recognize quick taps
1846      * even when they are shorter than ViewConfiguration.getTapTimeout().
1847      *
1848      * @hide
1849      */
1850     private static final int PFLAG_PREPRESSED          = 0x02000000;
1851
1852     /**
1853      * Indicates whether the view is temporarily detached.
1854      *
1855      * @hide
1856      */
1857     static final int PFLAG_CANCEL_NEXT_UP_EVENT        = 0x04000000;
1858
1859     /**
1860      * Indicates that we should awaken scroll bars once attached
1861      *
1862      * PLEASE NOTE: This flag is now unused as we now send onVisibilityChanged
1863      * during window attachment and it is no longer needed. Feel free to repurpose it.
1864      *
1865      * @hide
1866      */
1867     private static final int PFLAG_AWAKEN_SCROLL_BARS_ON_ATTACH = 0x08000000;
1868
1869     /**
1870      * Indicates that the view has received HOVER_ENTER.  Cleared on HOVER_EXIT.
1871      * @hide
1872      */
1873     private static final int PFLAG_HOVERED             = 0x10000000;
1874
1875     /**
1876      * no longer needed, should be reused
1877      */
1878     private static final int PFLAG_DOES_NOTHING_REUSE_PLEASE = 0x20000000;
1879
1880     /** {@hide} */
1881     static final int PFLAG_ACTIVATED                   = 0x40000000;
1882
1883     /**
1884      * Indicates that this view was specifically invalidated, not just dirtied because some
1885      * child view was invalidated. The flag is used to determine when we need to recreate
1886      * a view's display list (as opposed to just returning a reference to its existing
1887      * display list).
1888      *
1889      * @hide
1890      */
1891     static final int PFLAG_INVALIDATED                 = 0x80000000;
1892
1893     /**
1894      * Masks for mPrivateFlags2, as generated by dumpFlags():
1895      *
1896      * |-------|-------|-------|-------|
1897      *                                 1 PFLAG2_DRAG_CAN_ACCEPT
1898      *                                1  PFLAG2_DRAG_HOVERED
1899      *                              11   PFLAG2_LAYOUT_DIRECTION_MASK
1900      *                             1     PFLAG2_LAYOUT_DIRECTION_RESOLVED_RTL
1901      *                            1      PFLAG2_LAYOUT_DIRECTION_RESOLVED
1902      *                            11     PFLAG2_LAYOUT_DIRECTION_RESOLVED_MASK
1903      *                           1       PFLAG2_TEXT_DIRECTION_FLAGS[1]
1904      *                          1        PFLAG2_TEXT_DIRECTION_FLAGS[2]
1905      *                          11       PFLAG2_TEXT_DIRECTION_FLAGS[3]
1906      *                         1         PFLAG2_TEXT_DIRECTION_FLAGS[4]
1907      *                         1 1       PFLAG2_TEXT_DIRECTION_FLAGS[5]
1908      *                         11        PFLAG2_TEXT_DIRECTION_FLAGS[6]
1909      *                         111       PFLAG2_TEXT_DIRECTION_FLAGS[7]
1910      *                         111       PFLAG2_TEXT_DIRECTION_MASK
1911      *                        1          PFLAG2_TEXT_DIRECTION_RESOLVED
1912      *                       1           PFLAG2_TEXT_DIRECTION_RESOLVED_DEFAULT
1913      *                     111           PFLAG2_TEXT_DIRECTION_RESOLVED_MASK
1914      *                    1              PFLAG2_TEXT_ALIGNMENT_FLAGS[1]
1915      *                   1               PFLAG2_TEXT_ALIGNMENT_FLAGS[2]
1916      *                   11              PFLAG2_TEXT_ALIGNMENT_FLAGS[3]
1917      *                  1                PFLAG2_TEXT_ALIGNMENT_FLAGS[4]
1918      *                  1 1              PFLAG2_TEXT_ALIGNMENT_FLAGS[5]
1919      *                  11               PFLAG2_TEXT_ALIGNMENT_FLAGS[6]
1920      *                  111              PFLAG2_TEXT_ALIGNMENT_MASK
1921      *                 1                 PFLAG2_TEXT_ALIGNMENT_RESOLVED
1922      *                1                  PFLAG2_TEXT_ALIGNMENT_RESOLVED_DEFAULT
1923      *              111                  PFLAG2_TEXT_ALIGNMENT_RESOLVED_MASK
1924      *           111                     PFLAG2_IMPORTANT_FOR_ACCESSIBILITY_MASK
1925      *         11                        PFLAG2_ACCESSIBILITY_LIVE_REGION_MASK
1926      *       1                           PFLAG2_ACCESSIBILITY_FOCUSED
1927      *      1                            PFLAG2_SUBTREE_ACCESSIBILITY_STATE_CHANGED
1928      *     1                             PFLAG2_VIEW_QUICK_REJECTED
1929      *    1                              PFLAG2_PADDING_RESOLVED
1930      *   1                               PFLAG2_DRAWABLE_RESOLVED
1931      *  1                                PFLAG2_HAS_TRANSIENT_STATE
1932      * |-------|-------|-------|-------|
1933      */
1934
1935     /**
1936      * Indicates that this view has reported that it can accept the current drag's content.
1937      * Cleared when the drag operation concludes.
1938      * @hide
1939      */
1940     static final int PFLAG2_DRAG_CAN_ACCEPT            = 0x00000001;
1941
1942     /**
1943      * Indicates that this view is currently directly under the drag location in a
1944      * drag-and-drop operation involving content that it can accept.  Cleared when
1945      * the drag exits the view, or when the drag operation concludes.
1946      * @hide
1947      */
1948     static final int PFLAG2_DRAG_HOVERED               = 0x00000002;
1949
1950     /** @hide */
1951     @IntDef({
1952         LAYOUT_DIRECTION_LTR,
1953         LAYOUT_DIRECTION_RTL,
1954         LAYOUT_DIRECTION_INHERIT,
1955         LAYOUT_DIRECTION_LOCALE
1956     })
1957     @Retention(RetentionPolicy.SOURCE)
1958     // Not called LayoutDirection to avoid conflict with android.util.LayoutDirection
1959     public @interface LayoutDir {}
1960
1961     /** @hide */
1962     @IntDef({
1963         LAYOUT_DIRECTION_LTR,
1964         LAYOUT_DIRECTION_RTL
1965     })
1966     @Retention(RetentionPolicy.SOURCE)
1967     public @interface ResolvedLayoutDir {}
1968
1969     /**
1970      * A flag to indicate that the layout direction of this view has not been defined yet.
1971      * @hide
1972      */
1973     public static final int LAYOUT_DIRECTION_UNDEFINED = LayoutDirection.UNDEFINED;
1974
1975     /**
1976      * Horizontal layout direction of this view is from Left to Right.
1977      * Use with {@link #setLayoutDirection}.
1978      */
1979     public static final int LAYOUT_DIRECTION_LTR = LayoutDirection.LTR;
1980
1981     /**
1982      * Horizontal layout direction of this view is from Right to Left.
1983      * Use with {@link #setLayoutDirection}.
1984      */
1985     public static final int LAYOUT_DIRECTION_RTL = LayoutDirection.RTL;
1986
1987     /**
1988      * Horizontal layout direction of this view is inherited from its parent.
1989      * Use with {@link #setLayoutDirection}.
1990      */
1991     public static final int LAYOUT_DIRECTION_INHERIT = LayoutDirection.INHERIT;
1992
1993     /**
1994      * Horizontal layout direction of this view is from deduced from the default language
1995      * script for the locale. Use with {@link #setLayoutDirection}.
1996      */
1997     public static final int LAYOUT_DIRECTION_LOCALE = LayoutDirection.LOCALE;
1998
1999     /**
2000      * Bit shift to get the horizontal layout direction. (bits after DRAG_HOVERED)
2001      * @hide
2002      */
2003     static final int PFLAG2_LAYOUT_DIRECTION_MASK_SHIFT = 2;
2004
2005     /**
2006      * Mask for use with private flags indicating bits used for horizontal layout direction.
2007      * @hide
2008      */
2009     static final int PFLAG2_LAYOUT_DIRECTION_MASK = 0x00000003 << PFLAG2_LAYOUT_DIRECTION_MASK_SHIFT;
2010
2011     /**
2012      * Indicates whether the view horizontal layout direction has been resolved and drawn to the
2013      * right-to-left direction.
2014      * @hide
2015      */
2016     static final int PFLAG2_LAYOUT_DIRECTION_RESOLVED_RTL = 4 << PFLAG2_LAYOUT_DIRECTION_MASK_SHIFT;
2017
2018     /**
2019      * Indicates whether the view horizontal layout direction has been resolved.
2020      * @hide
2021      */
2022     static final int PFLAG2_LAYOUT_DIRECTION_RESOLVED = 8 << PFLAG2_LAYOUT_DIRECTION_MASK_SHIFT;
2023
2024     /**
2025      * Mask for use with private flags indicating bits used for resolved horizontal layout direction.
2026      * @hide
2027      */
2028     static final int PFLAG2_LAYOUT_DIRECTION_RESOLVED_MASK = 0x0000000C
2029             << PFLAG2_LAYOUT_DIRECTION_MASK_SHIFT;
2030
2031     /*
2032      * Array of horizontal layout direction flags for mapping attribute "layoutDirection" to correct
2033      * flag value.
2034      * @hide
2035      */
2036     private static final int[] LAYOUT_DIRECTION_FLAGS = {
2037             LAYOUT_DIRECTION_LTR,
2038             LAYOUT_DIRECTION_RTL,
2039             LAYOUT_DIRECTION_INHERIT,
2040             LAYOUT_DIRECTION_LOCALE
2041     };
2042
2043     /**
2044      * Default horizontal layout direction.
2045      */
2046     private static final int LAYOUT_DIRECTION_DEFAULT = LAYOUT_DIRECTION_INHERIT;
2047
2048     /**
2049      * Default horizontal layout direction.
2050      * @hide
2051      */
2052     static final int LAYOUT_DIRECTION_RESOLVED_DEFAULT = LAYOUT_DIRECTION_LTR;
2053
2054     /**
2055      * Text direction is inherited through {@link ViewGroup}
2056      */
2057     public static final int TEXT_DIRECTION_INHERIT = 0;
2058
2059     /**
2060      * Text direction is using "first strong algorithm". The first strong directional character
2061      * determines the paragraph direction. If there is no strong directional character, the
2062      * paragraph direction is the view's resolved layout direction.
2063      */
2064     public static final int TEXT_DIRECTION_FIRST_STRONG = 1;
2065
2066     /**
2067      * Text direction is using "any-RTL" algorithm. The paragraph direction is RTL if it contains
2068      * any strong RTL character, otherwise it is LTR if it contains any strong LTR characters.
2069      * If there are neither, the paragraph direction is the view's resolved layout direction.
2070      */
2071     public static final int TEXT_DIRECTION_ANY_RTL = 2;
2072
2073     /**
2074      * Text direction is forced to LTR.
2075      */
2076     public static final int TEXT_DIRECTION_LTR = 3;
2077
2078     /**
2079      * Text direction is forced to RTL.
2080      */
2081     public static final int TEXT_DIRECTION_RTL = 4;
2082
2083     /**
2084      * Text direction is coming from the system Locale.
2085      */
2086     public static final int TEXT_DIRECTION_LOCALE = 5;
2087
2088     /**
2089      * Text direction is using "first strong algorithm". The first strong directional character
2090      * determines the paragraph direction. If there is no strong directional character, the
2091      * paragraph direction is LTR.
2092      */
2093     public static final int TEXT_DIRECTION_FIRST_STRONG_LTR = 6;
2094
2095     /**
2096      * Text direction is using "first strong algorithm". The first strong directional character
2097      * determines the paragraph direction. If there is no strong directional character, the
2098      * paragraph direction is RTL.
2099      */
2100     public static final int TEXT_DIRECTION_FIRST_STRONG_RTL = 7;
2101
2102     /**
2103      * Default text direction is inherited
2104      */
2105     private static final int TEXT_DIRECTION_DEFAULT = TEXT_DIRECTION_INHERIT;
2106
2107     /**
2108      * Default resolved text direction
2109      * @hide
2110      */
2111     static final int TEXT_DIRECTION_RESOLVED_DEFAULT = TEXT_DIRECTION_FIRST_STRONG;
2112
2113     /**
2114      * Bit shift to get the horizontal layout direction. (bits after LAYOUT_DIRECTION_RESOLVED)
2115      * @hide
2116      */
2117     static final int PFLAG2_TEXT_DIRECTION_MASK_SHIFT = 6;
2118
2119     /**
2120      * Mask for use with private flags indicating bits used for text direction.
2121      * @hide
2122      */
2123     static final int PFLAG2_TEXT_DIRECTION_MASK = 0x00000007
2124             << PFLAG2_TEXT_DIRECTION_MASK_SHIFT;
2125
2126     /**
2127      * Array of text direction flags for mapping attribute "textDirection" to correct
2128      * flag value.
2129      * @hide
2130      */
2131     private static final int[] PFLAG2_TEXT_DIRECTION_FLAGS = {
2132             TEXT_DIRECTION_INHERIT << PFLAG2_TEXT_DIRECTION_MASK_SHIFT,
2133             TEXT_DIRECTION_FIRST_STRONG << PFLAG2_TEXT_DIRECTION_MASK_SHIFT,
2134             TEXT_DIRECTION_ANY_RTL << PFLAG2_TEXT_DIRECTION_MASK_SHIFT,
2135             TEXT_DIRECTION_LTR << PFLAG2_TEXT_DIRECTION_MASK_SHIFT,
2136             TEXT_DIRECTION_RTL << PFLAG2_TEXT_DIRECTION_MASK_SHIFT,
2137             TEXT_DIRECTION_LOCALE << PFLAG2_TEXT_DIRECTION_MASK_SHIFT,
2138             TEXT_DIRECTION_FIRST_STRONG_LTR << PFLAG2_TEXT_DIRECTION_MASK_SHIFT,
2139             TEXT_DIRECTION_FIRST_STRONG_RTL << PFLAG2_TEXT_DIRECTION_MASK_SHIFT
2140     };
2141
2142     /**
2143      * Indicates whether the view text direction has been resolved.
2144      * @hide
2145      */
2146     static final int PFLAG2_TEXT_DIRECTION_RESOLVED = 0x00000008
2147             << PFLAG2_TEXT_DIRECTION_MASK_SHIFT;
2148
2149     /**
2150      * Bit shift to get the horizontal layout direction. (bits after DRAG_HOVERED)
2151      * @hide
2152      */
2153     static final int PFLAG2_TEXT_DIRECTION_RESOLVED_MASK_SHIFT = 10;
2154
2155     /**
2156      * Mask for use with private flags indicating bits used for resolved text direction.
2157      * @hide
2158      */
2159     static final int PFLAG2_TEXT_DIRECTION_RESOLVED_MASK = 0x00000007
2160             << PFLAG2_TEXT_DIRECTION_RESOLVED_MASK_SHIFT;
2161
2162     /**
2163      * Indicates whether the view text direction has been resolved to the "first strong" heuristic.
2164      * @hide
2165      */
2166     static final int PFLAG2_TEXT_DIRECTION_RESOLVED_DEFAULT =
2167             TEXT_DIRECTION_RESOLVED_DEFAULT << PFLAG2_TEXT_DIRECTION_RESOLVED_MASK_SHIFT;
2168
2169     /** @hide */
2170     @IntDef({
2171         TEXT_ALIGNMENT_INHERIT,
2172         TEXT_ALIGNMENT_GRAVITY,
2173         TEXT_ALIGNMENT_CENTER,
2174         TEXT_ALIGNMENT_TEXT_START,
2175         TEXT_ALIGNMENT_TEXT_END,
2176         TEXT_ALIGNMENT_VIEW_START,
2177         TEXT_ALIGNMENT_VIEW_END
2178     })
2179     @Retention(RetentionPolicy.SOURCE)
2180     public @interface TextAlignment {}
2181
2182     /**
2183      * Default text alignment. The text alignment of this View is inherited from its parent.
2184      * Use with {@link #setTextAlignment(int)}
2185      */
2186     public static final int TEXT_ALIGNMENT_INHERIT = 0;
2187
2188     /**
2189      * Default for the root view. The gravity determines the text alignment, ALIGN_NORMAL,
2190      * ALIGN_CENTER, or ALIGN_OPPOSITE, which are relative to each paragraph’s text direction.
2191      *
2192      * Use with {@link #setTextAlignment(int)}
2193      */
2194     public static final int TEXT_ALIGNMENT_GRAVITY = 1;
2195
2196     /**
2197      * Align to the start of the paragraph, e.g. ALIGN_NORMAL.
2198      *
2199      * Use with {@link #setTextAlignment(int)}
2200      */
2201     public static final int TEXT_ALIGNMENT_TEXT_START = 2;
2202
2203     /**
2204      * Align to the end of the paragraph, e.g. ALIGN_OPPOSITE.
2205      *
2206      * Use with {@link #setTextAlignment(int)}
2207      */
2208     public static final int TEXT_ALIGNMENT_TEXT_END = 3;
2209
2210     /**
2211      * Center the paragraph, e.g. ALIGN_CENTER.
2212      *
2213      * Use with {@link #setTextAlignment(int)}
2214      */
2215     public static final int TEXT_ALIGNMENT_CENTER = 4;
2216
2217     /**
2218      * Align to the start of the view, which is ALIGN_LEFT if the view’s resolved
2219      * layoutDirection is LTR, and ALIGN_RIGHT otherwise.
2220      *
2221      * Use with {@link #setTextAlignment(int)}
2222      */
2223     public static final int TEXT_ALIGNMENT_VIEW_START = 5;
2224
2225     /**
2226      * Align to the end of the view, which is ALIGN_RIGHT if the view’s resolved
2227      * layoutDirection is LTR, and ALIGN_LEFT otherwise.
2228      *
2229      * Use with {@link #setTextAlignment(int)}
2230      */
2231     public static final int TEXT_ALIGNMENT_VIEW_END = 6;
2232
2233     /**
2234      * Default text alignment is inherited
2235      */
2236     private static final int TEXT_ALIGNMENT_DEFAULT = TEXT_ALIGNMENT_GRAVITY;
2237
2238     /**
2239      * Default resolved text alignment
2240      * @hide
2241      */
2242     static final int TEXT_ALIGNMENT_RESOLVED_DEFAULT = TEXT_ALIGNMENT_GRAVITY;
2243
2244     /**
2245       * Bit shift to get the horizontal layout direction. (bits after DRAG_HOVERED)
2246       * @hide
2247       */
2248     static final int PFLAG2_TEXT_ALIGNMENT_MASK_SHIFT = 13;
2249
2250     /**
2251       * Mask for use with private flags indicating bits used for text alignment.
2252       * @hide
2253       */
2254     static final int PFLAG2_TEXT_ALIGNMENT_MASK = 0x00000007 << PFLAG2_TEXT_ALIGNMENT_MASK_SHIFT;
2255
2256     /**
2257      * Array of text direction flags for mapping attribute "textAlignment" to correct
2258      * flag value.
2259      * @hide
2260      */
2261     private static final int[] PFLAG2_TEXT_ALIGNMENT_FLAGS = {
2262             TEXT_ALIGNMENT_INHERIT << PFLAG2_TEXT_ALIGNMENT_MASK_SHIFT,
2263             TEXT_ALIGNMENT_GRAVITY << PFLAG2_TEXT_ALIGNMENT_MASK_SHIFT,
2264             TEXT_ALIGNMENT_TEXT_START << PFLAG2_TEXT_ALIGNMENT_MASK_SHIFT,
2265             TEXT_ALIGNMENT_TEXT_END << PFLAG2_TEXT_ALIGNMENT_MASK_SHIFT,
2266             TEXT_ALIGNMENT_CENTER << PFLAG2_TEXT_ALIGNMENT_MASK_SHIFT,
2267             TEXT_ALIGNMENT_VIEW_START << PFLAG2_TEXT_ALIGNMENT_MASK_SHIFT,
2268             TEXT_ALIGNMENT_VIEW_END << PFLAG2_TEXT_ALIGNMENT_MASK_SHIFT
2269     };
2270
2271     /**
2272      * Indicates whether the view text alignment has been resolved.
2273      * @hide
2274      */
2275     static final int PFLAG2_TEXT_ALIGNMENT_RESOLVED = 0x00000008 << PFLAG2_TEXT_ALIGNMENT_MASK_SHIFT;
2276
2277     /**
2278      * Bit shift to get the resolved text alignment.
2279      * @hide
2280      */
2281     static final int PFLAG2_TEXT_ALIGNMENT_RESOLVED_MASK_SHIFT = 17;
2282
2283     /**
2284      * Mask for use with private flags indicating bits used for text alignment.
2285      * @hide
2286      */
2287     static final int PFLAG2_TEXT_ALIGNMENT_RESOLVED_MASK = 0x00000007
2288             << PFLAG2_TEXT_ALIGNMENT_RESOLVED_MASK_SHIFT;
2289
2290     /**
2291      * Indicates whether if the view text alignment has been resolved to gravity
2292      */
2293     private static final int PFLAG2_TEXT_ALIGNMENT_RESOLVED_DEFAULT =
2294             TEXT_ALIGNMENT_RESOLVED_DEFAULT << PFLAG2_TEXT_ALIGNMENT_RESOLVED_MASK_SHIFT;
2295
2296     // Accessiblity constants for mPrivateFlags2
2297
2298     /**
2299      * Shift for the bits in {@link #mPrivateFlags2} related to the
2300      * "importantForAccessibility" attribute.
2301      */
2302     static final int PFLAG2_IMPORTANT_FOR_ACCESSIBILITY_SHIFT = 20;
2303
2304     /**
2305      * Automatically determine whether a view is important for accessibility.
2306      */
2307     public static final int IMPORTANT_FOR_ACCESSIBILITY_AUTO = 0x00000000;
2308
2309     /**
2310      * The view is important for accessibility.
2311      */
2312     public static final int IMPORTANT_FOR_ACCESSIBILITY_YES = 0x00000001;
2313
2314     /**
2315      * The view is not important for accessibility.
2316      */
2317     public static final int IMPORTANT_FOR_ACCESSIBILITY_NO = 0x00000002;
2318
2319     /**
2320      * The view is not important for accessibility, nor are any of its
2321      * descendant views.
2322      */
2323     public static final int IMPORTANT_FOR_ACCESSIBILITY_NO_HIDE_DESCENDANTS = 0x00000004;
2324
2325     /**
2326      * The default whether the view is important for accessibility.
2327      */
2328     static final int IMPORTANT_FOR_ACCESSIBILITY_DEFAULT = IMPORTANT_FOR_ACCESSIBILITY_AUTO;
2329
2330     /**
2331      * Mask for obtainig the bits which specify how to determine
2332      * whether a view is important for accessibility.
2333      */
2334     static final int PFLAG2_IMPORTANT_FOR_ACCESSIBILITY_MASK = (IMPORTANT_FOR_ACCESSIBILITY_AUTO
2335         | IMPORTANT_FOR_ACCESSIBILITY_YES | IMPORTANT_FOR_ACCESSIBILITY_NO
2336         | IMPORTANT_FOR_ACCESSIBILITY_NO_HIDE_DESCENDANTS)
2337         << PFLAG2_IMPORTANT_FOR_ACCESSIBILITY_SHIFT;
2338
2339     /**
2340      * Shift for the bits in {@link #mPrivateFlags2} related to the
2341      * "accessibilityLiveRegion" attribute.
2342      */
2343     static final int PFLAG2_ACCESSIBILITY_LIVE_REGION_SHIFT = 23;
2344
2345     /**
2346      * Live region mode specifying that accessibility services should not
2347      * automatically announce changes to this view. This is the default live
2348      * region mode for most views.
2349      * <p>
2350      * Use with {@link #setAccessibilityLiveRegion(int)}.
2351      */
2352     public static final int ACCESSIBILITY_LIVE_REGION_NONE = 0x00000000;
2353
2354     /**
2355      * Live region mode specifying that accessibility services should announce
2356      * changes to this view.
2357      * <p>
2358      * Use with {@link #setAccessibilityLiveRegion(int)}.
2359      */
2360     public static final int ACCESSIBILITY_LIVE_REGION_POLITE = 0x00000001;
2361
2362     /**
2363      * Live region mode specifying that accessibility services should interrupt
2364      * ongoing speech to immediately announce changes to this view.
2365      * <p>
2366      * Use with {@link #setAccessibilityLiveRegion(int)}.
2367      */
2368     public static final int ACCESSIBILITY_LIVE_REGION_ASSERTIVE = 0x00000002;
2369
2370     /**
2371      * The default whether the view is important for accessibility.
2372      */
2373     static final int ACCESSIBILITY_LIVE_REGION_DEFAULT = ACCESSIBILITY_LIVE_REGION_NONE;
2374
2375     /**
2376      * Mask for obtaining the bits which specify a view's accessibility live
2377      * region mode.
2378      */
2379     static final int PFLAG2_ACCESSIBILITY_LIVE_REGION_MASK = (ACCESSIBILITY_LIVE_REGION_NONE
2380             | ACCESSIBILITY_LIVE_REGION_POLITE | ACCESSIBILITY_LIVE_REGION_ASSERTIVE)
2381             << PFLAG2_ACCESSIBILITY_LIVE_REGION_SHIFT;
2382
2383     /**
2384      * Flag indicating whether a view has accessibility focus.
2385      */
2386     static final int PFLAG2_ACCESSIBILITY_FOCUSED = 0x04000000;
2387
2388     /**
2389      * Flag whether the accessibility state of the subtree rooted at this view changed.
2390      */
2391     static final int PFLAG2_SUBTREE_ACCESSIBILITY_STATE_CHANGED = 0x08000000;
2392
2393     /**
2394      * Flag indicating whether a view failed the quickReject() check in draw(). This condition
2395      * is used to check whether later changes to the view's transform should invalidate the
2396      * view to force the quickReject test to run again.
2397      */
2398     static final int PFLAG2_VIEW_QUICK_REJECTED = 0x10000000;
2399
2400     /**
2401      * Flag indicating that start/end padding has been resolved into left/right padding
2402      * for use in measurement, layout, drawing, etc. This is set by {@link #resolvePadding()}
2403      * and checked by {@link #measure(int, int)} to determine if padding needs to be resolved
2404      * during measurement. In some special cases this is required such as when an adapter-based
2405      * view measures prospective children without attaching them to a window.
2406      */
2407     static final int PFLAG2_PADDING_RESOLVED = 0x20000000;
2408
2409     /**
2410      * Flag indicating that the start/end drawables has been resolved into left/right ones.
2411      */
2412     static final int PFLAG2_DRAWABLE_RESOLVED = 0x40000000;
2413
2414     /**
2415      * Indicates that the view is tracking some sort of transient state
2416      * that the app should not need to be aware of, but that the framework
2417      * should take special care to preserve.
2418      */
2419     static final int PFLAG2_HAS_TRANSIENT_STATE = 0x80000000;
2420
2421     /**
2422      * Group of bits indicating that RTL properties resolution is done.
2423      */
2424     static final int ALL_RTL_PROPERTIES_RESOLVED = PFLAG2_LAYOUT_DIRECTION_RESOLVED |
2425             PFLAG2_TEXT_DIRECTION_RESOLVED |
2426             PFLAG2_TEXT_ALIGNMENT_RESOLVED |
2427             PFLAG2_PADDING_RESOLVED |
2428             PFLAG2_DRAWABLE_RESOLVED;
2429
2430     // There are a couple of flags left in mPrivateFlags2
2431
2432     /* End of masks for mPrivateFlags2 */
2433
2434     /**
2435      * Masks for mPrivateFlags3, as generated by dumpFlags():
2436      *
2437      * |-------|-------|-------|-------|
2438      *                                 1 PFLAG3_VIEW_IS_ANIMATING_TRANSFORM
2439      *                                1  PFLAG3_VIEW_IS_ANIMATING_ALPHA
2440      *                               1   PFLAG3_IS_LAID_OUT
2441      *                              1    PFLAG3_MEASURE_NEEDED_BEFORE_LAYOUT
2442      *                             1     PFLAG3_CALLED_SUPER
2443      *                            1      PFLAG3_APPLYING_INSETS
2444      *                           1       PFLAG3_FITTING_SYSTEM_WINDOWS
2445      *                          1        PFLAG3_NESTED_SCROLLING_ENABLED
2446      *                         1         PFLAG3_SCROLL_INDICATOR_TOP
2447      *                        1          PFLAG3_SCROLL_INDICATOR_BOTTOM
2448      *                       1           PFLAG3_SCROLL_INDICATOR_LEFT
2449      *                      1            PFLAG3_SCROLL_INDICATOR_RIGHT
2450      *                     1             PFLAG3_SCROLL_INDICATOR_START
2451      *                    1              PFLAG3_SCROLL_INDICATOR_END
2452      *                   1               PFLAG3_ASSIST_BLOCKED
2453      *                  1                PFLAG3_POINTER_ICON_NULL
2454      *                 1                 PFLAG3_POINTER_ICON_VALUE_START
2455      *           11111111                PFLAG3_POINTER_ICON_MASK
2456      *          1                        PFLAG3_OVERLAPPING_RENDERING_FORCED_VALUE
2457      *         1                         PFLAG3_HAS_OVERLAPPING_RENDERING_FORCED
2458      *        1                          PFLAG3_TEMPORARY_DETACH
2459      *       1                           PFLAG3_NO_REVEAL_ON_FOCUS
2460      * |-------|-------|-------|-------|
2461      */
2462
2463     /**
2464      * Flag indicating that view has a transform animation set on it. This is used to track whether
2465      * an animation is cleared between successive frames, in order to tell the associated
2466      * DisplayList to clear its animation matrix.
2467      */
2468     static final int PFLAG3_VIEW_IS_ANIMATING_TRANSFORM = 0x1;
2469
2470     /**
2471      * Flag indicating that view has an alpha animation set on it. This is used to track whether an
2472      * animation is cleared between successive frames, in order to tell the associated
2473      * DisplayList to restore its alpha value.
2474      */
2475     static final int PFLAG3_VIEW_IS_ANIMATING_ALPHA = 0x2;
2476
2477     /**
2478      * Flag indicating that the view has been through at least one layout since it
2479      * was last attached to a window.
2480      */
2481     static final int PFLAG3_IS_LAID_OUT = 0x4;
2482
2483     /**
2484      * Flag indicating that a call to measure() was skipped and should be done
2485      * instead when layout() is invoked.
2486      */
2487     static final int PFLAG3_MEASURE_NEEDED_BEFORE_LAYOUT = 0x8;
2488
2489     /**
2490      * Flag indicating that an overridden method correctly called down to
2491      * the superclass implementation as required by the API spec.
2492      */
2493     static final int PFLAG3_CALLED_SUPER = 0x10;
2494
2495     /**
2496      * Flag indicating that we're in the process of applying window insets.
2497      */
2498     static final int PFLAG3_APPLYING_INSETS = 0x20;
2499
2500     /**
2501      * Flag indicating that we're in the process of fitting system windows using the old method.
2502      */
2503     static final int PFLAG3_FITTING_SYSTEM_WINDOWS = 0x40;
2504
2505     /**
2506      * Flag indicating that nested scrolling is enabled for this view.
2507      * The view will optionally cooperate with views up its parent chain to allow for
2508      * integrated nested scrolling along the same axis.
2509      */
2510     static final int PFLAG3_NESTED_SCROLLING_ENABLED = 0x80;
2511
2512     /**
2513      * Flag indicating that the bottom scroll indicator should be displayed
2514      * when this view can scroll up.
2515      */
2516     static final int PFLAG3_SCROLL_INDICATOR_TOP = 0x0100;
2517
2518     /**
2519      * Flag indicating that the bottom scroll indicator should be displayed
2520      * when this view can scroll down.
2521      */
2522     static final int PFLAG3_SCROLL_INDICATOR_BOTTOM = 0x0200;
2523
2524     /**
2525      * Flag indicating that the left scroll indicator should be displayed
2526      * when this view can scroll left.
2527      */
2528     static final int PFLAG3_SCROLL_INDICATOR_LEFT = 0x0400;
2529
2530     /**
2531      * Flag indicating that the right scroll indicator should be displayed
2532      * when this view can scroll right.
2533      */
2534     static final int PFLAG3_SCROLL_INDICATOR_RIGHT = 0x0800;
2535
2536     /**
2537      * Flag indicating that the start scroll indicator should be displayed
2538      * when this view can scroll in the start direction.
2539      */
2540     static final int PFLAG3_SCROLL_INDICATOR_START = 0x1000;
2541
2542     /**
2543      * Flag indicating that the end scroll indicator should be displayed
2544      * when this view can scroll in the end direction.
2545      */
2546     static final int PFLAG3_SCROLL_INDICATOR_END = 0x2000;
2547
2548     static final int DRAG_MASK = PFLAG2_DRAG_CAN_ACCEPT | PFLAG2_DRAG_HOVERED;
2549
2550     static final int SCROLL_INDICATORS_NONE = 0x0000;
2551
2552     /**
2553      * Mask for use with setFlags indicating bits used for indicating which
2554      * scroll indicators are enabled.
2555      */
2556     static final int SCROLL_INDICATORS_PFLAG3_MASK = PFLAG3_SCROLL_INDICATOR_TOP
2557             | PFLAG3_SCROLL_INDICATOR_BOTTOM | PFLAG3_SCROLL_INDICATOR_LEFT
2558             | PFLAG3_SCROLL_INDICATOR_RIGHT | PFLAG3_SCROLL_INDICATOR_START
2559             | PFLAG3_SCROLL_INDICATOR_END;
2560
2561     /**
2562      * Left-shift required to translate between public scroll indicator flags
2563      * and internal PFLAGS3 flags. When used as a right-shift, translates
2564      * PFLAGS3 flags to public flags.
2565      */
2566     static final int SCROLL_INDICATORS_TO_PFLAGS3_LSHIFT = 8;
2567
2568     /** @hide */
2569     @Retention(RetentionPolicy.SOURCE)
2570     @IntDef(flag = true,
2571             value = {
2572                     SCROLL_INDICATOR_TOP,
2573                     SCROLL_INDICATOR_BOTTOM,
2574                     SCROLL_INDICATOR_LEFT,
2575                     SCROLL_INDICATOR_RIGHT,
2576                     SCROLL_INDICATOR_START,
2577                     SCROLL_INDICATOR_END,
2578             })
2579     public @interface ScrollIndicators {}
2580
2581     /**
2582      * Scroll indicator direction for the top edge of the view.
2583      *
2584      * @see #setScrollIndicators(int)
2585      * @see #setScrollIndicators(int, int)
2586      * @see #getScrollIndicators()
2587      */
2588     public static final int SCROLL_INDICATOR_TOP =
2589             PFLAG3_SCROLL_INDICATOR_TOP >> SCROLL_INDICATORS_TO_PFLAGS3_LSHIFT;
2590
2591     /**
2592      * Scroll indicator direction for the bottom edge of the view.
2593      *
2594      * @see #setScrollIndicators(int)
2595      * @see #setScrollIndicators(int, int)
2596      * @see #getScrollIndicators()
2597      */
2598     public static final int SCROLL_INDICATOR_BOTTOM =
2599             PFLAG3_SCROLL_INDICATOR_BOTTOM >> SCROLL_INDICATORS_TO_PFLAGS3_LSHIFT;
2600
2601     /**
2602      * Scroll indicator direction for the left edge of the view.
2603      *
2604      * @see #setScrollIndicators(int)
2605      * @see #setScrollIndicators(int, int)
2606      * @see #getScrollIndicators()
2607      */
2608     public static final int SCROLL_INDICATOR_LEFT =
2609             PFLAG3_SCROLL_INDICATOR_LEFT >> SCROLL_INDICATORS_TO_PFLAGS3_LSHIFT;
2610
2611     /**
2612      * Scroll indicator direction for the right edge of the view.
2613      *
2614      * @see #setScrollIndicators(int)
2615      * @see #setScrollIndicators(int, int)
2616      * @see #getScrollIndicators()
2617      */
2618     public static final int SCROLL_INDICATOR_RIGHT =
2619             PFLAG3_SCROLL_INDICATOR_RIGHT >> SCROLL_INDICATORS_TO_PFLAGS3_LSHIFT;
2620
2621     /**
2622      * Scroll indicator direction for the starting edge of the view.
2623      * <p>
2624      * Resolved according to the view's layout direction, see
2625      * {@link #getLayoutDirection()} for more information.
2626      *
2627      * @see #setScrollIndicators(int)
2628      * @see #setScrollIndicators(int, int)
2629      * @see #getScrollIndicators()
2630      */
2631     public static final int SCROLL_INDICATOR_START =
2632             PFLAG3_SCROLL_INDICATOR_START >> SCROLL_INDICATORS_TO_PFLAGS3_LSHIFT;
2633
2634     /**
2635      * Scroll indicator direction for the ending edge of the view.
2636      * <p>
2637      * Resolved according to the view's layout direction, see
2638      * {@link #getLayoutDirection()} for more information.
2639      *
2640      * @see #setScrollIndicators(int)
2641      * @see #setScrollIndicators(int, int)
2642      * @see #getScrollIndicators()
2643      */
2644     public static final int SCROLL_INDICATOR_END =
2645             PFLAG3_SCROLL_INDICATOR_END >> SCROLL_INDICATORS_TO_PFLAGS3_LSHIFT;
2646
2647     /**
2648      * <p>Indicates that we are allowing {@link ViewStructure} to traverse
2649      * into this view.<p>
2650      */
2651     static final int PFLAG3_ASSIST_BLOCKED = 0x4000;
2652
2653     /**
2654      * The mask for use with private flags indicating bits used for pointer icon shapes.
2655      */
2656     static final int PFLAG3_POINTER_ICON_MASK = 0x7f8000;
2657
2658     /**
2659      * Left-shift used for pointer icon shape values in private flags.
2660      */
2661     static final int PFLAG3_POINTER_ICON_LSHIFT = 15;
2662
2663     /**
2664      * Value indicating no specific pointer icons.
2665      */
2666     private static final int PFLAG3_POINTER_ICON_NOT_SPECIFIED = 0 << PFLAG3_POINTER_ICON_LSHIFT;
2667
2668     /**
2669      * Value indicating {@link PointerIcon.TYPE_NULL}.
2670      */
2671     private static final int PFLAG3_POINTER_ICON_NULL = 1 << PFLAG3_POINTER_ICON_LSHIFT;
2672
2673     /**
2674      * The base value for other pointer icon shapes.
2675      */
2676     private static final int PFLAG3_POINTER_ICON_VALUE_START = 2 << PFLAG3_POINTER_ICON_LSHIFT;
2677
2678     /**
2679      * Whether this view has rendered elements that overlap (see {@link
2680      * #hasOverlappingRendering()}, {@link #forceHasOverlappingRendering(boolean)}, and
2681      * {@link #getHasOverlappingRendering()} ). The value in this bit is only valid when
2682      * PFLAG3_HAS_OVERLAPPING_RENDERING_FORCED has been set. Otherwise, the value is
2683      * determined by whatever {@link #hasOverlappingRendering()} returns.
2684      */
2685     private static final int PFLAG3_OVERLAPPING_RENDERING_FORCED_VALUE = 0x800000;
2686
2687     /**
2688      * Whether {@link #forceHasOverlappingRendering(boolean)} has been called. When true, value
2689      * in PFLAG3_OVERLAPPING_RENDERING_FORCED_VALUE is valid.
2690      */
2691     private static final int PFLAG3_HAS_OVERLAPPING_RENDERING_FORCED = 0x1000000;
2692
2693     /**
2694      * Flag indicating that the view is temporarily detached from the parent view.
2695      *
2696      * @see #onStartTemporaryDetach()
2697      * @see #onFinishTemporaryDetach()
2698      */
2699     static final int PFLAG3_TEMPORARY_DETACH = 0x2000000;
2700
2701     /**
2702      * Flag indicating that the view does not wish to be revealed within its parent
2703      * hierarchy when it gains focus. Expressed in the negative since the historical
2704      * default behavior is to reveal on focus; this flag suppresses that behavior.
2705      *
2706      * @see #setRevealOnFocusHint(boolean)
2707      * @see #getRevealOnFocusHint()
2708      */
2709     private static final int PFLAG3_NO_REVEAL_ON_FOCUS = 0x4000000;
2710
2711     /* End of masks for mPrivateFlags3 */
2712
2713     /**
2714      * Always allow a user to over-scroll this view, provided it is a
2715      * view that can scroll.
2716      *
2717      * @see #getOverScrollMode()
2718      * @see #setOverScrollMode(int)
2719      */
2720     public static final int OVER_SCROLL_ALWAYS = 0;
2721
2722     /**
2723      * Allow a user to over-scroll this view only if the content is large
2724      * enough to meaningfully scroll, provided it is a view that can scroll.
2725      *
2726      * @see #getOverScrollMode()
2727      * @see #setOverScrollMode(int)
2728      */
2729     public static final int OVER_SCROLL_IF_CONTENT_SCROLLS = 1;
2730
2731     /**
2732      * Never allow a user to over-scroll this view.
2733      *
2734      * @see #getOverScrollMode()
2735      * @see #setOverScrollMode(int)
2736      */
2737     public static final int OVER_SCROLL_NEVER = 2;
2738
2739     /**
2740      * Special constant for {@link #setSystemUiVisibility(int)}: View has
2741      * requested the system UI (status bar) to be visible (the default).
2742      *
2743      * @see #setSystemUiVisibility(int)
2744      */
2745     public static final int SYSTEM_UI_FLAG_VISIBLE = 0;
2746
2747     /**
2748      * Flag for {@link #setSystemUiVisibility(int)}: View has requested the
2749      * system UI to enter an unobtrusive "low profile" mode.
2750      *
2751      * <p>This is for use in games, book readers, video players, or any other
2752      * "immersive" application where the usual system chrome is deemed too distracting.
2753      *
2754      * <p>In low profile mode, the status bar and/or navigation icons may dim.
2755      *
2756      * @see #setSystemUiVisibility(int)
2757      */
2758     public static final int SYSTEM_UI_FLAG_LOW_PROFILE = 0x00000001;
2759
2760     /**
2761      * Flag for {@link #setSystemUiVisibility(int)}: View has requested that the
2762      * system navigation be temporarily hidden.
2763      *
2764      * <p>This is an even less obtrusive state than that called for by
2765      * {@link #SYSTEM_UI_FLAG_LOW_PROFILE}; on devices that draw essential navigation controls
2766      * (Home, Back, and the like) on screen, <code>SYSTEM_UI_FLAG_HIDE_NAVIGATION</code> will cause
2767      * those to disappear. This is useful (in conjunction with the
2768      * {@link android.view.WindowManager.LayoutParams#FLAG_FULLSCREEN FLAG_FULLSCREEN} and
2769      * {@link android.view.WindowManager.LayoutParams#FLAG_LAYOUT_IN_SCREEN FLAG_LAYOUT_IN_SCREEN}
2770      * window flags) for displaying content using every last pixel on the display.
2771      *
2772      * <p>There is a limitation: because navigation controls are so important, the least user
2773      * interaction will cause them to reappear immediately.  When this happens, both
2774      * this flag and {@link #SYSTEM_UI_FLAG_FULLSCREEN} will be cleared automatically,
2775      * so that both elements reappear at the same time.
2776      *
2777      * @see #setSystemUiVisibility(int)
2778      */
2779     public static final int SYSTEM_UI_FLAG_HIDE_NAVIGATION = 0x00000002;
2780
2781     /**
2782      * Flag for {@link #setSystemUiVisibility(int)}: View has requested to go
2783      * into the normal fullscreen mode so that its content can take over the screen
2784      * while still allowing the user to interact with the application.
2785      *
2786      * <p>This has the same visual effect as
2787      * {@link android.view.WindowManager.LayoutParams#FLAG_FULLSCREEN
2788      * WindowManager.LayoutParams.FLAG_FULLSCREEN},
2789      * meaning that non-critical screen decorations (such as the status bar) will be
2790      * hidden while the user is in the View's window, focusing the experience on
2791      * that content.  Unlike the window flag, if you are using ActionBar in
2792      * overlay mode with {@link Window#FEATURE_ACTION_BAR_OVERLAY
2793      * Window.FEATURE_ACTION_BAR_OVERLAY}, then enabling this flag will also
2794      * hide the action bar.
2795      *
2796      * <p>This approach to going fullscreen is best used over the window flag when
2797      * it is a transient state -- that is, the application does this at certain
2798      * points in its user interaction where it wants to allow the user to focus
2799      * on content, but not as a continuous state.  For situations where the application
2800      * would like to simply stay full screen the entire time (such as a game that
2801      * wants to take over the screen), the
2802      * {@link android.view.WindowManager.LayoutParams#FLAG_FULLSCREEN window flag}
2803      * is usually a better approach.  The state set here will be removed by the system
2804      * in various situations (such as the user moving to another application) like
2805      * the other system UI states.
2806      *
2807      * <p>When using this flag, the application should provide some easy facility
2808      * for the user to go out of it.  A common example would be in an e-book
2809      * reader, where tapping on the screen brings back whatever screen and UI
2810      * decorations that had been hidden while the user was immersed in reading
2811      * the book.
2812      *
2813      * @see #setSystemUiVisibility(int)
2814      */
2815     public static final int SYSTEM_UI_FLAG_FULLSCREEN = 0x00000004;
2816
2817     /**
2818      * Flag for {@link #setSystemUiVisibility(int)}: When using other layout
2819      * flags, we would like a stable view of the content insets given to
2820      * {@link #fitSystemWindows(Rect)}.  This means that the insets seen there
2821      * will always represent the worst case that the application can expect
2822      * as a continuous state.  In the stock Android UI this is the space for
2823      * the system bar, nav bar, and status bar, but not more transient elements
2824      * such as an input method.
2825      *
2826      * The stable layout your UI sees is based on the system UI modes you can
2827      * switch to.  That is, if you specify {@link #SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN}
2828      * then you will get a stable layout for changes of the
2829      * {@link #SYSTEM_UI_FLAG_FULLSCREEN} mode; if you specify
2830      * {@link #SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN} and
2831      * {@link #SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION}, then you can transition
2832      * to {@link #SYSTEM_UI_FLAG_FULLSCREEN} and {@link #SYSTEM_UI_FLAG_HIDE_NAVIGATION}
2833      * with a stable layout.  (Note that you should avoid using
2834      * {@link #SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION} by itself.)
2835      *
2836      * If you have set the window flag {@link WindowManager.LayoutParams#FLAG_FULLSCREEN}
2837      * to hide the status bar (instead of using {@link #SYSTEM_UI_FLAG_FULLSCREEN}),
2838      * then a hidden status bar will be considered a "stable" state for purposes
2839      * here.  This allows your UI to continually hide the status bar, while still
2840      * using the system UI flags to hide the action bar while still retaining
2841      * a stable layout.  Note that changing the window fullscreen flag will never
2842      * provide a stable layout for a clean transition.
2843      *
2844      * <p>If you are using ActionBar in
2845      * overlay mode with {@link Window#FEATURE_ACTION_BAR_OVERLAY
2846      * Window.FEATURE_ACTION_BAR_OVERLAY}, this flag will also impact the
2847      * insets it adds to those given to the application.
2848      */
2849     public static final int SYSTEM_UI_FLAG_LAYOUT_STABLE = 0x00000100;
2850
2851     /**
2852      * Flag for {@link #setSystemUiVisibility(int)}: View would like its window
2853      * to be laid out as if it has requested
2854      * {@link #SYSTEM_UI_FLAG_HIDE_NAVIGATION}, even if it currently hasn't.  This
2855      * allows it to avoid artifacts when switching in and out of that mode, at
2856      * the expense that some of its user interface may be covered by screen
2857      * decorations when they are shown.  You can perform layout of your inner
2858      * UI elements to account for the navigation system UI through the
2859      * {@link #fitSystemWindows(Rect)} method.
2860      */
2861     public static final int SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION = 0x00000200;
2862
2863     /**
2864      * Flag for {@link #setSystemUiVisibility(int)}: View would like its window
2865      * to be laid out as if it has requested
2866      * {@link #SYSTEM_UI_FLAG_FULLSCREEN}, even if it currently hasn't.  This
2867      * allows it to avoid artifacts when switching in and out of that mode, at
2868      * the expense that some of its user interface may be covered by screen
2869      * decorations when they are shown.  You can perform layout of your inner
2870      * UI elements to account for non-fullscreen system UI through the
2871      * {@link #fitSystemWindows(Rect)} method.
2872      */
2873     public static final int SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN = 0x00000400;
2874
2875     /**
2876      * Flag for {@link #setSystemUiVisibility(int)}: View would like to remain interactive when
2877      * hiding the navigation bar with {@link #SYSTEM_UI_FLAG_HIDE_NAVIGATION}.  If this flag is
2878      * not set, {@link #SYSTEM_UI_FLAG_HIDE_NAVIGATION} will be force cleared by the system on any
2879      * user interaction.
2880      * <p>Since this flag is a modifier for {@link #SYSTEM_UI_FLAG_HIDE_NAVIGATION}, it only
2881      * has an effect when used in combination with that flag.</p>
2882      */
2883     public static final int SYSTEM_UI_FLAG_IMMERSIVE = 0x00000800;
2884
2885     /**
2886      * Flag for {@link #setSystemUiVisibility(int)}: View would like to remain interactive when
2887      * hiding the status bar with {@link #SYSTEM_UI_FLAG_FULLSCREEN} and/or hiding the navigation
2888      * bar with {@link #SYSTEM_UI_FLAG_HIDE_NAVIGATION}.  Use this flag to create an immersive
2889      * experience while also hiding the system bars.  If this flag is not set,
2890      * {@link #SYSTEM_UI_FLAG_HIDE_NAVIGATION} will be force cleared by the system on any user
2891      * interaction, and {@link #SYSTEM_UI_FLAG_FULLSCREEN} will be force-cleared by the system
2892      * if the user swipes from the top of the screen.
2893      * <p>When system bars are hidden in immersive mode, they can be revealed temporarily with
2894      * system gestures, such as swiping from the top of the screen.  These transient system bars
2895      * will overlay app’s content, may have some degree of transparency, and will automatically
2896      * hide after a short timeout.
2897      * </p><p>Since this flag is a modifier for {@link #SYSTEM_UI_FLAG_FULLSCREEN} and
2898      * {@link #SYSTEM_UI_FLAG_HIDE_NAVIGATION}, it only has an effect when used in combination
2899      * with one or both of those flags.</p>
2900      */
2901     public static final int SYSTEM_UI_FLAG_IMMERSIVE_STICKY = 0x00001000;
2902
2903     /**
2904      * Flag for {@link #setSystemUiVisibility(int)}: Requests the status bar to draw in a mode that
2905      * is compatible with light status bar backgrounds.
2906      *
2907      * <p>For this to take effect, the window must request
2908      * {@link android.view.WindowManager.LayoutParams#FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS
2909      *         FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS} but not
2910      * {@link android.view.WindowManager.LayoutParams#FLAG_TRANSLUCENT_STATUS
2911      *         FLAG_TRANSLUCENT_STATUS}.
2912      *
2913      * @see android.R.attr#windowLightStatusBar
2914      */
2915     public static final int SYSTEM_UI_FLAG_LIGHT_STATUS_BAR = 0x00002000;
2916
2917     /**
2918      * @deprecated Use {@link #SYSTEM_UI_FLAG_LOW_PROFILE} instead.
2919      */
2920     public static final int STATUS_BAR_HIDDEN = SYSTEM_UI_FLAG_LOW_PROFILE;
2921
2922     /**
2923      * @deprecated Use {@link #SYSTEM_UI_FLAG_VISIBLE} instead.
2924      */
2925     public static final int STATUS_BAR_VISIBLE = SYSTEM_UI_FLAG_VISIBLE;
2926
2927     /**
2928      * @hide
2929      *
2930      * NOTE: This flag may only be used in subtreeSystemUiVisibility. It is masked
2931      * out of the public fields to keep the undefined bits out of the developer's way.
2932      *
2933      * Flag to make the status bar not expandable.  Unless you also
2934      * set {@link #STATUS_BAR_DISABLE_NOTIFICATION_ICONS}, new notifications will continue to show.
2935      */
2936     public static final int STATUS_BAR_DISABLE_EXPAND = 0x00010000;
2937
2938     /**
2939      * @hide
2940      *
2941      * NOTE: This flag may only be used in subtreeSystemUiVisibility. It is masked
2942      * out of the public fields to keep the undefined bits out of the developer's way.
2943      *
2944      * Flag to hide notification icons and scrolling ticker text.
2945      */
2946     public static final int STATUS_BAR_DISABLE_NOTIFICATION_ICONS = 0x00020000;
2947
2948     /**
2949      * @hide
2950      *
2951      * NOTE: This flag may only be used in subtreeSystemUiVisibility. It is masked
2952      * out of the public fields to keep the undefined bits out of the developer's way.
2953      *
2954      * Flag to disable incoming notification alerts.  This will not block
2955      * icons, but it will block sound, vibrating and other visual or aural notifications.
2956      */
2957     public static final int STATUS_BAR_DISABLE_NOTIFICATION_ALERTS = 0x00040000;
2958
2959     /**
2960      * @hide
2961      *
2962      * NOTE: This flag may only be used in subtreeSystemUiVisibility. It is masked
2963      * out of the public fields to keep the undefined bits out of the developer's way.
2964      *
2965      * Flag to hide only the scrolling ticker.  Note that
2966      * {@link #STATUS_BAR_DISABLE_NOTIFICATION_ICONS} implies
2967      * {@link #STATUS_BAR_DISABLE_NOTIFICATION_TICKER}.
2968      */
2969     public static final int STATUS_BAR_DISABLE_NOTIFICATION_TICKER = 0x00080000;
2970
2971     /**
2972      * @hide
2973      *
2974      * NOTE: This flag may only be used in subtreeSystemUiVisibility. It is masked
2975      * out of the public fields to keep the undefined bits out of the developer's way.
2976      *
2977      * Flag to hide the center system info area.
2978      */
2979     public static final int STATUS_BAR_DISABLE_SYSTEM_INFO = 0x00100000;
2980
2981     /**
2982      * @hide
2983      *
2984      * NOTE: This flag may only be used in subtreeSystemUiVisibility. It is masked
2985      * out of the public fields to keep the undefined bits out of the developer's way.
2986      *
2987      * Flag to hide only the home button.  Don't use this
2988      * unless you're a special part of the system UI (i.e., setup wizard, keyguard).
2989      */
2990     public static final int STATUS_BAR_DISABLE_HOME = 0x00200000;
2991
2992     /**
2993      * @hide
2994      *
2995      * NOTE: This flag may only be used in subtreeSystemUiVisibility. It is masked
2996      * out of the public fields to keep the undefined bits out of the developer's way.
2997      *
2998      * Flag to hide only the back button. Don't use this
2999      * unless you're a special part of the system UI (i.e., setup wizard, keyguard).
3000      */
3001     public static final int STATUS_BAR_DISABLE_BACK = 0x00400000;
3002
3003     /**
3004      * @hide
3005      *
3006      * NOTE: This flag may only be used in subtreeSystemUiVisibility. It is masked
3007      * out of the public fields to keep the undefined bits out of the developer's way.
3008      *
3009      * Flag to hide only the clock.  You might use this if your activity has
3010      * its own clock making the status bar's clock redundant.
3011      */
3012     public static final int STATUS_BAR_DISABLE_CLOCK = 0x00800000;
3013
3014     /**
3015      * @hide
3016      *
3017      * NOTE: This flag may only be used in subtreeSystemUiVisibility. It is masked
3018      * out of the public fields to keep the undefined bits out of the developer's way.
3019      *
3020      * Flag to hide only the recent apps button. Don't use this
3021      * unless you're a special part of the system UI (i.e., setup wizard, keyguard).
3022      */
3023     public static final int STATUS_BAR_DISABLE_RECENT = 0x01000000;
3024
3025     /**
3026      * @hide
3027      *
3028      * NOTE: This flag may only be used in subtreeSystemUiVisibility. It is masked
3029      * out of the public fields to keep the undefined bits out of the developer's way.
3030      *
3031      * Flag to disable the global search gesture. Don't use this
3032      * unless you're a special part of the system UI (i.e., setup wizard, keyguard).
3033      */
3034     public static final int STATUS_BAR_DISABLE_SEARCH = 0x02000000;
3035
3036     /**
3037      * @hide
3038      *
3039      * NOTE: This flag may only be used in subtreeSystemUiVisibility. It is masked
3040      * out of the public fields to keep the undefined bits out of the developer's way.
3041      *
3042      * Flag to specify that the status bar is displayed in transient mode.
3043      */
3044     public static final int STATUS_BAR_TRANSIENT = 0x04000000;
3045
3046     /**
3047      * @hide
3048      *
3049      * NOTE: This flag may only be used in subtreeSystemUiVisibility. It is masked
3050      * out of the public fields to keep the undefined bits out of the developer's way.
3051      *
3052      * Flag to specify that the navigation bar is displayed in transient mode.
3053      */
3054     public static final int NAVIGATION_BAR_TRANSIENT = 0x08000000;
3055
3056     /**
3057      * @hide
3058      *
3059      * NOTE: This flag may only be used in subtreeSystemUiVisibility. It is masked
3060      * out of the public fields to keep the undefined bits out of the developer's way.
3061      *
3062      * Flag to specify that the hidden status bar would like to be shown.
3063      */
3064     public static final int STATUS_BAR_UNHIDE = 0x10000000;
3065
3066     /**
3067      * @hide
3068      *
3069      * NOTE: This flag may only be used in subtreeSystemUiVisibility. It is masked
3070      * out of the public fields to keep the undefined bits out of the developer's way.
3071      *
3072      * Flag to specify that the hidden navigation bar would like to be shown.
3073      */
3074     public static final int NAVIGATION_BAR_UNHIDE = 0x20000000;
3075
3076     /**
3077      * @hide
3078      *
3079      * NOTE: This flag may only be used in subtreeSystemUiVisibility. It is masked
3080      * out of the public fields to keep the undefined bits out of the developer's way.
3081      *
3082      * Flag to specify that the status bar is displayed in translucent mode.
3083      */
3084     public static final int STATUS_BAR_TRANSLUCENT = 0x40000000;
3085
3086     /**
3087      * @hide
3088      *
3089      * NOTE: This flag may only be used in subtreeSystemUiVisibility. It is masked
3090      * out of the public fields to keep the undefined bits out of the developer's way.
3091      *
3092      * Flag to specify that the navigation bar is displayed in translucent mode.
3093      */
3094     public static final int NAVIGATION_BAR_TRANSLUCENT = 0x80000000;
3095
3096     /**
3097      * @hide
3098      *
3099      * Makes navigation bar transparent (but not the status bar).
3100      */
3101     public static final int NAVIGATION_BAR_TRANSPARENT = 0x00008000;
3102
3103     /**
3104      * @hide
3105      *
3106      * Makes status bar transparent (but not the navigation bar).
3107      */
3108     public static final int STATUS_BAR_TRANSPARENT = 0x0000008;
3109
3110     /**
3111      * @hide
3112      *
3113      * Makes both status bar and navigation bar transparent.
3114      */
3115     public static final int SYSTEM_UI_TRANSPARENT = NAVIGATION_BAR_TRANSPARENT
3116             | STATUS_BAR_TRANSPARENT;
3117
3118     /**
3119      * @hide
3120      */
3121     public static final int PUBLIC_STATUS_BAR_VISIBILITY_MASK = 0x00003FF7;
3122
3123     /**
3124      * These are the system UI flags that can be cleared by events outside
3125      * of an application.  Currently this is just the ability to tap on the
3126      * screen while hiding the navigation bar to have it return.
3127      * @hide
3128      */
3129     public static final int SYSTEM_UI_CLEARABLE_FLAGS =
3130             SYSTEM_UI_FLAG_LOW_PROFILE | SYSTEM_UI_FLAG_HIDE_NAVIGATION
3131             | SYSTEM_UI_FLAG_FULLSCREEN;
3132
3133     /**
3134      * Flags that can impact the layout in relation to system UI.
3135      */
3136     public static final int SYSTEM_UI_LAYOUT_FLAGS =
3137             SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION
3138             | SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN;
3139
3140     /** @hide */
3141     @IntDef(flag = true,
3142             value = { FIND_VIEWS_WITH_TEXT, FIND_VIEWS_WITH_CONTENT_DESCRIPTION })
3143     @Retention(RetentionPolicy.SOURCE)
3144     public @interface FindViewFlags {}
3145
3146     /**
3147      * Find views that render the specified text.
3148      *
3149      * @see #findViewsWithText(ArrayList, CharSequence, int)
3150      */
3151     public static final int FIND_VIEWS_WITH_TEXT = 0x00000001;
3152
3153     /**
3154      * Find find views that contain the specified content description.
3155      *
3156      * @see #findViewsWithText(ArrayList, CharSequence, int)
3157      */
3158     public static final int FIND_VIEWS_WITH_CONTENT_DESCRIPTION = 0x00000002;
3159
3160     /**
3161      * Find views that contain {@link AccessibilityNodeProvider}. Such
3162      * a View is a root of virtual view hierarchy and may contain the searched
3163      * text. If this flag is set Views with providers are automatically
3164      * added and it is a responsibility of the client to call the APIs of
3165      * the provider to determine whether the virtual tree rooted at this View
3166      * contains the text, i.e. getting the list of {@link AccessibilityNodeInfo}s
3167      * representing the virtual views with this text.
3168      *
3169      * @see #findViewsWithText(ArrayList, CharSequence, int)
3170      *
3171      * @hide
3172      */
3173     public static final int FIND_VIEWS_WITH_ACCESSIBILITY_NODE_PROVIDERS = 0x00000004;
3174
3175     /**
3176      * The undefined cursor position.
3177      *
3178      * @hide
3179      */
3180     public static final int ACCESSIBILITY_CURSOR_POSITION_UNDEFINED = -1;
3181
3182     /**
3183      * Indicates that the screen has changed state and is now off.
3184      *
3185      * @see #onScreenStateChanged(int)
3186      */
3187     public static final int SCREEN_STATE_OFF = 0x0;
3188
3189     /**
3190      * Indicates that the screen has changed state and is now on.
3191      *
3192      * @see #onScreenStateChanged(int)
3193      */
3194     public static final int SCREEN_STATE_ON = 0x1;
3195
3196     /**
3197      * Indicates no axis of view scrolling.
3198      */
3199     public static final int SCROLL_AXIS_NONE = 0;
3200
3201     /**
3202      * Indicates scrolling along the horizontal axis.
3203      */
3204     public static final int SCROLL_AXIS_HORIZONTAL = 1 << 0;
3205
3206     /**
3207      * Indicates scrolling along the vertical axis.
3208      */
3209     public static final int SCROLL_AXIS_VERTICAL = 1 << 1;
3210
3211     /**
3212      * Controls the over-scroll mode for this view.
3213      * See {@link #overScrollBy(int, int, int, int, int, int, int, int, boolean)},
3214      * {@link #OVER_SCROLL_ALWAYS}, {@link #OVER_SCROLL_IF_CONTENT_SCROLLS},
3215      * and {@link #OVER_SCROLL_NEVER}.
3216      */
3217     private int mOverScrollMode;
3218
3219     /**
3220      * The parent this view is attached to.
3221      * {@hide}
3222      *
3223      * @see #getParent()
3224      */
3225     protected ViewParent mParent;
3226
3227     /**
3228      * {@hide}
3229      */
3230     AttachInfo mAttachInfo;
3231
3232     /**
3233      * {@hide}
3234      */
3235     @ViewDebug.ExportedProperty(flagMapping = {
3236         @ViewDebug.FlagToString(mask = PFLAG_FORCE_LAYOUT, equals = PFLAG_FORCE_LAYOUT,
3237                 name = "FORCE_LAYOUT"),
3238         @ViewDebug.FlagToString(mask = PFLAG_LAYOUT_REQUIRED, equals = PFLAG_LAYOUT_REQUIRED,
3239                 name = "LAYOUT_REQUIRED"),
3240         @ViewDebug.FlagToString(mask = PFLAG_DRAWING_CACHE_VALID, equals = PFLAG_DRAWING_CACHE_VALID,
3241             name = "DRAWING_CACHE_INVALID", outputIf = false),
3242         @ViewDebug.FlagToString(mask = PFLAG_DRAWN, equals = PFLAG_DRAWN, name = "DRAWN", outputIf = true),
3243         @ViewDebug.FlagToString(mask = PFLAG_DRAWN, equals = PFLAG_DRAWN, name = "NOT_DRAWN", outputIf = false),
3244         @ViewDebug.FlagToString(mask = PFLAG_DIRTY_MASK, equals = PFLAG_DIRTY_OPAQUE, name = "DIRTY_OPAQUE"),
3245         @ViewDebug.FlagToString(mask = PFLAG_DIRTY_MASK, equals = PFLAG_DIRTY, name = "DIRTY")
3246     }, formatToHexString = true)
3247     int mPrivateFlags;
3248     int mPrivateFlags2;
3249     int mPrivateFlags3;
3250
3251     /**
3252      * This view's request for the visibility of the status bar.
3253      * @hide
3254      */
3255     @ViewDebug.ExportedProperty(flagMapping = {
3256         @ViewDebug.FlagToString(mask = SYSTEM_UI_FLAG_LOW_PROFILE,
3257                                 equals = SYSTEM_UI_FLAG_LOW_PROFILE,
3258                                 name = "SYSTEM_UI_FLAG_LOW_PROFILE", outputIf = true),
3259         @ViewDebug.FlagToString(mask = SYSTEM_UI_FLAG_HIDE_NAVIGATION,
3260                                 equals = SYSTEM_UI_FLAG_HIDE_NAVIGATION,
3261                                 name = "SYSTEM_UI_FLAG_HIDE_NAVIGATION", outputIf = true),
3262         @ViewDebug.FlagToString(mask = PUBLIC_STATUS_BAR_VISIBILITY_MASK,
3263                                 equals = SYSTEM_UI_FLAG_VISIBLE,
3264                                 name = "SYSTEM_UI_FLAG_VISIBLE", outputIf = true)
3265     }, formatToHexString = true)
3266     int mSystemUiVisibility;
3267
3268     /**
3269      * Reference count for transient state.
3270      * @see #setHasTransientState(boolean)
3271      */
3272     int mTransientStateCount = 0;
3273
3274     /**
3275      * Count of how many windows this view has been attached to.
3276      */
3277     int mWindowAttachCount;
3278
3279     /**
3280      * The layout parameters associated with this view and used by the parent
3281      * {@link android.view.ViewGroup} to determine how this view should be
3282      * laid out.
3283      * {@hide}
3284      */
3285     protected ViewGroup.LayoutParams mLayoutParams;
3286
3287     /**
3288      * The view flags hold various views states.
3289      * {@hide}
3290      */
3291     @ViewDebug.ExportedProperty(formatToHexString = true)
3292     int mViewFlags;
3293
3294     static class TransformationInfo {
3295         /**
3296          * The transform matrix for the View. This transform is calculated internally
3297          * based on the translation, rotation, and scale properties.
3298          *
3299          * Do *not* use this variable directly; instead call getMatrix(), which will
3300          * load the value from the View's RenderNode.
3301          */
3302         private final Matrix mMatrix = new Matrix();
3303
3304         /**
3305          * The inverse transform matrix for the View. This transform is calculated
3306          * internally based on the translation, rotation, and scale properties.
3307          *
3308          * Do *not* use this variable directly; instead call getInverseMatrix(),
3309          * which will load the value from the View's RenderNode.
3310          */
3311         private Matrix mInverseMatrix;
3312
3313         /**
3314          * The opacity of the View. This is a value from 0 to 1, where 0 means
3315          * completely transparent and 1 means completely opaque.
3316          */
3317         @ViewDebug.ExportedProperty
3318         float mAlpha = 1f;
3319
3320         /**
3321          * The opacity of the view as manipulated by the Fade transition. This is a hidden
3322          * property only used by transitions, which is composited with the other alpha
3323          * values to calculate the final visual alpha value.
3324          */
3325         float mTransitionAlpha = 1f;
3326     }
3327
3328     TransformationInfo mTransformationInfo;
3329
3330     /**
3331      * Current clip bounds. to which all drawing of this view are constrained.
3332      */
3333     Rect mClipBounds = null;
3334
3335     private boolean mLastIsOpaque;
3336
3337     /**
3338      * The distance in pixels from the left edge of this view's parent
3339      * to the left edge of this view.
3340      * {@hide}
3341      */
3342     @ViewDebug.ExportedProperty(category = "layout")
3343     protected int mLeft;
3344     /**
3345      * The distance in pixels from the left edge of this view's parent
3346      * to the right edge of this view.
3347      * {@hide}
3348      */
3349     @ViewDebug.ExportedProperty(category = "layout")
3350     protected int mRight;
3351     /**
3352      * The distance in pixels from the top edge of this view's parent
3353      * to the top edge of this view.
3354      * {@hide}
3355      */
3356     @ViewDebug.ExportedProperty(category = "layout")
3357     protected int mTop;
3358     /**
3359      * The distance in pixels from the top edge of this view's parent
3360      * to the bottom edge of this view.
3361      * {@hide}
3362      */
3363     @ViewDebug.ExportedProperty(category = "layout")
3364     protected int mBottom;
3365
3366     /**
3367      * The offset, in pixels, by which the content of this view is scrolled
3368      * horizontally.
3369      * {@hide}
3370      */
3371     @ViewDebug.ExportedProperty(category = "scrolling")
3372     protected int mScrollX;
3373     /**
3374      * The offset, in pixels, by which the content of this view is scrolled
3375      * vertically.
3376      * {@hide}
3377      */
3378     @ViewDebug.ExportedProperty(category = "scrolling")
3379     protected int mScrollY;
3380
3381     /**
3382      * The left padding in pixels, that is the distance in pixels between the
3383      * left edge of this view and the left edge of its content.
3384      * {@hide}
3385      */
3386     @ViewDebug.ExportedProperty(category = "padding")
3387     protected int mPaddingLeft = 0;
3388     /**
3389      * The right padding in pixels, that is the distance in pixels between the
3390      * right edge of this view and the right edge of its content.
3391      * {@hide}
3392      */
3393     @ViewDebug.ExportedProperty(category = "padding")
3394     protected int mPaddingRight = 0;
3395     /**
3396      * The top padding in pixels, that is the distance in pixels between the
3397      * top edge of this view and the top edge of its content.
3398      * {@hide}
3399      */
3400     @ViewDebug.ExportedProperty(category = "padding")
3401     protected int mPaddingTop;
3402     /**
3403      * The bottom padding in pixels, that is the distance in pixels between the
3404      * bottom edge of this view and the bottom edge of its content.
3405      * {@hide}
3406      */
3407     @ViewDebug.ExportedProperty(category = "padding")
3408     protected int mPaddingBottom;
3409
3410     /**
3411      * The layout insets in pixels, that is the distance in pixels between the
3412      * visible edges of this view its bounds.
3413      */
3414     private Insets mLayoutInsets;
3415
3416     /**
3417      * Briefly describes the view and is primarily used for accessibility support.
3418      */
3419     private CharSequence mContentDescription;
3420
3421     /**
3422      * Specifies the id of a view for which this view serves as a label for
3423      * accessibility purposes.
3424      */
3425     private int mLabelForId = View.NO_ID;
3426
3427     /**
3428      * Predicate for matching labeled view id with its label for
3429      * accessibility purposes.
3430      */
3431     private MatchLabelForPredicate mMatchLabelForPredicate;
3432
3433     /**
3434      * Specifies a view before which this one is visited in accessibility traversal.
3435      */
3436     private int mAccessibilityTraversalBeforeId = NO_ID;
3437
3438     /**
3439      * Specifies a view after which this one is visited in accessibility traversal.
3440      */
3441     private int mAccessibilityTraversalAfterId = NO_ID;
3442
3443     /**
3444      * Predicate for matching a view by its id.
3445      */
3446     private MatchIdPredicate mMatchIdPredicate;
3447
3448     /**
3449      * Cache the paddingRight set by the user to append to the scrollbar's size.
3450      *
3451      * @hide
3452      */
3453     @ViewDebug.ExportedProperty(category = "padding")
3454     protected int mUserPaddingRight;
3455
3456     /**
3457      * Cache the paddingBottom set by the user to append to the scrollbar's size.
3458      *
3459      * @hide
3460      */
3461     @ViewDebug.ExportedProperty(category = "padding")
3462     protected int mUserPaddingBottom;
3463
3464     /**
3465      * Cache the paddingLeft set by the user to append to the scrollbar's size.
3466      *
3467      * @hide
3468      */
3469     @ViewDebug.ExportedProperty(category = "padding")
3470     protected int mUserPaddingLeft;
3471
3472     /**
3473      * Cache the paddingStart set by the user to append to the scrollbar's size.
3474      *
3475      */
3476     @ViewDebug.ExportedProperty(category = "padding")
3477     int mUserPaddingStart;
3478
3479     /**
3480      * Cache the paddingEnd set by the user to append to the scrollbar's size.
3481      *
3482      */
3483     @ViewDebug.ExportedProperty(category = "padding")
3484     int mUserPaddingEnd;
3485
3486     /**
3487      * Cache initial left padding.
3488      *
3489      * @hide
3490      */
3491     int mUserPaddingLeftInitial;
3492
3493     /**
3494      * Cache initial right padding.
3495      *
3496      * @hide
3497      */
3498     int mUserPaddingRightInitial;
3499
3500     /**
3501      * Default undefined padding
3502      */
3503     private static final int UNDEFINED_PADDING = Integer.MIN_VALUE;
3504
3505     /**
3506      * Cache if a left padding has been defined
3507      */
3508     private boolean mLeftPaddingDefined = false;
3509
3510     /**
3511      * Cache if a right padding has been defined
3512      */
3513     private boolean mRightPaddingDefined = false;
3514
3515     /**
3516      * @hide
3517      */
3518     int mOldWidthMeasureSpec = Integer.MIN_VALUE;
3519     /**
3520      * @hide
3521      */
3522     int mOldHeightMeasureSpec = Integer.MIN_VALUE;
3523
3524     private LongSparseLongArray mMeasureCache;
3525
3526     @ViewDebug.ExportedProperty(deepExport = true, prefix = "bg_")
3527     private Drawable mBackground;
3528     private TintInfo mBackgroundTint;
3529
3530     @ViewDebug.ExportedProperty(deepExport = true, prefix = "fg_")
3531     private ForegroundInfo mForegroundInfo;
3532
3533     private Drawable mScrollIndicatorDrawable;
3534
3535     /**
3536      * RenderNode used for backgrounds.
3537      * <p>
3538      * When non-null and valid, this is expected to contain an up-to-date copy
3539      * of the background drawable. It is cleared on temporary detach, and reset
3540      * on cleanup.
3541      */
3542     private RenderNode mBackgroundRenderNode;
3543
3544     private int mBackgroundResource;
3545     private boolean mBackgroundSizeChanged;
3546
3547     private String mTransitionName;
3548
3549     static class TintInfo {
3550         ColorStateList mTintList;
3551         PorterDuff.Mode mTintMode;
3552         boolean mHasTintMode;
3553         boolean mHasTintList;
3554     }
3555
3556     private static class ForegroundInfo {
3557         private Drawable mDrawable;
3558         private TintInfo mTintInfo;
3559         private int mGravity = Gravity.FILL;
3560         private boolean mInsidePadding = true;
3561         private boolean mBoundsChanged = true;
3562         private final Rect mSelfBounds = new Rect();
3563         private final Rect mOverlayBounds = new Rect();
3564     }
3565
3566     static class ListenerInfo {
3567         /**
3568          * Listener used to dispatch focus change events.
3569          * This field should be made private, so it is hidden from the SDK.
3570          * {@hide}
3571          */
3572         protected OnFocusChangeListener mOnFocusChangeListener;
3573
3574         /**
3575          * Listeners for layout change events.
3576          */
3577         private ArrayList<OnLayoutChangeListener> mOnLayoutChangeListeners;
3578
3579         protected OnScrollChangeListener mOnScrollChangeListener;
3580
3581         /**
3582          * Listeners for attach events.
3583          */
3584         private CopyOnWriteArrayList<OnAttachStateChangeListener> mOnAttachStateChangeListeners;
3585
3586         /**
3587          * Listener used to dispatch click events.
3588          * This field should be made private, so it is hidden from the SDK.
3589          * {@hide}
3590          */
3591         public OnClickListener mOnClickListener;
3592
3593         /**
3594          * Listener used to dispatch long click events.
3595          * This field should be made private, so it is hidden from the SDK.
3596          * {@hide}
3597          */
3598         protected OnLongClickListener mOnLongClickListener;
3599
3600         /**
3601          * Listener used to dispatch context click events. This field should be made private, so it
3602          * is hidden from the SDK.
3603          * {@hide}
3604          */
3605         protected OnContextClickListener mOnContextClickListener;
3606
3607         /**
3608          * Listener used to build the context menu.
3609          * This field should be made private, so it is hidden from the SDK.
3610          * {@hide}
3611          */
3612         protected OnCreateContextMenuListener mOnCreateContextMenuListener;
3613
3614         private OnKeyListener mOnKeyListener;
3615
3616         private OnTouchListener mOnTouchListener;
3617
3618         private OnHoverListener mOnHoverListener;
3619
3620         private OnGenericMotionListener mOnGenericMotionListener;
3621
3622         private OnDragListener mOnDragListener;
3623
3624         private OnSystemUiVisibilityChangeListener mOnSystemUiVisibilityChangeListener;
3625
3626         OnApplyWindowInsetsListener mOnApplyWindowInsetsListener;
3627     }
3628
3629     ListenerInfo mListenerInfo;
3630
3631     // Temporary values used to hold (x,y) coordinates when delegating from the
3632     // two-arg performLongClick() method to the legacy no-arg version.
3633     private float mLongClickX = Float.NaN;
3634     private float mLongClickY = Float.NaN;
3635
3636     /**
3637      * The application environment this view lives in.
3638      * This field should be made private, so it is hidden from the SDK.
3639      * {@hide}
3640      */
3641     @ViewDebug.ExportedProperty(deepExport = true)
3642     protected Context mContext;
3643
3644     private final Resources mResources;
3645
3646     private ScrollabilityCache mScrollCache;
3647
3648     private int[] mDrawableState = null;
3649
3650     ViewOutlineProvider mOutlineProvider = ViewOutlineProvider.BACKGROUND;
3651
3652     /**
3653      * Animator that automatically runs based on state changes.
3654      */
3655     private StateListAnimator mStateListAnimator;
3656
3657     /**
3658      * When this view has focus and the next focus is {@link #FOCUS_LEFT},
3659      * the user may specify which view to go to next.
3660      */
3661     private int mNextFocusLeftId = View.NO_ID;
3662
3663     /**
3664      * When this view has focus and the next focus is {@link #FOCUS_RIGHT},
3665      * the user may specify which view to go to next.
3666      */
3667     private int mNextFocusRightId = View.NO_ID;
3668
3669     /**
3670      * When this view has focus and the next focus is {@link #FOCUS_UP},
3671      * the user may specify which view to go to next.
3672      */
3673     private int mNextFocusUpId = View.NO_ID;
3674
3675     /**
3676      * When this view has focus and the next focus is {@link #FOCUS_DOWN},
3677      * the user may specify which view to go to next.
3678      */
3679     private int mNextFocusDownId = View.NO_ID;
3680
3681     /**
3682      * When this view has focus and the next focus is {@link #FOCUS_FORWARD},
3683      * the user may specify which view to go to next.
3684      */
3685     int mNextFocusForwardId = View.NO_ID;
3686
3687     private CheckForLongPress mPendingCheckForLongPress;
3688     private CheckForTap mPendingCheckForTap = null;
3689     private PerformClick mPerformClick;
3690     private SendViewScrolledAccessibilityEvent mSendViewScrolledAccessibilityEvent;
3691
3692     private UnsetPressedState mUnsetPressedState;
3693
3694     /**
3695      * Whether the long press's action has been invoked.  The tap's action is invoked on the
3696      * up event while a long press is invoked as soon as the long press duration is reached, so
3697      * a long press could be performed before the tap is checked, in which case the tap's action
3698      * should not be invoked.
3699      */
3700     private boolean mHasPerformedLongPress;
3701
3702     /**
3703      * Whether a context click button is currently pressed down. This is true when the stylus is
3704      * touching the screen and the primary button has been pressed, or if a mouse's right button is
3705      * pressed. This is false once the button is released or if the stylus has been lifted.
3706      */
3707     private boolean mInContextButtonPress;
3708
3709     /**
3710      * Whether the next up event should be ignored for the purposes of gesture recognition. This is
3711      * true after a stylus button press has occured, when the next up event should not be recognized
3712      * as a tap.
3713      */
3714     private boolean mIgnoreNextUpEvent;
3715
3716     /**
3717      * The minimum height of the view. We'll try our best to have the height
3718      * of this view to at least this amount.
3719      */
3720     @ViewDebug.ExportedProperty(category = "measurement")
3721     private int mMinHeight;
3722
3723     /**
3724      * The minimum width of the view. We'll try our best to have the width
3725      * of this view to at least this amount.
3726      */
3727     @ViewDebug.ExportedProperty(category = "measurement")
3728     private int mMinWidth;
3729
3730     /**
3731      * The delegate to handle touch events that are physically in this view
3732      * but should be handled by another view.
3733      */
3734     private TouchDelegate mTouchDelegate = null;
3735
3736     /**
3737      * Solid color to use as a background when creating the drawing cache. Enables
3738      * the cache to use 16 bit bitmaps instead of 32 bit.
3739      */
3740     private int mDrawingCacheBackgroundColor = 0;
3741
3742     /**
3743      * Special tree observer used when mAttachInfo is null.
3744      */
3745     private ViewTreeObserver mFloatingTreeObserver;
3746
3747     /**
3748      * Cache the touch slop from the context that created the view.
3749      */
3750     private int mTouchSlop;
3751
3752     /**
3753      * Object that handles automatic animation of view properties.
3754      */
3755     private ViewPropertyAnimator mAnimator = null;
3756
3757     /**
3758      * List of registered FrameMetricsObservers.
3759      */
3760     private ArrayList<FrameMetricsObserver> mFrameMetricsObservers;
3761
3762     /**
3763      * Flag indicating that a drag can cross window boundaries.  When
3764      * {@link #startDragAndDrop(ClipData, DragShadowBuilder, Object, int)} is called
3765      * with this flag set, all visible applications with targetSdkVersion >=
3766      * {@link android.os.Build.VERSION_CODES#N API 24} will be able to participate
3767      * in the drag operation and receive the dragged content.
3768      *
3769      * <p>If this is the only flag set, then the drag recipient will only have access to text data
3770      * and intents contained in the {@link ClipData} object. Access to URIs contained in the
3771      * {@link ClipData} is determined by other DRAG_FLAG_GLOBAL_* flags</p>
3772      */
3773     public static final int DRAG_FLAG_GLOBAL = 1 << 8;  // 256
3774
3775     /**
3776      * When this flag is used with {@link #DRAG_FLAG_GLOBAL}, the drag recipient will be able to
3777      * request read access to the content URI(s) contained in the {@link ClipData} object.
3778      * @see android.content.Intent.FLAG_GRANT_READ_URI_PERMISSION
3779      */
3780     public static final int DRAG_FLAG_GLOBAL_URI_READ = Intent.FLAG_GRANT_READ_URI_PERMISSION;
3781
3782     /**
3783      * When this flag is used with {@link #DRAG_FLAG_GLOBAL}, the drag recipient will be able to
3784      * request write access to the content URI(s) contained in the {@link ClipData} object.
3785      * @see android.content.Intent.FLAG_GRANT_WRITE_URI_PERMISSION
3786      */
3787     public static final int DRAG_FLAG_GLOBAL_URI_WRITE = Intent.FLAG_GRANT_WRITE_URI_PERMISSION;
3788
3789     /**
3790      * When this flag is used with {@link #DRAG_FLAG_GLOBAL_URI_READ} and/or {@link
3791      * #DRAG_FLAG_GLOBAL_URI_WRITE}, the URI permission grant can be persisted across device
3792      * reboots until explicitly revoked with
3793      * {@link android.content.Context#revokeUriPermission(Uri,int) Context.revokeUriPermission}.
3794      * @see android.content.Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION
3795      */
3796     public static final int DRAG_FLAG_GLOBAL_PERSISTABLE_URI_PERMISSION =
3797             Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION;
3798
3799     /**
3800      * When this flag is used with {@link #DRAG_FLAG_GLOBAL_URI_READ} and/or {@link
3801      * #DRAG_FLAG_GLOBAL_URI_WRITE}, the URI permission grant applies to any URI that is a prefix
3802      * match against the original granted URI.
3803      * @see android.content.Intent.FLAG_GRANT_PREFIX_URI_PERMISSION
3804      */
3805     public static final int DRAG_FLAG_GLOBAL_PREFIX_URI_PERMISSION =
3806             Intent.FLAG_GRANT_PREFIX_URI_PERMISSION;
3807
3808     /**
3809      * Flag indicating that the drag shadow will be opaque.  When
3810      * {@link #startDragAndDrop(ClipData, DragShadowBuilder, Object, int)} is called
3811      * with this flag set, the drag shadow will be opaque, otherwise, it will be semitransparent.
3812      */
3813     public static final int DRAG_FLAG_OPAQUE = 1 << 9;
3814
3815     /**
3816      * Vertical scroll factor cached by {@link #getVerticalScrollFactor}.
3817      */
3818     private float mVerticalScrollFactor;
3819
3820     /**
3821      * Position of the vertical scroll bar.
3822      */
3823     private int mVerticalScrollbarPosition;
3824
3825     /**
3826      * Position the scroll bar at the default position as determined by the system.
3827      */
3828     public static final int SCROLLBAR_POSITION_DEFAULT = 0;
3829
3830     /**
3831      * Position the scroll bar along the left edge.
3832      */
3833     public static final int SCROLLBAR_POSITION_LEFT = 1;
3834
3835     /**
3836      * Position the scroll bar along the right edge.
3837      */
3838     public static final int SCROLLBAR_POSITION_RIGHT = 2;
3839
3840     /**
3841      * Indicates that the view does not have a layer.
3842      *
3843      * @see #getLayerType()
3844      * @see #setLayerType(int, android.graphics.Paint)
3845      * @see #LAYER_TYPE_SOFTWARE
3846      * @see #LAYER_TYPE_HARDWARE
3847      */
3848     public static final int LAYER_TYPE_NONE = 0;
3849
3850     /**
3851      * <p>Indicates that the view has a software layer. A software layer is backed
3852      * by a bitmap and causes the view to be rendered using Android's software
3853      * rendering pipeline, even if hardware acceleration is enabled.</p>
3854      *
3855      * <p>Software layers have various usages:</p>
3856      * <p>When the application is not using hardware acceleration, a software layer
3857      * is useful to apply a specific color filter and/or blending mode and/or
3858      * translucency to a view and all its children.</p>
3859      * <p>When the application is using hardware acceleration, a software layer
3860      * is useful to render drawing primitives not supported by the hardware
3861      * accelerated pipeline. It can also be used to cache a complex view tree
3862      * into a texture and reduce the complexity of drawing operations. For instance,
3863      * when animating a complex view tree with a translation, a software layer can
3864      * be used to render the view tree only once.</p>
3865      * <p>Software layers should be avoided when the affected view tree updates
3866      * often. Every update will require to re-render the software layer, which can
3867      * potentially be slow (particularly when hardware acceleration is turned on
3868      * since the layer will have to be uploaded into a hardware texture after every
3869      * update.)</p>
3870      *
3871      * @see #getLayerType()
3872      * @see #setLayerType(int, android.graphics.Paint)
3873      * @see #LAYER_TYPE_NONE
3874      * @see #LAYER_TYPE_HARDWARE
3875      */
3876     public static final int LAYER_TYPE_SOFTWARE = 1;
3877
3878     /**
3879      * <p>Indicates that the view has a hardware layer. A hardware layer is backed
3880      * by a hardware specific texture (generally Frame Buffer Objects or FBO on
3881      * OpenGL hardware) and causes the view to be rendered using Android's hardware
3882      * rendering pipeline, but only if hardware acceleration is turned on for the
3883      * view hierarchy. When hardware acceleration is turned off, hardware layers
3884      * behave exactly as {@link #LAYER_TYPE_SOFTWARE software layers}.</p>
3885      *
3886      * <p>A hardware layer is useful to apply a specific color filter and/or
3887      * blending mode and/or translucency to a view and all its children.</p>
3888      * <p>A hardware layer can be used to cache a complex view tree into a
3889      * texture and reduce the complexity of drawing operations. For instance,
3890      * when animating a complex view tree with a translation, a hardware layer can
3891      * be used to render the view tree only once.</p>
3892      * <p>A hardware layer can also be used to increase the rendering quality when
3893      * rotation transformations are applied on a view. It can also be used to
3894      * prevent potential clipping issues when applying 3D transforms on a view.</p>
3895      *
3896      * @see #getLayerType()
3897      * @see #setLayerType(int, android.graphics.Paint)
3898      * @see #LAYER_TYPE_NONE
3899      * @see #LAYER_TYPE_SOFTWARE
3900      */
3901     public static final int LAYER_TYPE_HARDWARE = 2;
3902
3903     @ViewDebug.ExportedProperty(category = "drawing", mapping = {
3904             @ViewDebug.IntToString(from = LAYER_TYPE_NONE, to = "NONE"),
3905             @ViewDebug.IntToString(from = LAYER_TYPE_SOFTWARE, to = "SOFTWARE"),
3906             @ViewDebug.IntToString(from = LAYER_TYPE_HARDWARE, to = "HARDWARE")
3907     })
3908     int mLayerType = LAYER_TYPE_NONE;
3909     Paint mLayerPaint;
3910
3911     /**
3912      * Set to true when drawing cache is enabled and cannot be created.
3913      *
3914      * @hide
3915      */
3916     public boolean mCachingFailed;
3917     private Bitmap mDrawingCache;
3918     private Bitmap mUnscaledDrawingCache;
3919
3920     /**
3921      * RenderNode holding View properties, potentially holding a DisplayList of View content.
3922      * <p>
3923      * When non-null and valid, this is expected to contain an up-to-date copy
3924      * of the View content. Its DisplayList content is cleared on temporary detach and reset on
3925      * cleanup.
3926      */
3927     final RenderNode mRenderNode;
3928
3929     /**
3930      * Set to true when the view is sending hover accessibility events because it
3931      * is the innermost hovered view.
3932      */
3933     private boolean mSendingHoverAccessibilityEvents;
3934
3935     /**
3936      * Delegate for injecting accessibility functionality.
3937      */
3938     AccessibilityDelegate mAccessibilityDelegate;
3939
3940     /**
3941      * The view's overlay layer. Developers get a reference to the overlay via getOverlay()
3942      * and add/remove objects to/from the overlay directly through the Overlay methods.
3943      */
3944     ViewOverlay mOverlay;
3945
3946     /**
3947      * The currently active parent view for receiving delegated nested scrolling events.
3948      * This is set by {@link #startNestedScroll(int)} during a touch interaction and cleared
3949      * by {@link #stopNestedScroll()} at the same point where we clear
3950      * requestDisallowInterceptTouchEvent.
3951      */
3952     private ViewParent mNestedScrollingParent;
3953
3954     /**
3955      * Consistency verifier for debugging purposes.
3956      * @hide
3957      */
3958     protected final InputEventConsistencyVerifier mInputEventConsistencyVerifier =
3959             InputEventConsistencyVerifier.isInstrumentationEnabled() ?
3960                     new InputEventConsistencyVerifier(this, 0) : null;
3961
3962     private static final AtomicInteger sNextGeneratedId = new AtomicInteger(1);
3963
3964     private int[] mTempNestedScrollConsumed;
3965
3966     /**
3967      * An overlay is going to draw this View instead of being drawn as part of this
3968      * View's parent. mGhostView is the View in the Overlay that must be invalidated
3969      * when this view is invalidated.
3970      */
3971     GhostView mGhostView;
3972
3973     /**
3974      * Holds pairs of adjacent attribute data: attribute name followed by its value.
3975      * @hide
3976      */
3977     @ViewDebug.ExportedProperty(category = "attributes", hasAdjacentMapping = true)
3978     public String[] mAttributes;
3979
3980     /**
3981      * Maps a Resource id to its name.
3982      */
3983     private static SparseArray<String> mAttributeMap;
3984
3985     /**
3986      * Queue of pending runnables. Used to postpone calls to post() until this
3987      * view is attached and has a handler.
3988      */
3989     private HandlerActionQueue mRunQueue;
3990
3991     /**
3992      * The pointer icon when the mouse hovers on this view. The default is null.
3993      */
3994     private PointerIcon mPointerIcon;
3995
3996     /**
3997      * @hide
3998      */
3999     String mStartActivityRequestWho;
4000
4001     @Nullable
4002     private RoundScrollbarRenderer mRoundScrollbarRenderer;
4003
4004     /**
4005      * Simple constructor to use when creating a view from code.
4006      *
4007      * @param context The Context the view is running in, through which it can
4008      *        access the current theme, resources, etc.
4009      */
4010     public View(Context context) {
4011         mContext = context;
4012         mResources = context != null ? context.getResources() : null;
4013         mViewFlags = SOUND_EFFECTS_ENABLED | HAPTIC_FEEDBACK_ENABLED;
4014         // Set some flags defaults
4015         mPrivateFlags2 =
4016                 (LAYOUT_DIRECTION_DEFAULT << PFLAG2_LAYOUT_DIRECTION_MASK_SHIFT) |
4017                 (TEXT_DIRECTION_DEFAULT << PFLAG2_TEXT_DIRECTION_MASK_SHIFT) |
4018                 (PFLAG2_TEXT_DIRECTION_RESOLVED_DEFAULT) |
4019                 (TEXT_ALIGNMENT_DEFAULT << PFLAG2_TEXT_ALIGNMENT_MASK_SHIFT) |
4020                 (PFLAG2_TEXT_ALIGNMENT_RESOLVED_DEFAULT) |
4021                 (IMPORTANT_FOR_ACCESSIBILITY_DEFAULT << PFLAG2_IMPORTANT_FOR_ACCESSIBILITY_SHIFT);
4022         mTouchSlop = ViewConfiguration.get(context).getScaledTouchSlop();
4023         setOverScrollMode(OVER_SCROLL_IF_CONTENT_SCROLLS);
4024         mUserPaddingStart = UNDEFINED_PADDING;
4025         mUserPaddingEnd = UNDEFINED_PADDING;
4026         mRenderNode = RenderNode.create(getClass().getName(), this);
4027
4028         if (!sCompatibilityDone && context != null) {
4029             final int targetSdkVersion = context.getApplicationInfo().targetSdkVersion;
4030
4031             // Older apps may need this compatibility hack for measurement.
4032             sUseBrokenMakeMeasureSpec = targetSdkVersion <= JELLY_BEAN_MR1;
4033
4034             // Older apps expect onMeasure() to always be called on a layout pass, regardless
4035             // of whether a layout was requested on that View.
4036             sIgnoreMeasureCache = targetSdkVersion < KITKAT;
4037
4038             Canvas.sCompatibilityRestore = targetSdkVersion < M;
4039
4040             // In M and newer, our widgets can pass a "hint" value in the size
4041             // for UNSPECIFIED MeasureSpecs. This lets child views of scrolling containers
4042             // know what the expected parent size is going to be, so e.g. list items can size
4043             // themselves at 1/3 the size of their container. It breaks older apps though,
4044             // specifically apps that use some popular open source libraries.
4045             sUseZeroUnspecifiedMeasureSpec = targetSdkVersion < M;
4046
4047             // Old versions of the platform would give different results from
4048             // LinearLayout measurement passes using EXACTLY and non-EXACTLY
4049             // modes, so we always need to run an additional EXACTLY pass.
4050             sAlwaysRemeasureExactly = targetSdkVersion <= M;
4051
4052             // Prior to N, layout params could change without requiring a
4053             // subsequent call to setLayoutParams() and they would usually
4054             // work. Partial layout breaks this assumption.
4055             sLayoutParamsAlwaysChanged = targetSdkVersion <= M;
4056
4057             // Prior to N, TextureView would silently ignore calls to setBackground/setForeground.
4058             // On N+, we throw, but that breaks compatibility with apps that use these methods.
4059             sTextureViewIgnoresDrawableSetters = targetSdkVersion <= M;
4060
4061             // Prior to N, we would drop margins in LayoutParam conversions. The fix triggers bugs
4062             // in apps so we target check it to avoid breaking existing apps.
4063             sPreserveMarginParamsInLayoutParamConversion = targetSdkVersion >= N;
4064
4065             sCascadedDragDrop = targetSdkVersion < N;
4066
4067             sCompatibilityDone = true;
4068         }
4069     }
4070
4071     /**
4072      * Constructor that is called when inflating a view from XML. This is called
4073      * when a view is being constructed from an XML file, supplying attributes
4074      * that were specified in the XML file. This version uses a default style of
4075      * 0, so the only attribute values applied are those in the Context's Theme
4076      * and the given AttributeSet.
4077      *
4078      * <p>
4079      * The method onFinishInflate() will be called after all children have been
4080      * added.
4081      *
4082      * @param context The Context the view is running in, through which it can
4083      *        access the current theme, resources, etc.
4084      * @param attrs The attributes of the XML tag that is inflating the view.
4085      * @see #View(Context, AttributeSet, int)
4086      */
4087     public View(Context context, @Nullable AttributeSet attrs) {
4088         this(context, attrs, 0);
4089     }
4090
4091     /**
4092      * Perform inflation from XML and apply a class-specific base style from a
4093      * theme attribute. This constructor of View allows subclasses to use their
4094      * own base style when they are inflating. For example, a Button class's
4095      * constructor would call this version of the super class constructor and
4096      * supply <code>R.attr.buttonStyle</code> for <var>defStyleAttr</var>; this
4097      * allows the theme's button style to modify all of the base view attributes
4098      * (in particular its background) as well as the Button class's attributes.
4099      *
4100      * @param context The Context the view is running in, through which it can
4101      *        access the current theme, resources, etc.
4102      * @param attrs The attributes of the XML tag that is inflating the view.
4103      * @param defStyleAttr An attribute in the current theme that contains a
4104      *        reference to a style resource that supplies default values for
4105      *        the view. Can be 0 to not look for defaults.
4106      * @see #View(Context, AttributeSet)
4107      */
4108     public View(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
4109         this(context, attrs, defStyleAttr, 0);
4110     }
4111
4112     /**
4113      * Perform inflation from XML and apply a class-specific base style from a
4114      * theme attribute or style resource. This constructor of View allows
4115      * subclasses to use their own base style when they are inflating.
4116      * <p>
4117      * When determining the final value of a particular attribute, there are
4118      * four inputs that come into play:
4119      * <ol>
4120      * <li>Any attribute values in the given AttributeSet.
4121      * <li>The style resource specified in the AttributeSet (named "style").
4122      * <li>The default style specified by <var>defStyleAttr</var>.
4123      * <li>The default style specified by <var>defStyleRes</var>.
4124      * <li>The base values in this theme.
4125      * </ol>
4126      * <p>
4127      * Each of these inputs is considered in-order, with the first listed taking
4128      * precedence over the following ones. In other words, if in the
4129      * AttributeSet you have supplied <code>&lt;Button * textColor="#ff000000"&gt;</code>
4130      * , then the button's text will <em>always</em> be black, regardless of
4131      * what is specified in any of the styles.
4132      *
4133      * @param context The Context the view is running in, through which it can
4134      *        access the current theme, resources, etc.
4135      * @param attrs The attributes of the XML tag that is inflating the view.
4136      * @param defStyleAttr An attribute in the current theme that contains a
4137      *        reference to a style resource that supplies default values for
4138      *        the view. Can be 0 to not look for defaults.
4139      * @param defStyleRes A resource identifier of a style resource that
4140      *        supplies default values for the view, used only if
4141      *        defStyleAttr is 0 or can not be found in the theme. Can be 0
4142      *        to not look for defaults.
4143      * @see #View(Context, AttributeSet, int)
4144      */
4145     public View(Context context, @Nullable AttributeSet attrs, int defStyleAttr, int defStyleRes) {
4146         this(context);
4147
4148         final TypedArray a = context.obtainStyledAttributes(
4149                 attrs, com.android.internal.R.styleable.View, defStyleAttr, defStyleRes);
4150
4151         if (mDebugViewAttributes) {
4152             saveAttributeData(attrs, a);
4153         }
4154
4155         Drawable background = null;
4156
4157         int leftPadding = -1;
4158         int topPadding = -1;
4159         int rightPadding = -1;
4160         int bottomPadding = -1;
4161         int startPadding = UNDEFINED_PADDING;
4162         int endPadding = UNDEFINED_PADDING;
4163
4164         int padding = -1;
4165
4166         int viewFlagValues = 0;
4167         int viewFlagMasks = 0;
4168
4169         boolean setScrollContainer = false;
4170
4171         int x = 0;
4172         int y = 0;
4173
4174         float tx = 0;
4175         float ty = 0;
4176         float tz = 0;
4177         float elevation = 0;
4178         float rotation = 0;
4179         float rotationX = 0;
4180         float rotationY = 0;
4181         float sx = 1f;
4182         float sy = 1f;
4183         boolean transformSet = false;
4184
4185         int scrollbarStyle = SCROLLBARS_INSIDE_OVERLAY;
4186         int overScrollMode = mOverScrollMode;
4187         boolean initializeScrollbars = false;
4188         boolean initializeScrollIndicators = false;
4189
4190         boolean startPaddingDefined = false;
4191         boolean endPaddingDefined = false;
4192         boolean leftPaddingDefined = false;
4193         boolean rightPaddingDefined = false;
4194
4195         final int targetSdkVersion = context.getApplicationInfo().targetSdkVersion;
4196
4197         final int N = a.getIndexCount();
4198         for (int i = 0; i < N; i++) {
4199             int attr = a.getIndex(i);
4200             switch (attr) {
4201                 case com.android.internal.R.styleable.View_background:
4202                     background = a.getDrawable(attr);
4203                     break;
4204                 case com.android.internal.R.styleable.View_padding:
4205                     padding = a.getDimensionPixelSize(attr, -1);
4206                     mUserPaddingLeftInitial = padding;
4207                     mUserPaddingRightInitial = padding;
4208                     leftPaddingDefined = true;
4209                     rightPaddingDefined = true;
4210                     break;
4211                  case com.android.internal.R.styleable.View_paddingLeft:
4212                     leftPadding = a.getDimensionPixelSize(attr, -1);
4213                     mUserPaddingLeftInitial = leftPadding;
4214                     leftPaddingDefined = true;
4215                     break;
4216                 case com.android.internal.R.styleable.View_paddingTop:
4217                     topPadding = a.getDimensionPixelSize(attr, -1);
4218                     break;
4219                 case com.android.internal.R.styleable.View_paddingRight:
4220                     rightPadding = a.getDimensionPixelSize(attr, -1);
4221                     mUserPaddingRightInitial = rightPadding;
4222                     rightPaddingDefined = true;
4223                     break;
4224                 case com.android.internal.R.styleable.View_paddingBottom:
4225                     bottomPadding = a.getDimensionPixelSize(attr, -1);
4226                     break;
4227                 case com.android.internal.R.styleable.View_paddingStart:
4228                     startPadding = a.getDimensionPixelSize(attr, UNDEFINED_PADDING);
4229                     startPaddingDefined = (startPadding != UNDEFINED_PADDING);
4230                     break;
4231                 case com.android.internal.R.styleable.View_paddingEnd:
4232                     endPadding = a.getDimensionPixelSize(attr, UNDEFINED_PADDING);
4233                     endPaddingDefined = (endPadding != UNDEFINED_PADDING);
4234                     break;
4235                 case com.android.internal.R.styleable.View_scrollX:
4236                     x = a.getDimensionPixelOffset(attr, 0);
4237                     break;
4238                 case com.android.internal.R.styleable.View_scrollY:
4239                     y = a.getDimensionPixelOffset(attr, 0);
4240                     break;
4241                 case com.android.internal.R.styleable.View_alpha:
4242                     setAlpha(a.getFloat(attr, 1f));
4243                     break;
4244                 case com.android.internal.R.styleable.View_transformPivotX:
4245                     setPivotX(a.getDimension(attr, 0));
4246                     break;
4247                 case com.android.internal.R.styleable.View_transformPivotY:
4248                     setPivotY(a.getDimension(attr, 0));
4249                     break;
4250                 case com.android.internal.R.styleable.View_translationX:
4251                     tx = a.getDimension(attr, 0);
4252                     transformSet = true;
4253                     break;
4254                 case com.android.internal.R.styleable.View_translationY:
4255                     ty = a.getDimension(attr, 0);
4256                     transformSet = true;
4257                     break;
4258                 case com.android.internal.R.styleable.View_translationZ:
4259                     tz = a.getDimension(attr, 0);
4260                     transformSet = true;
4261                     break;
4262                 case com.android.internal.R.styleable.View_elevation:
4263                     elevation = a.getDimension(attr, 0);
4264                     transformSet = true;
4265                     break;
4266                 case com.android.internal.R.styleable.View_rotation:
4267                     rotation = a.getFloat(attr, 0);
4268                     transformSet = true;
4269                     break;
4270                 case com.android.internal.R.styleable.View_rotationX:
4271                     rotationX = a.getFloat(attr, 0);
4272                     transformSet = true;
4273                     break;
4274                 case com.android.internal.R.styleable.View_rotationY:
4275                     rotationY = a.getFloat(attr, 0);
4276                     transformSet = true;
4277                     break;
4278                 case com.android.internal.R.styleable.View_scaleX:
4279                     sx = a.getFloat(attr, 1f);
4280                     transformSet = true;
4281                     break;
4282                 case com.android.internal.R.styleable.View_scaleY:
4283                     sy = a.getFloat(attr, 1f);
4284                     transformSet = true;
4285                     break;
4286                 case com.android.internal.R.styleable.View_id:
4287                     mID = a.getResourceId(attr, NO_ID);
4288                     break;
4289                 case com.android.internal.R.styleable.View_tag:
4290                     mTag = a.getText(attr);
4291                     break;
4292                 case com.android.internal.R.styleable.View_fitsSystemWindows:
4293                     if (a.getBoolean(attr, false)) {
4294                         viewFlagValues |= FITS_SYSTEM_WINDOWS;
4295                         viewFlagMasks |= FITS_SYSTEM_WINDOWS;
4296                     }
4297                     break;
4298                 case com.android.internal.R.styleable.View_focusable:
4299                     if (a.getBoolean(attr, false)) {
4300                         viewFlagValues |= FOCUSABLE;
4301                         viewFlagMasks |= FOCUSABLE_MASK;
4302                     }
4303                     break;
4304                 case com.android.internal.R.styleable.View_focusableInTouchMode:
4305                     if (a.getBoolean(attr, false)) {
4306                         viewFlagValues |= FOCUSABLE_IN_TOUCH_MODE | FOCUSABLE;
4307                         viewFlagMasks |= FOCUSABLE_IN_TOUCH_MODE | FOCUSABLE_MASK;
4308                     }
4309                     break;
4310                 case com.android.internal.R.styleable.View_clickable:
4311                     if (a.getBoolean(attr, false)) {
4312                         viewFlagValues |= CLICKABLE;
4313                         viewFlagMasks |= CLICKABLE;
4314                     }
4315                     break;
4316                 case com.android.internal.R.styleable.View_longClickable:
4317                     if (a.getBoolean(attr, false)) {
4318                         viewFlagValues |= LONG_CLICKABLE;
4319                         viewFlagMasks |= LONG_CLICKABLE;
4320                     }
4321                     break;
4322                 case com.android.internal.R.styleable.View_contextClickable:
4323                     if (a.getBoolean(attr, false)) {
4324                         viewFlagValues |= CONTEXT_CLICKABLE;
4325                         viewFlagMasks |= CONTEXT_CLICKABLE;
4326                     }
4327                     break;
4328                 case com.android.internal.R.styleable.View_saveEnabled:
4329                     if (!a.getBoolean(attr, true)) {
4330                         viewFlagValues |= SAVE_DISABLED;
4331                         viewFlagMasks |= SAVE_DISABLED_MASK;
4332                     }
4333                     break;
4334                 case com.android.internal.R.styleable.View_duplicateParentState:
4335                     if (a.getBoolean(attr, false)) {
4336                         viewFlagValues |= DUPLICATE_PARENT_STATE;
4337                         viewFlagMasks |= DUPLICATE_PARENT_STATE;
4338                     }
4339                     break;
4340                 case com.android.internal.R.styleable.View_visibility:
4341                     final int visibility = a.getInt(attr, 0);
4342                     if (visibility != 0) {
4343                         viewFlagValues |= VISIBILITY_FLAGS[visibility];
4344                         viewFlagMasks |= VISIBILITY_MASK;
4345                     }
4346                     break;
4347                 case com.android.internal.R.styleable.View_layoutDirection:
4348                     // Clear any layout direction flags (included resolved bits) already set
4349                     mPrivateFlags2 &=
4350                             ~(PFLAG2_LAYOUT_DIRECTION_MASK | PFLAG2_LAYOUT_DIRECTION_RESOLVED_MASK);
4351                     // Set the layout direction flags depending on the value of the attribute
4352                     final int layoutDirection = a.getInt(attr, -1);
4353                     final int value = (layoutDirection != -1) ?
4354                             LAYOUT_DIRECTION_FLAGS[layoutDirection] : LAYOUT_DIRECTION_DEFAULT;
4355                     mPrivateFlags2 |= (value << PFLAG2_LAYOUT_DIRECTION_MASK_SHIFT);
4356                     break;
4357                 case com.android.internal.R.styleable.View_drawingCacheQuality:
4358                     final int cacheQuality = a.getInt(attr, 0);
4359                     if (cacheQuality != 0) {
4360                         viewFlagValues |= DRAWING_CACHE_QUALITY_FLAGS[cacheQuality];
4361                         viewFlagMasks |= DRAWING_CACHE_QUALITY_MASK;
4362                     }
4363                     break;
4364                 case com.android.internal.R.styleable.View_contentDescription:
4365                     setContentDescription(a.getString(attr));
4366                     break;
4367                 case com.android.internal.R.styleable.View_accessibilityTraversalBefore:
4368                     setAccessibilityTraversalBefore(a.getResourceId(attr, NO_ID));
4369                     break;
4370                 case com.android.internal.R.styleable.View_accessibilityTraversalAfter:
4371                     setAccessibilityTraversalAfter(a.getResourceId(attr, NO_ID));
4372                     break;
4373                 case com.android.internal.R.styleable.View_labelFor:
4374                     setLabelFor(a.getResourceId(attr, NO_ID));
4375                     break;
4376                 case com.android.internal.R.styleable.View_soundEffectsEnabled:
4377                     if (!a.getBoolean(attr, true)) {
4378                         viewFlagValues &= ~SOUND_EFFECTS_ENABLED;
4379                         viewFlagMasks |= SOUND_EFFECTS_ENABLED;
4380                     }
4381                     break;
4382                 case com.android.internal.R.styleable.View_hapticFeedbackEnabled:
4383                     if (!a.getBoolean(attr, true)) {
4384                         viewFlagValues &= ~HAPTIC_FEEDBACK_ENABLED;
4385                         viewFlagMasks |= HAPTIC_FEEDBACK_ENABLED;
4386                     }
4387                     break;
4388                 case R.styleable.View_scrollbars:
4389                     final int scrollbars = a.getInt(attr, SCROLLBARS_NONE);
4390                     if (scrollbars != SCROLLBARS_NONE) {
4391                         viewFlagValues |= scrollbars;
4392                         viewFlagMasks |= SCROLLBARS_MASK;
4393                         initializeScrollbars = true;
4394                     }
4395                     break;
4396                 //noinspection deprecation
4397                 case R.styleable.View_fadingEdge:
4398                     if (targetSdkVersion >= ICE_CREAM_SANDWICH) {
4399                         // Ignore the attribute starting with ICS
4400                         break;
4401                     }
4402                     // With builds < ICS, fall through and apply fading edges
4403                 case R.styleable.View_requiresFadingEdge:
4404                     final int fadingEdge = a.getInt(attr, FADING_EDGE_NONE);
4405                     if (fadingEdge != FADING_EDGE_NONE) {
4406                         viewFlagValues |= fadingEdge;
4407                         viewFlagMasks |= FADING_EDGE_MASK;
4408                         initializeFadingEdgeInternal(a);
4409                     }
4410                     break;
4411                 case R.styleable.View_scrollbarStyle:
4412                     scrollbarStyle = a.getInt(attr, SCROLLBARS_INSIDE_OVERLAY);
4413                     if (scrollbarStyle != SCROLLBARS_INSIDE_OVERLAY) {
4414                         viewFlagValues |= scrollbarStyle & SCROLLBARS_STYLE_MASK;
4415                         viewFlagMasks |= SCROLLBARS_STYLE_MASK;
4416                     }
4417                     break;
4418                 case R.styleable.View_isScrollContainer:
4419                     setScrollContainer = true;
4420                     if (a.getBoolean(attr, false)) {
4421                         setScrollContainer(true);
4422                     }
4423                     break;
4424                 case com.android.internal.R.styleable.View_keepScreenOn:
4425                     if (a.getBoolean(attr, false)) {
4426                         viewFlagValues |= KEEP_SCREEN_ON;
4427                         viewFlagMasks |= KEEP_SCREEN_ON;
4428                     }
4429                     break;
4430                 case R.styleable.View_filterTouchesWhenObscured:
4431                     if (a.getBoolean(attr, false)) {
4432                         viewFlagValues |= FILTER_TOUCHES_WHEN_OBSCURED;
4433                         viewFlagMasks |= FILTER_TOUCHES_WHEN_OBSCURED;
4434                     }
4435                     break;
4436                 case R.styleable.View_nextFocusLeft:
4437                     mNextFocusLeftId = a.getResourceId(attr, View.NO_ID);
4438                     break;
4439                 case R.styleable.View_nextFocusRight:
4440                     mNextFocusRightId = a.getResourceId(attr, View.NO_ID);
4441                     break;
4442                 case R.styleable.View_nextFocusUp:
4443                     mNextFocusUpId = a.getResourceId(attr, View.NO_ID);
4444                     break;
4445                 case R.styleable.View_nextFocusDown:
4446                     mNextFocusDownId = a.getResourceId(attr, View.NO_ID);
4447                     break;
4448                 case R.styleable.View_nextFocusForward:
4449                     mNextFocusForwardId = a.getResourceId(attr, View.NO_ID);
4450                     break;
4451                 case R.styleable.View_minWidth:
4452                     mMinWidth = a.getDimensionPixelSize(attr, 0);
4453                     break;
4454                 case R.styleable.View_minHeight:
4455                     mMinHeight = a.getDimensionPixelSize(attr, 0);
4456                     break;
4457                 case R.styleable.View_onClick:
4458                     if (context.isRestricted()) {
4459                         throw new IllegalStateException("The android:onClick attribute cannot "
4460                                 + "be used within a restricted context");
4461                     }
4462
4463                     final String handlerName = a.getString(attr);
4464                     if (handlerName != null) {
4465                         setOnClickListener(new DeclaredOnClickListener(this, handlerName));
4466                     }
4467                     break;
4468                 case R.styleable.View_overScrollMode:
4469                     overScrollMode = a.getInt(attr, OVER_SCROLL_IF_CONTENT_SCROLLS);
4470                     break;
4471                 case R.styleable.View_verticalScrollbarPosition:
4472                     mVerticalScrollbarPosition = a.getInt(attr, SCROLLBAR_POSITION_DEFAULT);
4473                     break;
4474                 case R.styleable.View_layerType:
4475                     setLayerType(a.getInt(attr, LAYER_TYPE_NONE), null);
4476                     break;
4477                 case R.styleable.View_textDirection:
4478                     // Clear any text direction flag already set
4479                     mPrivateFlags2 &= ~PFLAG2_TEXT_DIRECTION_MASK;
4480                     // Set the text direction flags depending on the value of the attribute
4481                     final int textDirection = a.getInt(attr, -1);
4482                     if (textDirection != -1) {
4483                         mPrivateFlags2 |= PFLAG2_TEXT_DIRECTION_FLAGS[textDirection];
4484                     }
4485                     break;
4486                 case R.styleable.View_textAlignment:
4487                     // Clear any text alignment flag already set
4488                     mPrivateFlags2 &= ~PFLAG2_TEXT_ALIGNMENT_MASK;
4489                     // Set the text alignment flag depending on the value of the attribute
4490                     final int textAlignment = a.getInt(attr, TEXT_ALIGNMENT_DEFAULT);
4491                     mPrivateFlags2 |= PFLAG2_TEXT_ALIGNMENT_FLAGS[textAlignment];
4492                     break;
4493                 case R.styleable.View_importantForAccessibility:
4494                     setImportantForAccessibility(a.getInt(attr,
4495                             IMPORTANT_FOR_ACCESSIBILITY_DEFAULT));
4496                     break;
4497                 case R.styleable.View_accessibilityLiveRegion:
4498                     setAccessibilityLiveRegion(a.getInt(attr, ACCESSIBILITY_LIVE_REGION_DEFAULT));
4499                     break;
4500                 case R.styleable.View_transitionName:
4501                     setTransitionName(a.getString(attr));
4502                     break;
4503                 case R.styleable.View_nestedScrollingEnabled:
4504                     setNestedScrollingEnabled(a.getBoolean(attr, false));
4505                     break;
4506                 case R.styleable.View_stateListAnimator:
4507                     setStateListAnimator(AnimatorInflater.loadStateListAnimator(context,
4508                             a.getResourceId(attr, 0)));
4509                     break;
4510                 case R.styleable.View_backgroundTint:
4511                     // This will get applied later during setBackground().
4512                     if (mBackgroundTint == null) {
4513                         mBackgroundTint = new TintInfo();
4514                     }
4515                     mBackgroundTint.mTintList = a.getColorStateList(
4516                             R.styleable.View_backgroundTint);
4517                     mBackgroundTint.mHasTintList = true;
4518                     break;
4519                 case R.styleable.View_backgroundTintMode:
4520                     // This will get applied later during setBackground().
4521                     if (mBackgroundTint == null) {
4522                         mBackgroundTint = new TintInfo();
4523                     }
4524                     mBackgroundTint.mTintMode = Drawable.parseTintMode(a.getInt(
4525                             R.styleable.View_backgroundTintMode, -1), null);
4526                     mBackgroundTint.mHasTintMode = true;
4527                     break;
4528                 case R.styleable.View_outlineProvider:
4529                     setOutlineProviderFromAttribute(a.getInt(R.styleable.View_outlineProvider,
4530                             PROVIDER_BACKGROUND));
4531                     break;
4532                 case R.styleable.View_foreground:
4533                     if (targetSdkVersion >= VERSION_CODES.M || this instanceof FrameLayout) {
4534                         setForeground(a.getDrawable(attr));
4535                     }
4536                     break;
4537                 case R.styleable.View_foregroundGravity:
4538                     if (targetSdkVersion >= VERSION_CODES.M || this instanceof FrameLayout) {
4539                         setForegroundGravity(a.getInt(attr, Gravity.NO_GRAVITY));
4540                     }
4541                     break;
4542                 case R.styleable.View_foregroundTintMode:
4543                     if (targetSdkVersion >= VERSION_CODES.M || this instanceof FrameLayout) {
4544                         setForegroundTintMode(Drawable.parseTintMode(a.getInt(attr, -1), null));
4545                     }
4546                     break;
4547                 case R.styleable.View_foregroundTint:
4548                     if (targetSdkVersion >= VERSION_CODES.M || this instanceof FrameLayout) {
4549                         setForegroundTintList(a.getColorStateList(attr));
4550                     }
4551                     break;
4552                 case R.styleable.View_foregroundInsidePadding:
4553                     if (targetSdkVersion >= VERSION_CODES.M || this instanceof FrameLayout) {
4554                         if (mForegroundInfo == null) {
4555                             mForegroundInfo = new ForegroundInfo();
4556                         }
4557                         mForegroundInfo.mInsidePadding = a.getBoolean(attr,
4558                                 mForegroundInfo.mInsidePadding);
4559                     }
4560                     break;
4561                 case R.styleable.View_scrollIndicators:
4562                     final int scrollIndicators =
4563                             (a.getInt(attr, 0) << SCROLL_INDICATORS_TO_PFLAGS3_LSHIFT)
4564                                     & SCROLL_INDICATORS_PFLAG3_MASK;
4565                     if (scrollIndicators != 0) {
4566                         mPrivateFlags3 |= scrollIndicators;
4567                         initializeScrollIndicators = true;
4568                     }
4569                     break;
4570                 case R.styleable.View_pointerIcon:
4571                     final int resourceId = a.getResourceId(attr, 0);
4572                     if (resourceId != 0) {
4573                         setPointerIcon(PointerIcon.load(
4574                                 context.getResources(), resourceId));
4575                     } else {
4576                         final int pointerType = a.getInt(attr, PointerIcon.TYPE_NOT_SPECIFIED);
4577                         if (pointerType != PointerIcon.TYPE_NOT_SPECIFIED) {
4578                             setPointerIcon(PointerIcon.getSystemIcon(context, pointerType));
4579                         }
4580                     }
4581                     break;
4582                 case R.styleable.View_forceHasOverlappingRendering:
4583                     if (a.peekValue(attr) != null) {
4584                         forceHasOverlappingRendering(a.getBoolean(attr, true));
4585                     }
4586                     break;
4587
4588             }
4589         }
4590
4591         setOverScrollMode(overScrollMode);
4592
4593         // Cache start/end user padding as we cannot fully resolve padding here (we dont have yet
4594         // the resolved layout direction). Those cached values will be used later during padding
4595         // resolution.
4596         mUserPaddingStart = startPadding;
4597         mUserPaddingEnd = endPadding;
4598
4599         if (background != null) {
4600             setBackground(background);
4601         }
4602
4603         // setBackground above will record that padding is currently provided by the background.
4604         // If we have padding specified via xml, record that here instead and use it.
4605         mLeftPaddingDefined = leftPaddingDefined;
4606         mRightPaddingDefined = rightPaddingDefined;
4607
4608         if (padding >= 0) {
4609             leftPadding = padding;
4610             topPadding = padding;
4611             rightPadding = padding;
4612             bottomPadding = padding;
4613             mUserPaddingLeftInitial = padding;
4614             mUserPaddingRightInitial = padding;
4615         }
4616
4617         if (isRtlCompatibilityMode()) {
4618             // RTL compatibility mode: pre Jelly Bean MR1 case OR no RTL support case.
4619             // left / right padding are used if defined (meaning here nothing to do). If they are not
4620             // defined and start / end padding are defined (e.g. in Frameworks resources), then we use
4621             // start / end and resolve them as left / right (layout direction is not taken into account).
4622             // Padding from the background drawable is stored at this point in mUserPaddingLeftInitial
4623             // and mUserPaddingRightInitial) so drawable padding will be used as ultimate default if
4624             // defined.
4625             if (!mLeftPaddingDefined && startPaddingDefined) {
4626                 leftPadding = startPadding;
4627             }
4628             mUserPaddingLeftInitial = (leftPadding >= 0) ? leftPadding : mUserPaddingLeftInitial;
4629             if (!mRightPaddingDefined && endPaddingDefined) {
4630                 rightPadding = endPadding;
4631             }
4632             mUserPaddingRightInitial = (rightPadding >= 0) ? rightPadding : mUserPaddingRightInitial;
4633         } else {
4634             // Jelly Bean MR1 and after case: if start/end defined, they will override any left/right
4635             // values defined. Otherwise, left /right values are used.
4636             // Padding from the background drawable is stored at this point in mUserPaddingLeftInitial
4637             // and mUserPaddingRightInitial) so drawable padding will be used as ultimate default if
4638             // defined.
4639             final boolean hasRelativePadding = startPaddingDefined || endPaddingDefined;
4640
4641             if (mLeftPaddingDefined && !hasRelativePadding) {
4642                 mUserPaddingLeftInitial = leftPadding;
4643             }
4644             if (mRightPaddingDefined && !hasRelativePadding) {
4645                 mUserPaddingRightInitial = rightPadding;
4646             }
4647         }
4648
4649         internalSetPadding(
4650                 mUserPaddingLeftInitial,
4651                 topPadding >= 0 ? topPadding : mPaddingTop,
4652                 mUserPaddingRightInitial,
4653                 bottomPadding >= 0 ? bottomPadding : mPaddingBottom);
4654
4655         if (viewFlagMasks != 0) {
4656             setFlags(viewFlagValues, viewFlagMasks);
4657         }
4658
4659         if (initializeScrollbars) {
4660             initializeScrollbarsInternal(a);
4661         }
4662
4663         if (initializeScrollIndicators) {
4664             initializeScrollIndicatorsInternal();
4665         }
4666
4667         a.recycle();
4668
4669         // Needs to be called after mViewFlags is set
4670         if (scrollbarStyle != SCROLLBARS_INSIDE_OVERLAY) {
4671             recomputePadding();
4672         }
4673
4674         if (x != 0 || y != 0) {
4675             scrollTo(x, y);
4676         }
4677
4678         if (transformSet) {
4679             setTranslationX(tx);
4680             setTranslationY(ty);
4681             setTranslationZ(tz);
4682             setElevation(elevation);
4683             setRotation(rotation);
4684             setRotationX(rotationX);
4685             setRotationY(rotationY);
4686             setScaleX(sx);
4687             setScaleY(sy);
4688         }
4689
4690         if (!setScrollContainer && (viewFlagValues&SCROLLBARS_VERTICAL) != 0) {
4691             setScrollContainer(true);
4692         }
4693
4694         computeOpaqueFlags();
4695     }
4696
4697     /**
4698      * An implementation of OnClickListener that attempts to lazily load a
4699      * named click handling method from a parent or ancestor context.
4700      */
4701     private static class DeclaredOnClickListener implements OnClickListener {
4702         private final View mHostView;
4703         private final String mMethodName;
4704
4705         private Method mResolvedMethod;
4706         private Context mResolvedContext;
4707
4708         public DeclaredOnClickListener(@NonNull View hostView, @NonNull String methodName) {
4709             mHostView = hostView;
4710             mMethodName = methodName;
4711         }
4712
4713         @Override
4714         public void onClick(@NonNull View v) {
4715             if (mResolvedMethod == null) {
4716                 resolveMethod(mHostView.getContext(), mMethodName);
4717             }
4718
4719             try {
4720                 mResolvedMethod.invoke(mResolvedContext, v);
4721             } catch (IllegalAccessException e) {
4722                 throw new IllegalStateException(
4723                         "Could not execute non-public method for android:onClick", e);
4724             } catch (InvocationTargetException e) {
4725                 throw new IllegalStateException(
4726                         "Could not execute method for android:onClick", e);
4727             }
4728         }
4729
4730         @NonNull
4731         private void resolveMethod(@Nullable Context context, @NonNull String name) {
4732             while (context != null) {
4733                 try {
4734                     if (!context.isRestricted()) {
4735                         final Method method = context.getClass().getMethod(mMethodName, View.class);
4736                         if (method != null) {
4737                             mResolvedMethod = method;
4738                             mResolvedContext = context;
4739                             return;
4740                         }
4741                     }
4742                 } catch (NoSuchMethodException e) {
4743                     // Failed to find method, keep searching up the hierarchy.
4744                 }
4745
4746                 if (context instanceof ContextWrapper) {
4747                     context = ((ContextWrapper) context).getBaseContext();
4748                 } else {
4749                     // Can't search up the hierarchy, null out and fail.
4750                     context = null;
4751                 }
4752             }
4753
4754             final int id = mHostView.getId();
4755             final String idText = id == NO_ID ? "" : " with id '"
4756                     + mHostView.getContext().getResources().getResourceEntryName(id) + "'";
4757             throw new IllegalStateException("Could not find method " + mMethodName
4758                     + "(View) in a parent or ancestor Context for android:onClick "
4759                     + "attribute defined on view " + mHostView.getClass() + idText);
4760         }
4761     }
4762
4763     /**
4764      * Non-public constructor for use in testing
4765      */
4766     View() {
4767         mResources = null;
4768         mRenderNode = RenderNode.create(getClass().getName(), this);
4769     }
4770
4771     private static SparseArray<String> getAttributeMap() {
4772         if (mAttributeMap == null) {
4773             mAttributeMap = new SparseArray<>();
4774         }
4775         return mAttributeMap;
4776     }
4777
4778     private void saveAttributeData(@Nullable AttributeSet attrs, @NonNull TypedArray t) {
4779         final int attrsCount = attrs == null ? 0 : attrs.getAttributeCount();
4780         final int indexCount = t.getIndexCount();
4781         final String[] attributes = new String[(attrsCount + indexCount) * 2];
4782
4783         int i = 0;
4784
4785         // Store raw XML attributes.
4786         for (int j = 0; j < attrsCount; ++j) {
4787             attributes[i] = attrs.getAttributeName(j);
4788             attributes[i + 1] = attrs.getAttributeValue(j);
4789             i += 2;
4790         }
4791
4792         // Store resolved styleable attributes.
4793         final Resources res = t.getResources();
4794         final SparseArray<String> attributeMap = getAttributeMap();
4795         for (int j = 0; j < indexCount; ++j) {
4796             final int index = t.getIndex(j);
4797             if (!t.hasValueOrEmpty(index)) {
4798                 // Value is undefined. Skip it.
4799                 continue;
4800             }
4801
4802             final int resourceId = t.getResourceId(index, 0);
4803             if (resourceId == 0) {
4804                 // Value is not a reference. Skip it.
4805                 continue;
4806             }
4807
4808             String resourceName = attributeMap.get(resourceId);
4809             if (resourceName == null) {
4810                 try {
4811                     resourceName = res.getResourceName(resourceId);
4812                 } catch (Resources.NotFoundException e) {
4813                     resourceName = "0x" + Integer.toHexString(resourceId);
4814                 }
4815                 attributeMap.put(resourceId, resourceName);
4816             }
4817
4818             attributes[i] = resourceName;
4819             attributes[i + 1] = t.getString(index);
4820             i += 2;
4821         }
4822
4823         // Trim to fit contents.
4824         final String[] trimmed = new String[i];
4825         System.arraycopy(attributes, 0, trimmed, 0, i);
4826         mAttributes = trimmed;
4827     }
4828
4829     public String toString() {
4830         StringBuilder out = new StringBuilder(128);
4831         out.append(getClass().getName());
4832         out.append('{');
4833         out.append(Integer.toHexString(System.identityHashCode(this)));
4834         out.append(' ');
4835         switch (mViewFlags&VISIBILITY_MASK) {
4836             case VISIBLE: out.append('V'); break;
4837             case INVISIBLE: out.append('I'); break;
4838             case GONE: out.append('G'); break;
4839             default: out.append('.'); break;
4840         }
4841         out.append((mViewFlags&FOCUSABLE_MASK) == FOCUSABLE ? 'F' : '.');
4842         out.append((mViewFlags&ENABLED_MASK) == ENABLED ? 'E' : '.');
4843         out.append((mViewFlags&DRAW_MASK) == WILL_NOT_DRAW ? '.' : 'D');
4844         out.append((mViewFlags&SCROLLBARS_HORIZONTAL) != 0 ? 'H' : '.');
4845         out.append((mViewFlags&SCROLLBARS_VERTICAL) != 0 ? 'V' : '.');
4846         out.append((mViewFlags&CLICKABLE) != 0 ? 'C' : '.');
4847         out.append((mViewFlags&LONG_CLICKABLE) != 0 ? 'L' : '.');
4848         out.append((mViewFlags&CONTEXT_CLICKABLE) != 0 ? 'X' : '.');
4849         out.append(' ');
4850         out.append((mPrivateFlags&PFLAG_IS_ROOT_NAMESPACE) != 0 ? 'R' : '.');
4851         out.append((mPrivateFlags&PFLAG_FOCUSED) != 0 ? 'F' : '.');
4852         out.append((mPrivateFlags&PFLAG_SELECTED) != 0 ? 'S' : '.');
4853         if ((mPrivateFlags&PFLAG_PREPRESSED) != 0) {
4854             out.append('p');
4855         } else {
4856             out.append((mPrivateFlags&PFLAG_PRESSED) != 0 ? 'P' : '.');
4857         }
4858         out.append((mPrivateFlags&PFLAG_HOVERED) != 0 ? 'H' : '.');
4859         out.append((mPrivateFlags&PFLAG_ACTIVATED) != 0 ? 'A' : '.');
4860         out.append((mPrivateFlags&PFLAG_INVALIDATED) != 0 ? 'I' : '.');
4861         out.append((mPrivateFlags&PFLAG_DIRTY_MASK) != 0 ? 'D' : '.');
4862         out.append(' ');
4863         out.append(mLeft);
4864         out.append(',');
4865         out.append(mTop);
4866         out.append('-');
4867         out.append(mRight);
4868         out.append(',');
4869         out.append(mBottom);
4870         final int id = getId();
4871         if (id != NO_ID) {
4872             out.append(" #");
4873             out.append(Integer.toHexString(id));
4874             final Resources r = mResources;
4875             if (id > 0 && Resources.resourceHasPackage(id) && r != null) {
4876                 try {
4877                     String pkgname;
4878                     switch (id&0xff000000) {
4879                         case 0x7f000000:
4880                             pkgname="app";
4881                             break;
4882                         case 0x01000000:
4883                             pkgname="android";
4884                             break;
4885                         default:
4886                             pkgname = r.getResourcePackageName(id);
4887                             break;
4888                     }
4889                     String typename = r.getResourceTypeName(id);
4890                     String entryname = r.getResourceEntryName(id);
4891                     out.append(" ");
4892                     out.append(pkgname);
4893                     out.append(":");
4894                     out.append(typename);
4895                     out.append("/");
4896                     out.append(entryname);
4897                 } catch (Resources.NotFoundException e) {
4898                 }
4899             }
4900         }
4901         out.append("}");
4902         return out.toString();
4903     }
4904
4905     /**
4906      * <p>
4907      * Initializes the fading edges from a given set of styled attributes. This
4908      * method should be called by subclasses that need fading edges and when an
4909      * instance of these subclasses is created programmatically rather than
4910      * being inflated from XML. This method is automatically called when the XML
4911      * is inflated.
4912      * </p>
4913      *
4914      * @param a the styled attributes set to initialize the fading edges from
4915      *
4916      * @removed
4917      */
4918     protected void initializeFadingEdge(TypedArray a) {
4919         // This method probably shouldn't have been included in the SDK to begin with.
4920         // It relies on 'a' having been initialized using an attribute filter array that is
4921         // not publicly available to the SDK. The old method has been renamed
4922         // to initializeFadingEdgeInternal and hidden for framework use only;
4923         // this one initializes using defaults to make it safe to call for apps.
4924
4925         TypedArray arr = mContext.obtainStyledAttributes(com.android.internal.R.styleable.View);
4926
4927         initializeFadingEdgeInternal(arr);
4928
4929         arr.recycle();
4930     }
4931
4932     /**
4933      * <p>
4934      * Initializes the fading edges from a given set of styled attributes. This
4935      * method should be called by subclasses that need fading edges and when an
4936      * instance of these subclasses is created programmatically rather than
4937      * being inflated from XML. This method is automatically called when the XML
4938      * is inflated.
4939      * </p>
4940      *
4941      * @param a the styled attributes set to initialize the fading edges from
4942      * @hide This is the real method; the public one is shimmed to be safe to call from apps.
4943      */
4944     protected void initializeFadingEdgeInternal(TypedArray a) {
4945         initScrollCache();
4946
4947         mScrollCache.fadingEdgeLength = a.getDimensionPixelSize(
4948                 R.styleable.View_fadingEdgeLength,
4949                 ViewConfiguration.get(mContext).getScaledFadingEdgeLength());
4950     }
4951
4952     /**
4953      * Returns the size of the vertical faded edges used to indicate that more
4954      * content in this view is visible.
4955      *
4956      * @return The size in pixels of the vertical faded edge or 0 if vertical
4957      *         faded edges are not enabled for this view.
4958      * @attr ref android.R.styleable#View_fadingEdgeLength
4959      */
4960     public int getVerticalFadingEdgeLength() {
4961         if (isVerticalFadingEdgeEnabled()) {
4962             ScrollabilityCache cache = mScrollCache;
4963             if (cache != null) {
4964                 return cache.fadingEdgeLength;
4965             }
4966         }
4967         return 0;
4968     }
4969
4970     /**
4971      * Set the size of the faded edge used to indicate that more content in this
4972      * view is available.  Will not change whether the fading edge is enabled; use
4973      * {@link #setVerticalFadingEdgeEnabled(boolean)} or
4974      * {@link #setHorizontalFadingEdgeEnabled(boolean)} to enable the fading edge
4975      * for the vertical or horizontal fading edges.
4976      *
4977      * @param length The size in pixels of the faded edge used to indicate that more
4978      *        content in this view is visible.
4979      */
4980     public void setFadingEdgeLength(int length) {
4981         initScrollCache();
4982         mScrollCache.fadingEdgeLength = length;
4983     }
4984
4985     /**
4986      * Returns the size of the horizontal faded edges used to indicate that more
4987      * content in this view is visible.
4988      *
4989      * @return The size in pixels of the horizontal faded edge or 0 if horizontal
4990      *         faded edges are not enabled for this view.
4991      * @attr ref android.R.styleable#View_fadingEdgeLength
4992      */
4993     public int getHorizontalFadingEdgeLength() {
4994         if (isHorizontalFadingEdgeEnabled()) {
4995             ScrollabilityCache cache = mScrollCache;
4996             if (cache != null) {
4997                 return cache.fadingEdgeLength;
4998             }
4999         }
5000         return 0;
5001     }
5002
5003     /**
5004      * Returns the width of the vertical scrollbar.
5005      *
5006      * @return The width in pixels of the vertical scrollbar or 0 if there
5007      *         is no vertical scrollbar.
5008      */
5009     public int getVerticalScrollbarWidth() {
5010         ScrollabilityCache cache = mScrollCache;
5011         if (cache != null) {
5012             ScrollBarDrawable scrollBar = cache.scrollBar;
5013             if (scrollBar != null) {
5014                 int size = scrollBar.getSize(true);
5015                 if (size <= 0) {
5016                     size = cache.scrollBarSize;
5017                 }
5018                 return size;
5019             }
5020             return 0;
5021         }
5022         return 0;
5023     }
5024
5025     /**
5026      * Returns the height of the horizontal scrollbar.
5027      *
5028      * @return The height in pixels of the horizontal scrollbar or 0 if
5029      *         there is no horizontal scrollbar.
5030      */
5031     protected int getHorizontalScrollbarHeight() {
5032         ScrollabilityCache cache = mScrollCache;
5033         if (cache != null) {
5034             ScrollBarDrawable scrollBar = cache.scrollBar;
5035             if (scrollBar != null) {
5036                 int size = scrollBar.getSize(false);
5037                 if (size <= 0) {
5038                     size = cache.scrollBarSize;
5039                 }
5040                 return size;
5041             }
5042             return 0;
5043         }
5044         return 0;
5045     }
5046
5047     /**
5048      * <p>
5049      * Initializes the scrollbars from a given set of styled attributes. This
5050      * method should be called by subclasses that need scrollbars and when an
5051      * instance of these subclasses is created programmatically rather than
5052      * being inflated from XML. This method is automatically called when the XML
5053      * is inflated.
5054      * </p>
5055      *
5056      * @param a the styled attributes set to initialize the scrollbars from
5057      *
5058      * @removed
5059      */
5060     protected void initializeScrollbars(TypedArray a) {
5061         // It's not safe to use this method from apps. The parameter 'a' must have been obtained
5062         // using the View filter array which is not available to the SDK. As such, internal
5063         // framework usage now uses initializeScrollbarsInternal and we grab a default
5064         // TypedArray with the right filter instead here.
5065         TypedArray arr = mContext.obtainStyledAttributes(com.android.internal.R.styleable.View);
5066
5067         initializeScrollbarsInternal(arr);
5068
5069         // We ignored the method parameter. Recycle the one we actually did use.
5070         arr.recycle();
5071     }
5072
5073     /**
5074      * <p>
5075      * Initializes the scrollbars from a given set of styled attributes. This
5076      * method should be called by subclasses that need scrollbars and when an
5077      * instance of these subclasses is created programmatically rather than
5078      * being inflated from XML. This method is automatically called when the XML
5079      * is inflated.
5080      * </p>
5081      *
5082      * @param a the styled attributes set to initialize the scrollbars from
5083      * @hide
5084      */
5085     protected void initializeScrollbarsInternal(TypedArray a) {
5086         initScrollCache();
5087
5088         final ScrollabilityCache scrollabilityCache = mScrollCache;
5089
5090         if (scrollabilityCache.scrollBar == null) {
5091             scrollabilityCache.scrollBar = new ScrollBarDrawable();
5092             scrollabilityCache.scrollBar.setState(getDrawableState());
5093             scrollabilityCache.scrollBar.setCallback(this);
5094         }
5095
5096         final boolean fadeScrollbars = a.getBoolean(R.styleable.View_fadeScrollbars, true);
5097
5098         if (!fadeScrollbars) {
5099             scrollabilityCache.state = ScrollabilityCache.ON;
5100         }
5101         scrollabilityCache.fadeScrollBars = fadeScrollbars;
5102
5103
5104         scrollabilityCache.scrollBarFadeDuration = a.getInt(
5105                 R.styleable.View_scrollbarFadeDuration, ViewConfiguration
5106                         .getScrollBarFadeDuration());
5107         scrollabilityCache.scrollBarDefaultDelayBeforeFade = a.getInt(
5108                 R.styleable.View_scrollbarDefaultDelayBeforeFade,
5109                 ViewConfiguration.getScrollDefaultDelay());
5110
5111
5112         scrollabilityCache.scrollBarSize = a.getDimensionPixelSize(
5113                 com.android.internal.R.styleable.View_scrollbarSize,
5114                 ViewConfiguration.get(mContext).getScaledScrollBarSize());
5115
5116         Drawable track = a.getDrawable(R.styleable.View_scrollbarTrackHorizontal);
5117         scrollabilityCache.scrollBar.setHorizontalTrackDrawable(track);
5118
5119         Drawable thumb = a.getDrawable(R.styleable.View_scrollbarThumbHorizontal);
5120         if (thumb != null) {
5121             scrollabilityCache.scrollBar.setHorizontalThumbDrawable(thumb);
5122         }
5123
5124         boolean alwaysDraw = a.getBoolean(R.styleable.View_scrollbarAlwaysDrawHorizontalTrack,
5125                 false);
5126         if (alwaysDraw) {
5127             scrollabilityCache.scrollBar.setAlwaysDrawHorizontalTrack(true);
5128         }
5129
5130         track = a.getDrawable(R.styleable.View_scrollbarTrackVertical);
5131         scrollabilityCache.scrollBar.setVerticalTrackDrawable(track);
5132
5133         thumb = a.getDrawable(R.styleable.View_scrollbarThumbVertical);
5134         if (thumb != null) {
5135             scrollabilityCache.scrollBar.setVerticalThumbDrawable(thumb);
5136         }
5137
5138         alwaysDraw = a.getBoolean(R.styleable.View_scrollbarAlwaysDrawVerticalTrack,
5139                 false);
5140         if (alwaysDraw) {
5141             scrollabilityCache.scrollBar.setAlwaysDrawVerticalTrack(true);
5142         }
5143
5144         // Apply layout direction to the new Drawables if needed
5145         final int layoutDirection = getLayoutDirection();
5146         if (track != null) {
5147             track.setLayoutDirection(layoutDirection);
5148         }
5149         if (thumb != null) {
5150             thumb.setLayoutDirection(layoutDirection);
5151         }
5152
5153         // Re-apply user/background padding so that scrollbar(s) get added
5154         resolvePadding();
5155     }
5156
5157     private void initializeScrollIndicatorsInternal() {
5158         // Some day maybe we'll break this into top/left/start/etc. and let the
5159         // client control it. Until then, you can have any scroll indicator you
5160         // want as long as it's a 1dp foreground-colored rectangle.
5161         if (mScrollIndicatorDrawable == null) {
5162             mScrollIndicatorDrawable = mContext.getDrawable(R.drawable.scroll_indicator_material);
5163         }
5164     }
5165
5166     /**
5167      * <p>
5168      * Initalizes the scrollability cache if necessary.
5169      * </p>
5170      */
5171     private void initScrollCache() {
5172         if (mScrollCache == null) {
5173             mScrollCache = new ScrollabilityCache(ViewConfiguration.get(mContext), this);
5174         }
5175     }
5176
5177     private ScrollabilityCache getScrollCache() {
5178         initScrollCache();
5179         return mScrollCache;
5180     }
5181
5182     /**
5183      * Set the position of the vertical scroll bar. Should be one of
5184      * {@link #SCROLLBAR_POSITION_DEFAULT}, {@link #SCROLLBAR_POSITION_LEFT} or
5185      * {@link #SCROLLBAR_POSITION_RIGHT}.
5186      *
5187      * @param position Where the vertical scroll bar should be positioned.
5188      */
5189     public void setVerticalScrollbarPosition(int position) {
5190         if (mVerticalScrollbarPosition != position) {
5191             mVerticalScrollbarPosition = position;
5192             computeOpaqueFlags();
5193             resolvePadding();
5194         }
5195     }
5196
5197     /**
5198      * @return The position where the vertical scroll bar will show, if applicable.
5199      * @see #setVerticalScrollbarPosition(int)
5200      */
5201     public int getVerticalScrollbarPosition() {
5202         return mVerticalScrollbarPosition;
5203     }
5204
5205     boolean isOnScrollbar(float x, float y) {
5206         if (mScrollCache == null) {
5207             return false;
5208         }
5209         x += getScrollX();
5210         y += getScrollY();
5211         if (isVerticalScrollBarEnabled() && !isVerticalScrollBarHidden()) {
5212             final Rect bounds = mScrollCache.mScrollBarBounds;
5213             getVerticalScrollBarBounds(bounds);
5214             if (bounds.contains((int)x, (int)y)) {
5215                 return true;
5216             }
5217         }
5218         if (isHorizontalScrollBarEnabled()) {
5219             final Rect bounds = mScrollCache.mScrollBarBounds;
5220             getHorizontalScrollBarBounds(bounds);
5221             if (bounds.contains((int)x, (int)y)) {
5222                 return true;
5223             }
5224         }
5225         return false;
5226     }
5227
5228     boolean isOnScrollbarThumb(float x, float y) {
5229         return isOnVerticalScrollbarThumb(x, y) || isOnHorizontalScrollbarThumb(x, y);
5230     }
5231
5232     private boolean isOnVerticalScrollbarThumb(float x, float y) {
5233         if (mScrollCache == null) {
5234             return false;
5235         }
5236         if (isVerticalScrollBarEnabled() && !isVerticalScrollBarHidden()) {
5237             x += getScrollX();
5238             y += getScrollY();
5239             final Rect bounds = mScrollCache.mScrollBarBounds;
5240             getVerticalScrollBarBounds(bounds);
5241             final int range = computeVerticalScrollRange();
5242             final int offset = computeVerticalScrollOffset();
5243             final int extent = computeVerticalScrollExtent();
5244             final int thumbLength = ScrollBarUtils.getThumbLength(bounds.height(), bounds.width(),
5245                     extent, range);
5246             final int thumbOffset = ScrollBarUtils.getThumbOffset(bounds.height(), thumbLength,
5247                     extent, range, offset);
5248             final int thumbTop = bounds.top + thumbOffset;
5249             if (x >= bounds.left && x <= bounds.right && y >= thumbTop
5250                     && y <= thumbTop + thumbLength) {
5251                 return true;
5252             }
5253         }
5254         return false;
5255     }
5256
5257     private boolean isOnHorizontalScrollbarThumb(float x, float y) {
5258         if (mScrollCache == null) {
5259             return false;
5260         }
5261         if (isHorizontalScrollBarEnabled()) {
5262             x += getScrollX();
5263             y += getScrollY();
5264             final Rect bounds = mScrollCache.mScrollBarBounds;
5265             getHorizontalScrollBarBounds(bounds);
5266             final int range = computeHorizontalScrollRange();
5267             final int offset = computeHorizontalScrollOffset();
5268             final int extent = computeHorizontalScrollExtent();
5269             final int thumbLength = ScrollBarUtils.getThumbLength(bounds.width(), bounds.height(),
5270                     extent, range);
5271             final int thumbOffset = ScrollBarUtils.getThumbOffset(bounds.width(), thumbLength,
5272                     extent, range, offset);
5273             final int thumbLeft = bounds.left + thumbOffset;
5274             if (x >= thumbLeft && x <= thumbLeft + thumbLength && y >= bounds.top
5275                     && y <= bounds.bottom) {
5276                 return true;
5277             }
5278         }
5279         return false;
5280     }
5281
5282     boolean isDraggingScrollBar() {
5283         return mScrollCache != null
5284                 && mScrollCache.mScrollBarDraggingState != ScrollabilityCache.NOT_DRAGGING;
5285     }
5286
5287     /**
5288      * Sets the state of all scroll indicators.
5289      * <p>
5290      * See {@link #setScrollIndicators(int, int)} for usage information.
5291      *
5292      * @param indicators a bitmask of indicators that should be enabled, or
5293      *                   {@code 0} to disable all indicators
5294      * @see #setScrollIndicators(int, int)
5295      * @see #getScrollIndicators()
5296      * @attr ref android.R.styleable#View_scrollIndicators
5297      */
5298     public void setScrollIndicators(@ScrollIndicators int indicators) {
5299         setScrollIndicators(indicators,
5300                 SCROLL_INDICATORS_PFLAG3_MASK >>> SCROLL_INDICATORS_TO_PFLAGS3_LSHIFT);
5301     }
5302
5303     /**
5304      * Sets the state of the scroll indicators specified by the mask. To change
5305      * all scroll indicators at once, see {@link #setScrollIndicators(int)}.
5306      * <p>
5307      * When a scroll indicator is enabled, it will be displayed if the view
5308      * can scroll in the direction of the indicator.
5309      * <p>
5310      * Multiple indicator types may be enabled or disabled by passing the
5311      * logical OR of the desired types. If multiple types are specified, they
5312      * will all be set to the same enabled state.
5313      * <p>
5314      * For example, to enable the top scroll indicatorExample: {@code setScrollIndicators
5315      *
5316      * @param indicators the indicator direction, or the logical OR of multiple
5317      *             indicator directions. One or more of:
5318      *             <ul>
5319      *               <li>{@link #SCROLL_INDICATOR_TOP}</li>
5320      *               <li>{@link #SCROLL_INDICATOR_BOTTOM}</li>
5321      *               <li>{@link #SCROLL_INDICATOR_LEFT}</li>
5322      *               <li>{@link #SCROLL_INDICATOR_RIGHT}</li>
5323      *               <li>{@link #SCROLL_INDICATOR_START}</li>
5324      *               <li>{@link #SCROLL_INDICATOR_END}</li>
5325      *             </ul>
5326      * @see #setScrollIndicators(int)
5327      * @see #getScrollIndicators()
5328      * @attr ref android.R.styleable#View_scrollIndicators
5329      */
5330     public void setScrollIndicators(@ScrollIndicators int indicators, @ScrollIndicators int mask) {
5331         // Shift and sanitize mask.
5332         mask <<= SCROLL_INDICATORS_TO_PFLAGS3_LSHIFT;
5333         mask &= SCROLL_INDICATORS_PFLAG3_MASK;
5334
5335         // Shift and mask indicators.
5336         indicators <<= SCROLL_INDICATORS_TO_PFLAGS3_LSHIFT;
5337         indicators &= mask;
5338
5339         // Merge with non-masked flags.
5340         final int updatedFlags = indicators | (mPrivateFlags3 & ~mask);
5341
5342         if (mPrivateFlags3 != updatedFlags) {
5343             mPrivateFlags3 = updatedFlags;
5344
5345             if (indicators != 0) {
5346                 initializeScrollIndicatorsInternal();
5347             }
5348             invalidate();
5349         }
5350     }
5351
5352     /**
5353      * Returns a bitmask representing the enabled scroll indicators.
5354      * <p>
5355      * For example, if the top and left scroll indicators are enabled and all
5356      * other indicators are disabled, the return value will be
5357      * {@code View.SCROLL_INDICATOR_TOP | View.SCROLL_INDICATOR_LEFT}.
5358      * <p>
5359      * To check whether the bottom scroll indicator is enabled, use the value
5360      * of {@code (getScrollIndicators() & View.SCROLL_INDICATOR_BOTTOM) != 0}.
5361      *
5362      * @return a bitmask representing the enabled scroll indicators
5363      */
5364     @ScrollIndicators
5365     public int getScrollIndicators() {
5366         return (mPrivateFlags3 & SCROLL_INDICATORS_PFLAG3_MASK)
5367                 >>> SCROLL_INDICATORS_TO_PFLAGS3_LSHIFT;
5368     }
5369
5370     ListenerInfo getListenerInfo() {
5371         if (mListenerInfo != null) {
5372             return mListenerInfo;
5373         }
5374         mListenerInfo = new ListenerInfo();
5375         return mListenerInfo;
5376     }
5377
5378     /**
5379      * Register a callback to be invoked when the scroll X or Y positions of
5380      * this view change.
5381      * <p>
5382      * <b>Note:</b> Some views handle scrolling independently from View and may
5383      * have their own separate listeners for scroll-type events. For example,
5384      * {@link android.widget.ListView ListView} allows clients to register an
5385      * {@link android.widget.ListView#setOnScrollListener(android.widget.AbsListView.OnScrollListener) AbsListView.OnScrollListener}
5386      * to listen for changes in list scroll position.
5387      *
5388      * @param l The listener to notify when the scroll X or Y position changes.
5389      * @see android.view.View#getScrollX()
5390      * @see android.view.View#getScrollY()
5391      */
5392     public void setOnScrollChangeListener(OnScrollChangeListener l) {
5393         getListenerInfo().mOnScrollChangeListener = l;
5394     }
5395
5396     /**
5397      * Register a callback to be invoked when focus of this view changed.
5398      *
5399      * @param l The callback that will run.
5400      */
5401     public void setOnFocusChangeListener(OnFocusChangeListener l) {
5402         getListenerInfo().mOnFocusChangeListener = l;
5403     }
5404
5405     /**
5406      * Add a listener that will be called when the bounds of the view change due to
5407      * layout processing.
5408      *
5409      * @param listener The listener that will be called when layout bounds change.
5410      */
5411     public void addOnLayoutChangeListener(OnLayoutChangeListener listener) {
5412         ListenerInfo li = getListenerInfo();
5413         if (li.mOnLayoutChangeListeners == null) {
5414             li.mOnLayoutChangeListeners = new ArrayList<OnLayoutChangeListener>();
5415         }
5416         if (!li.mOnLayoutChangeListeners.contains(listener)) {
5417             li.mOnLayoutChangeListeners.add(listener);
5418         }
5419     }
5420
5421     /**
5422      * Remove a listener for layout changes.
5423      *
5424      * @param listener The listener for layout bounds change.
5425      */
5426     public void removeOnLayoutChangeListener(OnLayoutChangeListener listener) {
5427         ListenerInfo li = mListenerInfo;
5428         if (li == null || li.mOnLayoutChangeListeners == null) {
5429             return;
5430         }
5431         li.mOnLayoutChangeListeners.remove(listener);
5432     }
5433
5434     /**
5435      * Add a listener for attach state changes.
5436      *
5437      * This listener will be called whenever this view is attached or detached
5438      * from a window. Remove the listener using
5439      * {@link #removeOnAttachStateChangeListener(OnAttachStateChangeListener)}.
5440      *
5441      * @param listener Listener to attach
5442      * @see #removeOnAttachStateChangeListener(OnAttachStateChangeListener)
5443      */
5444     public void addOnAttachStateChangeListener(OnAttachStateChangeListener listener) {
5445         ListenerInfo li = getListenerInfo();
5446         if (li.mOnAttachStateChangeListeners == null) {
5447             li.mOnAttachStateChangeListeners
5448                     = new CopyOnWriteArrayList<OnAttachStateChangeListener>();
5449         }
5450         li.mOnAttachStateChangeListeners.add(listener);
5451     }
5452
5453     /**
5454      * Remove a listener for attach state changes. The listener will receive no further
5455      * notification of window attach/detach events.
5456      *
5457      * @param listener Listener to remove
5458      * @see #addOnAttachStateChangeListener(OnAttachStateChangeListener)
5459      */
5460     public void removeOnAttachStateChangeListener(OnAttachStateChangeListener listener) {
5461         ListenerInfo li = mListenerInfo;
5462         if (li == null || li.mOnAttachStateChangeListeners == null) {
5463             return;
5464         }
5465         li.mOnAttachStateChangeListeners.remove(listener);
5466     }
5467
5468     /**
5469      * Returns the focus-change callback registered for this view.
5470      *
5471      * @return The callback, or null if one is not registered.
5472      */
5473     public OnFocusChangeListener getOnFocusChangeListener() {
5474         ListenerInfo li = mListenerInfo;
5475         return li != null ? li.mOnFocusChangeListener : null;
5476     }
5477
5478     /**
5479      * Register a callback to be invoked when this view is clicked. If this view is not
5480      * clickable, it becomes clickable.
5481      *
5482      * @param l The callback that will run
5483      *
5484      * @see #setClickable(boolean)
5485      */
5486     public void setOnClickListener(@Nullable OnClickListener l) {
5487         if (!isClickable()) {
5488             setClickable(true);
5489         }
5490         getListenerInfo().mOnClickListener = l;
5491     }
5492
5493     /**
5494      * Return whether this view has an attached OnClickListener.  Returns
5495      * true if there is a listener, false if there is none.
5496      */
5497     public boolean hasOnClickListeners() {
5498         ListenerInfo li = mListenerInfo;
5499         return (li != null && li.mOnClickListener != null);
5500     }
5501
5502     /**
5503      * Register a callback to be invoked when this view is clicked and held. If this view is not
5504      * long clickable, it becomes long clickable.
5505      *
5506      * @param l The callback that will run
5507      *
5508      * @see #setLongClickable(boolean)
5509      */
5510     public void setOnLongClickListener(@Nullable OnLongClickListener l) {
5511         if (!isLongClickable()) {
5512             setLongClickable(true);
5513         }
5514         getListenerInfo().mOnLongClickListener = l;
5515     }
5516
5517     /**
5518      * Register a callback to be invoked when this view is context clicked. If the view is not
5519      * context clickable, it becomes context clickable.
5520      *
5521      * @param l The callback that will run
5522      * @see #setContextClickable(boolean)
5523      */
5524     public void setOnContextClickListener(@Nullable OnContextClickListener l) {
5525         if (!isContextClickable()) {
5526             setContextClickable(true);
5527         }
5528         getListenerInfo().mOnContextClickListener = l;
5529     }
5530
5531     /**
5532      * Register a callback to be invoked when the context menu for this view is
5533      * being built. If this view is not long clickable, it becomes long clickable.
5534      *
5535      * @param l The callback that will run
5536      *
5537      */
5538     public void setOnCreateContextMenuListener(OnCreateContextMenuListener l) {
5539         if (!isLongClickable()) {
5540             setLongClickable(true);
5541         }
5542         getListenerInfo().mOnCreateContextMenuListener = l;
5543     }
5544
5545     /**
5546      * Set an observer to collect stats for each frame rendered for this view.
5547      *
5548      * @hide
5549      */
5550     public void addFrameMetricsListener(Window window,
5551             Window.OnFrameMetricsAvailableListener listener,
5552             Handler handler) {
5553         if (mAttachInfo != null) {
5554             if (mAttachInfo.mHardwareRenderer != null) {
5555                 if (mFrameMetricsObservers == null) {
5556                     mFrameMetricsObservers = new ArrayList<>();
5557                 }
5558
5559                 FrameMetricsObserver fmo = new FrameMetricsObserver(window,
5560                         handler.getLooper(), listener);
5561                 mFrameMetricsObservers.add(fmo);
5562                 mAttachInfo.mHardwareRenderer.addFrameMetricsObserver(fmo);
5563             } else {
5564                 Log.w(VIEW_LOG_TAG, "View not hardware-accelerated. Unable to observe frame stats");
5565             }
5566         } else {
5567             if (mFrameMetricsObservers == null) {
5568                 mFrameMetricsObservers = new ArrayList<>();
5569             }
5570
5571             FrameMetricsObserver fmo = new FrameMetricsObserver(window,
5572                     handler.getLooper(), listener);
5573             mFrameMetricsObservers.add(fmo);
5574         }
5575     }
5576
5577     /**
5578      * Remove observer configured to collect frame stats for this view.
5579      *
5580      * @hide
5581      */
5582     public void removeFrameMetricsListener(
5583             Window.OnFrameMetricsAvailableListener listener) {
5584         ThreadedRenderer renderer = getHardwareRenderer();
5585         FrameMetricsObserver fmo = findFrameMetricsObserver(listener);
5586         if (fmo == null) {
5587             throw new IllegalArgumentException(
5588                     "attempt to remove OnFrameMetricsAvailableListener that was never added");
5589         }
5590
5591         if (mFrameMetricsObservers != null) {
5592             mFrameMetricsObservers.remove(fmo);
5593             if (renderer != null) {
5594                 renderer.removeFrameMetricsObserver(fmo);
5595             }
5596         }
5597     }
5598
5599     private void registerPendingFrameMetricsObservers() {
5600         if (mFrameMetricsObservers != null) {
5601             ThreadedRenderer renderer = getHardwareRenderer();
5602             if (renderer != null) {
5603                 for (FrameMetricsObserver fmo : mFrameMetricsObservers) {
5604                     renderer.addFrameMetricsObserver(fmo);
5605                 }
5606             } else {
5607                 Log.w(VIEW_LOG_TAG, "View not hardware-accelerated. Unable to observe frame stats");
5608             }
5609         }
5610     }
5611
5612     private FrameMetricsObserver findFrameMetricsObserver(
5613             Window.OnFrameMetricsAvailableListener listener) {
5614         for (int i = 0; i < mFrameMetricsObservers.size(); i++) {
5615             FrameMetricsObserver observer = mFrameMetricsObservers.get(i);
5616             if (observer.mListener == listener) {
5617                 return observer;
5618             }
5619         }
5620
5621         return null;
5622     }
5623
5624     /**
5625      * Call this view's OnClickListener, if it is defined.  Performs all normal
5626      * actions associated with clicking: reporting accessibility event, playing
5627      * a sound, etc.
5628      *
5629      * @return True there was an assigned OnClickListener that was called, false
5630      *         otherwise is returned.
5631      */
5632     public boolean performClick() {
5633         final boolean result;
5634         final ListenerInfo li = mListenerInfo;
5635         if (li != null && li.mOnClickListener != null) {
5636             playSoundEffect(SoundEffectConstants.CLICK);
5637             li.mOnClickListener.onClick(this);
5638             result = true;
5639         } else {
5640             result = false;
5641         }
5642
5643         sendAccessibilityEvent(AccessibilityEvent.TYPE_VIEW_CLICKED);
5644         return result;
5645     }
5646
5647     /**
5648      * Directly call any attached OnClickListener.  Unlike {@link #performClick()},
5649      * this only calls the listener, and does not do any associated clicking
5650      * actions like reporting an accessibility event.
5651      *
5652      * @return True there was an assigned OnClickListener that was called, false
5653      *         otherwise is returned.
5654      */
5655     public boolean callOnClick() {
5656         ListenerInfo li = mListenerInfo;
5657         if (li != null && li.mOnClickListener != null) {
5658             li.mOnClickListener.onClick(this);
5659             return true;
5660         }
5661         return false;
5662     }
5663
5664     /**
5665      * Calls this view's OnLongClickListener, if it is defined. Invokes the
5666      * context menu if the OnLongClickListener did not consume the event.
5667      *
5668      * @return {@code true} if one of the above receivers consumed the event,
5669      *         {@code false} otherwise
5670      */
5671     public boolean performLongClick() {
5672         return performLongClickInternal(mLongClickX, mLongClickY);
5673     }
5674
5675     /**
5676      * Calls this view's OnLongClickListener, if it is defined. Invokes the
5677      * context menu if the OnLongClickListener did not consume the event,
5678      * anchoring it to an (x,y) coordinate.
5679      *
5680      * @param x x coordinate of the anchoring touch event, or {@link Float#NaN}
5681      *          to disable anchoring
5682      * @param y y coordinate of the anchoring touch event, or {@link Float#NaN}
5683      *          to disable anchoring
5684      * @return {@code true} if one of the above receivers consumed the event,
5685      *         {@code false} otherwise
5686      */
5687     public boolean performLongClick(float x, float y) {
5688         mLongClickX = x;
5689         mLongClickY = y;
5690         final boolean handled = performLongClick();
5691         mLongClickX = Float.NaN;
5692         mLongClickY = Float.NaN;
5693         return handled;
5694     }
5695
5696     /**
5697      * Calls this view's OnLongClickListener, if it is defined. Invokes the
5698      * context menu if the OnLongClickListener did not consume the event,
5699      * optionally anchoring it to an (x,y) coordinate.
5700      *
5701      * @param x x coordinate of the anchoring touch event, or {@link Float#NaN}
5702      *          to disable anchoring
5703      * @param y y coordinate of the anchoring touch event, or {@link Float#NaN}
5704      *          to disable anchoring
5705      * @return {@code true} if one of the above receivers consumed the event,
5706      *         {@code false} otherwise
5707      */
5708     private boolean performLongClickInternal(float x, float y) {
5709         sendAccessibilityEvent(AccessibilityEvent.TYPE_VIEW_LONG_CLICKED);
5710
5711         boolean handled = false;
5712         final ListenerInfo li = mListenerInfo;
5713         if (li != null && li.mOnLongClickListener != null) {
5714             handled = li.mOnLongClickListener.onLongClick(View.this);
5715         }
5716         if (!handled) {
5717             final boolean isAnchored = !Float.isNaN(x) && !Float.isNaN(y);
5718             handled = isAnchored ? showContextMenu(x, y) : showContextMenu();
5719         }
5720         if (handled) {
5721             performHapticFeedback(HapticFeedbackConstants.LONG_PRESS);
5722         }
5723         return handled;
5724     }
5725
5726     /**
5727      * Call this view's OnContextClickListener, if it is defined.
5728      *
5729      * @param x the x coordinate of the context click
5730      * @param y the y coordinate of the context click
5731      * @return True if there was an assigned OnContextClickListener that consumed the event, false
5732      *         otherwise.
5733      */
5734     public boolean performContextClick(float x, float y) {
5735         return performContextClick();
5736     }
5737
5738     /**
5739      * Call this view's OnContextClickListener, if it is defined.
5740      *
5741      * @return True if there was an assigned OnContextClickListener that consumed the event, false
5742      *         otherwise.
5743      */
5744     public boolean performContextClick() {
5745         sendAccessibilityEvent(AccessibilityEvent.TYPE_VIEW_CONTEXT_CLICKED);
5746
5747         boolean handled = false;
5748         ListenerInfo li = mListenerInfo;
5749         if (li != null && li.mOnContextClickListener != null) {
5750             handled = li.mOnContextClickListener.onContextClick(View.this);
5751         }
5752         if (handled) {
5753             performHapticFeedback(HapticFeedbackConstants.CONTEXT_CLICK);
5754         }
5755         return handled;
5756     }
5757
5758     /**
5759      * Performs button-related actions during a touch down event.
5760      *
5761      * @param event The event.
5762      * @return True if the down was consumed.
5763      *
5764      * @hide
5765      */
5766     protected boolean performButtonActionOnTouchDown(MotionEvent event) {
5767         if (event.isFromSource(InputDevice.SOURCE_MOUSE) &&
5768             (event.getButtonState() & MotionEvent.BUTTON_SECONDARY) != 0) {
5769             showContextMenu(event.getX(), event.getY());
5770             mPrivateFlags |= PFLAG_CANCEL_NEXT_UP_EVENT;
5771             return true;
5772         }
5773         return false;
5774     }
5775
5776     /**
5777      * Shows the context menu for this view.
5778      *
5779      * @return {@code true} if the context menu was shown, {@code false}
5780      *         otherwise
5781      * @see #showContextMenu(float, float)
5782      */
5783     public boolean showContextMenu() {
5784         return getParent().showContextMenuForChild(this);
5785     }
5786
5787     /**
5788      * Shows the context menu for this view anchored to the specified
5789      * view-relative coordinate.
5790      *
5791      * @param x the X coordinate in pixels relative to the view to which the
5792      *          menu should be anchored, or {@link Float#NaN} to disable anchoring
5793      * @param y the Y coordinate in pixels relative to the view to which the
5794      *          menu should be anchored, or {@link Float#NaN} to disable anchoring
5795      * @return {@code true} if the context menu was shown, {@code false}
5796      *         otherwise
5797      */
5798     public boolean showContextMenu(float x, float y) {
5799         return getParent().showContextMenuForChild(this, x, y);
5800     }
5801
5802     /**
5803      * Start an action mode with the default type {@link ActionMode#TYPE_PRIMARY}.
5804      *
5805      * @param callback Callback that will control the lifecycle of the action mode
5806      * @return The new action mode if it is started, null otherwise
5807      *
5808      * @see ActionMode
5809      * @see #startActionMode(android.view.ActionMode.Callback, int)
5810      */
5811     public ActionMode startActionMode(ActionMode.Callback callback) {
5812         return startActionMode(callback, ActionMode.TYPE_PRIMARY);
5813     }
5814
5815     /**
5816      * Start an action mode with the given type.
5817      *
5818      * @param callback Callback that will control the lifecycle of the action mode
5819      * @param type One of {@link ActionMode#TYPE_PRIMARY} or {@link ActionMode#TYPE_FLOATING}.
5820      * @return The new action mode if it is started, null otherwise
5821      *
5822      * @see ActionMode
5823      */
5824     public ActionMode startActionMode(ActionMode.Callback callback, int type) {
5825         ViewParent parent = getParent();
5826         if (parent == null) return null;
5827         try {
5828             return parent.startActionModeForChild(this, callback, type);
5829         } catch (AbstractMethodError ame) {
5830             // Older implementations of custom views might not implement this.
5831             return parent.startActionModeForChild(this, callback);
5832         }
5833     }
5834
5835     /**
5836      * Call {@link Context#startActivityForResult(String, Intent, int, Bundle)} for the View's
5837      * Context, creating a unique View identifier to retrieve the result.
5838      *
5839      * @param intent The Intent to be started.
5840      * @param requestCode The request code to use.
5841      * @hide
5842      */
5843     public void startActivityForResult(Intent intent, int requestCode) {
5844         mStartActivityRequestWho = "@android:view:" + System.identityHashCode(this);
5845         getContext().startActivityForResult(mStartActivityRequestWho, intent, requestCode, null);
5846     }
5847
5848     /**
5849      * If this View corresponds to the calling who, dispatches the activity result.
5850      * @param who The identifier for the targeted View to receive the result.
5851      * @param requestCode The integer request code originally supplied to
5852      *                    startActivityForResult(), allowing you to identify who this
5853      *                    result came from.
5854      * @param resultCode The integer result code returned by the child activity
5855      *                   through its setResult().
5856      * @param data An Intent, which can return result data to the caller
5857      *               (various data can be attached to Intent "extras").
5858      * @return {@code true} if the activity result was dispatched.
5859      * @hide
5860      */
5861     public boolean dispatchActivityResult(
5862             String who, int requestCode, int resultCode, Intent data) {
5863         if (mStartActivityRequestWho != null && mStartActivityRequestWho.equals(who)) {
5864             onActivityResult(requestCode, resultCode, data);
5865             mStartActivityRequestWho = null;
5866             return true;
5867         }
5868         return false;
5869     }
5870
5871     /**
5872      * Receive the result from a previous call to {@link #startActivityForResult(Intent, int)}.
5873      *
5874      * @param requestCode The integer request code originally supplied to
5875      *                    startActivityForResult(), allowing you to identify who this
5876      *                    result came from.
5877      * @param resultCode The integer result code returned by the child activity
5878      *                   through its setResult().
5879      * @param data An Intent, which can return result data to the caller
5880      *               (various data can be attached to Intent "extras").
5881      * @hide
5882      */
5883     public void onActivityResult(int requestCode, int resultCode, Intent data) {
5884         // Do nothing.
5885     }
5886
5887     /**
5888      * Register a callback to be invoked when a hardware key is pressed in this view.
5889      * Key presses in software input methods will generally not trigger the methods of
5890      * this listener.
5891      * @param l the key listener to attach to this view
5892      */
5893     public void setOnKeyListener(OnKeyListener l) {
5894         getListenerInfo().mOnKeyListener = l;
5895     }
5896
5897     /**
5898      * Register a callback to be invoked when a touch event is sent to this view.
5899      * @param l the touch listener to attach to this view
5900      */
5901     public void setOnTouchListener(OnTouchListener l) {
5902         getListenerInfo().mOnTouchListener = l;
5903     }
5904
5905     /**
5906      * Register a callback to be invoked when a generic motion event is sent to this view.
5907      * @param l the generic motion listener to attach to this view
5908      */
5909     public void setOnGenericMotionListener(OnGenericMotionListener l) {
5910         getListenerInfo().mOnGenericMotionListener = l;
5911     }
5912
5913     /**
5914      * Register a callback to be invoked when a hover event is sent to this view.
5915      * @param l the hover listener to attach to this view
5916      */
5917     public void setOnHoverListener(OnHoverListener l) {
5918         getListenerInfo().mOnHoverListener = l;
5919     }
5920
5921     /**
5922      * Register a drag event listener callback object for this View. The parameter is
5923      * an implementation of {@link android.view.View.OnDragListener}. To send a drag event to a
5924      * View, the system calls the
5925      * {@link android.view.View.OnDragListener#onDrag(View,DragEvent)} method.
5926      * @param l An implementation of {@link android.view.View.OnDragListener}.
5927      */
5928     public void setOnDragListener(OnDragListener l) {
5929         getListenerInfo().mOnDragListener = l;
5930     }
5931
5932     /**
5933      * Give this view focus. This will cause
5934      * {@link #onFocusChanged(boolean, int, android.graphics.Rect)} to be called.
5935      *
5936      * Note: this does not check whether this {@link View} should get focus, it just
5937      * gives it focus no matter what.  It should only be called internally by framework
5938      * code that knows what it is doing, namely {@link #requestFocus(int, Rect)}.
5939      *
5940      * @param direction values are {@link View#FOCUS_UP}, {@link View#FOCUS_DOWN},
5941      *        {@link View#FOCUS_LEFT} or {@link View#FOCUS_RIGHT}. This is the direction which
5942      *        focus moved when requestFocus() is called. It may not always
5943      *        apply, in which case use the default View.FOCUS_DOWN.
5944      * @param previouslyFocusedRect The rectangle of the view that had focus
5945      *        prior in this View's coordinate system.
5946      */
5947     void handleFocusGainInternal(@FocusRealDirection int direction, Rect previouslyFocusedRect) {
5948         if (DBG) {
5949             System.out.println(this + " requestFocus()");
5950         }
5951
5952         if ((mPrivateFlags & PFLAG_FOCUSED) == 0) {
5953             mPrivateFlags |= PFLAG_FOCUSED;
5954
5955             View oldFocus = (mAttachInfo != null) ? getRootView().findFocus() : null;
5956
5957             if (mParent != null) {
5958                 mParent.requestChildFocus(this, this);
5959             }
5960
5961             if (mAttachInfo != null) {
5962                 mAttachInfo.mTreeObserver.dispatchOnGlobalFocusChange(oldFocus, this);
5963             }
5964
5965             onFocusChanged(true, direction, previouslyFocusedRect);
5966             refreshDrawableState();
5967         }
5968     }
5969
5970     /**
5971      * Sets this view's preference for reveal behavior when it gains focus.
5972      *
5973      * <p>When set to true, this is a signal to ancestor views in the hierarchy that
5974      * this view would prefer to be brought fully into view when it gains focus.
5975      * For example, a text field that a user is meant to type into. Other views such
5976      * as scrolling containers may prefer to opt-out of this behavior.</p>
5977      *
5978      * <p>The default value for views is true, though subclasses may change this
5979      * based on their preferred behavior.</p>
5980      *
5981      * @param revealOnFocus true to request reveal on focus in ancestors, false otherwise
5982      *
5983      * @see #getRevealOnFocusHint()
5984      */
5985     public final void setRevealOnFocusHint(boolean revealOnFocus) {
5986         if (revealOnFocus) {
5987             mPrivateFlags3 &= ~PFLAG3_NO_REVEAL_ON_FOCUS;
5988         } else {
5989             mPrivateFlags3 |= PFLAG3_NO_REVEAL_ON_FOCUS;
5990         }
5991     }
5992
5993     /**
5994      * Returns this view's preference for reveal behavior when it gains focus.
5995      *
5996      * <p>When this method returns true for a child view requesting focus, ancestor
5997      * views responding to a focus change in {@link ViewParent#requestChildFocus(View, View)}
5998      * should make a best effort to make the newly focused child fully visible to the user.
5999      * When it returns false, ancestor views should preferably not disrupt scroll positioning or
6000      * other properties affecting visibility to the user as part of the focus change.</p>
6001      *
6002      * @return true if this view would prefer to become fully visible when it gains focus,
6003      *         false if it would prefer not to disrupt scroll positioning
6004      *
6005      * @see #setRevealOnFocusHint(boolean)
6006      */
6007     public final boolean getRevealOnFocusHint() {
6008         return (mPrivateFlags3 & PFLAG3_NO_REVEAL_ON_FOCUS) == 0;
6009     }
6010
6011     /**
6012      * Populates <code>outRect</code> with the hotspot bounds. By default,
6013      * the hotspot bounds are identical to the screen bounds.
6014      *
6015      * @param outRect rect to populate with hotspot bounds
6016      * @hide Only for internal use by views and widgets.
6017      */
6018     public void getHotspotBounds(Rect outRect) {
6019         final Drawable background = getBackground();
6020         if (background != null) {
6021             background.getHotspotBounds(outRect);
6022         } else {
6023             getBoundsOnScreen(outRect);
6024         }
6025     }
6026
6027     /**
6028      * Request that a rectangle of this view be visible on the screen,
6029      * scrolling if necessary just enough.
6030      *
6031      * <p>A View should call this if it maintains some notion of which part
6032      * of its content is interesting.  For example, a text editing view
6033      * should call this when its cursor moves.
6034      * <p>The Rectangle passed into this method should be in the View's content coordinate space.
6035      * It should not be affected by which part of the View is currently visible or its scroll
6036      * position.
6037      *
6038      * @param rectangle The rectangle in the View's content coordinate space
6039      * @return Whether any parent scrolled.
6040      */
6041     public boolean requestRectangleOnScreen(Rect rectangle) {
6042         return requestRectangleOnScreen(rectangle, false);
6043     }
6044
6045     /**
6046      * Request that a rectangle of this view be visible on the screen,
6047      * scrolling if necessary just enough.
6048      *
6049      * <p>A View should call this if it maintains some notion of which part
6050      * of its content is interesting.  For example, a text editing view
6051      * should call this when its cursor moves.
6052      * <p>The Rectangle passed into this method should be in the View's content coordinate space.
6053      * It should not be affected by which part of the View is currently visible or its scroll
6054      * position.
6055      * <p>When <code>immediate</code> is set to true, scrolling will not be
6056      * animated.
6057      *
6058      * @param rectangle The rectangle in the View's content coordinate space
6059      * @param immediate True to forbid animated scrolling, false otherwise
6060      * @return Whether any parent scrolled.
6061      */
6062     public boolean requestRectangleOnScreen(Rect rectangle, boolean immediate) {
6063         if (mParent == null) {
6064             return false;
6065         }
6066
6067         View child = this;
6068
6069         RectF position = (mAttachInfo != null) ? mAttachInfo.mTmpTransformRect : new RectF();
6070         position.set(rectangle);
6071
6072         ViewParent parent = mParent;
6073         boolean scrolled = false;
6074         while (parent != null) {
6075             rectangle.set((int) position.left, (int) position.top,
6076                     (int) position.right, (int) position.bottom);
6077
6078             scrolled |= parent.requestChildRectangleOnScreen(child, rectangle, immediate);
6079
6080             if (!(parent instanceof View)) {
6081                 break;
6082             }
6083
6084             // move it from child's content coordinate space to parent's content coordinate space
6085             position.offset(child.mLeft - child.getScrollX(), child.mTop -child.getScrollY());
6086
6087             child = (View) parent;
6088             parent = child.getParent();
6089         }
6090
6091         return scrolled;
6092     }
6093
6094     /**
6095      * Called when this view wants to give up focus. If focus is cleared
6096      * {@link #onFocusChanged(boolean, int, android.graphics.Rect)} is called.
6097      * <p>
6098      * <strong>Note:</strong> When a View clears focus the framework is trying
6099      * to give focus to the first focusable View from the top. Hence, if this
6100      * View is the first from the top that can take focus, then all callbacks
6101      * related to clearing focus will be invoked after which the framework will
6102      * give focus to this view.
6103      * </p>
6104      */
6105     public void clearFocus() {
6106         if (DBG) {
6107             System.out.println(this + " clearFocus()");
6108         }
6109
6110         clearFocusInternal(null, true, true);
6111     }
6112
6113     /**
6114      * Clears focus from the view, optionally propagating the change up through
6115      * the parent hierarchy and requesting that the root view place new focus.
6116      *
6117      * @param propagate whether to propagate the change up through the parent
6118      *            hierarchy
6119      * @param refocus when propagate is true, specifies whether to request the
6120      *            root view place new focus
6121      */
6122     void clearFocusInternal(View focused, boolean propagate, boolean refocus) {
6123         if ((mPrivateFlags & PFLAG_FOCUSED) != 0) {
6124             mPrivateFlags &= ~PFLAG_FOCUSED;
6125
6126             if (propagate && mParent != null) {
6127                 mParent.clearChildFocus(this);
6128             }
6129
6130             onFocusChanged(false, 0, null);
6131             refreshDrawableState();
6132
6133             if (propagate && (!refocus || !rootViewRequestFocus())) {
6134                 notifyGlobalFocusCleared(this);
6135             }
6136         }
6137     }
6138
6139     void notifyGlobalFocusCleared(View oldFocus) {
6140         if (oldFocus != null && mAttachInfo != null) {
6141             mAttachInfo.mTreeObserver.dispatchOnGlobalFocusChange(oldFocus, null);
6142         }
6143     }
6144
6145     boolean rootViewRequestFocus() {
6146         final View root = getRootView();
6147         return root != null && root.requestFocus();
6148     }
6149
6150     /**
6151      * Called internally by the view system when a new view is getting focus.
6152      * This is what clears the old focus.
6153      * <p>
6154      * <b>NOTE:</b> The parent view's focused child must be updated manually
6155      * after calling this method. Otherwise, the view hierarchy may be left in
6156      * an inconstent state.
6157      */
6158     void unFocus(View focused) {
6159         if (DBG) {
6160             System.out.println(this + " unFocus()");
6161         }
6162
6163         clearFocusInternal(focused, false, false);
6164     }
6165
6166     /**
6167      * Returns true if this view has focus itself, or is the ancestor of the
6168      * view that has focus.
6169      *
6170      * @return True if this view has or contains focus, false otherwise.
6171      */
6172     @ViewDebug.ExportedProperty(category = "focus")
6173     public boolean hasFocus() {
6174         return (mPrivateFlags & PFLAG_FOCUSED) != 0;
6175     }
6176
6177     /**
6178      * Returns true if this view is focusable or if it contains a reachable View
6179      * for which {@link #hasFocusable()} returns true. A "reachable hasFocusable()"
6180      * is a View whose parents do not block descendants focus.
6181      *
6182      * Only {@link #VISIBLE} views are considered focusable.
6183      *
6184      * @return True if the view is focusable or if the view contains a focusable
6185      *         View, false otherwise.
6186      *
6187      * @see ViewGroup#FOCUS_BLOCK_DESCENDANTS
6188      * @see ViewGroup#getTouchscreenBlocksFocus()
6189      */
6190     public boolean hasFocusable() {
6191         if (!isFocusableInTouchMode()) {
6192             for (ViewParent p = mParent; p instanceof ViewGroup; p = p.getParent()) {
6193                 final ViewGroup g = (ViewGroup) p;
6194                 if (g.shouldBlockFocusForTouchscreen()) {
6195                     return false;
6196                 }
6197             }
6198         }
6199         return (mViewFlags & VISIBILITY_MASK) == VISIBLE && isFocusable();
6200     }
6201
6202     /**
6203      * Called by the view system when the focus state of this view changes.
6204      * When the focus change event is caused by directional navigation, direction
6205      * and previouslyFocusedRect provide insight into where the focus is coming from.
6206      * When overriding, be sure to call up through to the super class so that
6207      * the standard focus handling will occur.
6208      *
6209      * @param gainFocus True if the View has focus; false otherwise.
6210      * @param direction The direction focus has moved when requestFocus()
6211      *                  is called to give this view focus. Values are
6212      *                  {@link #FOCUS_UP}, {@link #FOCUS_DOWN}, {@link #FOCUS_LEFT},
6213      *                  {@link #FOCUS_RIGHT}, {@link #FOCUS_FORWARD}, or {@link #FOCUS_BACKWARD}.
6214      *                  It may not always apply, in which case use the default.
6215      * @param previouslyFocusedRect The rectangle, in this view's coordinate
6216      *        system, of the previously focused view.  If applicable, this will be
6217      *        passed in as finer grained information about where the focus is coming
6218      *        from (in addition to direction).  Will be <code>null</code> otherwise.
6219      */
6220     @CallSuper
6221     protected void onFocusChanged(boolean gainFocus, @FocusDirection int direction,
6222             @Nullable Rect previouslyFocusedRect) {
6223         if (gainFocus) {
6224             sendAccessibilityEvent(AccessibilityEvent.TYPE_VIEW_FOCUSED);
6225         } else {
6226             notifyViewAccessibilityStateChangedIfNeeded(
6227                     AccessibilityEvent.CONTENT_CHANGE_TYPE_UNDEFINED);
6228         }
6229
6230         InputMethodManager imm = InputMethodManager.peekInstance();
6231         if (!gainFocus) {
6232             if (isPressed()) {
6233                 setPressed(false);
6234             }
6235             if (imm != null && mAttachInfo != null
6236                     && mAttachInfo.mHasWindowFocus) {
6237                 imm.focusOut(this);
6238             }
6239             onFocusLost();
6240         } else if (imm != null && mAttachInfo != null
6241                 && mAttachInfo.mHasWindowFocus) {
6242             imm.focusIn(this);
6243         }
6244
6245         invalidate(true);
6246         ListenerInfo li = mListenerInfo;
6247         if (li != null && li.mOnFocusChangeListener != null) {
6248             li.mOnFocusChangeListener.onFocusChange(this, gainFocus);
6249         }
6250
6251         if (mAttachInfo != null) {
6252             mAttachInfo.mKeyDispatchState.reset(this);
6253         }
6254     }
6255
6256     /**
6257      * Sends an accessibility event of the given type. If accessibility is
6258      * not enabled this method has no effect. The default implementation calls
6259      * {@link #onInitializeAccessibilityEvent(AccessibilityEvent)} first
6260      * to populate information about the event source (this View), then calls
6261      * {@link #dispatchPopulateAccessibilityEvent(AccessibilityEvent)} to
6262      * populate the text content of the event source including its descendants,
6263      * and last calls
6264      * {@link ViewParent#requestSendAccessibilityEvent(View, AccessibilityEvent)}
6265      * on its parent to request sending of the event to interested parties.
6266      * <p>
6267      * If an {@link AccessibilityDelegate} has been specified via calling
6268      * {@link #setAccessibilityDelegate(AccessibilityDelegate)} its
6269      * {@link AccessibilityDelegate#sendAccessibilityEvent(View, int)} is
6270      * responsible for handling this call.
6271      * </p>
6272      *
6273      * @param eventType The type of the event to send, as defined by several types from
6274      * {@link android.view.accessibility.AccessibilityEvent}, such as
6275      * {@link android.view.accessibility.AccessibilityEvent#TYPE_VIEW_CLICKED} or
6276      * {@link android.view.accessibility.AccessibilityEvent#TYPE_VIEW_HOVER_ENTER}.
6277      *
6278      * @see #onInitializeAccessibilityEvent(AccessibilityEvent)
6279      * @see #dispatchPopulateAccessibilityEvent(AccessibilityEvent)
6280      * @see ViewParent#requestSendAccessibilityEvent(View, AccessibilityEvent)
6281      * @see AccessibilityDelegate
6282      */
6283     public void sendAccessibilityEvent(int eventType) {
6284         if (mAccessibilityDelegate != null) {
6285             mAccessibilityDelegate.sendAccessibilityEvent(this, eventType);
6286         } else {
6287             sendAccessibilityEventInternal(eventType);
6288         }
6289     }
6290
6291     /**
6292      * Convenience method for sending a {@link AccessibilityEvent#TYPE_ANNOUNCEMENT}
6293      * {@link AccessibilityEvent} to make an announcement which is related to some
6294      * sort of a context change for which none of the events representing UI transitions
6295      * is a good fit. For example, announcing a new page in a book. If accessibility
6296      * is not enabled this method does nothing.
6297      *
6298      * @param text The announcement text.
6299      */
6300     public void announceForAccessibility(CharSequence text) {
6301         if (AccessibilityManager.getInstance(mContext).isEnabled() && mParent != null) {
6302             AccessibilityEvent event = AccessibilityEvent.obtain(
6303                     AccessibilityEvent.TYPE_ANNOUNCEMENT);
6304             onInitializeAccessibilityEvent(event);
6305             event.getText().add(text);
6306             event.setContentDescription(null);
6307             mParent.requestSendAccessibilityEvent(this, event);
6308         }
6309     }
6310
6311     /**
6312      * @see #sendAccessibilityEvent(int)
6313      *
6314      * Note: Called from the default {@link AccessibilityDelegate}.
6315      *
6316      * @hide
6317      */
6318     public void sendAccessibilityEventInternal(int eventType) {
6319         if (AccessibilityManager.getInstance(mContext).isEnabled()) {
6320             sendAccessibilityEventUnchecked(AccessibilityEvent.obtain(eventType));
6321         }
6322     }
6323
6324     /**
6325      * This method behaves exactly as {@link #sendAccessibilityEvent(int)} but
6326      * takes as an argument an empty {@link AccessibilityEvent} and does not
6327      * perform a check whether accessibility is enabled.
6328      * <p>
6329      * If an {@link AccessibilityDelegate} has been specified via calling
6330      * {@link #setAccessibilityDelegate(AccessibilityDelegate)} its
6331      * {@link AccessibilityDelegate#sendAccessibilityEventUnchecked(View, AccessibilityEvent)}
6332      * is responsible for handling this call.
6333      * </p>
6334      *
6335      * @param event The event to send.
6336      *
6337      * @see #sendAccessibilityEvent(int)
6338      */
6339     public void sendAccessibilityEventUnchecked(AccessibilityEvent event) {
6340         if (mAccessibilityDelegate != null) {
6341             mAccessibilityDelegate.sendAccessibilityEventUnchecked(this, event);
6342         } else {
6343             sendAccessibilityEventUncheckedInternal(event);
6344         }
6345     }
6346
6347     /**
6348      * @see #sendAccessibilityEventUnchecked(AccessibilityEvent)
6349      *
6350      * Note: Called from the default {@link AccessibilityDelegate}.
6351      *
6352      * @hide
6353      */
6354     public void sendAccessibilityEventUncheckedInternal(AccessibilityEvent event) {
6355         if (!isShown()) {
6356             return;
6357         }
6358         onInitializeAccessibilityEvent(event);
6359         // Only a subset of accessibility events populates text content.
6360         if ((event.getEventType() & POPULATING_ACCESSIBILITY_EVENT_TYPES) != 0) {
6361             dispatchPopulateAccessibilityEvent(event);
6362         }
6363         // In the beginning we called #isShown(), so we know that getParent() is not null.
6364         getParent().requestSendAccessibilityEvent(this, event);
6365     }
6366
6367     /**
6368      * Dispatches an {@link AccessibilityEvent} to the {@link View} first and then
6369      * to its children for adding their text content to the event. Note that the
6370      * event text is populated in a separate dispatch path since we add to the
6371      * event not only the text of the source but also the text of all its descendants.
6372      * A typical implementation will call
6373      * {@link #onPopulateAccessibilityEvent(AccessibilityEvent)} on the this view
6374      * and then call the {@link #dispatchPopulateAccessibilityEvent(AccessibilityEvent)}
6375      * on each child. Override this method if custom population of the event text
6376      * content is required.
6377      * <p>
6378      * If an {@link AccessibilityDelegate} has been specified via calling
6379      * {@link #setAccessibilityDelegate(AccessibilityDelegate)} its
6380      * {@link AccessibilityDelegate#dispatchPopulateAccessibilityEvent(View, AccessibilityEvent)}
6381      * is responsible for handling this call.
6382      * </p>
6383      * <p>
6384      * <em>Note:</em> Accessibility events of certain types are not dispatched for
6385      * populating the event text via this method. For details refer to {@link AccessibilityEvent}.
6386      * </p>
6387      *
6388      * @param event The event.
6389      *
6390      * @return True if the event population was completed.
6391      */
6392     public boolean dispatchPopulateAccessibilityEvent(AccessibilityEvent event) {
6393         if (mAccessibilityDelegate != null) {
6394             return mAccessibilityDelegate.dispatchPopulateAccessibilityEvent(this, event);
6395         } else {
6396             return dispatchPopulateAccessibilityEventInternal(event);
6397         }
6398     }
6399
6400     /**
6401      * @see #dispatchPopulateAccessibilityEvent(AccessibilityEvent)
6402      *
6403      * Note: Called from the default {@link AccessibilityDelegate}.
6404      *
6405      * @hide
6406      */
6407     public boolean dispatchPopulateAccessibilityEventInternal(AccessibilityEvent event) {
6408         onPopulateAccessibilityEvent(event);
6409         return false;
6410     }
6411
6412     /**
6413      * Called from {@link #dispatchPopulateAccessibilityEvent(AccessibilityEvent)}
6414      * giving a chance to this View to populate the accessibility event with its
6415      * text content. While this method is free to modify event
6416      * attributes other than text content, doing so should normally be performed in
6417      * {@link #onInitializeAccessibilityEvent(AccessibilityEvent)}.
6418      * <p>
6419      * Example: Adding formatted date string to an accessibility event in addition
6420      *          to the text added by the super implementation:
6421      * <pre> public void onPopulateAccessibilityEvent(AccessibilityEvent event) {
6422      *     super.onPopulateAccessibilityEvent(event);
6423      *     final int flags = DateUtils.FORMAT_SHOW_DATE | DateUtils.FORMAT_SHOW_WEEKDAY;
6424      *     String selectedDateUtterance = DateUtils.formatDateTime(mContext,
6425      *         mCurrentDate.getTimeInMillis(), flags);
6426      *     event.getText().add(selectedDateUtterance);
6427      * }</pre>
6428      * <p>
6429      * If an {@link AccessibilityDelegate} has been specified via calling
6430      * {@link #setAccessibilityDelegate(AccessibilityDelegate)} its
6431      * {@link AccessibilityDelegate#onPopulateAccessibilityEvent(View, AccessibilityEvent)}
6432      * is responsible for handling this call.
6433      * </p>
6434      * <p class="note"><strong>Note:</strong> Always call the super implementation before adding
6435      * information to the event, in case the default implementation has basic information to add.
6436      * </p>
6437      *
6438      * @param event The accessibility event which to populate.
6439      *
6440      * @see #sendAccessibilityEvent(int)
6441      * @see #dispatchPopulateAccessibilityEvent(AccessibilityEvent)
6442      */
6443     @CallSuper
6444     public void onPopulateAccessibilityEvent(AccessibilityEvent event) {
6445         if (mAccessibilityDelegate != null) {
6446             mAccessibilityDelegate.onPopulateAccessibilityEvent(this, event);
6447         } else {
6448             onPopulateAccessibilityEventInternal(event);
6449         }
6450     }
6451
6452     /**
6453      * @see #onPopulateAccessibilityEvent(AccessibilityEvent)
6454      *
6455      * Note: Called from the default {@link AccessibilityDelegate}.
6456      *
6457      * @hide
6458      */
6459     public void onPopulateAccessibilityEventInternal(AccessibilityEvent event) {
6460     }
6461
6462     /**
6463      * Initializes an {@link AccessibilityEvent} with information about
6464      * this View which is the event source. In other words, the source of
6465      * an accessibility event is the view whose state change triggered firing
6466      * the event.
6467      * <p>
6468      * Example: Setting the password property of an event in addition
6469      *          to properties set by the super implementation:
6470      * <pre> public void onInitializeAccessibilityEvent(AccessibilityEvent event) {
6471      *     super.onInitializeAccessibilityEvent(event);
6472      *     event.setPassword(true);
6473      * }</pre>
6474      * <p>
6475      * If an {@link AccessibilityDelegate} has been specified via calling
6476      * {@link #setAccessibilityDelegate(AccessibilityDelegate)} its
6477      * {@link AccessibilityDelegate#onInitializeAccessibilityEvent(View, AccessibilityEvent)}
6478      * is responsible for handling this call.
6479      * </p>
6480      * <p class="note"><strong>Note:</strong> Always call the super implementation before adding
6481      * information to the event, in case the default implementation has basic information to add.
6482      * </p>
6483      * @param event The event to initialize.
6484      *
6485      * @see #sendAccessibilityEvent(int)
6486      * @see #dispatchPopulateAccessibilityEvent(AccessibilityEvent)
6487      */
6488     @CallSuper
6489     public void onInitializeAccessibilityEvent(AccessibilityEvent event) {
6490         if (mAccessibilityDelegate != null) {
6491             mAccessibilityDelegate.onInitializeAccessibilityEvent(this, event);
6492         } else {
6493             onInitializeAccessibilityEventInternal(event);
6494         }
6495     }
6496
6497     /**
6498      * @see #onInitializeAccessibilityEvent(AccessibilityEvent)
6499      *
6500      * Note: Called from the default {@link AccessibilityDelegate}.
6501      *
6502      * @hide
6503      */
6504     public void onInitializeAccessibilityEventInternal(AccessibilityEvent event) {
6505         event.setSource(this);
6506         event.setClassName(getAccessibilityClassName());
6507         event.setPackageName(getContext().getPackageName());
6508         event.setEnabled(isEnabled());
6509         event.setContentDescription(mContentDescription);
6510
6511         switch (event.getEventType()) {
6512             case AccessibilityEvent.TYPE_VIEW_FOCUSED: {
6513                 ArrayList<View> focusablesTempList = (mAttachInfo != null)
6514                         ? mAttachInfo.mTempArrayList : new ArrayList<View>();
6515                 getRootView().addFocusables(focusablesTempList, View.FOCUS_FORWARD, FOCUSABLES_ALL);
6516                 event.setItemCount(focusablesTempList.size());
6517                 event.setCurrentItemIndex(focusablesTempList.indexOf(this));
6518                 if (mAttachInfo != null) {
6519                     focusablesTempList.clear();
6520                 }
6521             } break;
6522             case AccessibilityEvent.TYPE_VIEW_TEXT_SELECTION_CHANGED: {
6523                 CharSequence text = getIterableTextForAccessibility();
6524                 if (text != null && text.length() > 0) {
6525                     event.setFromIndex(getAccessibilitySelectionStart());
6526                     event.setToIndex(getAccessibilitySelectionEnd());
6527                     event.setItemCount(text.length());
6528                 }
6529             } break;
6530         }
6531     }
6532
6533     /**
6534      * Returns an {@link AccessibilityNodeInfo} representing this view from the
6535      * point of view of an {@link android.accessibilityservice.AccessibilityService}.
6536      * This method is responsible for obtaining an accessibility node info from a
6537      * pool of reusable instances and calling
6538      * {@link #onInitializeAccessibilityNodeInfo(AccessibilityNodeInfo)} on this view to
6539      * initialize the former.
6540      * <p>
6541      * Note: The client is responsible for recycling the obtained instance by calling
6542      *       {@link AccessibilityNodeInfo#recycle()} to minimize object creation.
6543      * </p>
6544      *
6545      * @return A populated {@link AccessibilityNodeInfo}.
6546      *
6547      * @see AccessibilityNodeInfo
6548      */
6549     public AccessibilityNodeInfo createAccessibilityNodeInfo() {
6550         if (mAccessibilityDelegate != null) {
6551             return mAccessibilityDelegate.createAccessibilityNodeInfo(this);
6552         } else {
6553             return createAccessibilityNodeInfoInternal();
6554         }
6555     }
6556
6557     /**
6558      * @see #createAccessibilityNodeInfo()
6559      *
6560      * @hide
6561      */
6562     public AccessibilityNodeInfo createAccessibilityNodeInfoInternal() {
6563         AccessibilityNodeProvider provider = getAccessibilityNodeProvider();
6564         if (provider != null) {
6565             return provider.createAccessibilityNodeInfo(AccessibilityNodeProvider.HOST_VIEW_ID);
6566         } else {
6567             AccessibilityNodeInfo info = AccessibilityNodeInfo.obtain(this);
6568             onInitializeAccessibilityNodeInfo(info);
6569             return info;
6570         }
6571     }
6572
6573     /**
6574      * Initializes an {@link AccessibilityNodeInfo} with information about this view.
6575      * The base implementation sets:
6576      * <ul>
6577      *   <li>{@link AccessibilityNodeInfo#setParent(View)},</li>
6578      *   <li>{@link AccessibilityNodeInfo#setBoundsInParent(Rect)},</li>
6579      *   <li>{@link AccessibilityNodeInfo#setBoundsInScreen(Rect)},</li>
6580      *   <li>{@link AccessibilityNodeInfo#setPackageName(CharSequence)},</li>
6581      *   <li>{@link AccessibilityNodeInfo#setClassName(CharSequence)},</li>
6582      *   <li>{@link AccessibilityNodeInfo#setContentDescription(CharSequence)},</li>
6583      *   <li>{@link AccessibilityNodeInfo#setEnabled(boolean)},</li>
6584      *   <li>{@link AccessibilityNodeInfo#setClickable(boolean)},</li>
6585      *   <li>{@link AccessibilityNodeInfo#setFocusable(boolean)},</li>
6586      *   <li>{@link AccessibilityNodeInfo#setFocused(boolean)},</li>
6587      *   <li>{@link AccessibilityNodeInfo#setLongClickable(boolean)},</li>
6588      *   <li>{@link AccessibilityNodeInfo#setSelected(boolean)},</li>
6589      *   <li>{@link AccessibilityNodeInfo#setContextClickable(boolean)}</li>
6590      * </ul>
6591      * <p>
6592      * Subclasses should override this method, call the super implementation,
6593      * and set additional attributes.
6594      * </p>
6595      * <p>
6596      * If an {@link AccessibilityDelegate} has been specified via calling
6597      * {@link #setAccessibilityDelegate(AccessibilityDelegate)} its
6598      * {@link AccessibilityDelegate#onInitializeAccessibilityNodeInfo(View, AccessibilityNodeInfo)}
6599      * is responsible for handling this call.
6600      * </p>
6601      *
6602      * @param info The instance to initialize.
6603      */
6604     @CallSuper
6605     public void onInitializeAccessibilityNodeInfo(AccessibilityNodeInfo info) {
6606         if (mAccessibilityDelegate != null) {
6607             mAccessibilityDelegate.onInitializeAccessibilityNodeInfo(this, info);
6608         } else {
6609             onInitializeAccessibilityNodeInfoInternal(info);
6610         }
6611     }
6612
6613     /**
6614      * Gets the location of this view in screen coordinates.
6615      *
6616      * @param outRect The output location
6617      * @hide
6618      */
6619     public void getBoundsOnScreen(Rect outRect) {
6620         getBoundsOnScreen(outRect, false);
6621     }
6622
6623     /**
6624      * Gets the location of this view in screen coordinates.
6625      *
6626      * @param outRect The output location
6627      * @param clipToParent Whether to clip child bounds to the parent ones.
6628      * @hide
6629      */
6630     public void getBoundsOnScreen(Rect outRect, boolean clipToParent) {
6631         if (mAttachInfo == null) {
6632             return;
6633         }
6634
6635         RectF position = mAttachInfo.mTmpTransformRect;
6636         position.set(0, 0, mRight - mLeft, mBottom - mTop);
6637
6638         if (!hasIdentityMatrix()) {
6639             getMatrix().mapRect(position);
6640         }
6641
6642         position.offset(mLeft, mTop);
6643
6644         ViewParent parent = mParent;
6645         while (parent instanceof View) {
6646             View parentView = (View) parent;
6647
6648             position.offset(-parentView.mScrollX, -parentView.mScrollY);
6649
6650             if (clipToParent) {
6651                 position.left = Math.max(position.left, 0);
6652                 position.top = Math.max(position.top, 0);
6653                 position.right = Math.min(position.right, parentView.getWidth());
6654                 position.bottom = Math.min(position.bottom, parentView.getHeight());
6655             }
6656
6657             if (!parentView.hasIdentityMatrix()) {
6658                 parentView.getMatrix().mapRect(position);
6659             }
6660
6661             position.offset(parentView.mLeft, parentView.mTop);
6662
6663             parent = parentView.mParent;
6664         }
6665
6666         if (parent instanceof ViewRootImpl) {
6667             ViewRootImpl viewRootImpl = (ViewRootImpl) parent;
6668             position.offset(0, -viewRootImpl.mCurScrollY);
6669         }
6670
6671         position.offset(mAttachInfo.mWindowLeft, mAttachInfo.mWindowTop);
6672
6673         outRect.set(Math.round(position.left), Math.round(position.top),
6674                 Math.round(position.right), Math.round(position.bottom));
6675     }
6676
6677     /**
6678      * Return the class name of this object to be used for accessibility purposes.
6679      * Subclasses should only override this if they are implementing something that
6680      * should be seen as a completely new class of view when used by accessibility,
6681      * unrelated to the class it is deriving from.  This is used to fill in
6682      * {@link AccessibilityNodeInfo#setClassName AccessibilityNodeInfo.setClassName}.
6683      */
6684     public CharSequence getAccessibilityClassName() {
6685         return View.class.getName();
6686     }
6687
6688     /**
6689      * Called when assist structure is being retrieved from a view as part of
6690      * {@link android.app.Activity#onProvideAssistData Activity.onProvideAssistData}.
6691      * @param structure Fill in with structured view data.  The default implementation
6692      * fills in all data that can be inferred from the view itself.
6693      */
6694     public void onProvideStructure(ViewStructure structure) {
6695         final int id = mID;
6696         if (id > 0 && (id&0xff000000) != 0 && (id&0x00ff0000) != 0
6697                 && (id&0x0000ffff) != 0) {
6698             String pkg, type, entry;
6699             try {
6700                 final Resources res = getResources();
6701                 entry = res.getResourceEntryName(id);
6702                 type = res.getResourceTypeName(id);
6703                 pkg = res.getResourcePackageName(id);
6704             } catch (Resources.NotFoundException e) {
6705                 entry = type = pkg = null;
6706             }
6707             structure.setId(id, pkg, type, entry);
6708         } else {
6709             structure.setId(id, null, null, null);
6710         }
6711         structure.setDimens(mLeft, mTop, mScrollX, mScrollY, mRight - mLeft, mBottom - mTop);
6712         if (!hasIdentityMatrix()) {
6713             structure.setTransformation(getMatrix());
6714         }
6715         structure.setElevation(getZ());
6716         structure.setVisibility(getVisibility());
6717         structure.setEnabled(isEnabled());
6718         if (isClickable()) {
6719             structure.setClickable(true);
6720         }
6721         if (isFocusable()) {
6722             structure.setFocusable(true);
6723         }
6724         if (isFocused()) {
6725             structure.setFocused(true);
6726         }
6727         if (isAccessibilityFocused()) {
6728             structure.setAccessibilityFocused(true);
6729         }
6730         if (isSelected()) {
6731             structure.setSelected(true);
6732         }
6733         if (isActivated()) {
6734             structure.setActivated(true);
6735         }
6736         if (isLongClickable()) {
6737             structure.setLongClickable(true);
6738         }
6739         if (this instanceof Checkable) {
6740             structure.setCheckable(true);
6741             if (((Checkable)this).isChecked()) {
6742                 structure.setChecked(true);
6743             }
6744         }
6745         if (isContextClickable()) {
6746             structure.setContextClickable(true);
6747         }
6748         structure.setClassName(getAccessibilityClassName().toString());
6749         structure.setContentDescription(getContentDescription());
6750     }
6751
6752     /**
6753      * Called when assist structure is being retrieved from a view as part of
6754      * {@link android.app.Activity#onProvideAssistData Activity.onProvideAssistData} to
6755      * generate additional virtual structure under this view.  The defaullt implementation
6756      * uses {@link #getAccessibilityNodeProvider()} to try to generate this from the
6757      * view's virtual accessibility nodes, if any.  You can override this for a more
6758      * optimal implementation providing this data.
6759      */
6760     public void onProvideVirtualStructure(ViewStructure structure) {
6761         AccessibilityNodeProvider provider = getAccessibilityNodeProvider();
6762         if (provider != null) {
6763             AccessibilityNodeInfo info = createAccessibilityNodeInfo();
6764             structure.setChildCount(1);
6765             ViewStructure root = structure.newChild(0);
6766             populateVirtualStructure(root, provider, info);
6767             info.recycle();
6768         }
6769     }
6770
6771     private void populateVirtualStructure(ViewStructure structure,
6772             AccessibilityNodeProvider provider, AccessibilityNodeInfo info) {
6773         structure.setId(AccessibilityNodeInfo.getVirtualDescendantId(info.getSourceNodeId()),
6774                 null, null, null);
6775         Rect rect = structure.getTempRect();
6776         info.getBoundsInParent(rect);
6777         structure.setDimens(rect.left, rect.top, 0, 0, rect.width(), rect.height());
6778         structure.setVisibility(VISIBLE);
6779         structure.setEnabled(info.isEnabled());
6780         if (info.isClickable()) {
6781             structure.setClickable(true);
6782         }
6783         if (info.isFocusable()) {
6784             structure.setFocusable(true);
6785         }
6786         if (info.isFocused()) {
6787             structure.setFocused(true);
6788         }
6789         if (info.isAccessibilityFocused()) {
6790             structure.setAccessibilityFocused(true);
6791         }
6792         if (info.isSelected()) {
6793             structure.setSelected(true);
6794         }
6795         if (info.isLongClickable()) {
6796             structure.setLongClickable(true);
6797         }
6798         if (info.isCheckable()) {
6799             structure.setCheckable(true);
6800             if (info.isChecked()) {
6801                 structure.setChecked(true);
6802             }
6803         }
6804         if (info.isContextClickable()) {
6805             structure.setContextClickable(true);
6806         }
6807         CharSequence cname = info.getClassName();
6808         structure.setClassName(cname != null ? cname.toString() : null);
6809         structure.setContentDescription(info.getContentDescription());
6810         if (info.getText() != null || info.getError() != null) {
6811             structure.setText(info.getText(), info.getTextSelectionStart(),
6812                     info.getTextSelectionEnd());
6813         }
6814         final int NCHILDREN = info.getChildCount();
6815         if (NCHILDREN > 0) {
6816             structure.setChildCount(NCHILDREN);
6817             for (int i=0; i<NCHILDREN; i++) {
6818                 AccessibilityNodeInfo cinfo = provider.createAccessibilityNodeInfo(
6819                         AccessibilityNodeInfo.getVirtualDescendantId(info.getChildId(i)));
6820                 ViewStructure child = structure.newChild(i);
6821                 populateVirtualStructure(child, provider, cinfo);
6822                 cinfo.recycle();
6823             }
6824         }
6825     }
6826
6827     /**
6828      * Dispatch creation of {@link ViewStructure} down the hierarchy.  The default
6829      * implementation calls {@link #onProvideStructure} and
6830      * {@link #onProvideVirtualStructure}.
6831      */
6832     public void dispatchProvideStructure(ViewStructure structure) {
6833         if (!isAssistBlocked()) {
6834             onProvideStructure(structure);
6835             onProvideVirtualStructure(structure);
6836         } else {
6837             structure.setClassName(getAccessibilityClassName().toString());
6838             structure.setAssistBlocked(true);
6839         }
6840     }
6841
6842     /**
6843      * @see #onInitializeAccessibilityNodeInfo(AccessibilityNodeInfo)
6844      *
6845      * Note: Called from the default {@link AccessibilityDelegate}.
6846      *
6847      * @hide
6848      */
6849     public void onInitializeAccessibilityNodeInfoInternal(AccessibilityNodeInfo info) {
6850         if (mAttachInfo == null) {
6851             return;
6852         }
6853
6854         Rect bounds = mAttachInfo.mTmpInvalRect;
6855
6856         getDrawingRect(bounds);
6857         info.setBoundsInParent(bounds);
6858
6859         getBoundsOnScreen(bounds, true);
6860         info.setBoundsInScreen(bounds);
6861
6862         ViewParent parent = getParentForAccessibility();
6863         if (parent instanceof View) {
6864             info.setParent((View) parent);
6865         }
6866
6867         if (mID != View.NO_ID) {
6868             View rootView = getRootView();
6869             if (rootView == null) {
6870                 rootView = this;
6871             }
6872
6873             View label = rootView.findLabelForView(this, mID);
6874             if (label != null) {
6875                 info.setLabeledBy(label);
6876             }
6877
6878             if ((mAttachInfo.mAccessibilityFetchFlags
6879                     & AccessibilityNodeInfo.FLAG_REPORT_VIEW_IDS) != 0
6880                     && Resources.resourceHasPackage(mID)) {
6881                 try {
6882                     String viewId = getResources().getResourceName(mID);
6883                     info.setViewIdResourceName(viewId);
6884                 } catch (Resources.NotFoundException nfe) {
6885                     /* ignore */
6886                 }
6887             }
6888         }
6889
6890         if (mLabelForId != View.NO_ID) {
6891             View rootView = getRootView();
6892             if (rootView == null) {
6893                 rootView = this;
6894             }
6895             View labeled = rootView.findViewInsideOutShouldExist(this, mLabelForId);
6896             if (labeled != null) {
6897                 info.setLabelFor(labeled);
6898             }
6899         }
6900
6901         if (mAccessibilityTraversalBeforeId != View.NO_ID) {
6902             View rootView = getRootView();
6903             if (rootView == null) {
6904                 rootView = this;
6905             }
6906             View next = rootView.findViewInsideOutShouldExist(this,
6907                     mAccessibilityTraversalBeforeId);
6908             if (next != null && next.includeForAccessibility()) {
6909                 info.setTraversalBefore(next);
6910             }
6911         }
6912
6913         if (mAccessibilityTraversalAfterId != View.NO_ID) {
6914             View rootView = getRootView();
6915             if (rootView == null) {
6916                 rootView = this;
6917             }
6918             View next = rootView.findViewInsideOutShouldExist(this,
6919                     mAccessibilityTraversalAfterId);
6920             if (next != null && next.includeForAccessibility()) {
6921                 info.setTraversalAfter(next);
6922             }
6923         }
6924
6925         info.setVisibleToUser(isVisibleToUser());
6926
6927         if ((mAttachInfo != null) && ((mAttachInfo.mAccessibilityFetchFlags
6928                 & AccessibilityNodeInfo.FLAG_INCLUDE_NOT_IMPORTANT_VIEWS) != 0)) {
6929             info.setImportantForAccessibility(isImportantForAccessibility());
6930         } else {
6931             info.setImportantForAccessibility(true);
6932         }
6933
6934         info.setPackageName(mContext.getPackageName());
6935         info.setClassName(getAccessibilityClassName());
6936         info.setContentDescription(getContentDescription());
6937
6938         info.setEnabled(isEnabled());
6939         info.setClickable(isClickable());
6940         info.setFocusable(isFocusable());
6941         info.setFocused(isFocused());
6942         info.setAccessibilityFocused(isAccessibilityFocused());
6943         info.setSelected(isSelected());
6944         info.setLongClickable(isLongClickable());
6945         info.setContextClickable(isContextClickable());
6946         info.setLiveRegion(getAccessibilityLiveRegion());
6947
6948         // TODO: These make sense only if we are in an AdapterView but all
6949         // views can be selected. Maybe from accessibility perspective
6950         // we should report as selectable view in an AdapterView.
6951         info.addAction(AccessibilityNodeInfo.ACTION_SELECT);
6952         info.addAction(AccessibilityNodeInfo.ACTION_CLEAR_SELECTION);
6953
6954         if (isFocusable()) {
6955             if (isFocused()) {
6956                 info.addAction(AccessibilityNodeInfo.ACTION_CLEAR_FOCUS);
6957             } else {
6958                 info.addAction(AccessibilityNodeInfo.ACTION_FOCUS);
6959             }
6960         }
6961
6962         if (!isAccessibilityFocused()) {
6963             info.addAction(AccessibilityNodeInfo.ACTION_ACCESSIBILITY_FOCUS);
6964         } else {
6965             info.addAction(AccessibilityNodeInfo.ACTION_CLEAR_ACCESSIBILITY_FOCUS);
6966         }
6967
6968         if (isClickable() && isEnabled()) {
6969             info.addAction(AccessibilityNodeInfo.ACTION_CLICK);
6970         }
6971
6972         if (isLongClickable() && isEnabled()) {
6973             info.addAction(AccessibilityNodeInfo.ACTION_LONG_CLICK);
6974         }
6975
6976         if (isContextClickable() && isEnabled()) {
6977             info.addAction(AccessibilityAction.ACTION_CONTEXT_CLICK);
6978         }
6979
6980         CharSequence text = getIterableTextForAccessibility();
6981         if (text != null && text.length() > 0) {
6982             info.setTextSelection(getAccessibilitySelectionStart(), getAccessibilitySelectionEnd());
6983
6984             info.addAction(AccessibilityNodeInfo.ACTION_SET_SELECTION);
6985             info.addAction(AccessibilityNodeInfo.ACTION_NEXT_AT_MOVEMENT_GRANULARITY);
6986             info.addAction(AccessibilityNodeInfo.ACTION_PREVIOUS_AT_MOVEMENT_GRANULARITY);
6987             info.setMovementGranularities(AccessibilityNodeInfo.MOVEMENT_GRANULARITY_CHARACTER
6988                     | AccessibilityNodeInfo.MOVEMENT_GRANULARITY_WORD
6989                     | AccessibilityNodeInfo.MOVEMENT_GRANULARITY_PARAGRAPH);
6990         }
6991
6992         info.addAction(AccessibilityAction.ACTION_SHOW_ON_SCREEN);
6993         populateAccessibilityNodeInfoDrawingOrderInParent(info);
6994     }
6995
6996     /**
6997      * Determine the order in which this view will be drawn relative to its siblings for a11y
6998      *
6999      * @param info The info whose drawing order should be populated
7000      */
7001     private void populateAccessibilityNodeInfoDrawingOrderInParent(AccessibilityNodeInfo info) {
7002         /*
7003          * If the view's bounds haven't been set yet, layout has not completed. In that situation,
7004          * drawing order may not be well-defined, and some Views with custom drawing order may
7005          * not be initialized sufficiently to respond properly getChildDrawingOrder.
7006          */
7007         if ((mPrivateFlags & PFLAG_HAS_BOUNDS) == 0) {
7008             info.setDrawingOrder(0);
7009             return;
7010         }
7011         int drawingOrderInParent = 1;
7012         // Iterate up the hierarchy if parents are not important for a11y
7013         View viewAtDrawingLevel = this;
7014         final ViewParent parent = getParentForAccessibility();
7015         while (viewAtDrawingLevel != parent) {
7016             final ViewParent currentParent = viewAtDrawingLevel.getParent();
7017             if (!(currentParent instanceof ViewGroup)) {
7018                 // Should only happen for the Decor
7019                 drawingOrderInParent = 0;
7020                 break;
7021             } else {
7022                 final ViewGroup parentGroup = (ViewGroup) currentParent;
7023                 final int childCount = parentGroup.getChildCount();
7024                 if (childCount > 1) {
7025                     List<View> preorderedList = parentGroup.buildOrderedChildList();
7026                     if (preorderedList != null) {
7027                         final int childDrawIndex = preorderedList.indexOf(viewAtDrawingLevel);
7028                         for (int i = 0; i < childDrawIndex; i++) {
7029                             drawingOrderInParent += numViewsForAccessibility(preorderedList.get(i));
7030                         }
7031                     } else {
7032                         final int childIndex = parentGroup.indexOfChild(viewAtDrawingLevel);
7033                         final boolean customOrder = parentGroup.isChildrenDrawingOrderEnabled();
7034                         final int childDrawIndex = ((childIndex >= 0) && customOrder) ? parentGroup
7035                                 .getChildDrawingOrder(childCount, childIndex) : childIndex;
7036                         final int numChildrenToIterate = customOrder ? childCount : childDrawIndex;
7037                         if (childDrawIndex != 0) {
7038                             for (int i = 0; i < numChildrenToIterate; i++) {
7039                                 final int otherDrawIndex = (customOrder ?
7040                                         parentGroup.getChildDrawingOrder(childCount, i) : i);
7041                                 if (otherDrawIndex < childDrawIndex) {
7042                                     drawingOrderInParent +=
7043                                             numViewsForAccessibility(parentGroup.getChildAt(i));
7044                                 }
7045                             }
7046                         }
7047                     }
7048                 }
7049             }
7050             viewAtDrawingLevel = (View) currentParent;
7051         }
7052         info.setDrawingOrder(drawingOrderInParent);
7053     }
7054
7055     private static int numViewsForAccessibility(View view) {
7056         if (view != null) {
7057             if (view.includeForAccessibility()) {
7058                 return 1;
7059             } else if (view instanceof ViewGroup) {
7060                 return ((ViewGroup) view).getNumChildrenForAccessibility();
7061             }
7062         }
7063         return 0;
7064     }
7065
7066     private View findLabelForView(View view, int labeledId) {
7067         if (mMatchLabelForPredicate == null) {
7068             mMatchLabelForPredicate = new MatchLabelForPredicate();
7069         }
7070         mMatchLabelForPredicate.mLabeledId = labeledId;
7071         return findViewByPredicateInsideOut(view, mMatchLabelForPredicate);
7072     }
7073
7074     /**
7075      * Computes whether this view is visible to the user. Such a view is
7076      * attached, visible, all its predecessors are visible, it is not clipped
7077      * entirely by its predecessors, and has an alpha greater than zero.
7078      *
7079      * @return Whether the view is visible on the screen.
7080      *
7081      * @hide
7082      */
7083     protected boolean isVisibleToUser() {
7084         return isVisibleToUser(null);
7085     }
7086
7087     /**
7088      * Computes whether the given portion of this view is visible to the user.
7089      * Such a view is attached, visible, all its predecessors are visible,
7090      * has an alpha greater than zero, and the specified portion is not
7091      * clipped entirely by its predecessors.
7092      *
7093      * @param boundInView the portion of the view to test; coordinates should be relative; may be
7094      *                    <code>null</code>, and the entire view will be tested in this case.
7095      *                    When <code>true</code> is returned by the function, the actual visible
7096      *                    region will be stored in this parameter; that is, if boundInView is fully
7097      *                    contained within the view, no modification will be made, otherwise regions
7098      *                    outside of the visible area of the view will be clipped.
7099      *
7100      * @return Whether the specified portion of the view is visible on the screen.
7101      *
7102      * @hide
7103      */
7104     protected boolean isVisibleToUser(Rect boundInView) {
7105         if (mAttachInfo != null) {
7106             // Attached to invisible window means this view is not visible.
7107             if (mAttachInfo.mWindowVisibility != View.VISIBLE) {
7108                 return false;
7109             }
7110             // An invisible predecessor or one with alpha zero means
7111             // that this view is not visible to the user.
7112             Object current = this;
7113             while (current instanceof View) {
7114                 View view = (View) current;
7115                 // We have attach info so this view is attached and there is no
7116                 // need to check whether we reach to ViewRootImpl on the way up.
7117                 if (view.getAlpha() <= 0 || view.getTransitionAlpha() <= 0 ||
7118                         view.getVisibility() != VISIBLE) {
7119                     return false;
7120                 }
7121                 current = view.mParent;
7122             }
7123             // Check if the view is entirely covered by its predecessors.
7124             Rect visibleRect = mAttachInfo.mTmpInvalRect;
7125             Point offset = mAttachInfo.mPoint;
7126             if (!getGlobalVisibleRect(visibleRect, offset)) {
7127                 return false;
7128             }
7129             // Check if the visible portion intersects the rectangle of interest.
7130             if (boundInView != null) {
7131                 visibleRect.offset(-offset.x, -offset.y);
7132                 return boundInView.intersect(visibleRect);
7133             }
7134             return true;
7135         }
7136         return false;
7137     }
7138
7139     /**
7140      * Returns the delegate for implementing accessibility support via
7141      * composition. For more details see {@link AccessibilityDelegate}.
7142      *
7143      * @return The delegate, or null if none set.
7144      *
7145      * @hide
7146      */
7147     public AccessibilityDelegate getAccessibilityDelegate() {
7148         return mAccessibilityDelegate;
7149     }
7150
7151     /**
7152      * Sets a delegate for implementing accessibility support via composition
7153      * (as opposed to inheritance). For more details, see
7154      * {@link AccessibilityDelegate}.
7155      * <p>
7156      * <strong>Note:</strong> On platform versions prior to
7157      * {@link android.os.Build.VERSION_CODES#M API 23}, delegate methods on
7158      * views in the {@code android.widget.*} package are called <i>before</i>
7159      * host methods. This prevents certain properties such as class name from
7160      * being modified by overriding
7161      * {@link AccessibilityDelegate#onInitializeAccessibilityNodeInfo(View, AccessibilityNodeInfo)},
7162      * as any changes will be overwritten by the host class.
7163      * <p>
7164      * Starting in {@link android.os.Build.VERSION_CODES#M API 23}, delegate
7165      * methods are called <i>after</i> host methods, which all properties to be
7166      * modified without being overwritten by the host class.
7167      *
7168      * @param delegate the object to which accessibility method calls should be
7169      *                 delegated
7170      * @see AccessibilityDelegate
7171      */
7172     public void setAccessibilityDelegate(@Nullable AccessibilityDelegate delegate) {
7173         mAccessibilityDelegate = delegate;
7174     }
7175
7176     /**
7177      * Gets the provider for managing a virtual view hierarchy rooted at this View
7178      * and reported to {@link android.accessibilityservice.AccessibilityService}s
7179      * that explore the window content.
7180      * <p>
7181      * If this method returns an instance, this instance is responsible for managing
7182      * {@link AccessibilityNodeInfo}s describing the virtual sub-tree rooted at this
7183      * View including the one representing the View itself. Similarly the returned
7184      * instance is responsible for performing accessibility actions on any virtual
7185      * view or the root view itself.
7186      * </p>
7187      * <p>
7188      * If an {@link AccessibilityDelegate} has been specified via calling
7189      * {@link #setAccessibilityDelegate(AccessibilityDelegate)} its
7190      * {@link AccessibilityDelegate#getAccessibilityNodeProvider(View)}
7191      * is responsible for handling this call.
7192      * </p>
7193      *
7194      * @return The provider.
7195      *
7196      * @see AccessibilityNodeProvider
7197      */
7198     public AccessibilityNodeProvider getAccessibilityNodeProvider() {
7199         if (mAccessibilityDelegate != null) {
7200             return mAccessibilityDelegate.getAccessibilityNodeProvider(this);
7201         } else {
7202             return null;
7203         }
7204     }
7205
7206     /**
7207      * Gets the unique identifier of this view on the screen for accessibility purposes.
7208      * If this {@link View} is not attached to any window, {@value #NO_ID} is returned.
7209      *
7210      * @return The view accessibility id.
7211      *
7212      * @hide
7213      */
7214     public int getAccessibilityViewId() {
7215         if (mAccessibilityViewId == NO_ID) {
7216             mAccessibilityViewId = sNextAccessibilityViewId++;
7217         }
7218         return mAccessibilityViewId;
7219     }
7220
7221     /**
7222      * Gets the unique identifier of the window in which this View reseides.
7223      *
7224      * @return The window accessibility id.
7225      *
7226      * @hide
7227      */
7228     public int getAccessibilityWindowId() {
7229         return mAttachInfo != null ? mAttachInfo.mAccessibilityWindowId
7230                 : AccessibilityNodeInfo.UNDEFINED_ITEM_ID;
7231     }
7232
7233     /**
7234      * Returns the {@link View}'s content description.
7235      * <p>
7236      * <strong>Note:</strong> Do not override this method, as it will have no
7237      * effect on the content description presented to accessibility services.
7238      * You must call {@link #setContentDescription(CharSequence)} to modify the
7239      * content description.
7240      *
7241      * @return the content description
7242      * @see #setContentDescription(CharSequence)
7243      * @attr ref android.R.styleable#View_contentDescription
7244      */
7245     @ViewDebug.ExportedProperty(category = "accessibility")
7246     public CharSequence getContentDescription() {
7247         return mContentDescription;
7248     }
7249
7250     /**
7251      * Sets the {@link View}'s content description.
7252      * <p>
7253      * A content description briefly describes the view and is primarily used
7254      * for accessibility support to determine how a view should be presented to
7255      * the user. In the case of a view with no textual representation, such as
7256      * {@link android.widget.ImageButton}, a useful content description
7257      * explains what the view does. For example, an image button with a phone
7258      * icon that is used to place a call may use "Call" as its content
7259      * description. An image of a floppy disk that is used to save a file may
7260      * use "Save".
7261      *
7262      * @param contentDescription The content description.
7263      * @see #getContentDescription()
7264      * @attr ref android.R.styleable#View_contentDescription
7265      */
7266     @RemotableViewMethod
7267     public void setContentDescription(CharSequence contentDescription) {
7268         if (mContentDescription == null) {
7269             if (contentDescription == null) {
7270                 return;
7271             }
7272         } else if (mContentDescription.equals(contentDescription)) {
7273             return;
7274         }
7275         mContentDescription = contentDescription;
7276         final boolean nonEmptyDesc = contentDescription != null && contentDescription.length() > 0;
7277         if (nonEmptyDesc && getImportantForAccessibility() == IMPORTANT_FOR_ACCESSIBILITY_AUTO) {
7278             setImportantForAccessibility(IMPORTANT_FOR_ACCESSIBILITY_YES);
7279             notifySubtreeAccessibilityStateChangedIfNeeded();
7280         } else {
7281             notifyViewAccessibilityStateChangedIfNeeded(
7282                     AccessibilityEvent.CONTENT_CHANGE_TYPE_CONTENT_DESCRIPTION);
7283         }
7284     }
7285
7286     /**
7287      * Sets the id of a view before which this one is visited in accessibility traversal.
7288      * A screen-reader must visit the content of this view before the content of the one
7289      * it precedes. For example, if view B is set to be before view A, then a screen-reader
7290      * will traverse the entire content of B before traversing the entire content of A,
7291      * regardles of what traversal strategy it is using.
7292      * <p>
7293      * Views that do not have specified before/after relationships are traversed in order
7294      * determined by the screen-reader.
7295      * </p>
7296      * <p>
7297      * Setting that this view is before a view that is not important for accessibility
7298      * or if this view is not important for accessibility will have no effect as the
7299      * screen-reader is not aware of unimportant views.
7300      * </p>
7301      *
7302      * @param beforeId The id of a view this one precedes in accessibility traversal.
7303      *
7304      * @attr ref android.R.styleable#View_accessibilityTraversalBefore
7305      *
7306      * @see #setImportantForAccessibility(int)
7307      */
7308     @RemotableViewMethod
7309     public void setAccessibilityTraversalBefore(int beforeId) {
7310         if (mAccessibilityTraversalBeforeId == beforeId) {
7311             return;
7312         }
7313         mAccessibilityTraversalBeforeId = beforeId;
7314         notifyViewAccessibilityStateChangedIfNeeded(
7315                 AccessibilityEvent.CONTENT_CHANGE_TYPE_UNDEFINED);
7316     }
7317
7318     /**
7319      * Gets the id of a view before which this one is visited in accessibility traversal.
7320      *
7321      * @return The id of a view this one precedes in accessibility traversal if
7322      *         specified, otherwise {@link #NO_ID}.
7323      *
7324      * @see #setAccessibilityTraversalBefore(int)
7325      */
7326     public int getAccessibilityTraversalBefore() {
7327         return mAccessibilityTraversalBeforeId;
7328     }
7329
7330     /**
7331      * Sets the id of a view after which this one is visited in accessibility traversal.
7332      * A screen-reader must visit the content of the other view before the content of this
7333      * one. For example, if view B is set to be after view A, then a screen-reader
7334      * will traverse the entire content of A before traversing the entire content of B,
7335      * regardles of what traversal strategy it is using.
7336      * <p>
7337      * Views that do not have specified before/after relationships are traversed in order
7338      * determined by the screen-reader.
7339      * </p>
7340      * <p>
7341      * Setting that this view is after a view that is not important for accessibility
7342      * or if this view is not important for accessibility will have no effect as the
7343      * screen-reader is not aware of unimportant views.
7344      * </p>
7345      *
7346      * @param afterId The id of a view this one succedees in accessibility traversal.
7347      *
7348      * @attr ref android.R.styleable#View_accessibilityTraversalAfter
7349      *
7350      * @see #setImportantForAccessibility(int)
7351      */
7352     @RemotableViewMethod
7353     public void setAccessibilityTraversalAfter(int afterId) {
7354         if (mAccessibilityTraversalAfterId == afterId) {
7355             return;
7356         }
7357         mAccessibilityTraversalAfterId = afterId;
7358         notifyViewAccessibilityStateChangedIfNeeded(
7359                 AccessibilityEvent.CONTENT_CHANGE_TYPE_UNDEFINED);
7360     }
7361
7362     /**
7363      * Gets the id of a view after which this one is visited in accessibility traversal.
7364      *
7365      * @return The id of a view this one succeedes in accessibility traversal if
7366      *         specified, otherwise {@link #NO_ID}.
7367      *
7368      * @see #setAccessibilityTraversalAfter(int)
7369      */
7370     public int getAccessibilityTraversalAfter() {
7371         return mAccessibilityTraversalAfterId;
7372     }
7373
7374     /**
7375      * Gets the id of a view for which this view serves as a label for
7376      * accessibility purposes.
7377      *
7378      * @return The labeled view id.
7379      */
7380     @ViewDebug.ExportedProperty(category = "accessibility")
7381     public int getLabelFor() {
7382         return mLabelForId;
7383     }
7384
7385     /**
7386      * Sets the id of a view for which this view serves as a label for
7387      * accessibility purposes.
7388      *
7389      * @param id The labeled view id.
7390      */
7391     @RemotableViewMethod
7392     public void setLabelFor(@IdRes int id) {
7393         if (mLabelForId == id) {
7394             return;
7395         }
7396         mLabelForId = id;
7397         if (mLabelForId != View.NO_ID
7398                 && mID == View.NO_ID) {
7399             mID = generateViewId();
7400         }
7401         notifyViewAccessibilityStateChangedIfNeeded(
7402                 AccessibilityEvent.CONTENT_CHANGE_TYPE_UNDEFINED);
7403     }
7404
7405     /**
7406      * Invoked whenever this view loses focus, either by losing window focus or by losing
7407      * focus within its window. This method can be used to clear any state tied to the
7408      * focus. For instance, if a button is held pressed with the trackball and the window
7409      * loses focus, this method can be used to cancel the press.
7410      *
7411      * Subclasses of View overriding this method should always call super.onFocusLost().
7412      *
7413      * @see #onFocusChanged(boolean, int, android.graphics.Rect)
7414      * @see #onWindowFocusChanged(boolean)
7415      *
7416      * @hide pending API council approval
7417      */
7418     @CallSuper
7419     protected void onFocusLost() {
7420         resetPressedState();
7421     }
7422
7423     private void resetPressedState() {
7424         if ((mViewFlags & ENABLED_MASK) == DISABLED) {
7425             return;
7426         }
7427
7428         if (isPressed()) {
7429             setPressed(false);
7430
7431             if (!mHasPerformedLongPress) {
7432                 removeLongPressCallback();
7433             }
7434         }
7435     }
7436
7437     /**
7438      * Returns true if this view has focus
7439      *
7440      * @return True if this view has focus, false otherwise.
7441      */
7442     @ViewDebug.ExportedProperty(category = "focus")
7443     public boolean isFocused() {
7444         return (mPrivateFlags & PFLAG_FOCUSED) != 0;
7445     }
7446
7447     /**
7448      * Find the view in the hierarchy rooted at this view that currently has
7449      * focus.
7450      *
7451      * @return The view that currently has focus, or null if no focused view can
7452      *         be found.
7453      */
7454     public View findFocus() {
7455         return (mPrivateFlags & PFLAG_FOCUSED) != 0 ? this : null;
7456     }
7457
7458     /**
7459      * Indicates whether this view is one of the set of scrollable containers in
7460      * its window.
7461      *
7462      * @return whether this view is one of the set of scrollable containers in
7463      * its window
7464      *
7465      * @attr ref android.R.styleable#View_isScrollContainer
7466      */
7467     public boolean isScrollContainer() {
7468         return (mPrivateFlags & PFLAG_SCROLL_CONTAINER_ADDED) != 0;
7469     }
7470
7471     /**
7472      * Change whether this view is one of the set of scrollable containers in
7473      * its window.  This will be used to determine whether the window can
7474      * resize or must pan when a soft input area is open -- scrollable
7475      * containers allow the window to use resize mode since the container
7476      * will appropriately shrink.
7477      *
7478      * @attr ref android.R.styleable#View_isScrollContainer
7479      */
7480     public void setScrollContainer(boolean isScrollContainer) {
7481         if (isScrollContainer) {
7482             if (mAttachInfo != null && (mPrivateFlags&PFLAG_SCROLL_CONTAINER_ADDED) == 0) {
7483                 mAttachInfo.mScrollContainers.add(this);
7484                 mPrivateFlags |= PFLAG_SCROLL_CONTAINER_ADDED;
7485             }
7486             mPrivateFlags |= PFLAG_SCROLL_CONTAINER;
7487         } else {
7488             if ((mPrivateFlags&PFLAG_SCROLL_CONTAINER_ADDED) != 0) {
7489                 mAttachInfo.mScrollContainers.remove(this);
7490             }
7491             mPrivateFlags &= ~(PFLAG_SCROLL_CONTAINER|PFLAG_SCROLL_CONTAINER_ADDED);
7492         }
7493     }
7494
7495     /**
7496      * Returns the quality of the drawing cache.
7497      *
7498      * @return One of {@link #DRAWING_CACHE_QUALITY_AUTO},
7499      *         {@link #DRAWING_CACHE_QUALITY_LOW}, or {@link #DRAWING_CACHE_QUALITY_HIGH}
7500      *
7501      * @see #setDrawingCacheQuality(int)
7502      * @see #setDrawingCacheEnabled(boolean)
7503      * @see #isDrawingCacheEnabled()
7504      *
7505      * @attr ref android.R.styleable#View_drawingCacheQuality
7506      */
7507     @DrawingCacheQuality
7508     public int getDrawingCacheQuality() {
7509         return mViewFlags & DRAWING_CACHE_QUALITY_MASK;
7510     }
7511
7512     /**
7513      * Set the drawing cache quality of this view. This value is used only when the
7514      * drawing cache is enabled
7515      *
7516      * @param quality One of {@link #DRAWING_CACHE_QUALITY_AUTO},
7517      *        {@link #DRAWING_CACHE_QUALITY_LOW}, or {@link #DRAWING_CACHE_QUALITY_HIGH}
7518      *
7519      * @see #getDrawingCacheQuality()
7520      * @see #setDrawingCacheEnabled(boolean)
7521      * @see #isDrawingCacheEnabled()
7522      *
7523      * @attr ref android.R.styleable#View_drawingCacheQuality
7524      */
7525     public void setDrawingCacheQuality(@DrawingCacheQuality int quality) {
7526         setFlags(quality, DRAWING_CACHE_QUALITY_MASK);
7527     }
7528
7529     /**
7530      * Returns whether the screen should remain on, corresponding to the current
7531      * value of {@link #KEEP_SCREEN_ON}.
7532      *
7533      * @return Returns true if {@link #KEEP_SCREEN_ON} is set.
7534      *
7535      * @see #setKeepScreenOn(boolean)
7536      *
7537      * @attr ref android.R.styleable#View_keepScreenOn
7538      */
7539     public boolean getKeepScreenOn() {
7540         return (mViewFlags & KEEP_SCREEN_ON) != 0;
7541     }
7542
7543     /**
7544      * Controls whether the screen should remain on, modifying the
7545      * value of {@link #KEEP_SCREEN_ON}.
7546      *
7547      * @param keepScreenOn Supply true to set {@link #KEEP_SCREEN_ON}.
7548      *
7549      * @see #getKeepScreenOn()
7550      *
7551      * @attr ref android.R.styleable#View_keepScreenOn
7552      */
7553     public void setKeepScreenOn(boolean keepScreenOn) {
7554         setFlags(keepScreenOn ? KEEP_SCREEN_ON : 0, KEEP_SCREEN_ON);
7555     }
7556
7557     /**
7558      * Gets the id of the view to use when the next focus is {@link #FOCUS_LEFT}.
7559      * @return The next focus ID, or {@link #NO_ID} if the framework should decide automatically.
7560      *
7561      * @attr ref android.R.styleable#View_nextFocusLeft
7562      */
7563     public int getNextFocusLeftId() {
7564         return mNextFocusLeftId;
7565     }
7566
7567     /**
7568      * Sets the id of the view to use when the next focus is {@link #FOCUS_LEFT}.
7569      * @param nextFocusLeftId The next focus ID, or {@link #NO_ID} if the framework should
7570      * decide automatically.
7571      *
7572      * @attr ref android.R.styleable#View_nextFocusLeft
7573      */
7574     public void setNextFocusLeftId(int nextFocusLeftId) {
7575         mNextFocusLeftId = nextFocusLeftId;
7576     }
7577
7578     /**
7579      * Gets the id of the view to use when the next focus is {@link #FOCUS_RIGHT}.
7580      * @return The next focus ID, or {@link #NO_ID} if the framework should decide automatically.
7581      *
7582      * @attr ref android.R.styleable#View_nextFocusRight
7583      */
7584     public int getNextFocusRightId() {
7585         return mNextFocusRightId;
7586     }
7587
7588     /**
7589      * Sets the id of the view to use when the next focus is {@link #FOCUS_RIGHT}.
7590      * @param nextFocusRightId The next focus ID, or {@link #NO_ID} if the framework should
7591      * decide automatically.
7592      *
7593      * @attr ref android.R.styleable#View_nextFocusRight
7594      */
7595     public void setNextFocusRightId(int nextFocusRightId) {
7596         mNextFocusRightId = nextFocusRightId;
7597     }
7598
7599     /**
7600      * Gets the id of the view to use when the next focus is {@link #FOCUS_UP}.
7601      * @return The next focus ID, or {@link #NO_ID} if the framework should decide automatically.
7602      *
7603      * @attr ref android.R.styleable#View_nextFocusUp
7604      */
7605     public int getNextFocusUpId() {
7606         return mNextFocusUpId;
7607     }
7608
7609     /**
7610      * Sets the id of the view to use when the next focus is {@link #FOCUS_UP}.
7611      * @param nextFocusUpId The next focus ID, or {@link #NO_ID} if the framework should
7612      * decide automatically.
7613      *
7614      * @attr ref android.R.styleable#View_nextFocusUp
7615      */
7616     public void setNextFocusUpId(int nextFocusUpId) {
7617         mNextFocusUpId = nextFocusUpId;
7618     }
7619
7620     /**
7621      * Gets the id of the view to use when the next focus is {@link #FOCUS_DOWN}.
7622      * @return The next focus ID, or {@link #NO_ID} if the framework should decide automatically.
7623      *
7624      * @attr ref android.R.styleable#View_nextFocusDown
7625      */
7626     public int getNextFocusDownId() {
7627         return mNextFocusDownId;
7628     }
7629
7630     /**
7631      * Sets the id of the view to use when the next focus is {@link #FOCUS_DOWN}.
7632      * @param nextFocusDownId The next focus ID, or {@link #NO_ID} if the framework should
7633      * decide automatically.
7634      *
7635      * @attr ref android.R.styleable#View_nextFocusDown
7636      */
7637     public void setNextFocusDownId(int nextFocusDownId) {
7638         mNextFocusDownId = nextFocusDownId;
7639     }
7640
7641     /**
7642      * Gets the id of the view to use when the next focus is {@link #FOCUS_FORWARD}.
7643      * @return The next focus ID, or {@link #NO_ID} if the framework should decide automatically.
7644      *
7645      * @attr ref android.R.styleable#View_nextFocusForward
7646      */
7647     public int getNextFocusForwardId() {
7648         return mNextFocusForwardId;
7649     }
7650
7651     /**
7652      * Sets the id of the view to use when the next focus is {@link #FOCUS_FORWARD}.
7653      * @param nextFocusForwardId The next focus ID, or {@link #NO_ID} if the framework should
7654      * decide automatically.
7655      *
7656      * @attr ref android.R.styleable#View_nextFocusForward
7657      */
7658     public void setNextFocusForwardId(int nextFocusForwardId) {
7659         mNextFocusForwardId = nextFocusForwardId;
7660     }
7661
7662     /**
7663      * Returns the visibility of this view and all of its ancestors
7664      *
7665      * @return True if this view and all of its ancestors are {@link #VISIBLE}
7666      */
7667     public boolean isShown() {
7668         View current = this;
7669         //noinspection ConstantConditions
7670         do {
7671             if ((current.mViewFlags & VISIBILITY_MASK) != VISIBLE) {
7672                 return false;
7673             }
7674             ViewParent parent = current.mParent;
7675             if (parent == null) {
7676                 return false; // We are not attached to the view root
7677             }
7678             if (!(parent instanceof View)) {
7679                 return true;
7680             }
7681             current = (View) parent;
7682         } while (current != null);
7683
7684         return false;
7685     }
7686
7687     /**
7688      * Called by the view hierarchy when the content insets for a window have
7689      * changed, to allow it to adjust its content to fit within those windows.
7690      * The content insets tell you the space that the status bar, input method,
7691      * and other system windows infringe on the application's window.
7692      *
7693      * <p>You do not normally need to deal with this function, since the default
7694      * window decoration given to applications takes care of applying it to the
7695      * content of the window.  If you use {@link #SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN}
7696      * or {@link #SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION} this will not be the case,
7697      * and your content can be placed under those system elements.  You can then
7698      * use this method within your view hierarchy if you have parts of your UI
7699      * which you would like to ensure are not being covered.
7700      *
7701      * <p>The default implementation of this method simply applies the content
7702      * insets to the view's padding, consuming that content (modifying the
7703      * insets to be 0), and returning true.  This behavior is off by default, but can
7704      * be enabled through {@link #setFitsSystemWindows(boolean)}.
7705      *
7706      * <p>This function's traversal down the hierarchy is depth-first.  The same content
7707      * insets object is propagated down the hierarchy, so any changes made to it will
7708      * be seen by all following views (including potentially ones above in
7709      * the hierarchy since this is a depth-first traversal).  The first view
7710      * that returns true will abort the entire traversal.
7711      *
7712      * <p>The default implementation works well for a situation where it is
7713      * used with a container that covers the entire window, allowing it to
7714      * apply the appropriate insets to its content on all edges.  If you need
7715      * a more complicated layout (such as two different views fitting system
7716      * windows, one on the top of the window, and one on the bottom),
7717      * you can override the method and handle the insets however you would like.
7718      * Note that the insets provided by the framework are always relative to the
7719      * far edges of the window, not accounting for the location of the called view
7720      * within that window.  (In fact when this method is called you do not yet know
7721      * where the layout will place the view, as it is done before layout happens.)
7722      *
7723      * <p>Note: unlike many View methods, there is no dispatch phase to this
7724      * call.  If you are overriding it in a ViewGroup and want to allow the
7725      * call to continue to your children, you must be sure to call the super
7726      * implementation.
7727      *
7728      * <p>Here is a sample layout that makes use of fitting system windows
7729      * to have controls for a video view placed inside of the window decorations
7730      * that it hides and shows.  This can be used with code like the second
7731      * sample (video player) shown in {@link #setSystemUiVisibility(int)}.
7732      *
7733      * {@sample development/samples/ApiDemos/res/layout/video_player.xml complete}
7734      *
7735      * @param insets Current content insets of the window.  Prior to
7736      * {@link android.os.Build.VERSION_CODES#JELLY_BEAN} you must not modify
7737      * the insets or else you and Android will be unhappy.
7738      *
7739      * @return {@code true} if this view applied the insets and it should not
7740      * continue propagating further down the hierarchy, {@code false} otherwise.
7741      * @see #getFitsSystemWindows()
7742      * @see #setFitsSystemWindows(boolean)
7743      * @see #setSystemUiVisibility(int)
7744      *
7745      * @deprecated As of API 20 use {@link #dispatchApplyWindowInsets(WindowInsets)} to apply
7746      * insets to views. Views should override {@link #onApplyWindowInsets(WindowInsets)} or use
7747      * {@link #setOnApplyWindowInsetsListener(android.view.View.OnApplyWindowInsetsListener)}
7748      * to implement handling their own insets.
7749      */
7750     protected boolean fitSystemWindows(Rect insets) {
7751         if ((mPrivateFlags3 & PFLAG3_APPLYING_INSETS) == 0) {
7752             if (insets == null) {
7753                 // Null insets by definition have already been consumed.
7754                 // This call cannot apply insets since there are none to apply,
7755                 // so return false.
7756                 return false;
7757             }
7758             // If we're not in the process of dispatching the newer apply insets call,
7759             // that means we're not in the compatibility path. Dispatch into the newer
7760             // apply insets path and take things from there.
7761             try {
7762                 mPrivateFlags3 |= PFLAG3_FITTING_SYSTEM_WINDOWS;
7763                 return dispatchApplyWindowInsets(new WindowInsets(insets)).isConsumed();
7764             } finally {
7765                 mPrivateFlags3 &= ~PFLAG3_FITTING_SYSTEM_WINDOWS;
7766             }
7767         } else {
7768             // We're being called from the newer apply insets path.
7769             // Perform the standard fallback behavior.
7770             return fitSystemWindowsInt(insets);
7771         }
7772     }
7773
7774     private boolean fitSystemWindowsInt(Rect insets) {
7775         if ((mViewFlags & FITS_SYSTEM_WINDOWS) == FITS_SYSTEM_WINDOWS) {
7776             mUserPaddingStart = UNDEFINED_PADDING;
7777             mUserPaddingEnd = UNDEFINED_PADDING;
7778             Rect localInsets = sThreadLocal.get();
7779             if (localInsets == null) {
7780                 localInsets = new Rect();
7781                 sThreadLocal.set(localInsets);
7782             }
7783             boolean res = computeFitSystemWindows(insets, localInsets);
7784             mUserPaddingLeftInitial = localInsets.left;
7785             mUserPaddingRightInitial = localInsets.right;
7786             internalSetPadding(localInsets.left, localInsets.top,
7787                     localInsets.right, localInsets.bottom);
7788             return res;
7789         }
7790         return false;
7791     }
7792
7793     /**
7794      * Called when the view should apply {@link WindowInsets} according to its internal policy.
7795      *
7796      * <p>This method should be overridden by views that wish to apply a policy different from or
7797      * in addition to the default behavior. Clients that wish to force a view subtree
7798      * to apply insets should call {@link #dispatchApplyWindowInsets(WindowInsets)}.</p>
7799      *
7800      * <p>Clients may supply an {@link OnApplyWindowInsetsListener} to a view. If one is set
7801      * it will be called during dispatch instead of this method. The listener may optionally
7802      * call this method from its own implementation if it wishes to apply the view's default
7803      * insets policy in addition to its own.</p>
7804      *
7805      * <p>Implementations of this method should either return the insets parameter unchanged
7806      * or a new {@link WindowInsets} cloned from the supplied insets with any insets consumed
7807      * that this view applied itself. This allows new inset types added in future platform
7808      * versions to pass through existing implementations unchanged without being erroneously
7809      * consumed.</p>
7810      *
7811      * <p>By default if a view's {@link #setFitsSystemWindows(boolean) fitsSystemWindows}
7812      * property is set then the view will consume the system window insets and apply them
7813      * as padding for the view.</p>
7814      *
7815      * @param insets Insets to apply
7816      * @return The supplied insets with any applied insets consumed
7817      */
7818     public WindowInsets onApplyWindowInsets(WindowInsets insets) {
7819         if ((mPrivateFlags3 & PFLAG3_FITTING_SYSTEM_WINDOWS) == 0) {
7820             // We weren't called from within a direct call to fitSystemWindows,
7821             // call into it as a fallback in case we're in a class that overrides it
7822             // and has logic to perform.
7823             if (fitSystemWindows(insets.getSystemWindowInsets())) {
7824                 return insets.consumeSystemWindowInsets();
7825             }
7826         } else {
7827             // We were called from within a direct call to fitSystemWindows.
7828             if (fitSystemWindowsInt(insets.getSystemWindowInsets())) {
7829                 return insets.consumeSystemWindowInsets();
7830             }
7831         }
7832         return insets;
7833     }
7834
7835     /**
7836      * Set an {@link OnApplyWindowInsetsListener} to take over the policy for applying
7837      * window insets to this view. The listener's
7838      * {@link OnApplyWindowInsetsListener#onApplyWindowInsets(View, WindowInsets) onApplyWindowInsets}
7839      * method will be called instead of the view's
7840      * {@link #onApplyWindowInsets(WindowInsets) onApplyWindowInsets} method.
7841      *
7842      * @param listener Listener to set
7843      *
7844      * @see #onApplyWindowInsets(WindowInsets)
7845      */
7846     public void setOnApplyWindowInsetsListener(OnApplyWindowInsetsListener listener) {
7847         getListenerInfo().mOnApplyWindowInsetsListener = listener;
7848     }
7849
7850     /**
7851      * Request to apply the given window insets to this view or another view in its subtree.
7852      *
7853      * <p>This method should be called by clients wishing to apply insets corresponding to areas
7854      * obscured by window decorations or overlays. This can include the status and navigation bars,
7855      * action bars, input methods and more. New inset categories may be added in the future.
7856      * The method returns the insets provided minus any that were applied by this view or its
7857      * children.</p>
7858      *
7859      * <p>Clients wishing to provide custom behavior should override the
7860      * {@link #onApplyWindowInsets(WindowInsets)} method or alternatively provide a
7861      * {@link OnApplyWindowInsetsListener} via the
7862      * {@link #setOnApplyWindowInsetsListener(View.OnApplyWindowInsetsListener) setOnApplyWindowInsetsListener}
7863      * method.</p>
7864      *
7865      * <p>This method replaces the older {@link #fitSystemWindows(Rect) fitSystemWindows} method.
7866      * </p>
7867      *
7868      * @param insets Insets to apply
7869      * @return The provided insets minus the insets that were consumed
7870      */
7871     public WindowInsets dispatchApplyWindowInsets(WindowInsets insets) {
7872         try {
7873             mPrivateFlags3 |= PFLAG3_APPLYING_INSETS;
7874             if (mListenerInfo != null && mListenerInfo.mOnApplyWindowInsetsListener != null) {
7875                 return mListenerInfo.mOnApplyWindowInsetsListener.onApplyWindowInsets(this, insets);
7876             } else {
7877                 return onApplyWindowInsets(insets);
7878             }
7879         } finally {
7880             mPrivateFlags3 &= ~PFLAG3_APPLYING_INSETS;
7881         }
7882     }
7883
7884     /**
7885      * Compute the view's coordinate within the surface.
7886      *
7887      * <p>Computes the coordinates of this view in its surface. The argument
7888      * must be an array of two integers. After the method returns, the array
7889      * contains the x and y location in that order.</p>
7890      * @hide
7891      * @param location an array of two integers in which to hold the coordinates
7892      */
7893     public void getLocationInSurface(@Size(2) int[] location) {
7894         getLocationInWindow(location);
7895         if (mAttachInfo != null && mAttachInfo.mViewRootImpl != null) {
7896             location[0] += mAttachInfo.mViewRootImpl.mWindowAttributes.surfaceInsets.left;
7897             location[1] += mAttachInfo.mViewRootImpl.mWindowAttributes.surfaceInsets.top;
7898         }
7899     }
7900
7901     /**
7902      * Provide original WindowInsets that are dispatched to the view hierarchy. The insets are
7903      * only available if the view is attached.
7904      *
7905      * @return WindowInsets from the top of the view hierarchy or null if View is detached
7906      */
7907     public WindowInsets getRootWindowInsets() {
7908         if (mAttachInfo != null) {
7909             return mAttachInfo.mViewRootImpl.getWindowInsets(false /* forceConstruct */);
7910         }
7911         return null;
7912     }
7913
7914     /**
7915      * @hide Compute the insets that should be consumed by this view and the ones
7916      * that should propagate to those under it.
7917      */
7918     protected boolean computeFitSystemWindows(Rect inoutInsets, Rect outLocalInsets) {
7919         if ((mViewFlags & OPTIONAL_FITS_SYSTEM_WINDOWS) == 0
7920                 || mAttachInfo == null
7921                 || ((mAttachInfo.mSystemUiVisibility & SYSTEM_UI_LAYOUT_FLAGS) == 0
7922                         && !mAttachInfo.mOverscanRequested)) {
7923             outLocalInsets.set(inoutInsets);
7924             inoutInsets.set(0, 0, 0, 0);
7925             return true;
7926         } else {
7927             // The application wants to take care of fitting system window for
7928             // the content...  however we still need to take care of any overscan here.
7929             final Rect overscan = mAttachInfo.mOverscanInsets;
7930             outLocalInsets.set(overscan);
7931             inoutInsets.left -= overscan.left;
7932             inoutInsets.top -= overscan.top;
7933             inoutInsets.right -= overscan.right;
7934             inoutInsets.bottom -= overscan.bottom;
7935             return false;
7936         }
7937     }
7938
7939     /**
7940      * Compute insets that should be consumed by this view and the ones that should propagate
7941      * to those under it.
7942      *
7943      * @param in Insets currently being processed by this View, likely received as a parameter
7944      *           to {@link #onApplyWindowInsets(WindowInsets)}.
7945      * @param outLocalInsets A Rect that will receive the insets that should be consumed
7946      *                       by this view
7947      * @return Insets that should be passed along to views under this one
7948      */
7949     public WindowInsets computeSystemWindowInsets(WindowInsets in, Rect outLocalInsets) {
7950         if ((mViewFlags & OPTIONAL_FITS_SYSTEM_WINDOWS) == 0
7951                 || mAttachInfo == null
7952                 || (mAttachInfo.mSystemUiVisibility & SYSTEM_UI_LAYOUT_FLAGS) == 0) {
7953             outLocalInsets.set(in.getSystemWindowInsets());
7954             return in.consumeSystemWindowInsets();
7955         } else {
7956             outLocalInsets.set(0, 0, 0, 0);
7957             return in;
7958         }
7959     }
7960
7961     /**
7962      * Sets whether or not this view should account for system screen decorations
7963      * such as the status bar and inset its content; that is, controlling whether
7964      * the default implementation of {@link #fitSystemWindows(Rect)} will be
7965      * executed.  See that method for more details.
7966      *
7967      * <p>Note that if you are providing your own implementation of
7968      * {@link #fitSystemWindows(Rect)}, then there is no need to set this
7969      * flag to true -- your implementation will be overriding the default
7970      * implementation that checks this flag.
7971      *
7972      * @param fitSystemWindows If true, then the default implementation of
7973      * {@link #fitSystemWindows(Rect)} will be executed.
7974      *
7975      * @attr ref android.R.styleable#View_fitsSystemWindows
7976      * @see #getFitsSystemWindows()
7977      * @see #fitSystemWindows(Rect)
7978      * @see #setSystemUiVisibility(int)
7979      */
7980     public void setFitsSystemWindows(boolean fitSystemWindows) {
7981         setFlags(fitSystemWindows ? FITS_SYSTEM_WINDOWS : 0, FITS_SYSTEM_WINDOWS);
7982     }
7983
7984     /**
7985      * Check for state of {@link #setFitsSystemWindows(boolean)}. If this method
7986      * returns {@code true}, the default implementation of {@link #fitSystemWindows(Rect)}
7987      * will be executed.
7988      *
7989      * @return {@code true} if the default implementation of
7990      * {@link #fitSystemWindows(Rect)} will be executed.
7991      *
7992      * @attr ref android.R.styleable#View_fitsSystemWindows
7993      * @see #setFitsSystemWindows(boolean)
7994      * @see #fitSystemWindows(Rect)
7995      * @see #setSystemUiVisibility(int)
7996      */
7997     @ViewDebug.ExportedProperty
7998     public boolean getFitsSystemWindows() {
7999         return (mViewFlags & FITS_SYSTEM_WINDOWS) == FITS_SYSTEM_WINDOWS;
8000     }
8001
8002     /** @hide */
8003     public boolean fitsSystemWindows() {
8004         return getFitsSystemWindows();
8005     }
8006
8007     /**
8008      * Ask that a new dispatch of {@link #fitSystemWindows(Rect)} be performed.
8009      * @deprecated Use {@link #requestApplyInsets()} for newer platform versions.
8010      */
8011     public void requestFitSystemWindows() {
8012         if (mParent != null) {
8013             mParent.requestFitSystemWindows();
8014         }
8015     }
8016
8017     /**
8018      * Ask that a new dispatch of {@link #onApplyWindowInsets(WindowInsets)} be performed.
8019      */
8020     public void requestApplyInsets() {
8021         requestFitSystemWindows();
8022     }
8023
8024     /**
8025      * For use by PhoneWindow to make its own system window fitting optional.
8026      * @hide
8027      */
8028     public void makeOptionalFitsSystemWindows() {
8029         setFlags(OPTIONAL_FITS_SYSTEM_WINDOWS, OPTIONAL_FITS_SYSTEM_WINDOWS);
8030     }
8031
8032     /**
8033      * Returns the outsets, which areas of the device that aren't a surface, but we would like to
8034      * treat them as such.
8035      * @hide
8036      */
8037     public void getOutsets(Rect outOutsetRect) {
8038         if (mAttachInfo != null) {
8039             outOutsetRect.set(mAttachInfo.mOutsets);
8040         } else {
8041             outOutsetRect.setEmpty();
8042         }
8043     }
8044
8045     /**
8046      * Returns the visibility status for this view.
8047      *
8048      * @return One of {@link #VISIBLE}, {@link #INVISIBLE}, or {@link #GONE}.
8049      * @attr ref android.R.styleable#View_visibility
8050      */
8051     @ViewDebug.ExportedProperty(mapping = {
8052         @ViewDebug.IntToString(from = VISIBLE,   to = "VISIBLE"),
8053         @ViewDebug.IntToString(from = INVISIBLE, to = "INVISIBLE"),
8054         @ViewDebug.IntToString(from = GONE,      to = "GONE")
8055     })
8056     @Visibility
8057     public int getVisibility() {
8058         return mViewFlags & VISIBILITY_MASK;
8059     }
8060
8061     /**
8062      * Set the visibility state of this view.
8063      *
8064      * @param visibility One of {@link #VISIBLE}, {@link #INVISIBLE}, or {@link #GONE}.
8065      * @attr ref android.R.styleable#View_visibility
8066      */
8067     @RemotableViewMethod
8068     public void setVisibility(@Visibility int visibility) {
8069         setFlags(visibility, VISIBILITY_MASK);
8070     }
8071
8072     /**
8073      * Returns the enabled status for this view. The interpretation of the
8074      * enabled state varies by subclass.
8075      *
8076      * @return True if this view is enabled, false otherwise.
8077      */
8078     @ViewDebug.ExportedProperty
8079     public boolean isEnabled() {
8080         return (mViewFlags & ENABLED_MASK) == ENABLED;
8081     }
8082
8083     /**
8084      * Set the enabled state of this view. The interpretation of the enabled
8085      * state varies by subclass.
8086      *
8087      * @param enabled True if this view is enabled, false otherwise.
8088      */
8089     @RemotableViewMethod
8090     public void setEnabled(boolean enabled) {
8091         if (enabled == isEnabled()) return;
8092
8093         setFlags(enabled ? ENABLED : DISABLED, ENABLED_MASK);
8094
8095         /*
8096          * The View most likely has to change its appearance, so refresh
8097          * the drawable state.
8098          */
8099         refreshDrawableState();
8100
8101         // Invalidate too, since the default behavior for views is to be
8102         // be drawn at 50% alpha rather than to change the drawable.
8103         invalidate(true);
8104
8105         if (!enabled) {
8106             cancelPendingInputEvents();
8107         }
8108     }
8109
8110     /**
8111      * Set whether this view can receive the focus.
8112      *
8113      * Setting this to false will also ensure that this view is not focusable
8114      * in touch mode.
8115      *
8116      * @param focusable If true, this view can receive the focus.
8117      *
8118      * @see #setFocusableInTouchMode(boolean)
8119      * @attr ref android.R.styleable#View_focusable
8120      */
8121     public void setFocusable(boolean focusable) {
8122         if (!focusable) {
8123             setFlags(0, FOCUSABLE_IN_TOUCH_MODE);
8124         }
8125         setFlags(focusable ? FOCUSABLE : NOT_FOCUSABLE, FOCUSABLE_MASK);
8126     }
8127
8128     /**
8129      * Set whether this view can receive focus while in touch mode.
8130      *
8131      * Setting this to true will also ensure that this view is focusable.
8132      *
8133      * @param focusableInTouchMode If true, this view can receive the focus while
8134      *   in touch mode.
8135      *
8136      * @see #setFocusable(boolean)
8137      * @attr ref android.R.styleable#View_focusableInTouchMode
8138      */
8139     public void setFocusableInTouchMode(boolean focusableInTouchMode) {
8140         // Focusable in touch mode should always be set before the focusable flag
8141         // otherwise, setting the focusable flag will trigger a focusableViewAvailable()
8142         // which, in touch mode, will not successfully request focus on this view
8143         // because the focusable in touch mode flag is not set
8144         setFlags(focusableInTouchMode ? FOCUSABLE_IN_TOUCH_MODE : 0, FOCUSABLE_IN_TOUCH_MODE);
8145         if (focusableInTouchMode) {
8146             setFlags(FOCUSABLE, FOCUSABLE_MASK);
8147         }
8148     }
8149
8150     /**
8151      * Set whether this view should have sound effects enabled for events such as
8152      * clicking and touching.
8153      *
8154      * <p>You may wish to disable sound effects for a view if you already play sounds,
8155      * for instance, a dial key that plays dtmf tones.
8156      *
8157      * @param soundEffectsEnabled whether sound effects are enabled for this view.
8158      * @see #isSoundEffectsEnabled()
8159      * @see #playSoundEffect(int)
8160      * @attr ref android.R.styleable#View_soundEffectsEnabled
8161      */
8162     public void setSoundEffectsEnabled(boolean soundEffectsEnabled) {
8163         setFlags(soundEffectsEnabled ? SOUND_EFFECTS_ENABLED: 0, SOUND_EFFECTS_ENABLED);
8164     }
8165
8166     /**
8167      * @return whether this view should have sound effects enabled for events such as
8168      *     clicking and touching.
8169      *
8170      * @see #setSoundEffectsEnabled(boolean)
8171      * @see #playSoundEffect(int)
8172      * @attr ref android.R.styleable#View_soundEffectsEnabled
8173      */
8174     @ViewDebug.ExportedProperty
8175     public boolean isSoundEffectsEnabled() {
8176         return SOUND_EFFECTS_ENABLED == (mViewFlags & SOUND_EFFECTS_ENABLED);
8177     }
8178
8179     /**
8180      * Set whether this view should have haptic feedback for events such as
8181      * long presses.
8182      *
8183      * <p>You may wish to disable haptic feedback if your view already controls
8184      * its own haptic feedback.
8185      *
8186      * @param hapticFeedbackEnabled whether haptic feedback enabled for this view.
8187      * @see #isHapticFeedbackEnabled()
8188      * @see #performHapticFeedback(int)
8189      * @attr ref android.R.styleable#View_hapticFeedbackEnabled
8190      */
8191     public void setHapticFeedbackEnabled(boolean hapticFeedbackEnabled) {
8192         setFlags(hapticFeedbackEnabled ? HAPTIC_FEEDBACK_ENABLED: 0, HAPTIC_FEEDBACK_ENABLED);
8193     }
8194
8195     /**
8196      * @return whether this view should have haptic feedback enabled for events
8197      * long presses.
8198      *
8199      * @see #setHapticFeedbackEnabled(boolean)
8200      * @see #performHapticFeedback(int)
8201      * @attr ref android.R.styleable#View_hapticFeedbackEnabled
8202      */
8203     @ViewDebug.ExportedProperty
8204     public boolean isHapticFeedbackEnabled() {
8205         return HAPTIC_FEEDBACK_ENABLED == (mViewFlags & HAPTIC_FEEDBACK_ENABLED);
8206     }
8207
8208     /**
8209      * Returns the layout direction for this view.
8210      *
8211      * @return One of {@link #LAYOUT_DIRECTION_LTR},
8212      *   {@link #LAYOUT_DIRECTION_RTL},
8213      *   {@link #LAYOUT_DIRECTION_INHERIT} or
8214      *   {@link #LAYOUT_DIRECTION_LOCALE}.
8215      *
8216      * @attr ref android.R.styleable#View_layoutDirection
8217      *
8218      * @hide
8219      */
8220     @ViewDebug.ExportedProperty(category = "layout", mapping = {
8221         @ViewDebug.IntToString(from = LAYOUT_DIRECTION_LTR,     to = "LTR"),
8222         @ViewDebug.IntToString(from = LAYOUT_DIRECTION_RTL,     to = "RTL"),
8223         @ViewDebug.IntToString(from = LAYOUT_DIRECTION_INHERIT, to = "INHERIT"),
8224         @ViewDebug.IntToString(from = LAYOUT_DIRECTION_LOCALE,  to = "LOCALE")
8225     })
8226     @LayoutDir
8227     public int getRawLayoutDirection() {
8228         return (mPrivateFlags2 & PFLAG2_LAYOUT_DIRECTION_MASK) >> PFLAG2_LAYOUT_DIRECTION_MASK_SHIFT;
8229     }
8230
8231     /**
8232      * Set the layout direction for this view. This will propagate a reset of layout direction
8233      * resolution to the view's children and resolve layout direction for this view.
8234      *
8235      * @param layoutDirection the layout direction to set. Should be one of:
8236      *
8237      * {@link #LAYOUT_DIRECTION_LTR},
8238      * {@link #LAYOUT_DIRECTION_RTL},
8239      * {@link #LAYOUT_DIRECTION_INHERIT},
8240      * {@link #LAYOUT_DIRECTION_LOCALE}.
8241      *
8242      * Resolution will be done if the value is set to LAYOUT_DIRECTION_INHERIT. The resolution
8243      * proceeds up the parent chain of the view to get the value. If there is no parent, then it
8244      * will return the default {@link #LAYOUT_DIRECTION_LTR}.
8245      *
8246      * @attr ref android.R.styleable#View_layoutDirection
8247      */
8248     @RemotableViewMethod
8249     public void setLayoutDirection(@LayoutDir int layoutDirection) {
8250         if (getRawLayoutDirection() != layoutDirection) {
8251             // Reset the current layout direction and the resolved one
8252             mPrivateFlags2 &= ~PFLAG2_LAYOUT_DIRECTION_MASK;
8253             resetRtlProperties();
8254             // Set the new layout direction (filtered)
8255             mPrivateFlags2 |=
8256                     ((layoutDirection << PFLAG2_LAYOUT_DIRECTION_MASK_SHIFT) & PFLAG2_LAYOUT_DIRECTION_MASK);
8257             // We need to resolve all RTL properties as they all depend on layout direction
8258             resolveRtlPropertiesIfNeeded();
8259             requestLayout();
8260             invalidate(true);
8261         }
8262     }
8263
8264     /**
8265      * Returns the resolved layout direction for this view.
8266      *
8267      * @return {@link #LAYOUT_DIRECTION_RTL} if the layout direction is RTL or returns
8268      * {@link #LAYOUT_DIRECTION_LTR} if the layout direction is not RTL.
8269      *
8270      * For compatibility, this will return {@link #LAYOUT_DIRECTION_LTR} if API version
8271      * is lower than {@link android.os.Build.VERSION_CODES#JELLY_BEAN_MR1}.
8272      *
8273      * @attr ref android.R.styleable#View_layoutDirection
8274      */
8275     @ViewDebug.ExportedProperty(category = "layout", mapping = {
8276         @ViewDebug.IntToString(from = LAYOUT_DIRECTION_LTR, to = "RESOLVED_DIRECTION_LTR"),
8277         @ViewDebug.IntToString(from = LAYOUT_DIRECTION_RTL, to = "RESOLVED_DIRECTION_RTL")
8278     })
8279     @ResolvedLayoutDir
8280     public int getLayoutDirection() {
8281         final int targetSdkVersion = getContext().getApplicationInfo().targetSdkVersion;
8282         if (targetSdkVersion < JELLY_BEAN_MR1) {
8283             mPrivateFlags2 |= PFLAG2_LAYOUT_DIRECTION_RESOLVED;
8284             return LAYOUT_DIRECTION_RESOLVED_DEFAULT;
8285         }
8286         return ((mPrivateFlags2 & PFLAG2_LAYOUT_DIRECTION_RESOLVED_RTL) ==
8287                 PFLAG2_LAYOUT_DIRECTION_RESOLVED_RTL) ? LAYOUT_DIRECTION_RTL : LAYOUT_DIRECTION_LTR;
8288     }
8289
8290     /**
8291      * Indicates whether or not this view's layout is right-to-left. This is resolved from
8292      * layout attribute and/or the inherited value from the parent
8293      *
8294      * @return true if the layout is right-to-left.
8295      *
8296      * @hide
8297      */
8298     @ViewDebug.ExportedProperty(category = "layout")
8299     public boolean isLayoutRtl() {
8300         return (getLayoutDirection() == LAYOUT_DIRECTION_RTL);
8301     }
8302
8303     /**
8304      * Indicates whether the view is currently tracking transient state that the
8305      * app should not need to concern itself with saving and restoring, but that
8306      * the framework should take special note to preserve when possible.
8307      *
8308      * <p>A view with transient state cannot be trivially rebound from an external
8309      * data source, such as an adapter binding item views in a list. This may be
8310      * because the view is performing an animation, tracking user selection
8311      * of content, or similar.</p>
8312      *
8313      * @return true if the view has transient state
8314      */
8315     @ViewDebug.ExportedProperty(category = "layout")
8316     public boolean hasTransientState() {
8317         return (mPrivateFlags2 & PFLAG2_HAS_TRANSIENT_STATE) == PFLAG2_HAS_TRANSIENT_STATE;
8318     }
8319
8320     /**
8321      * Set whether this view is currently tracking transient state that the
8322      * framework should attempt to preserve when possible. This flag is reference counted,
8323      * so every call to setHasTransientState(true) should be paired with a later call
8324      * to setHasTransientState(false).
8325      *
8326      * <p>A view with transient state cannot be trivially rebound from an external
8327      * data source, such as an adapter binding item views in a list. This may be
8328      * because the view is performing an animation, tracking user selection
8329      * of content, or similar.</p>
8330      *
8331      * @param hasTransientState true if this view has transient state
8332      */
8333     public void setHasTransientState(boolean hasTransientState) {
8334         mTransientStateCount = hasTransientState ? mTransientStateCount + 1 :
8335                 mTransientStateCount - 1;
8336         if (mTransientStateCount < 0) {
8337             mTransientStateCount = 0;
8338             Log.e(VIEW_LOG_TAG, "hasTransientState decremented below 0: " +
8339                     "unmatched pair of setHasTransientState calls");
8340         } else if ((hasTransientState && mTransientStateCount == 1) ||
8341                 (!hasTransientState && mTransientStateCount == 0)) {
8342             // update flag if we've just incremented up from 0 or decremented down to 0
8343             mPrivateFlags2 = (mPrivateFlags2 & ~PFLAG2_HAS_TRANSIENT_STATE) |
8344                     (hasTransientState ? PFLAG2_HAS_TRANSIENT_STATE : 0);
8345             if (mParent != null) {
8346                 try {
8347                     mParent.childHasTransientStateChanged(this, hasTransientState);
8348                 } catch (AbstractMethodError e) {
8349                     Log.e(VIEW_LOG_TAG, mParent.getClass().getSimpleName() +
8350                             " does not fully implement ViewParent", e);
8351                 }
8352             }
8353         }
8354     }
8355
8356     /**
8357      * Returns true if this view is currently attached to a window.
8358      */
8359     public boolean isAttachedToWindow() {
8360         return mAttachInfo != null;
8361     }
8362
8363     /**
8364      * Returns true if this view has been through at least one layout since it
8365      * was last attached to or detached from a window.
8366      */
8367     public boolean isLaidOut() {
8368         return (mPrivateFlags3 & PFLAG3_IS_LAID_OUT) == PFLAG3_IS_LAID_OUT;
8369     }
8370
8371     /**
8372      * If this view doesn't do any drawing on its own, set this flag to
8373      * allow further optimizations. By default, this flag is not set on
8374      * View, but could be set on some View subclasses such as ViewGroup.
8375      *
8376      * Typically, if you override {@link #onDraw(android.graphics.Canvas)}
8377      * you should clear this flag.
8378      *
8379      * @param willNotDraw whether or not this View draw on its own
8380      */
8381     public void setWillNotDraw(boolean willNotDraw) {
8382         setFlags(willNotDraw ? WILL_NOT_DRAW : 0, DRAW_MASK);
8383     }
8384
8385     /**
8386      * Returns whether or not this View draws on its own.
8387      *
8388      * @return true if this view has nothing to draw, false otherwise
8389      */
8390     @ViewDebug.ExportedProperty(category = "drawing")
8391     public boolean willNotDraw() {
8392         return (mViewFlags & DRAW_MASK) == WILL_NOT_DRAW;
8393     }
8394
8395     /**
8396      * When a View's drawing cache is enabled, drawing is redirected to an
8397      * offscreen bitmap. Some views, like an ImageView, must be able to
8398      * bypass this mechanism if they already draw a single bitmap, to avoid
8399      * unnecessary usage of the memory.
8400      *
8401      * @param willNotCacheDrawing true if this view does not cache its
8402      *        drawing, false otherwise
8403      */
8404     public void setWillNotCacheDrawing(boolean willNotCacheDrawing) {
8405         setFlags(willNotCacheDrawing ? WILL_NOT_CACHE_DRAWING : 0, WILL_NOT_CACHE_DRAWING);
8406     }
8407
8408     /**
8409      * Returns whether or not this View can cache its drawing or not.
8410      *
8411      * @return true if this view does not cache its drawing, false otherwise
8412      */
8413     @ViewDebug.ExportedProperty(category = "drawing")
8414     public boolean willNotCacheDrawing() {
8415         return (mViewFlags & WILL_NOT_CACHE_DRAWING) == WILL_NOT_CACHE_DRAWING;
8416     }
8417
8418     /**
8419      * Indicates whether this view reacts to click events or not.
8420      *
8421      * @return true if the view is clickable, false otherwise
8422      *
8423      * @see #setClickable(boolean)
8424      * @attr ref android.R.styleable#View_clickable
8425      */
8426     @ViewDebug.ExportedProperty
8427     public boolean isClickable() {
8428         return (mViewFlags & CLICKABLE) == CLICKABLE;
8429     }
8430
8431     /**
8432      * Enables or disables click events for this view. When a view
8433      * is clickable it will change its state to "pressed" on every click.
8434      * Subclasses should set the view clickable to visually react to
8435      * user's clicks.
8436      *
8437      * @param clickable true to make the view clickable, false otherwise
8438      *
8439      * @see #isClickable()
8440      * @attr ref android.R.styleable#View_clickable
8441      */
8442     public void setClickable(boolean clickable) {
8443         setFlags(clickable ? CLICKABLE : 0, CLICKABLE);
8444     }
8445
8446     /**
8447      * Indicates whether this view reacts to long click events or not.
8448      *
8449      * @return true if the view is long clickable, false otherwise
8450      *
8451      * @see #setLongClickable(boolean)
8452      * @attr ref android.R.styleable#View_longClickable
8453      */
8454     public boolean isLongClickable() {
8455         return (mViewFlags & LONG_CLICKABLE) == LONG_CLICKABLE;
8456     }
8457
8458     /**
8459      * Enables or disables long click events for this view. When a view is long
8460      * clickable it reacts to the user holding down the button for a longer
8461      * duration than a tap. This event can either launch the listener or a
8462      * context menu.
8463      *
8464      * @param longClickable true to make the view long clickable, false otherwise
8465      * @see #isLongClickable()
8466      * @attr ref android.R.styleable#View_longClickable
8467      */
8468     public void setLongClickable(boolean longClickable) {
8469         setFlags(longClickable ? LONG_CLICKABLE : 0, LONG_CLICKABLE);
8470     }
8471
8472     /**
8473      * Indicates whether this view reacts to context clicks or not.
8474      *
8475      * @return true if the view is context clickable, false otherwise
8476      * @see #setContextClickable(boolean)
8477      * @attr ref android.R.styleable#View_contextClickable
8478      */
8479     public boolean isContextClickable() {
8480         return (mViewFlags & CONTEXT_CLICKABLE) == CONTEXT_CLICKABLE;
8481     }
8482
8483     /**
8484      * Enables or disables context clicking for this view. This event can launch the listener.
8485      *
8486      * @param contextClickable true to make the view react to a context click, false otherwise
8487      * @see #isContextClickable()
8488      * @attr ref android.R.styleable#View_contextClickable
8489      */
8490     public void setContextClickable(boolean contextClickable) {
8491         setFlags(contextClickable ? CONTEXT_CLICKABLE : 0, CONTEXT_CLICKABLE);
8492     }
8493
8494     /**
8495      * Sets the pressed state for this view and provides a touch coordinate for
8496      * animation hinting.
8497      *
8498      * @param pressed Pass true to set the View's internal state to "pressed",
8499      *            or false to reverts the View's internal state from a
8500      *            previously set "pressed" state.
8501      * @param x The x coordinate of the touch that caused the press
8502      * @param y The y coordinate of the touch that caused the press
8503      */
8504     private void setPressed(boolean pressed, float x, float y) {
8505         if (pressed) {
8506             drawableHotspotChanged(x, y);
8507         }
8508
8509         setPressed(pressed);
8510     }
8511
8512     /**
8513      * Sets the pressed state for this view.
8514      *
8515      * @see #isClickable()
8516      * @see #setClickable(boolean)
8517      *
8518      * @param pressed Pass true to set the View's internal state to "pressed", or false to reverts
8519      *        the View's internal state from a previously set "pressed" state.
8520      */
8521     public void setPressed(boolean pressed) {
8522         final boolean needsRefresh = pressed != ((mPrivateFlags & PFLAG_PRESSED) == PFLAG_PRESSED);
8523
8524         if (pressed) {
8525             mPrivateFlags |= PFLAG_PRESSED;
8526         } else {
8527             mPrivateFlags &= ~PFLAG_PRESSED;
8528         }
8529
8530         if (needsRefresh) {
8531             refreshDrawableState();
8532         }
8533         dispatchSetPressed(pressed);
8534     }
8535
8536     /**
8537      * Dispatch setPressed to all of this View's children.
8538      *
8539      * @see #setPressed(boolean)
8540      *
8541      * @param pressed The new pressed state
8542      */
8543     protected void dispatchSetPressed(boolean pressed) {
8544     }
8545
8546     /**
8547      * Indicates whether the view is currently in pressed state. Unless
8548      * {@link #setPressed(boolean)} is explicitly called, only clickable views can enter
8549      * the pressed state.
8550      *
8551      * @see #setPressed(boolean)
8552      * @see #isClickable()
8553      * @see #setClickable(boolean)
8554      *
8555      * @return true if the view is currently pressed, false otherwise
8556      */
8557     @ViewDebug.ExportedProperty
8558     public boolean isPressed() {
8559         return (mPrivateFlags & PFLAG_PRESSED) == PFLAG_PRESSED;
8560     }
8561
8562     /**
8563      * @hide
8564      * Indicates whether this view will participate in data collection through
8565      * {@link ViewStructure}.  If true, it will not provide any data
8566      * for itself or its children.  If false, the normal data collection will be allowed.
8567      *
8568      * @return Returns false if assist data collection is not blocked, else true.
8569      *
8570      * @see #setAssistBlocked(boolean)
8571      * @attr ref android.R.styleable#View_assistBlocked
8572      */
8573     public boolean isAssistBlocked() {
8574         return (mPrivateFlags3 & PFLAG3_ASSIST_BLOCKED) != 0;
8575     }
8576
8577     /**
8578      * @hide
8579      * Controls whether assist data collection from this view and its children is enabled
8580      * (that is, whether {@link #onProvideStructure} and
8581      * {@link #onProvideVirtualStructure} will be called).  The default value is false,
8582      * allowing normal assist collection.  Setting this to false will disable assist collection.
8583      *
8584      * @param enabled Set to true to <em>disable</em> assist data collection, or false
8585      * (the default) to allow it.
8586      *
8587      * @see #isAssistBlocked()
8588      * @see #onProvideStructure
8589      * @see #onProvideVirtualStructure
8590      * @attr ref android.R.styleable#View_assistBlocked
8591      */
8592     public void setAssistBlocked(boolean enabled) {
8593         if (enabled) {
8594             mPrivateFlags3 |= PFLAG3_ASSIST_BLOCKED;
8595         } else {
8596             mPrivateFlags3 &= ~PFLAG3_ASSIST_BLOCKED;
8597         }
8598     }
8599
8600     /**
8601      * Indicates whether this view will save its state (that is,
8602      * whether its {@link #onSaveInstanceState} method will be called).
8603      *
8604      * @return Returns true if the view state saving is enabled, else false.
8605      *
8606      * @see #setSaveEnabled(boolean)
8607      * @attr ref android.R.styleable#View_saveEnabled
8608      */
8609     public boolean isSaveEnabled() {
8610         return (mViewFlags & SAVE_DISABLED_MASK) != SAVE_DISABLED;
8611     }
8612
8613     /**
8614      * Controls whether the saving of this view's state is
8615      * enabled (that is, whether its {@link #onSaveInstanceState} method
8616      * will be called).  Note that even if freezing is enabled, the
8617      * view still must have an id assigned to it (via {@link #setId(int)})
8618      * for its state to be saved.  This flag can only disable the
8619      * saving of this view; any child views may still have their state saved.
8620      *
8621      * @param enabled Set to false to <em>disable</em> state saving, or true
8622      * (the default) to allow it.
8623      *
8624      * @see #isSaveEnabled()
8625      * @see #setId(int)
8626      * @see #onSaveInstanceState()
8627      * @attr ref android.R.styleable#View_saveEnabled
8628      */
8629     public void setSaveEnabled(boolean enabled) {
8630         setFlags(enabled ? 0 : SAVE_DISABLED, SAVE_DISABLED_MASK);
8631     }
8632
8633     /**
8634      * Gets whether the framework should discard touches when the view's
8635      * window is obscured by another visible window.
8636      * Refer to the {@link View} security documentation for more details.
8637      *
8638      * @return True if touch filtering is enabled.
8639      *
8640      * @see #setFilterTouchesWhenObscured(boolean)
8641      * @attr ref android.R.styleable#View_filterTouchesWhenObscured
8642      */
8643     @ViewDebug.ExportedProperty
8644     public boolean getFilterTouchesWhenObscured() {
8645         return (mViewFlags & FILTER_TOUCHES_WHEN_OBSCURED) != 0;
8646     }
8647
8648     /**
8649      * Sets whether the framework should discard touches when the view's
8650      * window is obscured by another visible window.
8651      * Refer to the {@link View} security documentation for more details.
8652      *
8653      * @param enabled True if touch filtering should be enabled.
8654      *
8655      * @see #getFilterTouchesWhenObscured
8656      * @attr ref android.R.styleable#View_filterTouchesWhenObscured
8657      */
8658     public void setFilterTouchesWhenObscured(boolean enabled) {
8659         setFlags(enabled ? FILTER_TOUCHES_WHEN_OBSCURED : 0,
8660                 FILTER_TOUCHES_WHEN_OBSCURED);
8661     }
8662
8663     /**
8664      * Indicates whether the entire hierarchy under this view will save its
8665      * state when a state saving traversal occurs from its parent.  The default
8666      * is true; if false, these views will not be saved unless
8667      * {@link #saveHierarchyState(SparseArray)} is called directly on this view.
8668      *
8669      * @return Returns true if the view state saving from parent is enabled, else false.
8670      *
8671      * @see #setSaveFromParentEnabled(boolean)
8672      */
8673     public boolean isSaveFromParentEnabled() {
8674         return (mViewFlags & PARENT_SAVE_DISABLED_MASK) != PARENT_SAVE_DISABLED;
8675     }
8676
8677     /**
8678      * Controls whether the entire hierarchy under this view will save its
8679      * state when a state saving traversal occurs from its parent.  The default
8680      * is true; if false, these views will not be saved unless
8681      * {@link #saveHierarchyState(SparseArray)} is called directly on this view.
8682      *
8683      * @param enabled Set to false to <em>disable</em> state saving, or true
8684      * (the default) to allow it.
8685      *
8686      * @see #isSaveFromParentEnabled()
8687      * @see #setId(int)
8688      * @see #onSaveInstanceState()
8689      */
8690     public void setSaveFromParentEnabled(boolean enabled) {
8691         setFlags(enabled ? 0 : PARENT_SAVE_DISABLED, PARENT_SAVE_DISABLED_MASK);
8692     }
8693
8694
8695     /**
8696      * Returns whether this View is able to take focus.
8697      *
8698      * @return True if this view can take focus, or false otherwise.
8699      * @attr ref android.R.styleable#View_focusable
8700      */
8701     @ViewDebug.ExportedProperty(category = "focus")
8702     public final boolean isFocusable() {
8703         return FOCUSABLE == (mViewFlags & FOCUSABLE_MASK);
8704     }
8705
8706     /**
8707      * When a view is focusable, it may not want to take focus when in touch mode.
8708      * For example, a button would like focus when the user is navigating via a D-pad
8709      * so that the user can click on it, but once the user starts touching the screen,
8710      * the button shouldn't take focus
8711      * @return Whether the view is focusable in touch mode.
8712      * @attr ref android.R.styleable#View_focusableInTouchMode
8713      */
8714     @ViewDebug.ExportedProperty
8715     public final boolean isFocusableInTouchMode() {
8716         return FOCUSABLE_IN_TOUCH_MODE == (mViewFlags & FOCUSABLE_IN_TOUCH_MODE);
8717     }
8718
8719     /**
8720      * Find the nearest view in the specified direction that can take focus.
8721      * This does not actually give focus to that view.
8722      *
8723      * @param direction One of FOCUS_UP, FOCUS_DOWN, FOCUS_LEFT, and FOCUS_RIGHT
8724      *
8725      * @return The nearest focusable in the specified direction, or null if none
8726      *         can be found.
8727      */
8728     public View focusSearch(@FocusRealDirection int direction) {
8729         if (mParent != null) {
8730             return mParent.focusSearch(this, direction);
8731         } else {
8732             return null;
8733         }
8734     }
8735
8736     /**
8737      * This method is the last chance for the focused view and its ancestors to
8738      * respond to an arrow key. This is called when the focused view did not
8739      * consume the key internally, nor could the view system find a new view in
8740      * the requested direction to give focus to.
8741      *
8742      * @param focused The currently focused view.
8743      * @param direction The direction focus wants to move. One of FOCUS_UP,
8744      *        FOCUS_DOWN, FOCUS_LEFT, and FOCUS_RIGHT.
8745      * @return True if the this view consumed this unhandled move.
8746      */
8747     public boolean dispatchUnhandledMove(View focused, @FocusRealDirection int direction) {
8748         return false;
8749     }
8750
8751     /**
8752      * If a user manually specified the next view id for a particular direction,
8753      * use the root to look up the view.
8754      * @param root The root view of the hierarchy containing this view.
8755      * @param direction One of FOCUS_UP, FOCUS_DOWN, FOCUS_LEFT, FOCUS_RIGHT, FOCUS_FORWARD,
8756      * or FOCUS_BACKWARD.
8757      * @return The user specified next view, or null if there is none.
8758      */
8759     View findUserSetNextFocus(View root, @FocusDirection int direction) {
8760         switch (direction) {
8761             case FOCUS_LEFT:
8762                 if (mNextFocusLeftId == View.NO_ID) return null;
8763                 return findViewInsideOutShouldExist(root, mNextFocusLeftId);
8764             case FOCUS_RIGHT:
8765                 if (mNextFocusRightId == View.NO_ID) return null;
8766                 return findViewInsideOutShouldExist(root, mNextFocusRightId);
8767             case FOCUS_UP:
8768                 if (mNextFocusUpId == View.NO_ID) return null;
8769                 return findViewInsideOutShouldExist(root, mNextFocusUpId);
8770             case FOCUS_DOWN:
8771                 if (mNextFocusDownId == View.NO_ID) return null;
8772                 return findViewInsideOutShouldExist(root, mNextFocusDownId);
8773             case FOCUS_FORWARD:
8774                 if (mNextFocusForwardId == View.NO_ID) return null;
8775                 return findViewInsideOutShouldExist(root, mNextFocusForwardId);
8776             case FOCUS_BACKWARD: {
8777                 if (mID == View.NO_ID) return null;
8778                 final int id = mID;
8779                 return root.findViewByPredicateInsideOut(this, new Predicate<View>() {
8780                     @Override
8781                     public boolean apply(View t) {
8782                         return t.mNextFocusForwardId == id;
8783                     }
8784                 });
8785             }
8786         }
8787         return null;
8788     }
8789
8790     private View findViewInsideOutShouldExist(View root, int id) {
8791         if (mMatchIdPredicate == null) {
8792             mMatchIdPredicate = new MatchIdPredicate();
8793         }
8794         mMatchIdPredicate.mId = id;
8795         View result = root.findViewByPredicateInsideOut(this, mMatchIdPredicate);
8796         if (result == null) {
8797             Log.w(VIEW_LOG_TAG, "couldn't find view with id " + id);
8798         }
8799         return result;
8800     }
8801
8802     /**
8803      * Find and return all focusable views that are descendants of this view,
8804      * possibly including this view if it is focusable itself.
8805      *
8806      * @param direction The direction of the focus
8807      * @return A list of focusable views
8808      */
8809     public ArrayList<View> getFocusables(@FocusDirection int direction) {
8810         ArrayList<View> result = new ArrayList<View>(24);
8811         addFocusables(result, direction);
8812         return result;
8813     }
8814
8815     /**
8816      * Add any focusable views that are descendants of this view (possibly
8817      * including this view if it is focusable itself) to views.  If we are in touch mode,
8818      * only add views that are also focusable in touch mode.
8819      *
8820      * @param views Focusable views found so far
8821      * @param direction The direction of the focus
8822      */
8823     public void addFocusables(ArrayList<View> views, @FocusDirection int direction) {
8824         addFocusables(views, direction, isInTouchMode() ? FOCUSABLES_TOUCH_MODE : FOCUSABLES_ALL);
8825     }
8826
8827     /**
8828      * Adds any focusable views that are descendants of this view (possibly
8829      * including this view if it is focusable itself) to views. This method
8830      * adds all focusable views regardless if we are in touch mode or
8831      * only views focusable in touch mode if we are in touch mode or
8832      * only views that can take accessibility focus if accessibility is enabled
8833      * depending on the focusable mode parameter.
8834      *
8835      * @param views Focusable views found so far or null if all we are interested is
8836      *        the number of focusables.
8837      * @param direction The direction of the focus.
8838      * @param focusableMode The type of focusables to be added.
8839      *
8840      * @see #FOCUSABLES_ALL
8841      * @see #FOCUSABLES_TOUCH_MODE
8842      */
8843     public void addFocusables(ArrayList<View> views, @FocusDirection int direction,
8844             @FocusableMode int focusableMode) {
8845         if (views == null) {
8846             return;
8847         }
8848         if (!isFocusable()) {
8849             return;
8850         }
8851         if ((focusableMode & FOCUSABLES_TOUCH_MODE) == FOCUSABLES_TOUCH_MODE
8852                 && !isFocusableInTouchMode()) {
8853             return;
8854         }
8855         views.add(this);
8856     }
8857
8858     /**
8859      * Finds the Views that contain given text. The containment is case insensitive.
8860      * The search is performed by either the text that the View renders or the content
8861      * description that describes the view for accessibility purposes and the view does
8862      * not render or both. Clients can specify how the search is to be performed via
8863      * passing the {@link #FIND_VIEWS_WITH_TEXT} and
8864      * {@link #FIND_VIEWS_WITH_CONTENT_DESCRIPTION} flags.
8865      *
8866      * @param outViews The output list of matching Views.
8867      * @param searched The text to match against.
8868      *
8869      * @see #FIND_VIEWS_WITH_TEXT
8870      * @see #FIND_VIEWS_WITH_CONTENT_DESCRIPTION
8871      * @see #setContentDescription(CharSequence)
8872      */
8873     public void findViewsWithText(ArrayList<View> outViews, CharSequence searched,
8874             @FindViewFlags int flags) {
8875         if (getAccessibilityNodeProvider() != null) {
8876             if ((flags & FIND_VIEWS_WITH_ACCESSIBILITY_NODE_PROVIDERS) != 0) {
8877                 outViews.add(this);
8878             }
8879         } else if ((flags & FIND_VIEWS_WITH_CONTENT_DESCRIPTION) != 0
8880                 && (searched != null && searched.length() > 0)
8881                 && (mContentDescription != null && mContentDescription.length() > 0)) {
8882             String searchedLowerCase = searched.toString().toLowerCase();
8883             String contentDescriptionLowerCase = mContentDescription.toString().toLowerCase();
8884             if (contentDescriptionLowerCase.contains(searchedLowerCase)) {
8885                 outViews.add(this);
8886             }
8887         }
8888     }
8889
8890     /**
8891      * Find and return all touchable views that are descendants of this view,
8892      * possibly including this view if it is touchable itself.
8893      *
8894      * @return A list of touchable views
8895      */
8896     public ArrayList<View> getTouchables() {
8897         ArrayList<View> result = new ArrayList<View>();
8898         addTouchables(result);
8899         return result;
8900     }
8901
8902     /**
8903      * Add any touchable views that are descendants of this view (possibly
8904      * including this view if it is touchable itself) to views.
8905      *
8906      * @param views Touchable views found so far
8907      */
8908     public void addTouchables(ArrayList<View> views) {
8909         final int viewFlags = mViewFlags;
8910
8911         if (((viewFlags & CLICKABLE) == CLICKABLE || (viewFlags & LONG_CLICKABLE) == LONG_CLICKABLE
8912                 || (viewFlags & CONTEXT_CLICKABLE) == CONTEXT_CLICKABLE)
8913                 && (viewFlags & ENABLED_MASK) == ENABLED) {
8914             views.add(this);
8915         }
8916     }
8917
8918     /**
8919      * Returns whether this View is accessibility focused.
8920      *
8921      * @return True if this View is accessibility focused.
8922      */
8923     public boolean isAccessibilityFocused() {
8924         return (mPrivateFlags2 & PFLAG2_ACCESSIBILITY_FOCUSED) != 0;
8925     }
8926
8927     /**
8928      * Call this to try to give accessibility focus to this view.
8929      *
8930      * A view will not actually take focus if {@link AccessibilityManager#isEnabled()}
8931      * returns false or the view is no visible or the view already has accessibility
8932      * focus.
8933      *
8934      * See also {@link #focusSearch(int)}, which is what you call to say that you
8935      * have focus, and you want your parent to look for the next one.
8936      *
8937      * @return Whether this view actually took accessibility focus.
8938      *
8939      * @hide
8940      */
8941     public boolean requestAccessibilityFocus() {
8942         AccessibilityManager manager = AccessibilityManager.getInstance(mContext);
8943         if (!manager.isEnabled() || !manager.isTouchExplorationEnabled()) {
8944             return false;
8945         }
8946         if ((mViewFlags & VISIBILITY_MASK) != VISIBLE) {
8947             return false;
8948         }
8949         if ((mPrivateFlags2 & PFLAG2_ACCESSIBILITY_FOCUSED) == 0) {
8950             mPrivateFlags2 |= PFLAG2_ACCESSIBILITY_FOCUSED;
8951             ViewRootImpl viewRootImpl = getViewRootImpl();
8952             if (viewRootImpl != null) {
8953                 viewRootImpl.setAccessibilityFocus(this, null);
8954             }
8955             invalidate();
8956             sendAccessibilityEvent(AccessibilityEvent.TYPE_VIEW_ACCESSIBILITY_FOCUSED);
8957             return true;
8958         }
8959         return false;
8960     }
8961
8962     /**
8963      * Call this to try to clear accessibility focus of this view.
8964      *
8965      * See also {@link #focusSearch(int)}, which is what you call to say that you
8966      * have focus, and you want your parent to look for the next one.
8967      *
8968      * @hide
8969      */
8970     public void clearAccessibilityFocus() {
8971         clearAccessibilityFocusNoCallbacks(0);
8972
8973         // Clear the global reference of accessibility focus if this view or
8974         // any of its descendants had accessibility focus. This will NOT send
8975         // an event or update internal state if focus is cleared from a
8976         // descendant view, which may leave views in inconsistent states.
8977         final ViewRootImpl viewRootImpl = getViewRootImpl();
8978         if (viewRootImpl != null) {
8979             final View focusHost = viewRootImpl.getAccessibilityFocusedHost();
8980             if (focusHost != null && ViewRootImpl.isViewDescendantOf(focusHost, this)) {
8981                 viewRootImpl.setAccessibilityFocus(null, null);
8982             }
8983         }
8984     }
8985
8986     private void sendAccessibilityHoverEvent(int eventType) {
8987         // Since we are not delivering to a client accessibility events from not
8988         // important views (unless the clinet request that) we need to fire the
8989         // event from the deepest view exposed to the client. As a consequence if
8990         // the user crosses a not exposed view the client will see enter and exit
8991         // of the exposed predecessor followed by and enter and exit of that same
8992         // predecessor when entering and exiting the not exposed descendant. This
8993         // is fine since the client has a clear idea which view is hovered at the
8994         // price of a couple more events being sent. This is a simple and
8995         // working solution.
8996         View source = this;
8997         while (true) {
8998             if (source.includeForAccessibility()) {
8999                 source.sendAccessibilityEvent(eventType);
9000                 return;
9001             }
9002             ViewParent parent = source.getParent();
9003             if (parent instanceof View) {
9004                 source = (View) parent;
9005             } else {
9006                 return;
9007             }
9008         }
9009     }
9010
9011     /**
9012      * Clears accessibility focus without calling any callback methods
9013      * normally invoked in {@link #clearAccessibilityFocus()}. This method
9014      * is used separately from that one for clearing accessibility focus when
9015      * giving this focus to another view.
9016      *
9017      * @param action The action, if any, that led to focus being cleared. Set to
9018      * AccessibilityNodeInfo#ACTION_ACCESSIBILITY_FOCUS to specify that focus is moving within
9019      * the window.
9020      */
9021     void clearAccessibilityFocusNoCallbacks(int action) {
9022         if ((mPrivateFlags2 & PFLAG2_ACCESSIBILITY_FOCUSED) != 0) {
9023             mPrivateFlags2 &= ~PFLAG2_ACCESSIBILITY_FOCUSED;
9024             invalidate();
9025             if (AccessibilityManager.getInstance(mContext).isEnabled()) {
9026                 AccessibilityEvent event = AccessibilityEvent.obtain(
9027                         AccessibilityEvent.TYPE_VIEW_ACCESSIBILITY_FOCUS_CLEARED);
9028                 event.setAction(action);
9029                 if (mAccessibilityDelegate != null) {
9030                     mAccessibilityDelegate.sendAccessibilityEventUnchecked(this, event);
9031                 } else {
9032                     sendAccessibilityEventUnchecked(event);
9033                 }
9034             }
9035         }
9036     }
9037
9038     /**
9039      * Call this to try to give focus to a specific view or to one of its
9040      * descendants.
9041      *
9042      * A view will not actually take focus if it is not focusable ({@link #isFocusable} returns
9043      * false), or if it is focusable and it is not focusable in touch mode
9044      * ({@link #isFocusableInTouchMode}) while the device is in touch mode.
9045      *
9046      * See also {@link #focusSearch(int)}, which is what you call to say that you
9047      * have focus, and you want your parent to look for the next one.
9048      *
9049      * This is equivalent to calling {@link #requestFocus(int, Rect)} with arguments
9050      * {@link #FOCUS_DOWN} and <code>null</code>.
9051      *
9052      * @return Whether this view or one of its descendants actually took focus.
9053      */
9054     public final boolean requestFocus() {
9055         return requestFocus(View.FOCUS_DOWN);
9056     }
9057
9058     /**
9059      * Call this to try to give focus to a specific view or to one of its
9060      * descendants and give it a hint about what direction focus is heading.
9061      *
9062      * A view will not actually take focus if it is not focusable ({@link #isFocusable} returns
9063      * false), or if it is focusable and it is not focusable in touch mode
9064      * ({@link #isFocusableInTouchMode}) while the device is in touch mode.
9065      *
9066      * See also {@link #focusSearch(int)}, which is what you call to say that you
9067      * have focus, and you want your parent to look for the next one.
9068      *
9069      * This is equivalent to calling {@link #requestFocus(int, Rect)} with
9070      * <code>null</code> set for the previously focused rectangle.
9071      *
9072      * @param direction One of FOCUS_UP, FOCUS_DOWN, FOCUS_LEFT, and FOCUS_RIGHT
9073      * @return Whether this view or one of its descendants actually took focus.
9074      */
9075     public final boolean requestFocus(int direction) {
9076         return requestFocus(direction, null);
9077     }
9078
9079     /**
9080      * Call this to try to give focus to a specific view or to one of its descendants
9081      * and give it hints about the direction and a specific rectangle that the focus
9082      * is coming from.  The rectangle can help give larger views a finer grained hint
9083      * about where focus is coming from, and therefore, where to show selection, or
9084      * forward focus change internally.
9085      *
9086      * A view will not actually take focus if it is not focusable ({@link #isFocusable} returns
9087      * false), or if it is focusable and it is not focusable in touch mode
9088      * ({@link #isFocusableInTouchMode}) while the device is in touch mode.
9089      *
9090      * A View will not take focus if it is not visible.
9091      *
9092      * A View will not take focus if one of its parents has
9093      * {@link android.view.ViewGroup#getDescendantFocusability()} equal to
9094      * {@link ViewGroup#FOCUS_BLOCK_DESCENDANTS}.
9095      *
9096      * See also {@link #focusSearch(int)}, which is what you call to say that you
9097      * have focus, and you want your parent to look for the next one.
9098      *
9099      * You may wish to override this method if your custom {@link View} has an internal
9100      * {@link View} that it wishes to forward the request to.
9101      *
9102      * @param direction One of FOCUS_UP, FOCUS_DOWN, FOCUS_LEFT, and FOCUS_RIGHT
9103      * @param previouslyFocusedRect The rectangle (in this View's coordinate system)
9104      *        to give a finer grained hint about where focus is coming from.  May be null
9105      *        if there is no hint.
9106      * @return Whether this view or one of its descendants actually took focus.
9107      */
9108     public boolean requestFocus(int direction, Rect previouslyFocusedRect) {
9109         return requestFocusNoSearch(direction, previouslyFocusedRect);
9110     }
9111
9112     private boolean requestFocusNoSearch(int direction, Rect previouslyFocusedRect) {
9113         // need to be focusable
9114         if ((mViewFlags & FOCUSABLE_MASK) != FOCUSABLE ||
9115                 (mViewFlags & VISIBILITY_MASK) != VISIBLE) {
9116             return false;
9117         }
9118
9119         // need to be focusable in touch mode if in touch mode
9120         if (isInTouchMode() &&
9121             (FOCUSABLE_IN_TOUCH_MODE != (mViewFlags & FOCUSABLE_IN_TOUCH_MODE))) {
9122                return false;
9123         }
9124
9125         // need to not have any parents blocking us
9126         if (hasAncestorThatBlocksDescendantFocus()) {
9127             return false;
9128         }
9129
9130         handleFocusGainInternal(direction, previouslyFocusedRect);
9131         return true;
9132     }
9133
9134     /**
9135      * Call this to try to give focus to a specific view or to one of its descendants. This is a
9136      * special variant of {@link #requestFocus() } that will allow views that are not focusable in
9137      * touch mode to request focus when they are touched.
9138      *
9139      * @return Whether this view or one of its descendants actually took focus.
9140      *
9141      * @see #isInTouchMode()
9142      *
9143      */
9144     public final boolean requestFocusFromTouch() {
9145         // Leave touch mode if we need to
9146         if (isInTouchMode()) {
9147             ViewRootImpl viewRoot = getViewRootImpl();
9148             if (viewRoot != null) {
9149                 viewRoot.ensureTouchMode(false);
9150             }
9151         }
9152         return requestFocus(View.FOCUS_DOWN);
9153     }
9154
9155     /**
9156      * @return Whether any ancestor of this view blocks descendant focus.
9157      */
9158     private boolean hasAncestorThatBlocksDescendantFocus() {
9159         final boolean focusableInTouchMode = isFocusableInTouchMode();
9160         ViewParent ancestor = mParent;
9161         while (ancestor instanceof ViewGroup) {
9162             final ViewGroup vgAncestor = (ViewGroup) ancestor;
9163             if (vgAncestor.getDescendantFocusability() == ViewGroup.FOCUS_BLOCK_DESCENDANTS
9164                     || (!focusableInTouchMode && vgAncestor.shouldBlockFocusForTouchscreen())) {
9165                 return true;
9166             } else {
9167                 ancestor = vgAncestor.getParent();
9168             }
9169         }
9170         return false;
9171     }
9172
9173     /**
9174      * Gets the mode for determining whether this View is important for accessibility
9175      * which is if it fires accessibility events and if it is reported to
9176      * accessibility services that query the screen.
9177      *
9178      * @return The mode for determining whether a View is important for accessibility.
9179      *
9180      * @attr ref android.R.styleable#View_importantForAccessibility
9181      *
9182      * @see #IMPORTANT_FOR_ACCESSIBILITY_YES
9183      * @see #IMPORTANT_FOR_ACCESSIBILITY_NO
9184      * @see #IMPORTANT_FOR_ACCESSIBILITY_NO_HIDE_DESCENDANTS
9185      * @see #IMPORTANT_FOR_ACCESSIBILITY_AUTO
9186      */
9187     @ViewDebug.ExportedProperty(category = "accessibility", mapping = {
9188             @ViewDebug.IntToString(from = IMPORTANT_FOR_ACCESSIBILITY_AUTO, to = "auto"),
9189             @ViewDebug.IntToString(from = IMPORTANT_FOR_ACCESSIBILITY_YES, to = "yes"),
9190             @ViewDebug.IntToString(from = IMPORTANT_FOR_ACCESSIBILITY_NO, to = "no"),
9191             @ViewDebug.IntToString(from = IMPORTANT_FOR_ACCESSIBILITY_NO_HIDE_DESCENDANTS,
9192                     to = "noHideDescendants")
9193         })
9194     public int getImportantForAccessibility() {
9195         return (mPrivateFlags2 & PFLAG2_IMPORTANT_FOR_ACCESSIBILITY_MASK)
9196                 >> PFLAG2_IMPORTANT_FOR_ACCESSIBILITY_SHIFT;
9197     }
9198
9199     /**
9200      * Sets the live region mode for this view. This indicates to accessibility
9201      * services whether they should automatically notify the user about changes
9202      * to the view's content description or text, or to the content descriptions
9203      * or text of the view's children (where applicable).
9204      * <p>
9205      * For example, in a login screen with a TextView that displays an "incorrect
9206      * password" notification, that view should be marked as a live region with
9207      * mode {@link #ACCESSIBILITY_LIVE_REGION_POLITE}.
9208      * <p>
9209      * To disable change notifications for this view, use
9210      * {@link #ACCESSIBILITY_LIVE_REGION_NONE}. This is the default live region
9211      * mode for most views.
9212      * <p>
9213      * To indicate that the user should be notified of changes, use
9214      * {@link #ACCESSIBILITY_LIVE_REGION_POLITE}.
9215      * <p>
9216      * If the view's changes should interrupt ongoing speech and notify the user
9217      * immediately, use {@link #ACCESSIBILITY_LIVE_REGION_ASSERTIVE}.
9218      *
9219      * @param mode The live region mode for this view, one of:
9220      *        <ul>
9221      *        <li>{@link #ACCESSIBILITY_LIVE_REGION_NONE}
9222      *        <li>{@link #ACCESSIBILITY_LIVE_REGION_POLITE}
9223      *        <li>{@link #ACCESSIBILITY_LIVE_REGION_ASSERTIVE}
9224      *        </ul>
9225      * @attr ref android.R.styleable#View_accessibilityLiveRegion
9226      */
9227     public void setAccessibilityLiveRegion(int mode) {
9228         if (mode != getAccessibilityLiveRegion()) {
9229             mPrivateFlags2 &= ~PFLAG2_ACCESSIBILITY_LIVE_REGION_MASK;
9230             mPrivateFlags2 |= (mode << PFLAG2_ACCESSIBILITY_LIVE_REGION_SHIFT)
9231                     & PFLAG2_ACCESSIBILITY_LIVE_REGION_MASK;
9232             notifyViewAccessibilityStateChangedIfNeeded(
9233                     AccessibilityEvent.CONTENT_CHANGE_TYPE_UNDEFINED);
9234         }
9235     }
9236
9237     /**
9238      * Gets the live region mode for this View.
9239      *
9240      * @return The live region mode for the view.
9241      *
9242      * @attr ref android.R.styleable#View_accessibilityLiveRegion
9243      *
9244      * @see #setAccessibilityLiveRegion(int)
9245      */
9246     public int getAccessibilityLiveRegion() {
9247         return (mPrivateFlags2 & PFLAG2_ACCESSIBILITY_LIVE_REGION_MASK)
9248                 >> PFLAG2_ACCESSIBILITY_LIVE_REGION_SHIFT;
9249     }
9250
9251     /**
9252      * Sets how to determine whether this view is important for accessibility
9253      * which is if it fires accessibility events and if it is reported to
9254      * accessibility services that query the screen.
9255      *
9256      * @param mode How to determine whether this view is important for accessibility.
9257      *
9258      * @attr ref android.R.styleable#View_importantForAccessibility
9259      *
9260      * @see #IMPORTANT_FOR_ACCESSIBILITY_YES
9261      * @see #IMPORTANT_FOR_ACCESSIBILITY_NO
9262      * @see #IMPORTANT_FOR_ACCESSIBILITY_NO_HIDE_DESCENDANTS
9263      * @see #IMPORTANT_FOR_ACCESSIBILITY_AUTO
9264      */
9265     public void setImportantForAccessibility(int mode) {
9266         final int oldMode = getImportantForAccessibility();
9267         if (mode != oldMode) {
9268             final boolean hideDescendants =
9269                     mode == IMPORTANT_FOR_ACCESSIBILITY_NO_HIDE_DESCENDANTS;
9270
9271             // If this node or its descendants are no longer important, try to
9272             // clear accessibility focus.
9273             if (mode == IMPORTANT_FOR_ACCESSIBILITY_NO || hideDescendants) {
9274                 final View focusHost = findAccessibilityFocusHost(hideDescendants);
9275                 if (focusHost != null) {
9276                     focusHost.clearAccessibilityFocus();
9277                 }
9278             }
9279
9280             // If we're moving between AUTO and another state, we might not need
9281             // to send a subtree changed notification. We'll store the computed
9282             // importance, since we'll need to check it later to make sure.
9283             final boolean maySkipNotify = oldMode == IMPORTANT_FOR_ACCESSIBILITY_AUTO
9284                     || mode == IMPORTANT_FOR_ACCESSIBILITY_AUTO;
9285             final boolean oldIncludeForAccessibility = maySkipNotify && includeForAccessibility();
9286             mPrivateFlags2 &= ~PFLAG2_IMPORTANT_FOR_ACCESSIBILITY_MASK;
9287             mPrivateFlags2 |= (mode << PFLAG2_IMPORTANT_FOR_ACCESSIBILITY_SHIFT)
9288                     & PFLAG2_IMPORTANT_FOR_ACCESSIBILITY_MASK;
9289             if (!maySkipNotify || oldIncludeForAccessibility != includeForAccessibility()) {
9290                 notifySubtreeAccessibilityStateChangedIfNeeded();
9291             } else {
9292                 notifyViewAccessibilityStateChangedIfNeeded(
9293                         AccessibilityEvent.CONTENT_CHANGE_TYPE_UNDEFINED);
9294             }
9295         }
9296     }
9297
9298     /**
9299      * Returns the view within this view's hierarchy that is hosting
9300      * accessibility focus.
9301      *
9302      * @param searchDescendants whether to search for focus in descendant views
9303      * @return the view hosting accessibility focus, or {@code null}
9304      */
9305     private View findAccessibilityFocusHost(boolean searchDescendants) {
9306         if (isAccessibilityFocusedViewOrHost()) {
9307             return this;
9308         }
9309
9310         if (searchDescendants) {
9311             final ViewRootImpl viewRoot = getViewRootImpl();
9312             if (viewRoot != null) {
9313                 final View focusHost = viewRoot.getAccessibilityFocusedHost();
9314                 if (focusHost != null && ViewRootImpl.isViewDescendantOf(focusHost, this)) {
9315                     return focusHost;
9316                 }
9317             }
9318         }
9319
9320         return null;
9321     }
9322
9323     /**
9324      * Computes whether this view should be exposed for accessibility. In
9325      * general, views that are interactive or provide information are exposed
9326      * while views that serve only as containers are hidden.
9327      * <p>
9328      * If an ancestor of this view has importance
9329      * {@link #IMPORTANT_FOR_ACCESSIBILITY_NO_HIDE_DESCENDANTS}, this method
9330      * returns <code>false</code>.
9331      * <p>
9332      * Otherwise, the value is computed according to the view's
9333      * {@link #getImportantForAccessibility()} value:
9334      * <ol>
9335      * <li>{@link #IMPORTANT_FOR_ACCESSIBILITY_NO} or
9336      * {@link #IMPORTANT_FOR_ACCESSIBILITY_NO_HIDE_DESCENDANTS}, return <code>false
9337      * </code>
9338      * <li>{@link #IMPORTANT_FOR_ACCESSIBILITY_YES}, return <code>true</code>
9339      * <li>{@link #IMPORTANT_FOR_ACCESSIBILITY_AUTO}, return <code>true</code> if
9340      * view satisfies any of the following:
9341      * <ul>
9342      * <li>Is actionable, e.g. {@link #isClickable()},
9343      * {@link #isLongClickable()}, or {@link #isFocusable()}
9344      * <li>Has an {@link AccessibilityDelegate}
9345      * <li>Has an interaction listener, e.g. {@link OnTouchListener},
9346      * {@link OnKeyListener}, etc.
9347      * <li>Is an accessibility live region, e.g.
9348      * {@link #getAccessibilityLiveRegion()} is not
9349      * {@link #ACCESSIBILITY_LIVE_REGION_NONE}.
9350      * </ul>
9351      * </ol>
9352      *
9353      * @return Whether the view is exposed for accessibility.
9354      * @see #setImportantForAccessibility(int)
9355      * @see #getImportantForAccessibility()
9356      */
9357     public boolean isImportantForAccessibility() {
9358         final int mode = (mPrivateFlags2 & PFLAG2_IMPORTANT_FOR_ACCESSIBILITY_MASK)
9359                 >> PFLAG2_IMPORTANT_FOR_ACCESSIBILITY_SHIFT;
9360         if (mode == IMPORTANT_FOR_ACCESSIBILITY_NO
9361                 || mode == IMPORTANT_FOR_ACCESSIBILITY_NO_HIDE_DESCENDANTS) {
9362             return false;
9363         }
9364
9365         // Check parent mode to ensure we're not hidden.
9366         ViewParent parent = mParent;
9367         while (parent instanceof View) {
9368             if (((View) parent).getImportantForAccessibility()
9369                     == IMPORTANT_FOR_ACCESSIBILITY_NO_HIDE_DESCENDANTS) {
9370                 return false;
9371             }
9372             parent = parent.getParent();
9373         }
9374
9375         return mode == IMPORTANT_FOR_ACCESSIBILITY_YES || isActionableForAccessibility()
9376                 || hasListenersForAccessibility() || getAccessibilityNodeProvider() != null
9377                 || getAccessibilityLiveRegion() != ACCESSIBILITY_LIVE_REGION_NONE;
9378     }
9379
9380     /**
9381      * Gets the parent for accessibility purposes. Note that the parent for
9382      * accessibility is not necessary the immediate parent. It is the first
9383      * predecessor that is important for accessibility.
9384      *
9385      * @return The parent for accessibility purposes.
9386      */
9387     public ViewParent getParentForAccessibility() {
9388         if (mParent instanceof View) {
9389             View parentView = (View) mParent;
9390             if (parentView.includeForAccessibility()) {
9391                 return mParent;
9392             } else {
9393                 return mParent.getParentForAccessibility();
9394             }
9395         }
9396         return null;
9397     }
9398
9399     /**
9400      * Adds the children of this View relevant for accessibility to the given list
9401      * as output. Since some Views are not important for accessibility the added
9402      * child views are not necessarily direct children of this view, rather they are
9403      * the first level of descendants important for accessibility.
9404      *
9405      * @param outChildren The output list that will receive children for accessibility.
9406      */
9407     public void addChildrenForAccessibility(ArrayList<View> outChildren) {
9408
9409     }
9410
9411     /**
9412      * Whether to regard this view for accessibility. A view is regarded for
9413      * accessibility if it is important for accessibility or the querying
9414      * accessibility service has explicitly requested that view not
9415      * important for accessibility are regarded.
9416      *
9417      * @return Whether to regard the view for accessibility.
9418      *
9419      * @hide
9420      */
9421     public boolean includeForAccessibility() {
9422         if (mAttachInfo != null) {
9423             return (mAttachInfo.mAccessibilityFetchFlags
9424                     & AccessibilityNodeInfo.FLAG_INCLUDE_NOT_IMPORTANT_VIEWS) != 0
9425                     || isImportantForAccessibility();
9426         }
9427         return false;
9428     }
9429
9430     /**
9431      * Returns whether the View is considered actionable from
9432      * accessibility perspective. Such view are important for
9433      * accessibility.
9434      *
9435      * @return True if the view is actionable for accessibility.
9436      *
9437      * @hide
9438      */
9439     public boolean isActionableForAccessibility() {
9440         return (isClickable() || isLongClickable() || isFocusable());
9441     }
9442
9443     /**
9444      * Returns whether the View has registered callbacks which makes it
9445      * important for accessibility.
9446      *
9447      * @return True if the view is actionable for accessibility.
9448      */
9449     private boolean hasListenersForAccessibility() {
9450         ListenerInfo info = getListenerInfo();
9451         return mTouchDelegate != null || info.mOnKeyListener != null
9452                 || info.mOnTouchListener != null || info.mOnGenericMotionListener != null
9453                 || info.mOnHoverListener != null || info.mOnDragListener != null;
9454     }
9455
9456     /**
9457      * Notifies that the accessibility state of this view changed. The change
9458      * is local to this view and does not represent structural changes such
9459      * as children and parent. For example, the view became focusable. The
9460      * notification is at at most once every
9461      * {@link ViewConfiguration#getSendRecurringAccessibilityEventsInterval()}
9462      * to avoid unnecessary load to the system. Also once a view has a pending
9463      * notification this method is a NOP until the notification has been sent.
9464      *
9465      * @hide
9466      */
9467     public void notifyViewAccessibilityStateChangedIfNeeded(int changeType) {
9468         if (!AccessibilityManager.getInstance(mContext).isEnabled() || mAttachInfo == null) {
9469             return;
9470         }
9471         if (mSendViewStateChangedAccessibilityEvent == null) {
9472             mSendViewStateChangedAccessibilityEvent =
9473                     new SendViewStateChangedAccessibilityEvent();
9474         }
9475         mSendViewStateChangedAccessibilityEvent.runOrPost(changeType);
9476     }
9477
9478     /**
9479      * Notifies that the accessibility state of this view changed. The change
9480      * is *not* local to this view and does represent structural changes such
9481      * as children and parent. For example, the view size changed. The
9482      * notification is at at most once every
9483      * {@link ViewConfiguration#getSendRecurringAccessibilityEventsInterval()}
9484      * to avoid unnecessary load to the system. Also once a view has a pending
9485      * notification this method is a NOP until the notification has been sent.
9486      *
9487      * @hide
9488      */
9489     public void notifySubtreeAccessibilityStateChangedIfNeeded() {
9490         if (!AccessibilityManager.getInstance(mContext).isEnabled() || mAttachInfo == null) {
9491             return;
9492         }
9493         if ((mPrivateFlags2 & PFLAG2_SUBTREE_ACCESSIBILITY_STATE_CHANGED) == 0) {
9494             mPrivateFlags2 |= PFLAG2_SUBTREE_ACCESSIBILITY_STATE_CHANGED;
9495             if (mParent != null) {
9496                 try {
9497                     mParent.notifySubtreeAccessibilityStateChanged(
9498                             this, this, AccessibilityEvent.CONTENT_CHANGE_TYPE_SUBTREE);
9499                 } catch (AbstractMethodError e) {
9500                     Log.e(VIEW_LOG_TAG, mParent.getClass().getSimpleName() +
9501                             " does not fully implement ViewParent", e);
9502                 }
9503             }
9504         }
9505     }
9506
9507     /**
9508      * Change the visibility of the View without triggering any other changes. This is
9509      * important for transitions, where visibility changes should not adjust focus or
9510      * trigger a new layout. This is only used when the visibility has already been changed
9511      * and we need a transient value during an animation. When the animation completes,
9512      * the original visibility value is always restored.
9513      *
9514      * @param visibility One of {@link #VISIBLE}, {@link #INVISIBLE}, or {@link #GONE}.
9515      * @hide
9516      */
9517     public void setTransitionVisibility(@Visibility int visibility) {
9518         mViewFlags = (mViewFlags & ~View.VISIBILITY_MASK) | visibility;
9519     }
9520
9521     /**
9522      * Reset the flag indicating the accessibility state of the subtree rooted
9523      * at this view changed.
9524      */
9525     void resetSubtreeAccessibilityStateChanged() {
9526         mPrivateFlags2 &= ~PFLAG2_SUBTREE_ACCESSIBILITY_STATE_CHANGED;
9527     }
9528
9529     /**
9530      * Report an accessibility action to this view's parents for delegated processing.
9531      *
9532      * <p>Implementations of {@link #performAccessibilityAction(int, Bundle)} may internally
9533      * call this method to delegate an accessibility action to a supporting parent. If the parent
9534      * returns true from its
9535      * {@link ViewParent#onNestedPrePerformAccessibilityAction(View, int, android.os.Bundle)}
9536      * method this method will return true to signify that the action was consumed.</p>
9537      *
9538      * <p>This method is useful for implementing nested scrolling child views. If
9539      * {@link #isNestedScrollingEnabled()} returns true and the action is a scrolling action
9540      * a custom view implementation may invoke this method to allow a parent to consume the
9541      * scroll first. If this method returns true the custom view should skip its own scrolling
9542      * behavior.</p>
9543      *
9544      * @param action Accessibility action to delegate
9545      * @param arguments Optional action arguments
9546      * @return true if the action was consumed by a parent
9547      */
9548     public boolean dispatchNestedPrePerformAccessibilityAction(int action, Bundle arguments) {
9549         for (ViewParent p = getParent(); p != null; p = p.getParent()) {
9550             if (p.onNestedPrePerformAccessibilityAction(this, action, arguments)) {
9551                 return true;
9552             }
9553         }
9554         return false;
9555     }
9556
9557     /**
9558      * Performs the specified accessibility action on the view. For
9559      * possible accessibility actions look at {@link AccessibilityNodeInfo}.
9560      * <p>
9561      * If an {@link AccessibilityDelegate} has been specified via calling
9562      * {@link #setAccessibilityDelegate(AccessibilityDelegate)} its
9563      * {@link AccessibilityDelegate#performAccessibilityAction(View, int, Bundle)}
9564      * is responsible for handling this call.
9565      * </p>
9566      *
9567      * <p>The default implementation will delegate
9568      * {@link AccessibilityNodeInfo#ACTION_SCROLL_BACKWARD} and
9569      * {@link AccessibilityNodeInfo#ACTION_SCROLL_FORWARD} to nested scrolling parents if
9570      * {@link #isNestedScrollingEnabled() nested scrolling is enabled} on this view.</p>
9571      *
9572      * @param action The action to perform.
9573      * @param arguments Optional action arguments.
9574      * @return Whether the action was performed.
9575      */
9576     public boolean performAccessibilityAction(int action, Bundle arguments) {
9577       if (mAccessibilityDelegate != null) {
9578           return mAccessibilityDelegate.performAccessibilityAction(this, action, arguments);
9579       } else {
9580           return performAccessibilityActionInternal(action, arguments);
9581       }
9582     }
9583
9584    /**
9585     * @see #performAccessibilityAction(int, Bundle)
9586     *
9587     * Note: Called from the default {@link AccessibilityDelegate}.
9588     *
9589     * @hide
9590     */
9591     public boolean performAccessibilityActionInternal(int action, Bundle arguments) {
9592         if (isNestedScrollingEnabled()
9593                 && (action == AccessibilityNodeInfo.ACTION_SCROLL_BACKWARD
9594                 || action == AccessibilityNodeInfo.ACTION_SCROLL_FORWARD
9595                 || action == R.id.accessibilityActionScrollUp
9596                 || action == R.id.accessibilityActionScrollLeft
9597                 || action == R.id.accessibilityActionScrollDown
9598                 || action == R.id.accessibilityActionScrollRight)) {
9599             if (dispatchNestedPrePerformAccessibilityAction(action, arguments)) {
9600                 return true;
9601             }
9602         }
9603
9604         switch (action) {
9605             case AccessibilityNodeInfo.ACTION_CLICK: {
9606                 if (isClickable()) {
9607                     performClick();
9608                     return true;
9609                 }
9610             } break;
9611             case AccessibilityNodeInfo.ACTION_LONG_CLICK: {
9612                 if (isLongClickable()) {
9613                     performLongClick();
9614                     return true;
9615                 }
9616             } break;
9617             case AccessibilityNodeInfo.ACTION_FOCUS: {
9618                 if (!hasFocus()) {
9619                     // Get out of touch mode since accessibility
9620                     // wants to move focus around.
9621                     getViewRootImpl().ensureTouchMode(false);
9622                     return requestFocus();
9623                 }
9624             } break;
9625             case AccessibilityNodeInfo.ACTION_CLEAR_FOCUS: {
9626                 if (hasFocus()) {
9627                     clearFocus();
9628                     return !isFocused();
9629                 }
9630             } break;
9631             case AccessibilityNodeInfo.ACTION_SELECT: {
9632                 if (!isSelected()) {
9633                     setSelected(true);
9634                     return isSelected();
9635                 }
9636             } break;
9637             case AccessibilityNodeInfo.ACTION_CLEAR_SELECTION: {
9638                 if (isSelected()) {
9639                     setSelected(false);
9640                     return !isSelected();
9641                 }
9642             } break;
9643             case AccessibilityNodeInfo.ACTION_ACCESSIBILITY_FOCUS: {
9644                 if (!isAccessibilityFocused()) {
9645                     return requestAccessibilityFocus();
9646                 }
9647             } break;
9648             case AccessibilityNodeInfo.ACTION_CLEAR_ACCESSIBILITY_FOCUS: {
9649                 if (isAccessibilityFocused()) {
9650                     clearAccessibilityFocus();
9651                     return true;
9652                 }
9653             } break;
9654             case AccessibilityNodeInfo.ACTION_NEXT_AT_MOVEMENT_GRANULARITY: {
9655                 if (arguments != null) {
9656                     final int granularity = arguments.getInt(
9657                             AccessibilityNodeInfo.ACTION_ARGUMENT_MOVEMENT_GRANULARITY_INT);
9658                     final boolean extendSelection = arguments.getBoolean(
9659                             AccessibilityNodeInfo.ACTION_ARGUMENT_EXTEND_SELECTION_BOOLEAN);
9660                     return traverseAtGranularity(granularity, true, extendSelection);
9661                 }
9662             } break;
9663             case AccessibilityNodeInfo.ACTION_PREVIOUS_AT_MOVEMENT_GRANULARITY: {
9664                 if (arguments != null) {
9665                     final int granularity = arguments.getInt(
9666                             AccessibilityNodeInfo.ACTION_ARGUMENT_MOVEMENT_GRANULARITY_INT);
9667                     final boolean extendSelection = arguments.getBoolean(
9668                             AccessibilityNodeInfo.ACTION_ARGUMENT_EXTEND_SELECTION_BOOLEAN);
9669                     return traverseAtGranularity(granularity, false, extendSelection);
9670                 }
9671             } break;
9672             case AccessibilityNodeInfo.ACTION_SET_SELECTION: {
9673                 CharSequence text = getIterableTextForAccessibility();
9674                 if (text == null) {
9675                     return false;
9676                 }
9677                 final int start = (arguments != null) ? arguments.getInt(
9678                         AccessibilityNodeInfo.ACTION_ARGUMENT_SELECTION_START_INT, -1) : -1;
9679                 final int end = (arguments != null) ? arguments.getInt(
9680                 AccessibilityNodeInfo.ACTION_ARGUMENT_SELECTION_END_INT, -1) : -1;
9681                 // Only cursor position can be specified (selection length == 0)
9682                 if ((getAccessibilitySelectionStart() != start
9683                         || getAccessibilitySelectionEnd() != end)
9684                         && (start == end)) {
9685                     setAccessibilitySelection(start, end);
9686                     notifyViewAccessibilityStateChangedIfNeeded(
9687                             AccessibilityEvent.CONTENT_CHANGE_TYPE_UNDEFINED);
9688                     return true;
9689                 }
9690             } break;
9691             case R.id.accessibilityActionShowOnScreen: {
9692                 if (mAttachInfo != null) {
9693                     final Rect r = mAttachInfo.mTmpInvalRect;
9694                     getDrawingRect(r);
9695                     return requestRectangleOnScreen(r, true);
9696                 }
9697             } break;
9698             case R.id.accessibilityActionContextClick: {
9699                 if (isContextClickable()) {
9700                     performContextClick();
9701                     return true;
9702                 }
9703             } break;
9704         }
9705         return false;
9706     }
9707
9708     private boolean traverseAtGranularity(int granularity, boolean forward,
9709             boolean extendSelection) {
9710         CharSequence text = getIterableTextForAccessibility();
9711         if (text == null || text.length() == 0) {
9712             return false;
9713         }
9714         TextSegmentIterator iterator = getIteratorForGranularity(granularity);
9715         if (iterator == null) {
9716             return false;
9717         }
9718         int current = getAccessibilitySelectionEnd();
9719         if (current == ACCESSIBILITY_CURSOR_POSITION_UNDEFINED) {
9720             current = forward ? 0 : text.length();
9721         }
9722         final int[] range = forward ? iterator.following(current) : iterator.preceding(current);
9723         if (range == null) {
9724             return false;
9725         }
9726         final int segmentStart = range[0];
9727         final int segmentEnd = range[1];
9728         int selectionStart;
9729         int selectionEnd;
9730         if (extendSelection && isAccessibilitySelectionExtendable()) {
9731             selectionStart = getAccessibilitySelectionStart();
9732             if (selectionStart == ACCESSIBILITY_CURSOR_POSITION_UNDEFINED) {
9733                 selectionStart = forward ? segmentStart : segmentEnd;
9734             }
9735             selectionEnd = forward ? segmentEnd : segmentStart;
9736         } else {
9737             selectionStart = selectionEnd= forward ? segmentEnd : segmentStart;
9738         }
9739         setAccessibilitySelection(selectionStart, selectionEnd);
9740         final int action = forward ? AccessibilityNodeInfo.ACTION_NEXT_AT_MOVEMENT_GRANULARITY
9741                 : AccessibilityNodeInfo.ACTION_PREVIOUS_AT_MOVEMENT_GRANULARITY;
9742         sendViewTextTraversedAtGranularityEvent(action, granularity, segmentStart, segmentEnd);
9743         return true;
9744     }
9745
9746     /**
9747      * Gets the text reported for accessibility purposes.
9748      *
9749      * @return The accessibility text.
9750      *
9751      * @hide
9752      */
9753     public CharSequence getIterableTextForAccessibility() {
9754         return getContentDescription();
9755     }
9756
9757     /**
9758      * Gets whether accessibility selection can be extended.
9759      *
9760      * @return If selection is extensible.
9761      *
9762      * @hide
9763      */
9764     public boolean isAccessibilitySelectionExtendable() {
9765         return false;
9766     }
9767
9768     /**
9769      * @hide
9770      */
9771     public int getAccessibilitySelectionStart() {
9772         return mAccessibilityCursorPosition;
9773     }
9774
9775     /**
9776      * @hide
9777      */
9778     public int getAccessibilitySelectionEnd() {
9779         return getAccessibilitySelectionStart();
9780     }
9781
9782     /**
9783      * @hide
9784      */
9785     public void setAccessibilitySelection(int start, int end) {
9786         if (start ==  end && end == mAccessibilityCursorPosition) {
9787             return;
9788         }
9789         if (start >= 0 && start == end && end <= getIterableTextForAccessibility().length()) {
9790             mAccessibilityCursorPosition = start;
9791         } else {
9792             mAccessibilityCursorPosition = ACCESSIBILITY_CURSOR_POSITION_UNDEFINED;
9793         }
9794         sendAccessibilityEvent(AccessibilityEvent.TYPE_VIEW_TEXT_SELECTION_CHANGED);
9795     }
9796
9797     private void sendViewTextTraversedAtGranularityEvent(int action, int granularity,
9798             int fromIndex, int toIndex) {
9799         if (mParent == null) {
9800             return;
9801         }
9802         AccessibilityEvent event = AccessibilityEvent.obtain(
9803                 AccessibilityEvent.TYPE_VIEW_TEXT_TRAVERSED_AT_MOVEMENT_GRANULARITY);
9804         onInitializeAccessibilityEvent(event);
9805         onPopulateAccessibilityEvent(event);
9806         event.setFromIndex(fromIndex);
9807         event.setToIndex(toIndex);
9808         event.setAction(action);
9809         event.setMovementGranularity(granularity);
9810         mParent.requestSendAccessibilityEvent(this, event);
9811     }
9812
9813     /**
9814      * @hide
9815      */
9816     public TextSegmentIterator getIteratorForGranularity(int granularity) {
9817         switch (granularity) {
9818             case AccessibilityNodeInfo.MOVEMENT_GRANULARITY_CHARACTER: {
9819                 CharSequence text = getIterableTextForAccessibility();
9820                 if (text != null && text.length() > 0) {
9821                     CharacterTextSegmentIterator iterator =
9822                         CharacterTextSegmentIterator.getInstance(
9823                                 mContext.getResources().getConfiguration().locale);
9824                     iterator.initialize(text.toString());
9825                     return iterator;
9826                 }
9827             } break;
9828             case AccessibilityNodeInfo.MOVEMENT_GRANULARITY_WORD: {
9829                 CharSequence text = getIterableTextForAccessibility();
9830                 if (text != null && text.length() > 0) {
9831                     WordTextSegmentIterator iterator =
9832                         WordTextSegmentIterator.getInstance(
9833                                 mContext.getResources().getConfiguration().locale);
9834                     iterator.initialize(text.toString());
9835                     return iterator;
9836                 }
9837             } break;
9838             case AccessibilityNodeInfo.MOVEMENT_GRANULARITY_PARAGRAPH: {
9839                 CharSequence text = getIterableTextForAccessibility();
9840                 if (text != null && text.length() > 0) {
9841                     ParagraphTextSegmentIterator iterator =
9842                         ParagraphTextSegmentIterator.getInstance();
9843                     iterator.initialize(text.toString());
9844                     return iterator;
9845                 }
9846             } break;
9847         }
9848         return null;
9849     }
9850
9851     /**
9852      * Tells whether the {@link View} is in the state between {@link #onStartTemporaryDetach()}
9853      * and {@link #onFinishTemporaryDetach()}.
9854      *
9855      * <p>This method always returns {@code true} when called directly or indirectly from
9856      * {@link #onStartTemporaryDetach()}. The return value when called directly or indirectly from
9857      * {@link #onFinishTemporaryDetach()}, however, depends on the OS version.
9858      * <ul>
9859      *     <li>{@code true} on {@link android.os.Build.VERSION_CODES#N API 24}</li>
9860      *     <li>{@code false} on {@link android.os.Build.VERSION_CODES#N_MR1 API 25}} and later</li>
9861      * </ul>
9862      * </p>
9863      *
9864      * @return {@code true} when the View is in the state between {@link #onStartTemporaryDetach()}
9865      * and {@link #onFinishTemporaryDetach()}.
9866      */
9867     public final boolean isTemporarilyDetached() {
9868         return (mPrivateFlags3 & PFLAG3_TEMPORARY_DETACH) != 0;
9869     }
9870
9871     /**
9872      * Dispatch {@link #onStartTemporaryDetach()} to this View and its direct children if this is
9873      * a container View.
9874      */
9875     @CallSuper
9876     public void dispatchStartTemporaryDetach() {
9877         mPrivateFlags3 |= PFLAG3_TEMPORARY_DETACH;
9878         onStartTemporaryDetach();
9879     }
9880
9881     /**
9882      * This is called when a container is going to temporarily detach a child, with
9883      * {@link ViewGroup#detachViewFromParent(View) ViewGroup.detachViewFromParent}.
9884      * It will either be followed by {@link #onFinishTemporaryDetach()} or
9885      * {@link #onDetachedFromWindow()} when the container is done.
9886      */
9887     public void onStartTemporaryDetach() {
9888         removeUnsetPressCallback();
9889         mPrivateFlags |= PFLAG_CANCEL_NEXT_UP_EVENT;
9890     }
9891
9892     /**
9893      * Dispatch {@link #onFinishTemporaryDetach()} to this View and its direct children if this is
9894      * a container View.
9895      */
9896     @CallSuper
9897     public void dispatchFinishTemporaryDetach() {
9898         mPrivateFlags3 &= ~PFLAG3_TEMPORARY_DETACH;
9899         onFinishTemporaryDetach();
9900         if (hasWindowFocus() && hasFocus()) {
9901             InputMethodManager.getInstance().focusIn(this);
9902         }
9903     }
9904
9905     /**
9906      * Called after {@link #onStartTemporaryDetach} when the container is done
9907      * changing the view.
9908      */
9909     public void onFinishTemporaryDetach() {
9910     }
9911
9912     /**
9913      * Return the global {@link KeyEvent.DispatcherState KeyEvent.DispatcherState}
9914      * for this view's window.  Returns null if the view is not currently attached
9915      * to the window.  Normally you will not need to use this directly, but
9916      * just use the standard high-level event callbacks like
9917      * {@link #onKeyDown(int, KeyEvent)}.
9918      */
9919     public KeyEvent.DispatcherState getKeyDispatcherState() {
9920         return mAttachInfo != null ? mAttachInfo.mKeyDispatchState : null;
9921     }
9922
9923     /**
9924      * Dispatch a key event before it is processed by any input method
9925      * associated with the view hierarchy.  This can be used to intercept
9926      * key events in special situations before the IME consumes them; a
9927      * typical example would be handling the BACK key to update the application's
9928      * UI instead of allowing the IME to see it and close itself.
9929      *
9930      * @param event The key event to be dispatched.
9931      * @return True if the event was handled, false otherwise.
9932      */
9933     public boolean dispatchKeyEventPreIme(KeyEvent event) {
9934         return onKeyPreIme(event.getKeyCode(), event);
9935     }
9936
9937     /**
9938      * Dispatch a key event to the next view on the focus path. This path runs
9939      * from the top of the view tree down to the currently focused view. If this
9940      * view has focus, it will dispatch to itself. Otherwise it will dispatch
9941      * the next node down the focus path. This method also fires any key
9942      * listeners.
9943      *
9944      * @param event The key event to be dispatched.
9945      * @return True if the event was handled, false otherwise.
9946      */
9947     public boolean dispatchKeyEvent(KeyEvent event) {
9948         if (mInputEventConsistencyVerifier != null) {
9949             mInputEventConsistencyVerifier.onKeyEvent(event, 0);
9950         }
9951
9952         // Give any attached key listener a first crack at the event.
9953         //noinspection SimplifiableIfStatement
9954         ListenerInfo li = mListenerInfo;
9955         if (li != null && li.mOnKeyListener != null && (mViewFlags & ENABLED_MASK) == ENABLED
9956                 && li.mOnKeyListener.onKey(this, event.getKeyCode(), event)) {
9957             return true;
9958         }
9959
9960         if (event.dispatch(this, mAttachInfo != null
9961                 ? mAttachInfo.mKeyDispatchState : null, this)) {
9962             return true;
9963         }
9964
9965         if (mInputEventConsistencyVerifier != null) {
9966             mInputEventConsistencyVerifier.onUnhandledEvent(event, 0);
9967         }
9968         return false;
9969     }
9970
9971     /**
9972      * Dispatches a key shortcut event.
9973      *
9974      * @param event The key event to be dispatched.
9975      * @return True if the event was handled by the view, false otherwise.
9976      */
9977     public boolean dispatchKeyShortcutEvent(KeyEvent event) {
9978         return onKeyShortcut(event.getKeyCode(), event);
9979     }
9980
9981     /**
9982      * Pass the touch screen motion event down to the target view, or this
9983      * view if it is the target.
9984      *
9985      * @param event The motion event to be dispatched.
9986      * @return True if the event was handled by the view, false otherwise.
9987      */
9988     public boolean dispatchTouchEvent(MotionEvent event) {
9989         // If the event should be handled by accessibility focus first.
9990         if (event.isTargetAccessibilityFocus()) {
9991             // We don't have focus or no virtual descendant has it, do not handle the event.
9992             if (!isAccessibilityFocusedViewOrHost()) {
9993                 return false;
9994             }
9995             // We have focus and got the event, then use normal event dispatch.
9996             event.setTargetAccessibilityFocus(false);
9997         }
9998
9999         boolean result = false;
10000
10001         if (mInputEventConsistencyVerifier != null) {
10002             mInputEventConsistencyVerifier.onTouchEvent(event, 0);
10003         }
10004
10005         final int actionMasked = event.getActionMasked();
10006         if (actionMasked == MotionEvent.ACTION_DOWN) {
10007             // Defensive cleanup for new gesture
10008             stopNestedScroll();
10009         }
10010
10011         if (onFilterTouchEventForSecurity(event)) {
10012             if ((mViewFlags & ENABLED_MASK) == ENABLED && handleScrollBarDragging(event)) {
10013                 result = true;
10014             }
10015             //noinspection SimplifiableIfStatement
10016             ListenerInfo li = mListenerInfo;
10017             if (li != null && li.mOnTouchListener != null
10018                     && (mViewFlags & ENABLED_MASK) == ENABLED
10019                     && li.mOnTouchListener.onTouch(this, event)) {
10020                 result = true;
10021             }
10022
10023             if (!result && onTouchEvent(event)) {
10024                 result = true;
10025             }
10026         }
10027
10028         if (!result && mInputEventConsistencyVerifier != null) {
10029             mInputEventConsistencyVerifier.onUnhandledEvent(event, 0);
10030         }
10031
10032         // Clean up after nested scrolls if this is the end of a gesture;
10033         // also cancel it if we tried an ACTION_DOWN but we didn't want the rest
10034         // of the gesture.
10035         if (actionMasked == MotionEvent.ACTION_UP ||
10036                 actionMasked == MotionEvent.ACTION_CANCEL ||
10037                 (actionMasked == MotionEvent.ACTION_DOWN && !result)) {
10038             stopNestedScroll();
10039         }
10040
10041         return result;
10042     }
10043
10044     boolean isAccessibilityFocusedViewOrHost() {
10045         return isAccessibilityFocused() || (getViewRootImpl() != null && getViewRootImpl()
10046                 .getAccessibilityFocusedHost() == this);
10047     }
10048
10049     /**
10050      * Filter the touch event to apply security policies.
10051      *
10052      * @param event The motion event to be filtered.
10053      * @return True if the event should be dispatched, false if the event should be dropped.
10054      *
10055      * @see #getFilterTouchesWhenObscured
10056      */
10057     public boolean onFilterTouchEventForSecurity(MotionEvent event) {
10058         //noinspection RedundantIfStatement
10059         if ((mViewFlags & FILTER_TOUCHES_WHEN_OBSCURED) != 0
10060                 && (event.getFlags() & MotionEvent.FLAG_WINDOW_IS_OBSCURED) != 0) {
10061             // Window is obscured, drop this touch.
10062             return false;
10063         }
10064         return true;
10065     }
10066
10067     /**
10068      * Pass a trackball motion event down to the focused view.
10069      *
10070      * @param event The motion event to be dispatched.
10071      * @return True if the event was handled by the view, false otherwise.
10072      */
10073     public boolean dispatchTrackballEvent(MotionEvent event) {
10074         if (mInputEventConsistencyVerifier != null) {
10075             mInputEventConsistencyVerifier.onTrackballEvent(event, 0);
10076         }
10077
10078         return onTrackballEvent(event);
10079     }
10080
10081     /**
10082      * Dispatch a generic motion event.
10083      * <p>
10084      * Generic motion events with source class {@link InputDevice#SOURCE_CLASS_POINTER}
10085      * are delivered to the view under the pointer.  All other generic motion events are
10086      * delivered to the focused view.  Hover events are handled specially and are delivered
10087      * to {@link #onHoverEvent(MotionEvent)}.
10088      * </p>
10089      *
10090      * @param event The motion event to be dispatched.
10091      * @return True if the event was handled by the view, false otherwise.
10092      */
10093     public boolean dispatchGenericMotionEvent(MotionEvent event) {
10094         if (mInputEventConsistencyVerifier != null) {
10095             mInputEventConsistencyVerifier.onGenericMotionEvent(event, 0);
10096         }
10097
10098         final int source = event.getSource();
10099         if ((source & InputDevice.SOURCE_CLASS_POINTER) != 0) {
10100             final int action = event.getAction();
10101             if (action == MotionEvent.ACTION_HOVER_ENTER
10102                     || action == MotionEvent.ACTION_HOVER_MOVE
10103                     || action == MotionEvent.ACTION_HOVER_EXIT) {
10104                 if (dispatchHoverEvent(event)) {
10105                     return true;
10106                 }
10107             } else if (dispatchGenericPointerEvent(event)) {
10108                 return true;
10109             }
10110         } else if (dispatchGenericFocusedEvent(event)) {
10111             return true;
10112         }
10113
10114         if (dispatchGenericMotionEventInternal(event)) {
10115             return true;
10116         }
10117
10118         if (mInputEventConsistencyVerifier != null) {
10119             mInputEventConsistencyVerifier.onUnhandledEvent(event, 0);
10120         }
10121         return false;
10122     }
10123
10124     private boolean dispatchGenericMotionEventInternal(MotionEvent event) {
10125         //noinspection SimplifiableIfStatement
10126         ListenerInfo li = mListenerInfo;
10127         if (li != null && li.mOnGenericMotionListener != null
10128                 && (mViewFlags & ENABLED_MASK) == ENABLED
10129                 && li.mOnGenericMotionListener.onGenericMotion(this, event)) {
10130             return true;
10131         }
10132
10133         if (onGenericMotionEvent(event)) {
10134             return true;
10135         }
10136
10137         final int actionButton = event.getActionButton();
10138         switch (event.getActionMasked()) {
10139             case MotionEvent.ACTION_BUTTON_PRESS:
10140                 if (isContextClickable() && !mInContextButtonPress && !mHasPerformedLongPress
10141                         && (actionButton == MotionEvent.BUTTON_STYLUS_PRIMARY
10142                         || actionButton == MotionEvent.BUTTON_SECONDARY)) {
10143                     if (performContextClick(event.getX(), event.getY())) {
10144                         mInContextButtonPress = true;
10145                         setPressed(true, event.getX(), event.getY());
10146                         removeTapCallback();
10147                         removeLongPressCallback();
10148                         return true;
10149                     }
10150                 }
10151                 break;
10152
10153             case MotionEvent.ACTION_BUTTON_RELEASE:
10154                 if (mInContextButtonPress && (actionButton == MotionEvent.BUTTON_STYLUS_PRIMARY
10155                         || actionButton == MotionEvent.BUTTON_SECONDARY)) {
10156                     mInContextButtonPress = false;
10157                     mIgnoreNextUpEvent = true;
10158                 }
10159                 break;
10160         }
10161
10162         if (mInputEventConsistencyVerifier != null) {
10163             mInputEventConsistencyVerifier.onUnhandledEvent(event, 0);
10164         }
10165         return false;
10166     }
10167
10168     /**
10169      * Dispatch a hover event.
10170      * <p>
10171      * Do not call this method directly.
10172      * Call {@link #dispatchGenericMotionEvent(MotionEvent)} instead.
10173      * </p>
10174      *
10175      * @param event The motion event to be dispatched.
10176      * @return True if the event was handled by the view, false otherwise.
10177      */
10178     protected boolean dispatchHoverEvent(MotionEvent event) {
10179         ListenerInfo li = mListenerInfo;
10180         //noinspection SimplifiableIfStatement
10181         if (li != null && li.mOnHoverListener != null
10182                 && (mViewFlags & ENABLED_MASK) == ENABLED
10183                 && li.mOnHoverListener.onHover(this, event)) {
10184             return true;
10185         }
10186
10187         return onHoverEvent(event);
10188     }
10189
10190     /**
10191      * Returns true if the view has a child to which it has recently sent
10192      * {@link MotionEvent#ACTION_HOVER_ENTER}.  If this view is hovered and
10193      * it does not have a hovered child, then it must be the innermost hovered view.
10194      * @hide
10195      */
10196     protected boolean hasHoveredChild() {
10197         return false;
10198     }
10199
10200     /**
10201      * Dispatch a generic motion event to the view under the first pointer.
10202      * <p>
10203      * Do not call this method directly.
10204      * Call {@link #dispatchGenericMotionEvent(MotionEvent)} instead.
10205      * </p>
10206      *
10207      * @param event The motion event to be dispatched.
10208      * @return True if the event was handled by the view, false otherwise.
10209      */
10210     protected boolean dispatchGenericPointerEvent(MotionEvent event) {
10211         return false;
10212     }
10213
10214     /**
10215      * Dispatch a generic motion event to the currently focused view.
10216      * <p>
10217      * Do not call this method directly.
10218      * Call {@link #dispatchGenericMotionEvent(MotionEvent)} instead.
10219      * </p>
10220      *
10221      * @param event The motion event to be dispatched.
10222      * @return True if the event was handled by the view, false otherwise.
10223      */
10224     protected boolean dispatchGenericFocusedEvent(MotionEvent event) {
10225         return false;
10226     }
10227
10228     /**
10229      * Dispatch a pointer event.
10230      * <p>
10231      * Dispatches touch related pointer events to {@link #onTouchEvent(MotionEvent)} and all
10232      * other events to {@link #onGenericMotionEvent(MotionEvent)}.  This separation of concerns
10233      * reinforces the invariant that {@link #onTouchEvent(MotionEvent)} is really about touches
10234      * and should not be expected to handle other pointing device features.
10235      * </p>
10236      *
10237      * @param event The motion event to be dispatched.
10238      * @return True if the event was handled by the view, false otherwise.
10239      * @hide
10240      */
10241     public final boolean dispatchPointerEvent(MotionEvent event) {
10242         if (event.isTouchEvent()) {
10243             return dispatchTouchEvent(event);
10244         } else {
10245             return dispatchGenericMotionEvent(event);
10246         }
10247     }
10248
10249     /**
10250      * Called when the window containing this view gains or loses window focus.
10251      * ViewGroups should override to route to their children.
10252      *
10253      * @param hasFocus True if the window containing this view now has focus,
10254      *        false otherwise.
10255      */
10256     public void dispatchWindowFocusChanged(boolean hasFocus) {
10257         onWindowFocusChanged(hasFocus);
10258     }
10259
10260     /**
10261      * Called when the window containing this view gains or loses focus.  Note
10262      * that this is separate from view focus: to receive key events, both
10263      * your view and its window must have focus.  If a window is displayed
10264      * on top of yours that takes input focus, then your own window will lose
10265      * focus but the view focus will remain unchanged.
10266      *
10267      * @param hasWindowFocus True if the window containing this view now has
10268      *        focus, false otherwise.
10269      */
10270     public void onWindowFocusChanged(boolean hasWindowFocus) {
10271         InputMethodManager imm = InputMethodManager.peekInstance();
10272         if (!hasWindowFocus) {
10273             if (isPressed()) {
10274                 setPressed(false);
10275             }
10276             if (imm != null && (mPrivateFlags & PFLAG_FOCUSED) != 0) {
10277                 imm.focusOut(this);
10278             }
10279             removeLongPressCallback();
10280             removeTapCallback();
10281             onFocusLost();
10282         } else if (imm != null && (mPrivateFlags & PFLAG_FOCUSED) != 0) {
10283             imm.focusIn(this);
10284         }
10285         refreshDrawableState();
10286     }
10287
10288     /**
10289      * Returns true if this view is in a window that currently has window focus.
10290      * Note that this is not the same as the view itself having focus.
10291      *
10292      * @return True if this view is in a window that currently has window focus.
10293      */
10294     public boolean hasWindowFocus() {
10295         return mAttachInfo != null && mAttachInfo.mHasWindowFocus;
10296     }
10297
10298     /**
10299      * Dispatch a view visibility change down the view hierarchy.
10300      * ViewGroups should override to route to their children.
10301      * @param changedView The view whose visibility changed. Could be 'this' or
10302      * an ancestor view.
10303      * @param visibility The new visibility of changedView: {@link #VISIBLE},
10304      * {@link #INVISIBLE} or {@link #GONE}.
10305      */
10306     protected void dispatchVisibilityChanged(@NonNull View changedView,
10307             @Visibility int visibility) {
10308         onVisibilityChanged(changedView, visibility);
10309     }
10310
10311     /**
10312      * Called when the visibility of the view or an ancestor of the view has
10313      * changed.
10314      *
10315      * @param changedView The view whose visibility changed. May be
10316      *                    {@code this} or an ancestor view.
10317      * @param visibility The new visibility, one of {@link #VISIBLE},
10318      *                   {@link #INVISIBLE} or {@link #GONE}.
10319      */
10320     protected void onVisibilityChanged(@NonNull View changedView, @Visibility int visibility) {
10321     }
10322
10323     /**
10324      * Dispatch a hint about whether this view is displayed. For instance, when
10325      * a View moves out of the screen, it might receives a display hint indicating
10326      * the view is not displayed. Applications should not <em>rely</em> on this hint
10327      * as there is no guarantee that they will receive one.
10328      *
10329      * @param hint A hint about whether or not this view is displayed:
10330      * {@link #VISIBLE} or {@link #INVISIBLE}.
10331      */
10332     public void dispatchDisplayHint(@Visibility int hint) {
10333         onDisplayHint(hint);
10334     }
10335
10336     /**
10337      * Gives this view a hint about whether is displayed or not. For instance, when
10338      * a View moves out of the screen, it might receives a display hint indicating
10339      * the view is not displayed. Applications should not <em>rely</em> on this hint
10340      * as there is no guarantee that they will receive one.
10341      *
10342      * @param hint A hint about whether or not this view is displayed:
10343      * {@link #VISIBLE} or {@link #INVISIBLE}.
10344      */
10345     protected void onDisplayHint(@Visibility int hint) {
10346     }
10347
10348     /**
10349      * Dispatch a window visibility change down the view hierarchy.
10350      * ViewGroups should override to route to their children.
10351      *
10352      * @param visibility The new visibility of the window.
10353      *
10354      * @see #onWindowVisibilityChanged(int)
10355      */
10356     public void dispatchWindowVisibilityChanged(@Visibility int visibility) {
10357         onWindowVisibilityChanged(visibility);
10358     }
10359
10360     /**
10361      * Called when the window containing has change its visibility
10362      * (between {@link #GONE}, {@link #INVISIBLE}, and {@link #VISIBLE}).  Note
10363      * that this tells you whether or not your window is being made visible
10364      * to the window manager; this does <em>not</em> tell you whether or not
10365      * your window is obscured by other windows on the screen, even if it
10366      * is itself visible.
10367      *
10368      * @param visibility The new visibility of the window.
10369      */
10370     protected void onWindowVisibilityChanged(@Visibility int visibility) {
10371         if (visibility == VISIBLE) {
10372             initialAwakenScrollBars();
10373         }
10374     }
10375
10376     /**
10377      * Internal dispatching method for {@link #onVisibilityAggregated}. Overridden by
10378      * ViewGroup. Intended to only be called when {@link #isAttachedToWindow()},
10379      * {@link #getWindowVisibility()} is {@link #VISIBLE} and this view's parent {@link #isShown()}.
10380      *
10381      * @param isVisible true if this view's visibility to the user is uninterrupted by its
10382      *                  ancestors or by window visibility
10383      * @return true if this view is visible to the user, not counting clipping or overlapping
10384      */
10385     boolean dispatchVisibilityAggregated(boolean isVisible) {
10386         final boolean thisVisible = getVisibility() == VISIBLE;
10387         // If we're not visible but something is telling us we are, ignore it.
10388         if (thisVisible || !isVisible) {
10389             onVisibilityAggregated(isVisible);
10390         }
10391         return thisVisible && isVisible;
10392     }
10393
10394     /**
10395      * Called when the user-visibility of this View is potentially affected by a change
10396      * to this view itself, an ancestor view or the window this view is attached to.
10397      *
10398      * @param isVisible true if this view and all of its ancestors are {@link #VISIBLE}
10399      *                  and this view's window is also visible
10400      */
10401     @CallSuper
10402     public void onVisibilityAggregated(boolean isVisible) {
10403         if (isVisible && mAttachInfo != null) {
10404             initialAwakenScrollBars();
10405         }
10406
10407         final Drawable dr = mBackground;
10408         if (dr != null && isVisible != dr.isVisible()) {
10409             dr.setVisible(isVisible, false);
10410         }
10411         final Drawable fg = mForegroundInfo != null ? mForegroundInfo.mDrawable : null;
10412         if (fg != null && isVisible != fg.isVisible()) {
10413             fg.setVisible(isVisible, false);
10414         }
10415     }
10416
10417     /**
10418      * Returns the current visibility of the window this view is attached to
10419      * (either {@link #GONE}, {@link #INVISIBLE}, or {@link #VISIBLE}).
10420      *
10421      * @return Returns the current visibility of the view's window.
10422      */
10423     @Visibility
10424     public int getWindowVisibility() {
10425         return mAttachInfo != null ? mAttachInfo.mWindowVisibility : GONE;
10426     }
10427
10428     /**
10429      * Retrieve the overall visible display size in which the window this view is
10430      * attached to has been positioned in.  This takes into account screen
10431      * decorations above the window, for both cases where the window itself
10432      * is being position inside of them or the window is being placed under
10433      * then and covered insets are used for the window to position its content
10434      * inside.  In effect, this tells you the available area where content can
10435      * be placed and remain visible to users.
10436      *
10437      * <p>This function requires an IPC back to the window manager to retrieve
10438      * the requested information, so should not be used in performance critical
10439      * code like drawing.
10440      *
10441      * @param outRect Filled in with the visible display frame.  If the view
10442      * is not attached to a window, this is simply the raw display size.
10443      */
10444     public void getWindowVisibleDisplayFrame(Rect outRect) {
10445         if (mAttachInfo != null) {
10446             try {
10447                 mAttachInfo.mSession.getDisplayFrame(mAttachInfo.mWindow, outRect);
10448             } catch (RemoteException e) {
10449                 return;
10450             }
10451             // XXX This is really broken, and probably all needs to be done
10452             // in the window manager, and we need to know more about whether
10453             // we want the area behind or in front of the IME.
10454             final Rect insets = mAttachInfo.mVisibleInsets;
10455             outRect.left += insets.left;
10456             outRect.top += insets.top;
10457             outRect.right -= insets.right;
10458             outRect.bottom -= insets.bottom;
10459             return;
10460         }
10461         // The view is not attached to a display so we don't have a context.
10462         // Make a best guess about the display size.
10463         Display d = DisplayManagerGlobal.getInstance().getRealDisplay(Display.DEFAULT_DISPLAY);
10464         d.getRectSize(outRect);
10465     }
10466
10467     /**
10468      * Like {@link #getWindowVisibleDisplayFrame}, but returns the "full" display frame this window
10469      * is currently in without any insets.
10470      *
10471      * @hide
10472      */
10473     public void getWindowDisplayFrame(Rect outRect) {
10474         if (mAttachInfo != null) {
10475             try {
10476                 mAttachInfo.mSession.getDisplayFrame(mAttachInfo.mWindow, outRect);
10477             } catch (RemoteException e) {
10478                 return;
10479             }
10480             return;
10481         }
10482         // The view is not attached to a display so we don't have a context.
10483         // Make a best guess about the display size.
10484         Display d = DisplayManagerGlobal.getInstance().getRealDisplay(Display.DEFAULT_DISPLAY);
10485         d.getRectSize(outRect);
10486     }
10487
10488     /**
10489      * Dispatch a notification about a resource configuration change down
10490      * the view hierarchy.
10491      * ViewGroups should override to route to their children.
10492      *
10493      * @param newConfig The new resource configuration.
10494      *
10495      * @see #onConfigurationChanged(android.content.res.Configuration)
10496      */
10497     public void dispatchConfigurationChanged(Configuration newConfig) {
10498         onConfigurationChanged(newConfig);
10499     }
10500
10501     /**
10502      * Called when the current configuration of the resources being used
10503      * by the application have changed.  You can use this to decide when
10504      * to reload resources that can changed based on orientation and other
10505      * configuration characteristics.  You only need to use this if you are
10506      * not relying on the normal {@link android.app.Activity} mechanism of
10507      * recreating the activity instance upon a configuration change.
10508      *
10509      * @param newConfig The new resource configuration.
10510      */
10511     protected void onConfigurationChanged(Configuration newConfig) {
10512     }
10513
10514     /**
10515      * Private function to aggregate all per-view attributes in to the view
10516      * root.
10517      */
10518     void dispatchCollectViewAttributes(AttachInfo attachInfo, int visibility) {
10519         performCollectViewAttributes(attachInfo, visibility);
10520     }
10521
10522     void performCollectViewAttributes(AttachInfo attachInfo, int visibility) {
10523         if ((visibility & VISIBILITY_MASK) == VISIBLE) {
10524             if ((mViewFlags & KEEP_SCREEN_ON) == KEEP_SCREEN_ON) {
10525                 attachInfo.mKeepScreenOn = true;
10526             }
10527             attachInfo.mSystemUiVisibility |= mSystemUiVisibility;
10528             ListenerInfo li = mListenerInfo;
10529             if (li != null && li.mOnSystemUiVisibilityChangeListener != null) {
10530                 attachInfo.mHasSystemUiListeners = true;
10531             }
10532         }
10533     }
10534
10535     void needGlobalAttributesUpdate(boolean force) {
10536         final AttachInfo ai = mAttachInfo;
10537         if (ai != null && !ai.mRecomputeGlobalAttributes) {
10538             if (force || ai.mKeepScreenOn || (ai.mSystemUiVisibility != 0)
10539                     || ai.mHasSystemUiListeners) {
10540                 ai.mRecomputeGlobalAttributes = true;
10541             }
10542         }
10543     }
10544
10545     /**
10546      * Returns whether the device is currently in touch mode.  Touch mode is entered
10547      * once the user begins interacting with the device by touch, and affects various
10548      * things like whether focus is always visible to the user.
10549      *
10550      * @return Whether the device is in touch mode.
10551      */
10552     @ViewDebug.ExportedProperty
10553     public boolean isInTouchMode() {
10554         if (mAttachInfo != null) {
10555             return mAttachInfo.mInTouchMode;
10556         } else {
10557             return ViewRootImpl.isInTouchMode();
10558         }
10559     }
10560
10561     /**
10562      * Returns the context the view is running in, through which it can
10563      * access the current theme, resources, etc.
10564      *
10565      * @return The view's Context.
10566      */
10567     @ViewDebug.CapturedViewProperty
10568     public final Context getContext() {
10569         return mContext;
10570     }
10571
10572     /**
10573      * Handle a key event before it is processed by any input method
10574      * associated with the view hierarchy.  This can be used to intercept
10575      * key events in special situations before the IME consumes them; a
10576      * typical example would be handling the BACK key to update the application's
10577      * UI instead of allowing the IME to see it and close itself.
10578      *
10579      * @param keyCode The value in event.getKeyCode().
10580      * @param event Description of the key event.
10581      * @return If you handled the event, return true. If you want to allow the
10582      *         event to be handled by the next receiver, return false.
10583      */
10584     public boolean onKeyPreIme(int keyCode, KeyEvent event) {
10585         return false;
10586     }
10587
10588     /**
10589      * Default implementation of {@link KeyEvent.Callback#onKeyDown(int, KeyEvent)
10590      * KeyEvent.Callback.onKeyDown()}: perform press of the view
10591      * when {@link KeyEvent#KEYCODE_DPAD_CENTER} or {@link KeyEvent#KEYCODE_ENTER}
10592      * is released, if the view is enabled and clickable.
10593      * <p>
10594      * Key presses in software keyboards will generally NOT trigger this
10595      * listener, although some may elect to do so in some situations. Do not
10596      * rely on this to catch software key presses.
10597      *
10598      * @param keyCode a key code that represents the button pressed, from
10599      *                {@link android.view.KeyEvent}
10600      * @param event the KeyEvent object that defines the button action
10601      */
10602     public boolean onKeyDown(int keyCode, KeyEvent event) {
10603         if (KeyEvent.isConfirmKey(keyCode)) {
10604             if ((mViewFlags & ENABLED_MASK) == DISABLED) {
10605                 return true;
10606             }
10607
10608             // Long clickable items don't necessarily have to be clickable.
10609             if (((mViewFlags & CLICKABLE) == CLICKABLE
10610                     || (mViewFlags & LONG_CLICKABLE) == LONG_CLICKABLE)
10611                     && (event.getRepeatCount() == 0)) {
10612                 // For the purposes of menu anchoring and drawable hotspots,
10613                 // key events are considered to be at the center of the view.
10614                 final float x = getWidth() / 2f;
10615                 final float y = getHeight() / 2f;
10616                 setPressed(true, x, y);
10617                 checkForLongClick(0, x, y);
10618                 return true;
10619             }
10620         }
10621
10622         return false;
10623     }
10624
10625     /**
10626      * Default implementation of {@link KeyEvent.Callback#onKeyLongPress(int, KeyEvent)
10627      * KeyEvent.Callback.onKeyLongPress()}: always returns false (doesn't handle
10628      * the event).
10629      * <p>Key presses in software keyboards will generally NOT trigger this listener,
10630      * although some may elect to do so in some situations. Do not rely on this to
10631      * catch software key presses.
10632      */
10633     public boolean onKeyLongPress(int keyCode, KeyEvent event) {
10634         return false;
10635     }
10636
10637     /**
10638      * Default implementation of {@link KeyEvent.Callback#onKeyUp(int, KeyEvent)
10639      * KeyEvent.Callback.onKeyUp()}: perform clicking of the view
10640      * when {@link KeyEvent#KEYCODE_DPAD_CENTER}, {@link KeyEvent#KEYCODE_ENTER}
10641      * or {@link KeyEvent#KEYCODE_SPACE} is released.
10642      * <p>Key presses in software keyboards will generally NOT trigger this listener,
10643      * although some may elect to do so in some situations. Do not rely on this to
10644      * catch software key presses.
10645      *
10646      * @param keyCode A key code that represents the button pressed, from
10647      *                {@link android.view.KeyEvent}.
10648      * @param event   The KeyEvent object that defines the button action.
10649      */
10650     public boolean onKeyUp(int keyCode, KeyEvent event) {
10651         if (KeyEvent.isConfirmKey(keyCode)) {
10652             if ((mViewFlags & ENABLED_MASK) == DISABLED) {
10653                 return true;
10654             }
10655             if ((mViewFlags & CLICKABLE) == CLICKABLE && isPressed()) {
10656                 setPressed(false);
10657
10658                 if (!mHasPerformedLongPress) {
10659                     // This is a tap, so remove the longpress check
10660                     removeLongPressCallback();
10661                     return performClick();
10662                 }
10663             }
10664         }
10665         return false;
10666     }
10667
10668     /**
10669      * Default implementation of {@link KeyEvent.Callback#onKeyMultiple(int, int, KeyEvent)
10670      * KeyEvent.Callback.onKeyMultiple()}: always returns false (doesn't handle
10671      * the event).
10672      * <p>Key presses in software keyboards will generally NOT trigger this listener,
10673      * although some may elect to do so in some situations. Do not rely on this to
10674      * catch software key presses.
10675      *
10676      * @param keyCode     A key code that represents the button pressed, from
10677      *                    {@link android.view.KeyEvent}.
10678      * @param repeatCount The number of times the action was made.
10679      * @param event       The KeyEvent object that defines the button action.
10680      */
10681     public boolean onKeyMultiple(int keyCode, int repeatCount, KeyEvent event) {
10682         return false;
10683     }
10684
10685     /**
10686      * Called on the focused view when a key shortcut event is not handled.
10687      * Override this method to implement local key shortcuts for the View.
10688      * Key shortcuts can also be implemented by setting the
10689      * {@link MenuItem#setShortcut(char, char) shortcut} property of menu items.
10690      *
10691      * @param keyCode The value in event.getKeyCode().
10692      * @param event Description of the key event.
10693      * @return If you handled the event, return true. If you want to allow the
10694      *         event to be handled by the next receiver, return false.
10695      */
10696     public boolean onKeyShortcut(int keyCode, KeyEvent event) {
10697         return false;
10698     }
10699
10700     /**
10701      * Check whether the called view is a text editor, in which case it
10702      * would make sense to automatically display a soft input window for
10703      * it.  Subclasses should override this if they implement
10704      * {@link #onCreateInputConnection(EditorInfo)} to return true if
10705      * a call on that method would return a non-null InputConnection, and
10706      * they are really a first-class editor that the user would normally
10707      * start typing on when the go into a window containing your view.
10708      *
10709      * <p>The default implementation always returns false.  This does
10710      * <em>not</em> mean that its {@link #onCreateInputConnection(EditorInfo)}
10711      * will not be called or the user can not otherwise perform edits on your
10712      * view; it is just a hint to the system that this is not the primary
10713      * purpose of this view.
10714      *
10715      * @return Returns true if this view is a text editor, else false.
10716      */
10717     public boolean onCheckIsTextEditor() {
10718         return false;
10719     }
10720
10721     /**
10722      * Create a new InputConnection for an InputMethod to interact
10723      * with the view.  The default implementation returns null, since it doesn't
10724      * support input methods.  You can override this to implement such support.
10725      * This is only needed for views that take focus and text input.
10726      *
10727      * <p>When implementing this, you probably also want to implement
10728      * {@link #onCheckIsTextEditor()} to indicate you will return a
10729      * non-null InputConnection.</p>
10730      *
10731      * <p>Also, take good care to fill in the {@link android.view.inputmethod.EditorInfo}
10732      * object correctly and in its entirety, so that the connected IME can rely
10733      * on its values. For example, {@link android.view.inputmethod.EditorInfo#initialSelStart}
10734      * and  {@link android.view.inputmethod.EditorInfo#initialSelEnd} members
10735      * must be filled in with the correct cursor position for IMEs to work correctly
10736      * with your application.</p>
10737      *
10738      * @param outAttrs Fill in with attribute information about the connection.
10739      */
10740     public InputConnection onCreateInputConnection(EditorInfo outAttrs) {
10741         return null;
10742     }
10743
10744     /**
10745      * Called by the {@link android.view.inputmethod.InputMethodManager}
10746      * when a view who is not the current
10747      * input connection target is trying to make a call on the manager.  The
10748      * default implementation returns false; you can override this to return
10749      * true for certain views if you are performing InputConnection proxying
10750      * to them.
10751      * @param view The View that is making the InputMethodManager call.
10752      * @return Return true to allow the call, false to reject.
10753      */
10754     public boolean checkInputConnectionProxy(View view) {
10755         return false;
10756     }
10757
10758     /**
10759      * Show the context menu for this view. It is not safe to hold on to the
10760      * menu after returning from this method.
10761      *
10762      * You should normally not overload this method. Overload
10763      * {@link #onCreateContextMenu(ContextMenu)} or define an
10764      * {@link OnCreateContextMenuListener} to add items to the context menu.
10765      *
10766      * @param menu The context menu to populate
10767      */
10768     public void createContextMenu(ContextMenu menu) {
10769         ContextMenuInfo menuInfo = getContextMenuInfo();
10770
10771         // Sets the current menu info so all items added to menu will have
10772         // my extra info set.
10773         ((MenuBuilder)menu).setCurrentMenuInfo(menuInfo);
10774
10775         onCreateContextMenu(menu);
10776         ListenerInfo li = mListenerInfo;
10777         if (li != null && li.mOnCreateContextMenuListener != null) {
10778             li.mOnCreateContextMenuListener.onCreateContextMenu(menu, this, menuInfo);
10779         }
10780
10781         // Clear the extra information so subsequent items that aren't mine don't
10782         // have my extra info.
10783         ((MenuBuilder)menu).setCurrentMenuInfo(null);
10784
10785         if (mParent != null) {
10786             mParent.createContextMenu(menu);
10787         }
10788     }
10789
10790     /**
10791      * Views should implement this if they have extra information to associate
10792      * with the context menu. The return result is supplied as a parameter to
10793      * the {@link OnCreateContextMenuListener#onCreateContextMenu(ContextMenu, View, ContextMenuInfo)}
10794      * callback.
10795      *
10796      * @return Extra information about the item for which the context menu
10797      *         should be shown. This information will vary across different
10798      *         subclasses of View.
10799      */
10800     protected ContextMenuInfo getContextMenuInfo() {
10801         return null;
10802     }
10803
10804     /**
10805      * Views should implement this if the view itself is going to add items to
10806      * the context menu.
10807      *
10808      * @param menu the context menu to populate
10809      */
10810     protected void onCreateContextMenu(ContextMenu menu) {
10811     }
10812
10813     /**
10814      * Implement this method to handle trackball motion events.  The
10815      * <em>relative</em> movement of the trackball since the last event
10816      * can be retrieve with {@link MotionEvent#getX MotionEvent.getX()} and
10817      * {@link MotionEvent#getY MotionEvent.getY()}.  These are normalized so
10818      * that a movement of 1 corresponds to the user pressing one DPAD key (so
10819      * they will often be fractional values, representing the more fine-grained
10820      * movement information available from a trackball).
10821      *
10822      * @param event The motion event.
10823      * @return True if the event was handled, false otherwise.
10824      */
10825     public boolean onTrackballEvent(MotionEvent event) {
10826         return false;
10827     }
10828
10829     /**
10830      * Implement this method to handle generic motion events.
10831      * <p>
10832      * Generic motion events describe joystick movements, mouse hovers, track pad
10833      * touches, scroll wheel movements and other input events.  The
10834      * {@link MotionEvent#getSource() source} of the motion event specifies
10835      * the class of input that was received.  Implementations of this method
10836      * must examine the bits in the source before processing the event.
10837      * The following code example shows how this is done.
10838      * </p><p>
10839      * Generic motion events with source class {@link InputDevice#SOURCE_CLASS_POINTER}
10840      * are delivered to the view under the pointer.  All other generic motion events are
10841      * delivered to the focused view.
10842      * </p>
10843      * <pre> public boolean onGenericMotionEvent(MotionEvent event) {
10844      *     if (event.isFromSource(InputDevice.SOURCE_CLASS_JOYSTICK)) {
10845      *         if (event.getAction() == MotionEvent.ACTION_MOVE) {
10846      *             // process the joystick movement...
10847      *             return true;
10848      *         }
10849      *     }
10850      *     if (event.isFromSource(InputDevice.SOURCE_CLASS_POINTER)) {
10851      *         switch (event.getAction()) {
10852      *             case MotionEvent.ACTION_HOVER_MOVE:
10853      *                 // process the mouse hover movement...
10854      *                 return true;
10855      *             case MotionEvent.ACTION_SCROLL:
10856      *                 // process the scroll wheel movement...
10857      *                 return true;
10858      *         }
10859      *     }
10860      *     return super.onGenericMotionEvent(event);
10861      * }</pre>
10862      *
10863      * @param event The generic motion event being processed.
10864      * @return True if the event was handled, false otherwise.
10865      */
10866     public boolean onGenericMotionEvent(MotionEvent event) {
10867         return false;
10868     }
10869
10870     /**
10871      * Implement this method to handle hover events.
10872      * <p>
10873      * This method is called whenever a pointer is hovering into, over, or out of the
10874      * bounds of a view and the view is not currently being touched.
10875      * Hover events are represented as pointer events with action
10876      * {@link MotionEvent#ACTION_HOVER_ENTER}, {@link MotionEvent#ACTION_HOVER_MOVE},
10877      * or {@link MotionEvent#ACTION_HOVER_EXIT}.
10878      * </p>
10879      * <ul>
10880      * <li>The view receives a hover event with action {@link MotionEvent#ACTION_HOVER_ENTER}
10881      * when the pointer enters the bounds of the view.</li>
10882      * <li>The view receives a hover event with action {@link MotionEvent#ACTION_HOVER_MOVE}
10883      * when the pointer has already entered the bounds of the view and has moved.</li>
10884      * <li>The view receives a hover event with action {@link MotionEvent#ACTION_HOVER_EXIT}
10885      * when the pointer has exited the bounds of the view or when the pointer is
10886      * about to go down due to a button click, tap, or similar user action that
10887      * causes the view to be touched.</li>
10888      * </ul>
10889      * <p>
10890      * The view should implement this method to return true to indicate that it is
10891      * handling the hover event, such as by changing its drawable state.
10892      * </p><p>
10893      * The default implementation calls {@link #setHovered} to update the hovered state
10894      * of the view when a hover enter or hover exit event is received, if the view
10895      * is enabled and is clickable.  The default implementation also sends hover
10896      * accessibility events.
10897      * </p>
10898      *
10899      * @param event The motion event that describes the hover.
10900      * @return True if the view handled the hover event.
10901      *
10902      * @see #isHovered
10903      * @see #setHovered
10904      * @see #onHoverChanged
10905      */
10906     public boolean onHoverEvent(MotionEvent event) {
10907         // The root view may receive hover (or touch) events that are outside the bounds of
10908         // the window.  This code ensures that we only send accessibility events for
10909         // hovers that are actually within the bounds of the root view.
10910         final int action = event.getActionMasked();
10911         if (!mSendingHoverAccessibilityEvents) {
10912             if ((action == MotionEvent.ACTION_HOVER_ENTER
10913                     || action == MotionEvent.ACTION_HOVER_MOVE)
10914                     && !hasHoveredChild()
10915                     && pointInView(event.getX(), event.getY())) {
10916                 sendAccessibilityHoverEvent(AccessibilityEvent.TYPE_VIEW_HOVER_ENTER);
10917                 mSendingHoverAccessibilityEvents = true;
10918             }
10919         } else {
10920             if (action == MotionEvent.ACTION_HOVER_EXIT
10921                     || (action == MotionEvent.ACTION_MOVE
10922                             && !pointInView(event.getX(), event.getY()))) {
10923                 mSendingHoverAccessibilityEvents = false;
10924                 sendAccessibilityHoverEvent(AccessibilityEvent.TYPE_VIEW_HOVER_EXIT);
10925             }
10926         }
10927
10928         if ((action == MotionEvent.ACTION_HOVER_ENTER || action == MotionEvent.ACTION_HOVER_MOVE)
10929                 && event.isFromSource(InputDevice.SOURCE_MOUSE)
10930                 && isOnScrollbar(event.getX(), event.getY())) {
10931             awakenScrollBars();
10932         }
10933         if (isHoverable()) {
10934             switch (action) {
10935                 case MotionEvent.ACTION_HOVER_ENTER:
10936                     setHovered(true);
10937                     break;
10938                 case MotionEvent.ACTION_HOVER_EXIT:
10939                     setHovered(false);
10940                     break;
10941             }
10942
10943             // Dispatch the event to onGenericMotionEvent before returning true.
10944             // This is to provide compatibility with existing applications that
10945             // handled HOVER_MOVE events in onGenericMotionEvent and that would
10946             // break because of the new default handling for hoverable views
10947             // in onHoverEvent.
10948             // Note that onGenericMotionEvent will be called by default when
10949             // onHoverEvent returns false (refer to dispatchGenericMotionEvent).
10950             dispatchGenericMotionEventInternal(event);
10951             // The event was already handled by calling setHovered(), so always
10952             // return true.
10953             return true;
10954         }
10955
10956         return false;
10957     }
10958
10959     /**
10960      * Returns true if the view should handle {@link #onHoverEvent}
10961      * by calling {@link #setHovered} to change its hovered state.
10962      *
10963      * @return True if the view is hoverable.
10964      */
10965     private boolean isHoverable() {
10966         final int viewFlags = mViewFlags;
10967         if ((viewFlags & ENABLED_MASK) == DISABLED) {
10968             return false;
10969         }
10970
10971         return (viewFlags & CLICKABLE) == CLICKABLE
10972                 || (viewFlags & LONG_CLICKABLE) == LONG_CLICKABLE
10973                 || (viewFlags & CONTEXT_CLICKABLE) == CONTEXT_CLICKABLE;
10974     }
10975
10976     /**
10977      * Returns true if the view is currently hovered.
10978      *
10979      * @return True if the view is currently hovered.
10980      *
10981      * @see #setHovered
10982      * @see #onHoverChanged
10983      */
10984     @ViewDebug.ExportedProperty
10985     public boolean isHovered() {
10986         return (mPrivateFlags & PFLAG_HOVERED) != 0;
10987     }
10988
10989     /**
10990      * Sets whether the view is currently hovered.
10991      * <p>
10992      * Calling this method also changes the drawable state of the view.  This
10993      * enables the view to react to hover by using different drawable resources
10994      * to change its appearance.
10995      * </p><p>
10996      * The {@link #onHoverChanged} method is called when the hovered state changes.
10997      * </p>
10998      *
10999      * @param hovered True if the view is hovered.
11000      *
11001      * @see #isHovered
11002      * @see #onHoverChanged
11003      */
11004     public void setHovered(boolean hovered) {
11005         if (hovered) {
11006             if ((mPrivateFlags & PFLAG_HOVERED) == 0) {
11007                 mPrivateFlags |= PFLAG_HOVERED;
11008                 refreshDrawableState();
11009                 onHoverChanged(true);
11010             }
11011         } else {
11012             if ((mPrivateFlags & PFLAG_HOVERED) != 0) {
11013                 mPrivateFlags &= ~PFLAG_HOVERED;
11014                 refreshDrawableState();
11015                 onHoverChanged(false);
11016             }
11017         }
11018     }
11019
11020     /**
11021      * Implement this method to handle hover state changes.
11022      * <p>
11023      * This method is called whenever the hover state changes as a result of a
11024      * call to {@link #setHovered}.
11025      * </p>
11026      *
11027      * @param hovered The current hover state, as returned by {@link #isHovered}.
11028      *
11029      * @see #isHovered
11030      * @see #setHovered
11031      */
11032     public void onHoverChanged(boolean hovered) {
11033     }
11034
11035     /**
11036      * Handles scroll bar dragging by mouse input.
11037      *
11038      * @hide
11039      * @param event The motion event.
11040      *
11041      * @return true if the event was handled as a scroll bar dragging, false otherwise.
11042      */
11043     protected boolean handleScrollBarDragging(MotionEvent event) {
11044         if (mScrollCache == null) {
11045             return false;
11046         }
11047         final float x = event.getX();
11048         final float y = event.getY();
11049         final int action = event.getAction();
11050         if ((mScrollCache.mScrollBarDraggingState == ScrollabilityCache.NOT_DRAGGING
11051                 && action != MotionEvent.ACTION_DOWN)
11052                     || !event.isFromSource(InputDevice.SOURCE_MOUSE)
11053                     || !event.isButtonPressed(MotionEvent.BUTTON_PRIMARY)) {
11054             mScrollCache.mScrollBarDraggingState = ScrollabilityCache.NOT_DRAGGING;
11055             return false;
11056         }
11057
11058         switch (action) {
11059             case MotionEvent.ACTION_MOVE:
11060                 if (mScrollCache.mScrollBarDraggingState == ScrollabilityCache.NOT_DRAGGING) {
11061                     return false;
11062                 }
11063                 if (mScrollCache.mScrollBarDraggingState
11064                         == ScrollabilityCache.DRAGGING_VERTICAL_SCROLL_BAR) {
11065                     final Rect bounds = mScrollCache.mScrollBarBounds;
11066                     getVerticalScrollBarBounds(bounds);
11067                     final int range = computeVerticalScrollRange();
11068                     final int offset = computeVerticalScrollOffset();
11069                     final int extent = computeVerticalScrollExtent();
11070
11071                     final int thumbLength = ScrollBarUtils.getThumbLength(
11072                             bounds.height(), bounds.width(), extent, range);
11073                     final int thumbOffset = ScrollBarUtils.getThumbOffset(
11074                             bounds.height(), thumbLength, extent, range, offset);
11075
11076                     final float diff = y - mScrollCache.mScrollBarDraggingPos;
11077                     final float maxThumbOffset = bounds.height() - thumbLength;
11078                     final float newThumbOffset =
11079                             Math.min(Math.max(thumbOffset + diff, 0.0f), maxThumbOffset);
11080                     final int height = getHeight();
11081                     if (Math.round(newThumbOffset) != thumbOffset && maxThumbOffset > 0
11082                             && height > 0 && extent > 0) {
11083                         final int newY = Math.round((range - extent)
11084                                 / ((float)extent / height) * (newThumbOffset / maxThumbOffset));
11085                         if (newY != getScrollY()) {
11086                             mScrollCache.mScrollBarDraggingPos = y;
11087                             setScrollY(newY);
11088                         }
11089                     }
11090                     return true;
11091                 }
11092                 if (mScrollCache.mScrollBarDraggingState
11093                         == ScrollabilityCache.DRAGGING_HORIZONTAL_SCROLL_BAR) {
11094                     final Rect bounds = mScrollCache.mScrollBarBounds;
11095                     getHorizontalScrollBarBounds(bounds);
11096                     final int range = computeHorizontalScrollRange();
11097                     final int offset = computeHorizontalScrollOffset();
11098                     final int extent = computeHorizontalScrollExtent();
11099
11100                     final int thumbLength = ScrollBarUtils.getThumbLength(
11101                             bounds.width(), bounds.height(), extent, range);
11102                     final int thumbOffset = ScrollBarUtils.getThumbOffset(
11103                             bounds.width(), thumbLength, extent, range, offset);
11104
11105                     final float diff = x - mScrollCache.mScrollBarDraggingPos;
11106                     final float maxThumbOffset = bounds.width() - thumbLength;
11107                     final float newThumbOffset =
11108                             Math.min(Math.max(thumbOffset + diff, 0.0f), maxThumbOffset);
11109                     final int width = getWidth();
11110                     if (Math.round(newThumbOffset) != thumbOffset && maxThumbOffset > 0
11111                             && width > 0 && extent > 0) {
11112                         final int newX = Math.round((range - extent)
11113                                 / ((float)extent / width) * (newThumbOffset / maxThumbOffset));
11114                         if (newX != getScrollX()) {
11115                             mScrollCache.mScrollBarDraggingPos = x;
11116                             setScrollX(newX);
11117                         }
11118                     }
11119                     return true;
11120                 }
11121             case MotionEvent.ACTION_DOWN:
11122                 if (mScrollCache.state == ScrollabilityCache.OFF) {
11123                     return false;
11124                 }
11125                 if (isOnVerticalScrollbarThumb(x, y)) {
11126                     mScrollCache.mScrollBarDraggingState =
11127                             ScrollabilityCache.DRAGGING_VERTICAL_SCROLL_BAR;
11128                     mScrollCache.mScrollBarDraggingPos = y;
11129                     return true;
11130                 }
11131                 if (isOnHorizontalScrollbarThumb(x, y)) {
11132                     mScrollCache.mScrollBarDraggingState =
11133                             ScrollabilityCache.DRAGGING_HORIZONTAL_SCROLL_BAR;
11134                     mScrollCache.mScrollBarDraggingPos = x;
11135                     return true;
11136                 }
11137         }
11138         mScrollCache.mScrollBarDraggingState = ScrollabilityCache.NOT_DRAGGING;
11139         return false;
11140     }
11141
11142     /**
11143      * Implement this method to handle touch screen motion events.
11144      * <p>
11145      * If this method is used to detect click actions, it is recommended that
11146      * the actions be performed by implementing and calling
11147      * {@link #performClick()}. This will ensure consistent system behavior,
11148      * including:
11149      * <ul>
11150      * <li>obeying click sound preferences
11151      * <li>dispatching OnClickListener calls
11152      * <li>handling {@link AccessibilityNodeInfo#ACTION_CLICK ACTION_CLICK} when
11153      * accessibility features are enabled
11154      * </ul>
11155      *
11156      * @param event The motion event.
11157      * @return True if the event was handled, false otherwise.
11158      */
11159     public boolean onTouchEvent(MotionEvent event) {
11160         final float x = event.getX();
11161         final float y = event.getY();
11162         final int viewFlags = mViewFlags;
11163         final int action = event.getAction();
11164
11165         if ((viewFlags & ENABLED_MASK) == DISABLED) {
11166             if (action == MotionEvent.ACTION_UP && (mPrivateFlags & PFLAG_PRESSED) != 0) {
11167                 setPressed(false);
11168             }
11169             // A disabled view that is clickable still consumes the touch
11170             // events, it just doesn't respond to them.
11171             return (((viewFlags & CLICKABLE) == CLICKABLE
11172                     || (viewFlags & LONG_CLICKABLE) == LONG_CLICKABLE)
11173                     || (viewFlags & CONTEXT_CLICKABLE) == CONTEXT_CLICKABLE);
11174         }
11175         if (mTouchDelegate != null) {
11176             if (mTouchDelegate.onTouchEvent(event)) {
11177                 return true;
11178             }
11179         }
11180
11181         if (((viewFlags & CLICKABLE) == CLICKABLE ||
11182                 (viewFlags & LONG_CLICKABLE) == LONG_CLICKABLE) ||
11183                 (viewFlags & CONTEXT_CLICKABLE) == CONTEXT_CLICKABLE) {
11184             switch (action) {
11185                 case MotionEvent.ACTION_UP:
11186                     boolean prepressed = (mPrivateFlags & PFLAG_PREPRESSED) != 0;
11187                     if ((mPrivateFlags & PFLAG_PRESSED) != 0 || prepressed) {
11188                         // take focus if we don't have it already and we should in
11189                         // touch mode.
11190                         boolean focusTaken = false;
11191                         if (isFocusable() && isFocusableInTouchMode() && !isFocused()) {
11192                             focusTaken = requestFocus();
11193                         }
11194
11195                         if (prepressed) {
11196                             // The button is being released before we actually
11197                             // showed it as pressed.  Make it show the pressed
11198                             // state now (before scheduling the click) to ensure
11199                             // the user sees it.
11200                             setPressed(true, x, y);
11201                        }
11202
11203                         if (!mHasPerformedLongPress && !mIgnoreNextUpEvent) {
11204                             // This is a tap, so remove the longpress check
11205                             removeLongPressCallback();
11206
11207                             // Only perform take click actions if we were in the pressed state
11208                             if (!focusTaken) {
11209                                 // Use a Runnable and post this rather than calling
11210                                 // performClick directly. This lets other visual state
11211                                 // of the view update before click actions start.
11212                                 if (mPerformClick == null) {
11213                                     mPerformClick = new PerformClick();
11214                                 }
11215                                 if (!post(mPerformClick)) {
11216                                     performClick();
11217                                 }
11218                             }
11219                         }
11220
11221                         if (mUnsetPressedState == null) {
11222                             mUnsetPressedState = new UnsetPressedState();
11223                         }
11224
11225                         if (prepressed) {
11226                             postDelayed(mUnsetPressedState,
11227                                     ViewConfiguration.getPressedStateDuration());
11228                         } else if (!post(mUnsetPressedState)) {
11229                             // If the post failed, unpress right now
11230                             mUnsetPressedState.run();
11231                         }
11232
11233                         removeTapCallback();
11234                     }
11235                     mIgnoreNextUpEvent = false;
11236                     break;
11237
11238                 case MotionEvent.ACTION_DOWN:
11239                     mHasPerformedLongPress = false;
11240
11241                     if (performButtonActionOnTouchDown(event)) {
11242                         break;
11243                     }
11244
11245                     // Walk up the hierarchy to determine if we're inside a scrolling container.
11246                     boolean isInScrollingContainer = isInScrollingContainer();
11247
11248                     // For views inside a scrolling container, delay the pressed feedback for
11249                     // a short period in case this is a scroll.
11250                     if (isInScrollingContainer) {
11251                         mPrivateFlags |= PFLAG_PREPRESSED;
11252                         if (mPendingCheckForTap == null) {
11253                             mPendingCheckForTap = new CheckForTap();
11254                         }
11255                         mPendingCheckForTap.x = event.getX();
11256                         mPendingCheckForTap.y = event.getY();
11257                         postDelayed(mPendingCheckForTap, ViewConfiguration.getTapTimeout());
11258                     } else {
11259                         // Not inside a scrolling container, so show the feedback right away
11260                         setPressed(true, x, y);
11261                         checkForLongClick(0, x, y);
11262                     }
11263                     break;
11264
11265                 case MotionEvent.ACTION_CANCEL:
11266                     setPressed(false);
11267                     removeTapCallback();
11268                     removeLongPressCallback();
11269                     mInContextButtonPress = false;
11270                     mHasPerformedLongPress = false;
11271                     mIgnoreNextUpEvent = false;
11272                     break;
11273
11274                 case MotionEvent.ACTION_MOVE:
11275                     drawableHotspotChanged(x, y);
11276
11277                     // Be lenient about moving outside of buttons
11278                     if (!pointInView(x, y, mTouchSlop)) {
11279                         // Outside button
11280                         removeTapCallback();
11281                         if ((mPrivateFlags & PFLAG_PRESSED) != 0) {
11282                             // Remove any future long press/tap checks
11283                             removeLongPressCallback();
11284
11285                             setPressed(false);
11286                         }
11287                     }
11288                     break;
11289             }
11290
11291             return true;
11292         }
11293
11294         return false;
11295     }
11296
11297     /**
11298      * @hide
11299      */
11300     public boolean isInScrollingContainer() {
11301         ViewParent p = getParent();
11302         while (p != null && p instanceof ViewGroup) {
11303             if (((ViewGroup) p).shouldDelayChildPressedState()) {
11304                 return true;
11305             }
11306             p = p.getParent();
11307         }
11308         return false;
11309     }
11310
11311     /**
11312      * Remove the longpress detection timer.
11313      */
11314     private void removeLongPressCallback() {
11315         if (mPendingCheckForLongPress != null) {
11316           removeCallbacks(mPendingCheckForLongPress);
11317         }
11318     }
11319
11320     /**
11321      * Remove the pending click action
11322      */
11323     private void removePerformClickCallback() {
11324         if (mPerformClick != null) {
11325             removeCallbacks(mPerformClick);
11326         }
11327     }
11328
11329     /**
11330      * Remove the prepress detection timer.
11331      */
11332     private void removeUnsetPressCallback() {
11333         if ((mPrivateFlags & PFLAG_PRESSED) != 0 && mUnsetPressedState != null) {
11334             setPressed(false);
11335             removeCallbacks(mUnsetPressedState);
11336         }
11337     }
11338
11339     /**
11340      * Remove the tap detection timer.
11341      */
11342     private void removeTapCallback() {
11343         if (mPendingCheckForTap != null) {
11344             mPrivateFlags &= ~PFLAG_PREPRESSED;
11345             removeCallbacks(mPendingCheckForTap);
11346         }
11347     }
11348
11349     /**
11350      * Cancels a pending long press.  Your subclass can use this if you
11351      * want the context menu to come up if the user presses and holds
11352      * at the same place, but you don't want it to come up if they press
11353      * and then move around enough to cause scrolling.
11354      */
11355     public void cancelLongPress() {
11356         removeLongPressCallback();
11357
11358         /*
11359          * The prepressed state handled by the tap callback is a display
11360          * construct, but the tap callback will post a long press callback
11361          * less its own timeout. Remove it here.
11362          */
11363         removeTapCallback();
11364     }
11365
11366     /**
11367      * Remove the pending callback for sending a
11368      * {@link AccessibilityEvent#TYPE_VIEW_SCROLLED} accessibility event.
11369      */
11370     private void removeSendViewScrolledAccessibilityEventCallback() {
11371         if (mSendViewScrolledAccessibilityEvent != null) {
11372             removeCallbacks(mSendViewScrolledAccessibilityEvent);
11373             mSendViewScrolledAccessibilityEvent.mIsPending = false;
11374         }
11375     }
11376
11377     /**
11378      * Sets the TouchDelegate for this View.
11379      */
11380     public void setTouchDelegate(TouchDelegate delegate) {
11381         mTouchDelegate = delegate;
11382     }
11383
11384     /**
11385      * Gets the TouchDelegate for this View.
11386      */
11387     public TouchDelegate getTouchDelegate() {
11388         return mTouchDelegate;
11389     }
11390
11391     /**
11392      * Request unbuffered dispatch of the given stream of MotionEvents to this View.
11393      *
11394      * Until this View receives a corresponding {@link MotionEvent#ACTION_UP}, ask that the input
11395      * system not batch {@link MotionEvent}s but instead deliver them as soon as they're
11396      * available. This method should only be called for touch events.
11397      *
11398      * <p class="note">This api is not intended for most applications. Buffered dispatch
11399      * provides many of benefits, and just requesting unbuffered dispatch on most MotionEvent
11400      * streams will not improve your input latency. Side effects include: increased latency,
11401      * jittery scrolls and inability to take advantage of system resampling. Talk to your input
11402      * professional to see if {@link #requestUnbufferedDispatch(MotionEvent)} is right for
11403      * you.</p>
11404      */
11405     public final void requestUnbufferedDispatch(MotionEvent event) {
11406         final int action = event.getAction();
11407         if (mAttachInfo == null
11408                 || action != MotionEvent.ACTION_DOWN && action != MotionEvent.ACTION_MOVE
11409                 || !event.isTouchEvent()) {
11410             return;
11411         }
11412         mAttachInfo.mUnbufferedDispatchRequested = true;
11413     }
11414
11415     /**
11416      * Set flags controlling behavior of this view.
11417      *
11418      * @param flags Constant indicating the value which should be set
11419      * @param mask Constant indicating the bit range that should be changed
11420      */
11421     void setFlags(int flags, int mask) {
11422         final boolean accessibilityEnabled =
11423                 AccessibilityManager.getInstance(mContext).isEnabled();
11424         final boolean oldIncludeForAccessibility = accessibilityEnabled && includeForAccessibility();
11425
11426         int old = mViewFlags;
11427         mViewFlags = (mViewFlags & ~mask) | (flags & mask);
11428
11429         int changed = mViewFlags ^ old;
11430         if (changed == 0) {
11431             return;
11432         }
11433         int privateFlags = mPrivateFlags;
11434
11435         /* Check if the FOCUSABLE bit has changed */
11436         if (((changed & FOCUSABLE_MASK) != 0) &&
11437                 ((privateFlags & PFLAG_HAS_BOUNDS) !=0)) {
11438             if (((old & FOCUSABLE_MASK) == FOCUSABLE)
11439                     && ((privateFlags & PFLAG_FOCUSED) != 0)) {
11440                 /* Give up focus if we are no longer focusable */
11441                 clearFocus();
11442             } else if (((old & FOCUSABLE_MASK) == NOT_FOCUSABLE)
11443                     && ((privateFlags & PFLAG_FOCUSED) == 0)) {
11444                 /*
11445                  * Tell the view system that we are now available to take focus
11446                  * if no one else already has it.
11447                  */
11448                 if (mParent != null) mParent.focusableViewAvailable(this);
11449             }
11450         }
11451
11452         final int newVisibility = flags & VISIBILITY_MASK;
11453         if (newVisibility == VISIBLE) {
11454             if ((changed & VISIBILITY_MASK) != 0) {
11455                 /*
11456                  * If this view is becoming visible, invalidate it in case it changed while
11457                  * it was not visible. Marking it drawn ensures that the invalidation will
11458                  * go through.
11459                  */
11460                 mPrivateFlags |= PFLAG_DRAWN;
11461                 invalidate(true);
11462
11463                 needGlobalAttributesUpdate(true);
11464
11465                 // a view becoming visible is worth notifying the parent
11466                 // about in case nothing has focus.  even if this specific view
11467                 // isn't focusable, it may contain something that is, so let
11468                 // the root view try to give this focus if nothing else does.
11469                 if ((mParent != null) && (mBottom > mTop) && (mRight > mLeft)) {
11470                     mParent.focusableViewAvailable(this);
11471                 }
11472             }
11473         }
11474
11475         /* Check if the GONE bit has changed */
11476         if ((changed & GONE) != 0) {
11477             needGlobalAttributesUpdate(false);
11478             requestLayout();
11479
11480             if (((mViewFlags & VISIBILITY_MASK) == GONE)) {
11481                 if (hasFocus()) clearFocus();
11482                 clearAccessibilityFocus();
11483                 destroyDrawingCache();
11484                 if (mParent instanceof View) {
11485                     // GONE views noop invalidation, so invalidate the parent
11486                     ((View) mParent).invalidate(true);
11487                 }
11488                 // Mark the view drawn to ensure that it gets invalidated properly the next
11489                 // time it is visible and gets invalidated
11490                 mPrivateFlags |= PFLAG_DRAWN;
11491             }
11492             if (mAttachInfo != null) {
11493                 mAttachInfo.mViewVisibilityChanged = true;
11494             }
11495         }
11496
11497         /* Check if the VISIBLE bit has changed */
11498         if ((changed & INVISIBLE) != 0) {
11499             needGlobalAttributesUpdate(false);
11500             /*
11501              * If this view is becoming invisible, set the DRAWN flag so that
11502              * the next invalidate() will not be skipped.
11503              */
11504             mPrivateFlags |= PFLAG_DRAWN;
11505
11506             if (((mViewFlags & VISIBILITY_MASK) == INVISIBLE)) {
11507                 // root view becoming invisible shouldn't clear focus and accessibility focus
11508                 if (getRootView() != this) {
11509                     if (hasFocus()) clearFocus();
11510                     clearAccessibilityFocus();
11511                 }
11512             }
11513             if (mAttachInfo != null) {
11514                 mAttachInfo.mViewVisibilityChanged = true;
11515             }
11516         }
11517
11518         if ((changed & VISIBILITY_MASK) != 0) {
11519             // If the view is invisible, cleanup its display list to free up resources
11520             if (newVisibility != VISIBLE && mAttachInfo != null) {
11521                 cleanupDraw();
11522             }
11523
11524             if (mParent instanceof ViewGroup) {
11525                 ((ViewGroup) mParent).onChildVisibilityChanged(this,
11526                         (changed & VISIBILITY_MASK), newVisibility);
11527                 ((View) mParent).invalidate(true);
11528             } else if (mParent != null) {
11529                 mParent.invalidateChild(this, null);
11530             }
11531
11532             if (mAttachInfo != null) {
11533                 dispatchVisibilityChanged(this, newVisibility);
11534
11535                 // Aggregated visibility changes are dispatched to attached views
11536                 // in visible windows where the parent is currently shown/drawn
11537                 // or the parent is not a ViewGroup (and therefore assumed to be a ViewRoot),
11538                 // discounting clipping or overlapping. This makes it a good place
11539                 // to change animation states.
11540                 if (mParent != null && getWindowVisibility() == VISIBLE &&
11541                         ((!(mParent instanceof ViewGroup)) || ((ViewGroup) mParent).isShown())) {
11542                     dispatchVisibilityAggregated(newVisibility == VISIBLE);
11543                 }
11544                 notifySubtreeAccessibilityStateChangedIfNeeded();
11545             }
11546         }
11547
11548         if ((changed & WILL_NOT_CACHE_DRAWING) != 0) {
11549             destroyDrawingCache();
11550         }
11551
11552         if ((changed & DRAWING_CACHE_ENABLED) != 0) {
11553             destroyDrawingCache();
11554             mPrivateFlags &= ~PFLAG_DRAWING_CACHE_VALID;
11555             invalidateParentCaches();
11556         }
11557
11558         if ((changed & DRAWING_CACHE_QUALITY_MASK) != 0) {
11559             destroyDrawingCache();
11560             mPrivateFlags &= ~PFLAG_DRAWING_CACHE_VALID;
11561         }
11562
11563         if ((changed & DRAW_MASK) != 0) {
11564             if ((mViewFlags & WILL_NOT_DRAW) != 0) {
11565                 if (mBackground != null
11566                         || (mForegroundInfo != null && mForegroundInfo.mDrawable != null)) {
11567                     mPrivateFlags &= ~PFLAG_SKIP_DRAW;
11568                 } else {
11569                     mPrivateFlags |= PFLAG_SKIP_DRAW;
11570                 }
11571             } else {
11572                 mPrivateFlags &= ~PFLAG_SKIP_DRAW;
11573             }
11574             requestLayout();
11575             invalidate(true);
11576         }
11577
11578         if ((changed & KEEP_SCREEN_ON) != 0) {
11579             if (mParent != null && mAttachInfo != null && !mAttachInfo.mRecomputeGlobalAttributes) {
11580                 mParent.recomputeViewAttributes(this);
11581             }
11582         }
11583
11584         if (accessibilityEnabled) {
11585             if ((changed & FOCUSABLE_MASK) != 0 || (changed & VISIBILITY_MASK) != 0
11586                     || (changed & CLICKABLE) != 0 || (changed & LONG_CLICKABLE) != 0
11587                     || (changed & CONTEXT_CLICKABLE) != 0) {
11588                 if (oldIncludeForAccessibility != includeForAccessibility()) {
11589                     notifySubtreeAccessibilityStateChangedIfNeeded();
11590                 } else {
11591                     notifyViewAccessibilityStateChangedIfNeeded(
11592                             AccessibilityEvent.CONTENT_CHANGE_TYPE_UNDEFINED);
11593                 }
11594             } else if ((changed & ENABLED_MASK) != 0) {
11595                 notifyViewAccessibilityStateChangedIfNeeded(
11596                         AccessibilityEvent.CONTENT_CHANGE_TYPE_UNDEFINED);
11597             }
11598         }
11599     }
11600
11601     /**
11602      * Change the view's z order in the tree, so it's on top of other sibling
11603      * views. This ordering change may affect layout, if the parent container
11604      * uses an order-dependent layout scheme (e.g., LinearLayout). Prior
11605      * to {@link android.os.Build.VERSION_CODES#KITKAT} this
11606      * method should be followed by calls to {@link #requestLayout()} and
11607      * {@link View#invalidate()} on the view's parent to force the parent to redraw
11608      * with the new child ordering.
11609      *
11610      * @see ViewGroup#bringChildToFront(View)
11611      */
11612     public void bringToFront() {
11613         if (mParent != null) {
11614             mParent.bringChildToFront(this);
11615         }
11616     }
11617
11618     /**
11619      * This is called in response to an internal scroll in this view (i.e., the
11620      * view scrolled its own contents). This is typically as a result of
11621      * {@link #scrollBy(int, int)} or {@link #scrollTo(int, int)} having been
11622      * called.
11623      *
11624      * @param l Current horizontal scroll origin.
11625      * @param t Current vertical scroll origin.
11626      * @param oldl Previous horizontal scroll origin.
11627      * @param oldt Previous vertical scroll origin.
11628      */
11629     protected void onScrollChanged(int l, int t, int oldl, int oldt) {
11630         notifySubtreeAccessibilityStateChangedIfNeeded();
11631
11632         if (AccessibilityManager.getInstance(mContext).isEnabled()) {
11633             postSendViewScrolledAccessibilityEventCallback();
11634         }
11635
11636         mBackgroundSizeChanged = true;
11637         if (mForegroundInfo != null) {
11638             mForegroundInfo.mBoundsChanged = true;
11639         }
11640
11641         final AttachInfo ai = mAttachInfo;
11642         if (ai != null) {
11643             ai.mViewScrollChanged = true;
11644         }
11645
11646         if (mListenerInfo != null && mListenerInfo.mOnScrollChangeListener != null) {
11647             mListenerInfo.mOnScrollChangeListener.onScrollChange(this, l, t, oldl, oldt);
11648         }
11649     }
11650
11651     /**
11652      * Interface definition for a callback to be invoked when the scroll
11653      * X or Y positions of a view change.
11654      * <p>
11655      * <b>Note:</b> Some views handle scrolling independently from View and may
11656      * have their own separate listeners for scroll-type events. For example,
11657      * {@link android.widget.ListView ListView} allows clients to register an
11658      * {@link android.widget.ListView#setOnScrollListener(android.widget.AbsListView.OnScrollListener) AbsListView.OnScrollListener}
11659      * to listen for changes in list scroll position.
11660      *
11661      * @see #setOnScrollChangeListener(View.OnScrollChangeListener)
11662      */
11663     public interface OnScrollChangeListener {
11664         /**
11665          * Called when the scroll position of a view changes.
11666          *
11667          * @param v The view whose scroll position has changed.
11668          * @param scrollX Current horizontal scroll origin.
11669          * @param scrollY Current vertical scroll origin.
11670          * @param oldScrollX Previous horizontal scroll origin.
11671          * @param oldScrollY Previous vertical scroll origin.
11672          */
11673         void onScrollChange(View v, int scrollX, int scrollY, int oldScrollX, int oldScrollY);
11674     }
11675
11676     /**
11677      * Interface definition for a callback to be invoked when the layout bounds of a view
11678      * changes due to layout processing.
11679      */
11680     public interface OnLayoutChangeListener {
11681         /**
11682          * Called when the layout bounds of a view changes due to layout processing.
11683          *
11684          * @param v The view whose bounds have changed.
11685          * @param left The new value of the view's left property.
11686          * @param top The new value of the view's top property.
11687          * @param right The new value of the view's right property.
11688          * @param bottom The new value of the view's bottom property.
11689          * @param oldLeft The previous value of the view's left property.
11690          * @param oldTop The previous value of the view's top property.
11691          * @param oldRight The previous value of the view's right property.
11692          * @param oldBottom The previous value of the view's bottom property.
11693          */
11694         void onLayoutChange(View v, int left, int top, int right, int bottom,
11695             int oldLeft, int oldTop, int oldRight, int oldBottom);
11696     }
11697
11698     /**
11699      * This is called during layout when the size of this view has changed. If
11700      * you were just added to the view hierarchy, you're called with the old
11701      * values of 0.
11702      *
11703      * @param w Current width of this view.
11704      * @param h Current height of this view.
11705      * @param oldw Old width of this view.
11706      * @param oldh Old height of this view.
11707      */
11708     protected void onSizeChanged(int w, int h, int oldw, int oldh) {
11709     }
11710
11711     /**
11712      * Called by draw to draw the child views. This may be overridden
11713      * by derived classes to gain control just before its children are drawn
11714      * (but after its own view has been drawn).
11715      * @param canvas the canvas on which to draw the view
11716      */
11717     protected void dispatchDraw(Canvas canvas) {
11718
11719     }
11720
11721     /**
11722      * Gets the parent of this view. Note that the parent is a
11723      * ViewParent and not necessarily a View.
11724      *
11725      * @return Parent of this view.
11726      */
11727     public final ViewParent getParent() {
11728         return mParent;
11729     }
11730
11731     /**
11732      * Set the horizontal scrolled position of your view. This will cause a call to
11733      * {@link #onScrollChanged(int, int, int, int)} and the view will be
11734      * invalidated.
11735      * @param value the x position to scroll to
11736      */
11737     public void setScrollX(int value) {
11738         scrollTo(value, mScrollY);
11739     }
11740
11741     /**
11742      * Set the vertical scrolled position of your view. This will cause a call to
11743      * {@link #onScrollChanged(int, int, int, int)} and the view will be
11744      * invalidated.
11745      * @param value the y position to scroll to
11746      */
11747     public void setScrollY(int value) {
11748         scrollTo(mScrollX, value);
11749     }
11750
11751     /**
11752      * Return the scrolled left position of this view. This is the left edge of
11753      * the displayed part of your view. You do not need to draw any pixels
11754      * farther left, since those are outside of the frame of your view on
11755      * screen.
11756      *
11757      * @return The left edge of the displayed part of your view, in pixels.
11758      */
11759     public final int getScrollX() {
11760         return mScrollX;
11761     }
11762
11763     /**
11764      * Return the scrolled top position of this view. This is the top edge of
11765      * the displayed part of your view. You do not need to draw any pixels above
11766      * it, since those are outside of the frame of your view on screen.
11767      *
11768      * @return The top edge of the displayed part of your view, in pixels.
11769      */
11770     public final int getScrollY() {
11771         return mScrollY;
11772     }
11773
11774     /**
11775      * Return the width of the your view.
11776      *
11777      * @return The width of your view, in pixels.
11778      */
11779     @ViewDebug.ExportedProperty(category = "layout")
11780     public final int getWidth() {
11781         return mRight - mLeft;
11782     }
11783
11784     /**
11785      * Return the height of your view.
11786      *
11787      * @return The height of your view, in pixels.
11788      */
11789     @ViewDebug.ExportedProperty(category = "layout")
11790     public final int getHeight() {
11791         return mBottom - mTop;
11792     }
11793
11794     /**
11795      * Return the visible drawing bounds of your view. Fills in the output
11796      * rectangle with the values from getScrollX(), getScrollY(),
11797      * getWidth(), and getHeight(). These bounds do not account for any
11798      * transformation properties currently set on the view, such as
11799      * {@link #setScaleX(float)} or {@link #setRotation(float)}.
11800      *
11801      * @param outRect The (scrolled) drawing bounds of the view.
11802      */
11803     public void getDrawingRect(Rect outRect) {
11804         outRect.left = mScrollX;
11805         outRect.top = mScrollY;
11806         outRect.right = mScrollX + (mRight - mLeft);
11807         outRect.bottom = mScrollY + (mBottom - mTop);
11808     }
11809
11810     /**
11811      * Like {@link #getMeasuredWidthAndState()}, but only returns the
11812      * raw width component (that is the result is masked by
11813      * {@link #MEASURED_SIZE_MASK}).
11814      *
11815      * @return The raw measured width of this view.
11816      */
11817     public final int getMeasuredWidth() {
11818         return mMeasuredWidth & MEASURED_SIZE_MASK;
11819     }
11820
11821     /**
11822      * Return the full width measurement information for this view as computed
11823      * by the most recent call to {@link #measure(int, int)}.  This result is a bit mask
11824      * as defined by {@link #MEASURED_SIZE_MASK} and {@link #MEASURED_STATE_TOO_SMALL}.
11825      * This should be used during measurement and layout calculations only. Use
11826      * {@link #getWidth()} to see how wide a view is after layout.
11827      *
11828      * @return The measured width of this view as a bit mask.
11829      */
11830     @ViewDebug.ExportedProperty(category = "measurement", flagMapping = {
11831             @ViewDebug.FlagToString(mask = MEASURED_STATE_MASK, equals = MEASURED_STATE_TOO_SMALL,
11832                     name = "MEASURED_STATE_TOO_SMALL"),
11833     })
11834     public final int getMeasuredWidthAndState() {
11835         return mMeasuredWidth;
11836     }
11837
11838     /**
11839      * Like {@link #getMeasuredHeightAndState()}, but only returns the
11840      * raw width component (that is the result is masked by
11841      * {@link #MEASURED_SIZE_MASK}).
11842      *
11843      * @return The raw measured height of this view.
11844      */
11845     public final int getMeasuredHeight() {
11846         return mMeasuredHeight & MEASURED_SIZE_MASK;
11847     }
11848
11849     /**
11850      * Return the full height measurement information for this view as computed
11851      * by the most recent call to {@link #measure(int, int)}.  This result is a bit mask
11852      * as defined by {@link #MEASURED_SIZE_MASK} and {@link #MEASURED_STATE_TOO_SMALL}.
11853      * This should be used during measurement and layout calculations only. Use
11854      * {@link #getHeight()} to see how wide a view is after layout.
11855      *
11856      * @return The measured width of this view as a bit mask.
11857      */
11858     @ViewDebug.ExportedProperty(category = "measurement", flagMapping = {
11859             @ViewDebug.FlagToString(mask = MEASURED_STATE_MASK, equals = MEASURED_STATE_TOO_SMALL,
11860                     name = "MEASURED_STATE_TOO_SMALL"),
11861     })
11862     public final int getMeasuredHeightAndState() {
11863         return mMeasuredHeight;
11864     }
11865
11866     /**
11867      * Return only the state bits of {@link #getMeasuredWidthAndState()}
11868      * and {@link #getMeasuredHeightAndState()}, combined into one integer.
11869      * The width component is in the regular bits {@link #MEASURED_STATE_MASK}
11870      * and the height component is at the shifted bits
11871      * {@link #MEASURED_HEIGHT_STATE_SHIFT}>>{@link #MEASURED_STATE_MASK}.
11872      */
11873     public final int getMeasuredState() {
11874         return (mMeasuredWidth&MEASURED_STATE_MASK)
11875                 | ((mMeasuredHeight>>MEASURED_HEIGHT_STATE_SHIFT)
11876                         & (MEASURED_STATE_MASK>>MEASURED_HEIGHT_STATE_SHIFT));
11877     }
11878
11879     /**
11880      * The transform matrix of this view, which is calculated based on the current
11881      * rotation, scale, and pivot properties.
11882      *
11883      * @see #getRotation()
11884      * @see #getScaleX()
11885      * @see #getScaleY()
11886      * @see #getPivotX()
11887      * @see #getPivotY()
11888      * @return The current transform matrix for the view
11889      */
11890     public Matrix getMatrix() {
11891         ensureTransformationInfo();
11892         final Matrix matrix = mTransformationInfo.mMatrix;
11893         mRenderNode.getMatrix(matrix);
11894         return matrix;
11895     }
11896
11897     /**
11898      * Returns true if the transform matrix is the identity matrix.
11899      * Recomputes the matrix if necessary.
11900      *
11901      * @return True if the transform matrix is the identity matrix, false otherwise.
11902      */
11903     final boolean hasIdentityMatrix() {
11904         return mRenderNode.hasIdentityMatrix();
11905     }
11906
11907     void ensureTransformationInfo() {
11908         if (mTransformationInfo == null) {
11909             mTransformationInfo = new TransformationInfo();
11910         }
11911     }
11912
11913     /**
11914      * Utility method to retrieve the inverse of the current mMatrix property.
11915      * We cache the matrix to avoid recalculating it when transform properties
11916      * have not changed.
11917      *
11918      * @return The inverse of the current matrix of this view.
11919      * @hide
11920      */
11921     public final Matrix getInverseMatrix() {
11922         ensureTransformationInfo();
11923         if (mTransformationInfo.mInverseMatrix == null) {
11924             mTransformationInfo.mInverseMatrix = new Matrix();
11925         }
11926         final Matrix matrix = mTransformationInfo.mInverseMatrix;
11927         mRenderNode.getInverseMatrix(matrix);
11928         return matrix;
11929     }
11930
11931     /**
11932      * Gets the distance along the Z axis from the camera to this view.
11933      *
11934      * @see #setCameraDistance(float)
11935      *
11936      * @return The distance along the Z axis.
11937      */
11938     public float getCameraDistance() {
11939         final float dpi = mResources.getDisplayMetrics().densityDpi;
11940         return -(mRenderNode.getCameraDistance() * dpi);
11941     }
11942
11943     /**
11944      * <p>Sets the distance along the Z axis (orthogonal to the X/Y plane on which
11945      * views are drawn) from the camera to this view. The camera's distance
11946      * affects 3D transformations, for instance rotations around the X and Y
11947      * axis. If the rotationX or rotationY properties are changed and this view is
11948      * large (more than half the size of the screen), it is recommended to always
11949      * use a camera distance that's greater than the height (X axis rotation) or
11950      * the width (Y axis rotation) of this view.</p>
11951      *
11952      * <p>The distance of the camera from the view plane can have an affect on the
11953      * perspective distortion of the view when it is rotated around the x or y axis.
11954      * For example, a large distance will result in a large viewing angle, and there
11955      * will not be much perspective distortion of the view as it rotates. A short
11956      * distance may cause much more perspective distortion upon rotation, and can
11957      * also result in some drawing artifacts if the rotated view ends up partially
11958      * behind the camera (which is why the recommendation is to use a distance at
11959      * least as far as the size of the view, if the view is to be rotated.)</p>
11960      *
11961      * <p>The distance is expressed in "depth pixels." The default distance depends
11962      * on the screen density. For instance, on a medium density display, the
11963      * default distance is 1280. On a high density display, the default distance
11964      * is 1920.</p>
11965      *
11966      * <p>If you want to specify a distance that leads to visually consistent
11967      * results across various densities, use the following formula:</p>
11968      * <pre>
11969      * float scale = context.getResources().getDisplayMetrics().density;
11970      * view.setCameraDistance(distance * scale);
11971      * </pre>
11972      *
11973      * <p>The density scale factor of a high density display is 1.5,
11974      * and 1920 = 1280 * 1.5.</p>
11975      *
11976      * @param distance The distance in "depth pixels", if negative the opposite
11977      *        value is used
11978      *
11979      * @see #setRotationX(float)
11980      * @see #setRotationY(float)
11981      */
11982     public void setCameraDistance(float distance) {
11983         final float dpi = mResources.getDisplayMetrics().densityDpi;
11984
11985         invalidateViewProperty(true, false);
11986         mRenderNode.setCameraDistance(-Math.abs(distance) / dpi);
11987         invalidateViewProperty(false, false);
11988
11989         invalidateParentIfNeededAndWasQuickRejected();
11990     }
11991
11992     /**
11993      * The degrees that the view is rotated around the pivot point.
11994      *
11995      * @see #setRotation(float)
11996      * @see #getPivotX()
11997      * @see #getPivotY()
11998      *
11999      * @return The degrees of rotation.
12000      */
12001     @ViewDebug.ExportedProperty(category = "drawing")
12002     public float getRotation() {
12003         return mRenderNode.getRotation();
12004     }
12005
12006     /**
12007      * Sets the degrees that the view is rotated around the pivot point. Increasing values
12008      * result in clockwise rotation.
12009      *
12010      * @param rotation The degrees of rotation.
12011      *
12012      * @see #getRotation()
12013      * @see #getPivotX()
12014      * @see #getPivotY()
12015      * @see #setRotationX(float)
12016      * @see #setRotationY(float)
12017      *
12018      * @attr ref android.R.styleable#View_rotation
12019      */
12020     public void setRotation(float rotation) {
12021         if (rotation != getRotation()) {
12022             // Double-invalidation is necessary to capture view's old and new areas
12023             invalidateViewProperty(true, false);
12024             mRenderNode.setRotation(rotation);
12025             invalidateViewProperty(false, true);
12026
12027             invalidateParentIfNeededAndWasQuickRejected();
12028             notifySubtreeAccessibilityStateChangedIfNeeded();
12029         }
12030     }
12031
12032     /**
12033      * The degrees that the view is rotated around the vertical axis through the pivot point.
12034      *
12035      * @see #getPivotX()
12036      * @see #getPivotY()
12037      * @see #setRotationY(float)
12038      *
12039      * @return The degrees of Y rotation.
12040      */
12041     @ViewDebug.ExportedProperty(category = "drawing")
12042     public float getRotationY() {
12043         return mRenderNode.getRotationY();
12044     }
12045
12046     /**
12047      * Sets the degrees that the view is rotated around the vertical axis through the pivot point.
12048      * Increasing values result in counter-clockwise rotation from the viewpoint of looking
12049      * down the y axis.
12050      *
12051      * When rotating large views, it is recommended to adjust the camera distance
12052      * accordingly. Refer to {@link #setCameraDistance(float)} for more information.
12053      *
12054      * @param rotationY The degrees of Y rotation.
12055      *
12056      * @see #getRotationY()
12057      * @see #getPivotX()
12058      * @see #getPivotY()
12059      * @see #setRotation(float)
12060      * @see #setRotationX(float)
12061      * @see #setCameraDistance(float)
12062      *
12063      * @attr ref android.R.styleable#View_rotationY
12064      */
12065     public void setRotationY(float rotationY) {
12066         if (rotationY != getRotationY()) {
12067             invalidateViewProperty(true, false);
12068             mRenderNode.setRotationY(rotationY);
12069             invalidateViewProperty(false, true);
12070
12071             invalidateParentIfNeededAndWasQuickRejected();
12072             notifySubtreeAccessibilityStateChangedIfNeeded();
12073         }
12074     }
12075
12076     /**
12077      * The degrees that the view is rotated around the horizontal axis through the pivot point.
12078      *
12079      * @see #getPivotX()
12080      * @see #getPivotY()
12081      * @see #setRotationX(float)
12082      *
12083      * @return The degrees of X rotation.
12084      */
12085     @ViewDebug.ExportedProperty(category = "drawing")
12086     public float getRotationX() {
12087         return mRenderNode.getRotationX();
12088     }
12089
12090     /**
12091      * Sets the degrees that the view is rotated around the horizontal axis through the pivot point.
12092      * Increasing values result in clockwise rotation from the viewpoint of looking down the
12093      * x axis.
12094      *
12095      * When rotating large views, it is recommended to adjust the camera distance
12096      * accordingly. Refer to {@link #setCameraDistance(float)} for more information.
12097      *
12098      * @param rotationX The degrees of X rotation.
12099      *
12100      * @see #getRotationX()
12101      * @see #getPivotX()
12102      * @see #getPivotY()
12103      * @see #setRotation(float)
12104      * @see #setRotationY(float)
12105      * @see #setCameraDistance(float)
12106      *
12107      * @attr ref android.R.styleable#View_rotationX
12108      */
12109     public void setRotationX(float rotationX) {
12110         if (rotationX != getRotationX()) {
12111             invalidateViewProperty(true, false);
12112             mRenderNode.setRotationX(rotationX);
12113             invalidateViewProperty(false, true);
12114
12115             invalidateParentIfNeededAndWasQuickRejected();
12116             notifySubtreeAccessibilityStateChangedIfNeeded();
12117         }
12118     }
12119
12120     /**
12121      * The amount that the view is scaled in x around the pivot point, as a proportion of
12122      * the view's unscaled width. A value of 1, the default, means that no scaling is applied.
12123      *
12124      * <p>By default, this is 1.0f.
12125      *
12126      * @see #getPivotX()
12127      * @see #getPivotY()
12128      * @return The scaling factor.
12129      */
12130     @ViewDebug.ExportedProperty(category = "drawing")
12131     public float getScaleX() {
12132         return mRenderNode.getScaleX();
12133     }
12134
12135     /**
12136      * Sets the amount that the view is scaled in x around the pivot point, as a proportion of
12137      * the view's unscaled width. A value of 1 means that no scaling is applied.
12138      *
12139      * @param scaleX The scaling factor.
12140      * @see #getPivotX()
12141      * @see #getPivotY()
12142      *
12143      * @attr ref android.R.styleable#View_scaleX
12144      */
12145     public void setScaleX(float scaleX) {
12146         if (scaleX != getScaleX()) {
12147             invalidateViewProperty(true, false);
12148             mRenderNode.setScaleX(scaleX);
12149             invalidateViewProperty(false, true);
12150
12151             invalidateParentIfNeededAndWasQuickRejected();
12152             notifySubtreeAccessibilityStateChangedIfNeeded();
12153         }
12154     }
12155
12156     /**
12157      * The amount that the view is scaled in y around the pivot point, as a proportion of
12158      * the view's unscaled height. A value of 1, the default, means that no scaling is applied.
12159      *
12160      * <p>By default, this is 1.0f.
12161      *
12162      * @see #getPivotX()
12163      * @see #getPivotY()
12164      * @return The scaling factor.
12165      */
12166     @ViewDebug.ExportedProperty(category = "drawing")
12167     public float getScaleY() {
12168         return mRenderNode.getScaleY();
12169     }
12170
12171     /**
12172      * Sets the amount that the view is scaled in Y around the pivot point, as a proportion of
12173      * the view's unscaled width. A value of 1 means that no scaling is applied.
12174      *
12175      * @param scaleY The scaling factor.
12176      * @see #getPivotX()
12177      * @see #getPivotY()
12178      *
12179      * @attr ref android.R.styleable#View_scaleY
12180      */
12181     public void setScaleY(float scaleY) {
12182         if (scaleY != getScaleY()) {
12183             invalidateViewProperty(true, false);
12184             mRenderNode.setScaleY(scaleY);
12185             invalidateViewProperty(false, true);
12186
12187             invalidateParentIfNeededAndWasQuickRejected();
12188             notifySubtreeAccessibilityStateChangedIfNeeded();
12189         }
12190     }
12191
12192     /**
12193      * The x location of the point around which the view is {@link #setRotation(float) rotated}
12194      * and {@link #setScaleX(float) scaled}.
12195      *
12196      * @see #getRotation()
12197      * @see #getScaleX()
12198      * @see #getScaleY()
12199      * @see #getPivotY()
12200      * @return The x location of the pivot point.
12201      *
12202      * @attr ref android.R.styleable#View_transformPivotX
12203      */
12204     @ViewDebug.ExportedProperty(category = "drawing")
12205     public float getPivotX() {
12206         return mRenderNode.getPivotX();
12207     }
12208
12209     /**
12210      * Sets the x location of the point around which the view is
12211      * {@link #setRotation(float) rotated} and {@link #setScaleX(float) scaled}.
12212      * By default, the pivot point is centered on the object.
12213      * Setting this property disables this behavior and causes the view to use only the
12214      * explicitly set pivotX and pivotY values.
12215      *
12216      * @param pivotX The x location of the pivot point.
12217      * @see #getRotation()
12218      * @see #getScaleX()
12219      * @see #getScaleY()
12220      * @see #getPivotY()
12221      *
12222      * @attr ref android.R.styleable#View_transformPivotX
12223      */
12224     public void setPivotX(float pivotX) {
12225         if (!mRenderNode.isPivotExplicitlySet() || pivotX != getPivotX()) {
12226             invalidateViewProperty(true, false);
12227             mRenderNode.setPivotX(pivotX);
12228             invalidateViewProperty(false, true);
12229
12230             invalidateParentIfNeededAndWasQuickRejected();
12231         }
12232     }
12233
12234     /**
12235      * The y location of the point around which the view is {@link #setRotation(float) rotated}
12236      * and {@link #setScaleY(float) scaled}.
12237      *
12238      * @see #getRotation()
12239      * @see #getScaleX()
12240      * @see #getScaleY()
12241      * @see #getPivotY()
12242      * @return The y location of the pivot point.
12243      *
12244      * @attr ref android.R.styleable#View_transformPivotY
12245      */
12246     @ViewDebug.ExportedProperty(category = "drawing")
12247     public float getPivotY() {
12248         return mRenderNode.getPivotY();
12249     }
12250
12251     /**
12252      * Sets the y location of the point around which the view is {@link #setRotation(float) rotated}
12253      * and {@link #setScaleY(float) scaled}. By default, the pivot point is centered on the object.
12254      * Setting this property disables this behavior and causes the view to use only the
12255      * explicitly set pivotX and pivotY values.
12256      *
12257      * @param pivotY The y location of the pivot point.
12258      * @see #getRotation()
12259      * @see #getScaleX()
12260      * @see #getScaleY()
12261      * @see #getPivotY()
12262      *
12263      * @attr ref android.R.styleable#View_transformPivotY
12264      */
12265     public void setPivotY(float pivotY) {
12266         if (!mRenderNode.isPivotExplicitlySet() || pivotY != getPivotY()) {
12267             invalidateViewProperty(true, false);
12268             mRenderNode.setPivotY(pivotY);
12269             invalidateViewProperty(false, true);
12270
12271             invalidateParentIfNeededAndWasQuickRejected();
12272         }
12273     }
12274
12275     /**
12276      * The opacity of the view. This is a value from 0 to 1, where 0 means the view is
12277      * completely transparent and 1 means the view is completely opaque.
12278      *
12279      * <p>By default this is 1.0f.
12280      * @return The opacity of the view.
12281      */
12282     @ViewDebug.ExportedProperty(category = "drawing")
12283     public float getAlpha() {
12284         return mTransformationInfo != null ? mTransformationInfo.mAlpha : 1;
12285     }
12286
12287     /**
12288      * Sets the behavior for overlapping rendering for this view (see {@link
12289      * #hasOverlappingRendering()} for more details on this behavior). Calling this method
12290      * is an alternative to overriding {@link #hasOverlappingRendering()} in a subclass,
12291      * providing the value which is then used internally. That is, when {@link
12292      * #forceHasOverlappingRendering(boolean)} is called, the value of {@link
12293      * #hasOverlappingRendering()} is ignored and the value passed into this method is used
12294      * instead.
12295      *
12296      * @param hasOverlappingRendering The value for overlapping rendering to be used internally
12297      * instead of that returned by {@link #hasOverlappingRendering()}.
12298      *
12299      * @attr ref android.R.styleable#View_forceHasOverlappingRendering
12300      */
12301     public void forceHasOverlappingRendering(boolean hasOverlappingRendering) {
12302         mPrivateFlags3 |= PFLAG3_HAS_OVERLAPPING_RENDERING_FORCED;
12303         if (hasOverlappingRendering) {
12304             mPrivateFlags3 |= PFLAG3_OVERLAPPING_RENDERING_FORCED_VALUE;
12305         } else {
12306             mPrivateFlags3 &= ~PFLAG3_OVERLAPPING_RENDERING_FORCED_VALUE;
12307         }
12308     }
12309
12310     /**
12311      * Returns the value for overlapping rendering that is used internally. This is either
12312      * the value passed into {@link #forceHasOverlappingRendering(boolean)}, if called, or
12313      * the return value of {@link #hasOverlappingRendering()}, otherwise.
12314      *
12315      * @return The value for overlapping rendering being used internally.
12316      */
12317     public final boolean getHasOverlappingRendering() {
12318         return (mPrivateFlags3 & PFLAG3_HAS_OVERLAPPING_RENDERING_FORCED) != 0 ?
12319                 (mPrivateFlags3 & PFLAG3_OVERLAPPING_RENDERING_FORCED_VALUE) != 0 :
12320                 hasOverlappingRendering();
12321     }
12322
12323     /**
12324      * Returns whether this View has content which overlaps.
12325      *
12326      * <p>This function, intended to be overridden by specific View types, is an optimization when
12327      * alpha is set on a view. If rendering overlaps in a view with alpha < 1, that view is drawn to
12328      * an offscreen buffer and then composited into place, which can be expensive. If the view has
12329      * no overlapping rendering, the view can draw each primitive with the appropriate alpha value
12330      * directly. An example of overlapping rendering is a TextView with a background image, such as
12331      * a Button. An example of non-overlapping rendering is a TextView with no background, or an
12332      * ImageView with only the foreground image. The default implementation returns true; subclasses
12333      * should override if they have cases which can be optimized.</p>
12334      *
12335      * <p>The current implementation of the saveLayer and saveLayerAlpha methods in {@link Canvas}
12336      * necessitates that a View return true if it uses the methods internally without passing the
12337      * {@link Canvas#CLIP_TO_LAYER_SAVE_FLAG}.</p>
12338      *
12339      * <p><strong>Note:</strong> The return value of this method is ignored if {@link
12340      * #forceHasOverlappingRendering(boolean)} has been called on this view.</p>
12341      *
12342      * @return true if the content in this view might overlap, false otherwise.
12343      */
12344     @ViewDebug.ExportedProperty(category = "drawing")
12345     public boolean hasOverlappingRendering() {
12346         return true;
12347     }
12348
12349     /**
12350      * Sets the opacity of the view to a value from 0 to 1, where 0 means the view is
12351      * completely transparent and 1 means the view is completely opaque.
12352      *
12353      * <p class="note"><strong>Note:</strong> setting alpha to a translucent value (0 < alpha < 1)
12354      * can have significant performance implications, especially for large views. It is best to use
12355      * the alpha property sparingly and transiently, as in the case of fading animations.</p>
12356      *
12357      * <p>For a view with a frequently changing alpha, such as during a fading animation, it is
12358      * strongly recommended for performance reasons to either override
12359      * {@link #hasOverlappingRendering()} to return <code>false</code> if appropriate, or setting a
12360      * {@link #setLayerType(int, android.graphics.Paint) layer type} on the view for the duration
12361      * of the animation. On versions {@link android.os.Build.VERSION_CODES#M} and below,
12362      * the default path for rendering an unlayered View with alpha could add multiple milliseconds
12363      * of rendering cost, even for simple or small views. Starting with
12364      * {@link android.os.Build.VERSION_CODES#M}, {@link #LAYER_TYPE_HARDWARE} is automatically
12365      * applied to the view at the rendering level.</p>
12366      *
12367      * <p>If this view overrides {@link #onSetAlpha(int)} to return true, then this view is
12368      * responsible for applying the opacity itself.</p>
12369      *
12370      * <p>On versions {@link android.os.Build.VERSION_CODES#LOLLIPOP_MR1} and below, note that if
12371      * the view is backed by a {@link #setLayerType(int, android.graphics.Paint) layer} and is
12372      * associated with a {@link #setLayerPaint(android.graphics.Paint) layer paint}, setting an
12373      * alpha value less than 1.0 will supersede the alpha of the layer paint.</p>
12374      *
12375      * <p>Starting with {@link android.os.Build.VERSION_CODES#M}, setting a translucent alpha
12376      * value will clip a View to its bounds, unless the View returns <code>false</code> from
12377      * {@link #hasOverlappingRendering}.</p>
12378      *
12379      * @param alpha The opacity of the view.
12380      *
12381      * @see #hasOverlappingRendering()
12382      * @see #setLayerType(int, android.graphics.Paint)
12383      *
12384      * @attr ref android.R.styleable#View_alpha
12385      */
12386     public void setAlpha(@FloatRange(from=0.0, to=1.0) float alpha) {
12387         ensureTransformationInfo();
12388         if (mTransformationInfo.mAlpha != alpha) {
12389             // Report visibility changes, which can affect children, to accessibility
12390             if ((alpha == 0) ^ (mTransformationInfo.mAlpha == 0)) {
12391                 notifySubtreeAccessibilityStateChangedIfNeeded();
12392             }
12393             mTransformationInfo.mAlpha = alpha;
12394             if (onSetAlpha((int) (alpha * 255))) {
12395                 mPrivateFlags |= PFLAG_ALPHA_SET;
12396                 // subclass is handling alpha - don't optimize rendering cache invalidation
12397                 invalidateParentCaches();
12398                 invalidate(true);
12399             } else {
12400                 mPrivateFlags &= ~PFLAG_ALPHA_SET;
12401                 invalidateViewProperty(true, false);
12402                 mRenderNode.setAlpha(getFinalAlpha());
12403             }
12404         }
12405     }
12406
12407     /**
12408      * Faster version of setAlpha() which performs the same steps except there are
12409      * no calls to invalidate(). The caller of this function should perform proper invalidation
12410      * on the parent and this object. The return value indicates whether the subclass handles
12411      * alpha (the return value for onSetAlpha()).
12412      *
12413      * @param alpha The new value for the alpha property
12414      * @return true if the View subclass handles alpha (the return value for onSetAlpha()) and
12415      *         the new value for the alpha property is different from the old value
12416      */
12417     boolean setAlphaNoInvalidation(float alpha) {
12418         ensureTransformationInfo();
12419         if (mTransformationInfo.mAlpha != alpha) {
12420             mTransformationInfo.mAlpha = alpha;
12421             boolean subclassHandlesAlpha = onSetAlpha((int) (alpha * 255));
12422             if (subclassHandlesAlpha) {
12423                 mPrivateFlags |= PFLAG_ALPHA_SET;
12424                 return true;
12425             } else {
12426                 mPrivateFlags &= ~PFLAG_ALPHA_SET;
12427                 mRenderNode.setAlpha(getFinalAlpha());
12428             }
12429         }
12430         return false;
12431     }
12432
12433     /**
12434      * This property is hidden and intended only for use by the Fade transition, which
12435      * animates it to produce a visual translucency that does not side-effect (or get
12436      * affected by) the real alpha property. This value is composited with the other
12437      * alpha value (and the AlphaAnimation value, when that is present) to produce
12438      * a final visual translucency result, which is what is passed into the DisplayList.
12439      *
12440      * @hide
12441      */
12442     public void setTransitionAlpha(float alpha) {
12443         ensureTransformationInfo();
12444         if (mTransformationInfo.mTransitionAlpha != alpha) {
12445             mTransformationInfo.mTransitionAlpha = alpha;
12446             mPrivateFlags &= ~PFLAG_ALPHA_SET;
12447             invalidateViewProperty(true, false);
12448             mRenderNode.setAlpha(getFinalAlpha());
12449         }
12450     }
12451
12452     /**
12453      * Calculates the visual alpha of this view, which is a combination of the actual
12454      * alpha value and the transitionAlpha value (if set).
12455      */
12456     private float getFinalAlpha() {
12457         if (mTransformationInfo != null) {
12458             return mTransformationInfo.mAlpha * mTransformationInfo.mTransitionAlpha;
12459         }
12460         return 1;
12461     }
12462
12463     /**
12464      * This property is hidden and intended only for use by the Fade transition, which
12465      * animates it to produce a visual translucency that does not side-effect (or get
12466      * affected by) the real alpha property. This value is composited with the other
12467      * alpha value (and the AlphaAnimation value, when that is present) to produce
12468      * a final visual translucency result, which is what is passed into the DisplayList.
12469      *
12470      * @hide
12471      */
12472     @ViewDebug.ExportedProperty(category = "drawing")
12473     public float getTransitionAlpha() {
12474         return mTransformationInfo != null ? mTransformationInfo.mTransitionAlpha : 1;
12475     }
12476
12477     /**
12478      * Top position of this view relative to its parent.
12479      *
12480      * @return The top of this view, in pixels.
12481      */
12482     @ViewDebug.CapturedViewProperty
12483     public final int getTop() {
12484         return mTop;
12485     }
12486
12487     /**
12488      * Sets the top position of this view relative to its parent. This method is meant to be called
12489      * by the layout system and should not generally be called otherwise, because the property
12490      * may be changed at any time by the layout.
12491      *
12492      * @param top The top of this view, in pixels.
12493      */
12494     public final void setTop(int top) {
12495         if (top != mTop) {
12496             final boolean matrixIsIdentity = hasIdentityMatrix();
12497             if (matrixIsIdentity) {
12498                 if (mAttachInfo != null) {
12499                     int minTop;
12500                     int yLoc;
12501                     if (top < mTop) {
12502                         minTop = top;
12503                         yLoc = top - mTop;
12504                     } else {
12505                         minTop = mTop;
12506                         yLoc = 0;
12507                     }
12508                     invalidate(0, yLoc, mRight - mLeft, mBottom - minTop);
12509                 }
12510             } else {
12511                 // Double-invalidation is necessary to capture view's old and new areas
12512                 invalidate(true);
12513             }
12514
12515             int width = mRight - mLeft;
12516             int oldHeight = mBottom - mTop;
12517
12518             mTop = top;
12519             mRenderNode.setTop(mTop);
12520
12521             sizeChange(width, mBottom - mTop, width, oldHeight);
12522
12523             if (!matrixIsIdentity) {
12524                 mPrivateFlags |= PFLAG_DRAWN; // force another invalidation with the new orientation
12525                 invalidate(true);
12526             }
12527             mBackgroundSizeChanged = true;
12528             if (mForegroundInfo != null) {
12529                 mForegroundInfo.mBoundsChanged = true;
12530             }
12531             invalidateParentIfNeeded();
12532             if ((mPrivateFlags2 & PFLAG2_VIEW_QUICK_REJECTED) == PFLAG2_VIEW_QUICK_REJECTED) {
12533                 // View was rejected last time it was drawn by its parent; this may have changed
12534                 invalidateParentIfNeeded();
12535             }
12536         }
12537     }
12538
12539     /**
12540      * Bottom position of this view relative to its parent.
12541      *
12542      * @return The bottom of this view, in pixels.
12543      */
12544     @ViewDebug.CapturedViewProperty
12545     public final int getBottom() {
12546         return mBottom;
12547     }
12548
12549     /**
12550      * True if this view has changed since the last time being drawn.
12551      *
12552      * @return The dirty state of this view.
12553      */
12554     public boolean isDirty() {
12555         return (mPrivateFlags & PFLAG_DIRTY_MASK) != 0;
12556     }
12557
12558     /**
12559      * Sets the bottom position of this view relative to its parent. This method is meant to be
12560      * called by the layout system and should not generally be called otherwise, because the
12561      * property may be changed at any time by the layout.
12562      *
12563      * @param bottom The bottom of this view, in pixels.
12564      */
12565     public final void setBottom(int bottom) {
12566         if (bottom != mBottom) {
12567             final boolean matrixIsIdentity = hasIdentityMatrix();
12568             if (matrixIsIdentity) {
12569                 if (mAttachInfo != null) {
12570                     int maxBottom;
12571                     if (bottom < mBottom) {
12572                         maxBottom = mBottom;
12573                     } else {
12574                         maxBottom = bottom;
12575                     }
12576                     invalidate(0, 0, mRight - mLeft, maxBottom - mTop);
12577                 }
12578             } else {
12579                 // Double-invalidation is necessary to capture view's old and new areas
12580                 invalidate(true);
12581             }
12582
12583             int width = mRight - mLeft;
12584             int oldHeight = mBottom - mTop;
12585
12586             mBottom = bottom;
12587             mRenderNode.setBottom(mBottom);
12588
12589             sizeChange(width, mBottom - mTop, width, oldHeight);
12590
12591             if (!matrixIsIdentity) {
12592                 mPrivateFlags |= PFLAG_DRAWN; // force another invalidation with the new orientation
12593                 invalidate(true);
12594             }
12595             mBackgroundSizeChanged = true;
12596             if (mForegroundInfo != null) {
12597                 mForegroundInfo.mBoundsChanged = true;
12598             }
12599             invalidateParentIfNeeded();
12600             if ((mPrivateFlags2 & PFLAG2_VIEW_QUICK_REJECTED) == PFLAG2_VIEW_QUICK_REJECTED) {
12601                 // View was rejected last time it was drawn by its parent; this may have changed
12602                 invalidateParentIfNeeded();
12603             }
12604         }
12605     }
12606
12607     /**
12608      * Left position of this view relative to its parent.
12609      *
12610      * @return The left edge of this view, in pixels.
12611      */
12612     @ViewDebug.CapturedViewProperty
12613     public final int getLeft() {
12614         return mLeft;
12615     }
12616
12617     /**
12618      * Sets the left position of this view relative to its parent. This method is meant to be called
12619      * by the layout system and should not generally be called otherwise, because the property
12620      * may be changed at any time by the layout.
12621      *
12622      * @param left The left of this view, in pixels.
12623      */
12624     public final void setLeft(int left) {
12625         if (left != mLeft) {
12626             final boolean matrixIsIdentity = hasIdentityMatrix();
12627             if (matrixIsIdentity) {
12628                 if (mAttachInfo != null) {
12629                     int minLeft;
12630                     int xLoc;
12631                     if (left < mLeft) {
12632                         minLeft = left;
12633                         xLoc = left - mLeft;
12634                     } else {
12635                         minLeft = mLeft;
12636                         xLoc = 0;
12637                     }
12638                     invalidate(xLoc, 0, mRight - minLeft, mBottom - mTop);
12639                 }
12640             } else {
12641                 // Double-invalidation is necessary to capture view's old and new areas
12642                 invalidate(true);
12643             }
12644
12645             int oldWidth = mRight - mLeft;
12646             int height = mBottom - mTop;
12647
12648             mLeft = left;
12649             mRenderNode.setLeft(left);
12650
12651             sizeChange(mRight - mLeft, height, oldWidth, height);
12652
12653             if (!matrixIsIdentity) {
12654                 mPrivateFlags |= PFLAG_DRAWN; // force another invalidation with the new orientation
12655                 invalidate(true);
12656             }
12657             mBackgroundSizeChanged = true;
12658             if (mForegroundInfo != null) {
12659                 mForegroundInfo.mBoundsChanged = true;
12660             }
12661             invalidateParentIfNeeded();
12662             if ((mPrivateFlags2 & PFLAG2_VIEW_QUICK_REJECTED) == PFLAG2_VIEW_QUICK_REJECTED) {
12663                 // View was rejected last time it was drawn by its parent; this may have changed
12664                 invalidateParentIfNeeded();
12665             }
12666         }
12667     }
12668
12669     /**
12670      * Right position of this view relative to its parent.
12671      *
12672      * @return The right edge of this view, in pixels.
12673      */
12674     @ViewDebug.CapturedViewProperty
12675     public final int getRight() {
12676         return mRight;
12677     }
12678
12679     /**
12680      * Sets the right position of this view relative to its parent. This method is meant to be called
12681      * by the layout system and should not generally be called otherwise, because the property
12682      * may be changed at any time by the layout.
12683      *
12684      * @param right The right of this view, in pixels.
12685      */
12686     public final void setRight(int right) {
12687         if (right != mRight) {
12688             final boolean matrixIsIdentity = hasIdentityMatrix();
12689             if (matrixIsIdentity) {
12690                 if (mAttachInfo != null) {
12691                     int maxRight;
12692                     if (right < mRight) {
12693                         maxRight = mRight;
12694                     } else {
12695                         maxRight = right;
12696                     }
12697                     invalidate(0, 0, maxRight - mLeft, mBottom - mTop);
12698                 }
12699             } else {
12700                 // Double-invalidation is necessary to capture view's old and new areas
12701                 invalidate(true);
12702             }
12703
12704             int oldWidth = mRight - mLeft;
12705             int height = mBottom - mTop;
12706
12707             mRight = right;
12708             mRenderNode.setRight(mRight);
12709
12710             sizeChange(mRight - mLeft, height, oldWidth, height);
12711
12712             if (!matrixIsIdentity) {
12713                 mPrivateFlags |= PFLAG_DRAWN; // force another invalidation with the new orientation
12714                 invalidate(true);
12715             }
12716             mBackgroundSizeChanged = true;
12717             if (mForegroundInfo != null) {
12718                 mForegroundInfo.mBoundsChanged = true;
12719             }
12720             invalidateParentIfNeeded();
12721             if ((mPrivateFlags2 & PFLAG2_VIEW_QUICK_REJECTED) == PFLAG2_VIEW_QUICK_REJECTED) {
12722                 // View was rejected last time it was drawn by its parent; this may have changed
12723                 invalidateParentIfNeeded();
12724             }
12725         }
12726     }
12727
12728     /**
12729      * The visual x position of this view, in pixels. This is equivalent to the
12730      * {@link #setTranslationX(float) translationX} property plus the current
12731      * {@link #getLeft() left} property.
12732      *
12733      * @return The visual x position of this view, in pixels.
12734      */
12735     @ViewDebug.ExportedProperty(category = "drawing")
12736     public float getX() {
12737         return mLeft + getTranslationX();
12738     }
12739
12740     /**
12741      * Sets the visual x position of this view, in pixels. This is equivalent to setting the
12742      * {@link #setTranslationX(float) translationX} property to be the difference between
12743      * the x value passed in and the current {@link #getLeft() left} property.
12744      *
12745      * @param x The visual x position of this view, in pixels.
12746      */
12747     public void setX(float x) {
12748         setTranslationX(x - mLeft);
12749     }
12750
12751     /**
12752      * The visual y position of this view, in pixels. This is equivalent to the
12753      * {@link #setTranslationY(float) translationY} property plus the current
12754      * {@link #getTop() top} property.
12755      *
12756      * @return The visual y position of this view, in pixels.
12757      */
12758     @ViewDebug.ExportedProperty(category = "drawing")
12759     public float getY() {
12760         return mTop + getTranslationY();
12761     }
12762
12763     /**
12764      * Sets the visual y position of this view, in pixels. This is equivalent to setting the
12765      * {@link #setTranslationY(float) translationY} property to be the difference between
12766      * the y value passed in and the current {@link #getTop() top} property.
12767      *
12768      * @param y The visual y position of this view, in pixels.
12769      */
12770     public void setY(float y) {
12771         setTranslationY(y - mTop);
12772     }
12773
12774     /**
12775      * The visual z position of this view, in pixels. This is equivalent to the
12776      * {@link #setTranslationZ(float) translationZ} property plus the current
12777      * {@link #getElevation() elevation} property.
12778      *
12779      * @return The visual z position of this view, in pixels.
12780      */
12781     @ViewDebug.ExportedProperty(category = "drawing")
12782     public float getZ() {
12783         return getElevation() + getTranslationZ();
12784     }
12785
12786     /**
12787      * Sets the visual z position of this view, in pixels. This is equivalent to setting the
12788      * {@link #setTranslationZ(float) translationZ} property to be the difference between
12789      * the x value passed in and the current {@link #getElevation() elevation} property.
12790      *
12791      * @param z The visual z position of this view, in pixels.
12792      */
12793     public void setZ(float z) {
12794         setTranslationZ(z - getElevation());
12795     }
12796
12797     /**
12798      * The base elevation of this view relative to its parent, in pixels.
12799      *
12800      * @return The base depth position of the view, in pixels.
12801      */
12802     @ViewDebug.ExportedProperty(category = "drawing")
12803     public float getElevation() {
12804         return mRenderNode.getElevation();
12805     }
12806
12807     /**
12808      * Sets the base elevation of this view, in pixels.
12809      *
12810      * @attr ref android.R.styleable#View_elevation
12811      */
12812     public void setElevation(float elevation) {
12813         if (elevation != getElevation()) {
12814             invalidateViewProperty(true, false);
12815             mRenderNode.setElevation(elevation);
12816             invalidateViewProperty(false, true);
12817
12818             invalidateParentIfNeededAndWasQuickRejected();
12819         }
12820     }
12821
12822     /**
12823      * The horizontal location of this view relative to its {@link #getLeft() left} position.
12824      * This position is post-layout, in addition to wherever the object's
12825      * layout placed it.
12826      *
12827      * @return The horizontal position of this view relative to its left position, in pixels.
12828      */
12829     @ViewDebug.ExportedProperty(category = "drawing")
12830     public float getTranslationX() {
12831         return mRenderNode.getTranslationX();
12832     }
12833
12834     /**
12835      * Sets the horizontal location of this view relative to its {@link #getLeft() left} position.
12836      * This effectively positions the object post-layout, in addition to wherever the object's
12837      * layout placed it.
12838      *
12839      * @param translationX The horizontal position of this view relative to its left position,
12840      * in pixels.
12841      *
12842      * @attr ref android.R.styleable#View_translationX
12843      */
12844     public void setTranslationX(float translationX) {
12845         if (translationX != getTranslationX()) {
12846             invalidateViewProperty(true, false);
12847             mRenderNode.setTranslationX(translationX);
12848             invalidateViewProperty(false, true);
12849
12850             invalidateParentIfNeededAndWasQuickRejected();
12851             notifySubtreeAccessibilityStateChangedIfNeeded();
12852         }
12853     }
12854
12855     /**
12856      * The vertical location of this view relative to its {@link #getTop() top} position.
12857      * This position is post-layout, in addition to wherever the object's
12858      * layout placed it.
12859      *
12860      * @return The vertical position of this view relative to its top position,
12861      * in pixels.
12862      */
12863     @ViewDebug.ExportedProperty(category = "drawing")
12864     public float getTranslationY() {
12865         return mRenderNode.getTranslationY();
12866     }
12867
12868     /**
12869      * Sets the vertical location of this view relative to its {@link #getTop() top} position.
12870      * This effectively positions the object post-layout, in addition to wherever the object's
12871      * layout placed it.
12872      *
12873      * @param translationY The vertical position of this view relative to its top position,
12874      * in pixels.
12875      *
12876      * @attr ref android.R.styleable#View_translationY
12877      */
12878     public void setTranslationY(float translationY) {
12879         if (translationY != getTranslationY()) {
12880             invalidateViewProperty(true, false);
12881             mRenderNode.setTranslationY(translationY);
12882             invalidateViewProperty(false, true);
12883
12884             invalidateParentIfNeededAndWasQuickRejected();
12885             notifySubtreeAccessibilityStateChangedIfNeeded();
12886         }
12887     }
12888
12889     /**
12890      * The depth location of this view relative to its {@link #getElevation() elevation}.
12891      *
12892      * @return The depth of this view relative to its elevation.
12893      */
12894     @ViewDebug.ExportedProperty(category = "drawing")
12895     public float getTranslationZ() {
12896         return mRenderNode.getTranslationZ();
12897     }
12898
12899     /**
12900      * Sets the depth location of this view relative to its {@link #getElevation() elevation}.
12901      *
12902      * @attr ref android.R.styleable#View_translationZ
12903      */
12904     public void setTranslationZ(float translationZ) {
12905         if (translationZ != getTranslationZ()) {
12906             invalidateViewProperty(true, false);
12907             mRenderNode.setTranslationZ(translationZ);
12908             invalidateViewProperty(false, true);
12909
12910             invalidateParentIfNeededAndWasQuickRejected();
12911         }
12912     }
12913
12914     /** @hide */
12915     public void setAnimationMatrix(Matrix matrix) {
12916         invalidateViewProperty(true, false);
12917         mRenderNode.setAnimationMatrix(matrix);
12918         invalidateViewProperty(false, true);
12919
12920         invalidateParentIfNeededAndWasQuickRejected();
12921     }
12922
12923     /**
12924      * Returns the current StateListAnimator if exists.
12925      *
12926      * @return StateListAnimator or null if it does not exists
12927      * @see    #setStateListAnimator(android.animation.StateListAnimator)
12928      */
12929     public StateListAnimator getStateListAnimator() {
12930         return mStateListAnimator;
12931     }
12932
12933     /**
12934      * Attaches the provided StateListAnimator to this View.
12935      * <p>
12936      * Any previously attached StateListAnimator will be detached.
12937      *
12938      * @param stateListAnimator The StateListAnimator to update the view
12939      * @see android.animation.StateListAnimator
12940      */
12941     public void setStateListAnimator(StateListAnimator stateListAnimator) {
12942         if (mStateListAnimator == stateListAnimator) {
12943             return;
12944         }
12945         if (mStateListAnimator != null) {
12946             mStateListAnimator.setTarget(null);
12947         }
12948         mStateListAnimator = stateListAnimator;
12949         if (stateListAnimator != null) {
12950             stateListAnimator.setTarget(this);
12951             if (isAttachedToWindow()) {
12952                 stateListAnimator.setState(getDrawableState());
12953             }
12954         }
12955     }
12956
12957     /**
12958      * Returns whether the Outline should be used to clip the contents of the View.
12959      * <p>
12960      * Note that this flag will only be respected if the View's Outline returns true from
12961      * {@link Outline#canClip()}.
12962      *
12963      * @see #setOutlineProvider(ViewOutlineProvider)
12964      * @see #setClipToOutline(boolean)
12965      */
12966     public final boolean getClipToOutline() {
12967         return mRenderNode.getClipToOutline();
12968     }
12969
12970     /**
12971      * Sets whether the View's Outline should be used to clip the contents of the View.
12972      * <p>
12973      * Only a single non-rectangular clip can be applied on a View at any time.
12974      * Circular clips from a {@link ViewAnimationUtils#createCircularReveal(View, int, int, float, float)
12975      * circular reveal} animation take priority over Outline clipping, and
12976      * child Outline clipping takes priority over Outline clipping done by a
12977      * parent.
12978      * <p>
12979      * Note that this flag will only be respected if the View's Outline returns true from
12980      * {@link Outline#canClip()}.
12981      *
12982      * @see #setOutlineProvider(ViewOutlineProvider)
12983      * @see #getClipToOutline()
12984      */
12985     public void setClipToOutline(boolean clipToOutline) {
12986         damageInParent();
12987         if (getClipToOutline() != clipToOutline) {
12988             mRenderNode.setClipToOutline(clipToOutline);
12989         }
12990     }
12991
12992     // correspond to the enum values of View_outlineProvider
12993     private static final int PROVIDER_BACKGROUND = 0;
12994     private static final int PROVIDER_NONE = 1;
12995     private static final int PROVIDER_BOUNDS = 2;
12996     private static final int PROVIDER_PADDED_BOUNDS = 3;
12997     private void setOutlineProviderFromAttribute(int providerInt) {
12998         switch (providerInt) {
12999             case PROVIDER_BACKGROUND:
13000                 setOutlineProvider(ViewOutlineProvider.BACKGROUND);
13001                 break;
13002             case PROVIDER_NONE:
13003                 setOutlineProvider(null);
13004                 break;
13005             case PROVIDER_BOUNDS:
13006                 setOutlineProvider(ViewOutlineProvider.BOUNDS);
13007                 break;
13008             case PROVIDER_PADDED_BOUNDS:
13009                 setOutlineProvider(ViewOutlineProvider.PADDED_BOUNDS);
13010                 break;
13011         }
13012     }
13013
13014     /**
13015      * Sets the {@link ViewOutlineProvider} of the view, which generates the Outline that defines
13016      * the shape of the shadow it casts, and enables outline clipping.
13017      * <p>
13018      * The default ViewOutlineProvider, {@link ViewOutlineProvider#BACKGROUND}, queries the Outline
13019      * from the View's background drawable, via {@link Drawable#getOutline(Outline)}. Changing the
13020      * outline provider with this method allows this behavior to be overridden.
13021      * <p>
13022      * If the ViewOutlineProvider is null, if querying it for an outline returns false,
13023      * or if the produced Outline is {@link Outline#isEmpty()}, shadows will not be cast.
13024      * <p>
13025      * Only outlines that return true from {@link Outline#canClip()} may be used for clipping.
13026      *
13027      * @see #setClipToOutline(boolean)
13028      * @see #getClipToOutline()
13029      * @see #getOutlineProvider()
13030      */
13031     public void setOutlineProvider(ViewOutlineProvider provider) {
13032         mOutlineProvider = provider;
13033         invalidateOutline();
13034     }
13035
13036     /**
13037      * Returns the current {@link ViewOutlineProvider} of the view, which generates the Outline
13038      * that defines the shape of the shadow it casts, and enables outline clipping.
13039      *
13040      * @see #setOutlineProvider(ViewOutlineProvider)
13041      */
13042     public ViewOutlineProvider getOutlineProvider() {
13043         return mOutlineProvider;
13044     }
13045
13046     /**
13047      * Called to rebuild this View's Outline from its {@link ViewOutlineProvider outline provider}
13048      *
13049      * @see #setOutlineProvider(ViewOutlineProvider)
13050      */
13051     public void invalidateOutline() {
13052         rebuildOutline();
13053
13054         notifySubtreeAccessibilityStateChangedIfNeeded();
13055         invalidateViewProperty(false, false);
13056     }
13057
13058     /**
13059      * Internal version of {@link #invalidateOutline()} which invalidates the
13060      * outline without invalidating the view itself. This is intended to be called from
13061      * within methods in the View class itself which are the result of the view being
13062      * invalidated already. For example, when we are drawing the background of a View,
13063      * we invalidate the outline in case it changed in the meantime, but we do not
13064      * need to invalidate the view because we're already drawing the background as part
13065      * of drawing the view in response to an earlier invalidation of the view.
13066      */
13067     private void rebuildOutline() {
13068         // Unattached views ignore this signal, and outline is recomputed in onAttachedToWindow()
13069         if (mAttachInfo == null) return;
13070
13071         if (mOutlineProvider == null) {
13072             // no provider, remove outline
13073             mRenderNode.setOutline(null);
13074         } else {
13075             final Outline outline = mAttachInfo.mTmpOutline;
13076             outline.setEmpty();
13077             outline.setAlpha(1.0f);
13078
13079             mOutlineProvider.getOutline(this, outline);
13080             mRenderNode.setOutline(outline);
13081         }
13082     }
13083
13084     /**
13085      * HierarchyViewer only
13086      *
13087      * @hide
13088      */
13089     @ViewDebug.ExportedProperty(category = "drawing")
13090     public boolean hasShadow() {
13091         return mRenderNode.hasShadow();
13092     }
13093
13094
13095     /** @hide */
13096     public void setRevealClip(boolean shouldClip, float x, float y, float radius) {
13097         mRenderNode.setRevealClip(shouldClip, x, y, radius);
13098         invalidateViewProperty(false, false);
13099     }
13100
13101     /**
13102      * Hit rectangle in parent's coordinates
13103      *
13104      * @param outRect The hit rectangle of the view.
13105      */
13106     public void getHitRect(Rect outRect) {
13107         if (hasIdentityMatrix() || mAttachInfo == null) {
13108             outRect.set(mLeft, mTop, mRight, mBottom);
13109         } else {
13110             final RectF tmpRect = mAttachInfo.mTmpTransformRect;
13111             tmpRect.set(0, 0, getWidth(), getHeight());
13112             getMatrix().mapRect(tmpRect); // TODO: mRenderNode.mapRect(tmpRect)
13113             outRect.set((int) tmpRect.left + mLeft, (int) tmpRect.top + mTop,
13114                     (int) tmpRect.right + mLeft, (int) tmpRect.bottom + mTop);
13115         }
13116     }
13117
13118     /**
13119      * Determines whether the given point, in local coordinates is inside the view.
13120      */
13121     /*package*/ final boolean pointInView(float localX, float localY) {
13122         return pointInView(localX, localY, 0);
13123     }
13124
13125     /**
13126      * Utility method to determine whether the given point, in local coordinates,
13127      * is inside the view, where the area of the view is expanded by the slop factor.
13128      * This method is called while processing touch-move events to determine if the event
13129      * is still within the view.
13130      *
13131      * @hide
13132      */
13133     public boolean pointInView(float localX, float localY, float slop) {
13134         return localX >= -slop && localY >= -slop && localX < ((mRight - mLeft) + slop) &&
13135                 localY < ((mBottom - mTop) + slop);
13136     }
13137
13138     /**
13139      * When a view has focus and the user navigates away from it, the next view is searched for
13140      * starting from the rectangle filled in by this method.
13141      *
13142      * By default, the rectangle is the {@link #getDrawingRect(android.graphics.Rect)})
13143      * of the view.  However, if your view maintains some idea of internal selection,
13144      * such as a cursor, or a selected row or column, you should override this method and
13145      * fill in a more specific rectangle.
13146      *
13147      * @param r The rectangle to fill in, in this view's coordinates.
13148      */
13149     public void getFocusedRect(Rect r) {
13150         getDrawingRect(r);
13151     }
13152
13153     /**
13154      * If some part of this view is not clipped by any of its parents, then
13155      * return that area in r in global (root) coordinates. To convert r to local
13156      * coordinates (without taking possible View rotations into account), offset
13157      * it by -globalOffset (e.g. r.offset(-globalOffset.x, -globalOffset.y)).
13158      * If the view is completely clipped or translated out, return false.
13159      *
13160      * @param r If true is returned, r holds the global coordinates of the
13161      *        visible portion of this view.
13162      * @param globalOffset If true is returned, globalOffset holds the dx,dy
13163      *        between this view and its root. globalOffet may be null.
13164      * @return true if r is non-empty (i.e. part of the view is visible at the
13165      *         root level.
13166      */
13167     public boolean getGlobalVisibleRect(Rect r, Point globalOffset) {
13168         int width = mRight - mLeft;
13169         int height = mBottom - mTop;
13170         if (width > 0 && height > 0) {
13171             r.set(0, 0, width, height);
13172             if (globalOffset != null) {
13173                 globalOffset.set(-mScrollX, -mScrollY);
13174             }
13175             return mParent == null || mParent.getChildVisibleRect(this, r, globalOffset);
13176         }
13177         return false;
13178     }
13179
13180     public final boolean getGlobalVisibleRect(Rect r) {
13181         return getGlobalVisibleRect(r, null);
13182     }
13183
13184     public final boolean getLocalVisibleRect(Rect r) {
13185         final Point offset = mAttachInfo != null ? mAttachInfo.mPoint : new Point();
13186         if (getGlobalVisibleRect(r, offset)) {
13187             r.offset(-offset.x, -offset.y); // make r local
13188             return true;
13189         }
13190         return false;
13191     }
13192
13193     /**
13194      * Offset this view's vertical location by the specified number of pixels.
13195      *
13196      * @param offset the number of pixels to offset the view by
13197      */
13198     public void offsetTopAndBottom(int offset) {
13199         if (offset != 0) {
13200             final boolean matrixIsIdentity = hasIdentityMatrix();
13201             if (matrixIsIdentity) {
13202                 if (isHardwareAccelerated()) {
13203                     invalidateViewProperty(false, false);
13204                 } else {
13205                     final ViewParent p = mParent;
13206                     if (p != null && mAttachInfo != null) {
13207                         final Rect r = mAttachInfo.mTmpInvalRect;
13208                         int minTop;
13209                         int maxBottom;
13210                         int yLoc;
13211                         if (offset < 0) {
13212                             minTop = mTop + offset;
13213                             maxBottom = mBottom;
13214                             yLoc = offset;
13215                         } else {
13216                             minTop = mTop;
13217                             maxBottom = mBottom + offset;
13218                             yLoc = 0;
13219                         }
13220                         r.set(0, yLoc, mRight - mLeft, maxBottom - minTop);
13221                         p.invalidateChild(this, r);
13222                     }
13223                 }
13224             } else {
13225                 invalidateViewProperty(false, false);
13226             }
13227
13228             mTop += offset;
13229             mBottom += offset;
13230             mRenderNode.offsetTopAndBottom(offset);
13231             if (isHardwareAccelerated()) {
13232                 invalidateViewProperty(false, false);
13233                 invalidateParentIfNeededAndWasQuickRejected();
13234             } else {
13235                 if (!matrixIsIdentity) {
13236                     invalidateViewProperty(false, true);
13237                 }
13238                 invalidateParentIfNeeded();
13239             }
13240             notifySubtreeAccessibilityStateChangedIfNeeded();
13241         }
13242     }
13243
13244     /**
13245      * Offset this view's horizontal location by the specified amount of pixels.
13246      *
13247      * @param offset the number of pixels to offset the view by
13248      */
13249     public void offsetLeftAndRight(int offset) {
13250         if (offset != 0) {
13251             final boolean matrixIsIdentity = hasIdentityMatrix();
13252             if (matrixIsIdentity) {
13253                 if (isHardwareAccelerated()) {
13254                     invalidateViewProperty(false, false);
13255                 } else {
13256                     final ViewParent p = mParent;
13257                     if (p != null && mAttachInfo != null) {
13258                         final Rect r = mAttachInfo.mTmpInvalRect;
13259                         int minLeft;
13260                         int maxRight;
13261                         if (offset < 0) {
13262                             minLeft = mLeft + offset;
13263                             maxRight = mRight;
13264                         } else {
13265                             minLeft = mLeft;
13266                             maxRight = mRight + offset;
13267                         }
13268                         r.set(0, 0, maxRight - minLeft, mBottom - mTop);
13269                         p.invalidateChild(this, r);
13270                     }
13271                 }
13272             } else {
13273                 invalidateViewProperty(false, false);
13274             }
13275
13276             mLeft += offset;
13277             mRight += offset;
13278             mRenderNode.offsetLeftAndRight(offset);
13279             if (isHardwareAccelerated()) {
13280                 invalidateViewProperty(false, false);
13281                 invalidateParentIfNeededAndWasQuickRejected();
13282             } else {
13283                 if (!matrixIsIdentity) {
13284                     invalidateViewProperty(false, true);
13285                 }
13286                 invalidateParentIfNeeded();
13287             }
13288             notifySubtreeAccessibilityStateChangedIfNeeded();
13289         }
13290     }
13291
13292     /**
13293      * Get the LayoutParams associated with this view. All views should have
13294      * layout parameters. These supply parameters to the <i>parent</i> of this
13295      * view specifying how it should be arranged. There are many subclasses of
13296      * ViewGroup.LayoutParams, and these correspond to the different subclasses
13297      * of ViewGroup that are responsible for arranging their children.
13298      *
13299      * This method may return null if this View is not attached to a parent
13300      * ViewGroup or {@link #setLayoutParams(android.view.ViewGroup.LayoutParams)}
13301      * was not invoked successfully. When a View is attached to a parent
13302      * ViewGroup, this method must not return null.
13303      *
13304      * @return The LayoutParams associated with this view, or null if no
13305      *         parameters have been set yet
13306      */
13307     @ViewDebug.ExportedProperty(deepExport = true, prefix = "layout_")
13308     public ViewGroup.LayoutParams getLayoutParams() {
13309         return mLayoutParams;
13310     }
13311
13312     /**
13313      * Set the layout parameters associated with this view. These supply
13314      * parameters to the <i>parent</i> of this view specifying how it should be
13315      * arranged. There are many subclasses of ViewGroup.LayoutParams, and these
13316      * correspond to the different subclasses of ViewGroup that are responsible
13317      * for arranging their children.
13318      *
13319      * @param params The layout parameters for this view, cannot be null
13320      */
13321     public void setLayoutParams(ViewGroup.LayoutParams params) {
13322         if (params == null) {
13323             throw new NullPointerException("Layout parameters cannot be null");
13324         }
13325         mLayoutParams = params;
13326         resolveLayoutParams();
13327         if (mParent instanceof ViewGroup) {
13328             ((ViewGroup) mParent).onSetLayoutParams(this, params);
13329         }
13330         requestLayout();
13331     }
13332
13333     /**
13334      * Resolve the layout parameters depending on the resolved layout direction
13335      *
13336      * @hide
13337      */
13338     public void resolveLayoutParams() {
13339         if (mLayoutParams != null) {
13340             mLayoutParams.resolveLayoutDirection(getLayoutDirection());
13341         }
13342     }
13343
13344     /**
13345      * Set the scrolled position of your view. This will cause a call to
13346      * {@link #onScrollChanged(int, int, int, int)} and the view will be
13347      * invalidated.
13348      * @param x the x position to scroll to
13349      * @param y the y position to scroll to
13350      */
13351     public void scrollTo(int x, int y) {
13352         if (mScrollX != x || mScrollY != y) {
13353             int oldX = mScrollX;
13354             int oldY = mScrollY;
13355             mScrollX = x;
13356             mScrollY = y;
13357             invalidateParentCaches();
13358             onScrollChanged(mScrollX, mScrollY, oldX, oldY);
13359             if (!awakenScrollBars()) {
13360                 postInvalidateOnAnimation();
13361             }
13362         }
13363     }
13364
13365     /**
13366      * Move the scrolled position of your view. This will cause a call to
13367      * {@link #onScrollChanged(int, int, int, int)} and the view will be
13368      * invalidated.
13369      * @param x the amount of pixels to scroll by horizontally
13370      * @param y the amount of pixels to scroll by vertically
13371      */
13372     public void scrollBy(int x, int y) {
13373         scrollTo(mScrollX + x, mScrollY + y);
13374     }
13375
13376     /**
13377      * <p>Trigger the scrollbars to draw. When invoked this method starts an
13378      * animation to fade the scrollbars out after a default delay. If a subclass
13379      * provides animated scrolling, the start delay should equal the duration
13380      * of the scrolling animation.</p>
13381      *
13382      * <p>The animation starts only if at least one of the scrollbars is
13383      * enabled, as specified by {@link #isHorizontalScrollBarEnabled()} and
13384      * {@link #isVerticalScrollBarEnabled()}. When the animation is started,
13385      * this method returns true, and false otherwise. If the animation is
13386      * started, this method calls {@link #invalidate()}; in that case the
13387      * caller should not call {@link #invalidate()}.</p>
13388      *
13389      * <p>This method should be invoked every time a subclass directly updates
13390      * the scroll parameters.</p>
13391      *
13392      * <p>This method is automatically invoked by {@link #scrollBy(int, int)}
13393      * and {@link #scrollTo(int, int)}.</p>
13394      *
13395      * @return true if the animation is played, false otherwise
13396      *
13397      * @see #awakenScrollBars(int)
13398      * @see #scrollBy(int, int)
13399      * @see #scrollTo(int, int)
13400      * @see #isHorizontalScrollBarEnabled()
13401      * @see #isVerticalScrollBarEnabled()
13402      * @see #setHorizontalScrollBarEnabled(boolean)
13403      * @see #setVerticalScrollBarEnabled(boolean)
13404      */
13405     protected boolean awakenScrollBars() {
13406         return mScrollCache != null &&
13407                 awakenScrollBars(mScrollCache.scrollBarDefaultDelayBeforeFade, true);
13408     }
13409
13410     /**
13411      * Trigger the scrollbars to draw.
13412      * This method differs from awakenScrollBars() only in its default duration.
13413      * initialAwakenScrollBars() will show the scroll bars for longer than
13414      * usual to give the user more of a chance to notice them.
13415      *
13416      * @return true if the animation is played, false otherwise.
13417      */
13418     private boolean initialAwakenScrollBars() {
13419         return mScrollCache != null &&
13420                 awakenScrollBars(mScrollCache.scrollBarDefaultDelayBeforeFade * 4, true);
13421     }
13422
13423     /**
13424      * <p>
13425      * Trigger the scrollbars to draw. When invoked this method starts an
13426      * animation to fade the scrollbars out after a fixed delay. If a subclass
13427      * provides animated scrolling, the start delay should equal the duration of
13428      * the scrolling animation.
13429      * </p>
13430      *
13431      * <p>
13432      * The animation starts only if at least one of the scrollbars is enabled,
13433      * as specified by {@link #isHorizontalScrollBarEnabled()} and
13434      * {@link #isVerticalScrollBarEnabled()}. When the animation is started,
13435      * this method returns true, and false otherwise. If the animation is
13436      * started, this method calls {@link #invalidate()}; in that case the caller
13437      * should not call {@link #invalidate()}.
13438      * </p>
13439      *
13440      * <p>
13441      * This method should be invoked every time a subclass directly updates the
13442      * scroll parameters.
13443      * </p>
13444      *
13445      * @param startDelay the delay, in milliseconds, after which the animation
13446      *        should start; when the delay is 0, the animation starts
13447      *        immediately
13448      * @return true if the animation is played, false otherwise
13449      *
13450      * @see #scrollBy(int, int)
13451      * @see #scrollTo(int, int)
13452      * @see #isHorizontalScrollBarEnabled()
13453      * @see #isVerticalScrollBarEnabled()
13454      * @see #setHorizontalScrollBarEnabled(boolean)
13455      * @see #setVerticalScrollBarEnabled(boolean)
13456      */
13457     protected boolean awakenScrollBars(int startDelay) {
13458         return awakenScrollBars(startDelay, true);
13459     }
13460
13461     /**
13462      * <p>
13463      * Trigger the scrollbars to draw. When invoked this method starts an
13464      * animation to fade the scrollbars out after a fixed delay. If a subclass
13465      * provides animated scrolling, the start delay should equal the duration of
13466      * the scrolling animation.
13467      * </p>
13468      *
13469      * <p>
13470      * The animation starts only if at least one of the scrollbars is enabled,
13471      * as specified by {@link #isHorizontalScrollBarEnabled()} and
13472      * {@link #isVerticalScrollBarEnabled()}. When the animation is started,
13473      * this method returns true, and false otherwise. If the animation is
13474      * started, this method calls {@link #invalidate()} if the invalidate parameter
13475      * is set to true; in that case the caller
13476      * should not call {@link #invalidate()}.
13477      * </p>
13478      *
13479      * <p>
13480      * This method should be invoked every time a subclass directly updates the
13481      * scroll parameters.
13482      * </p>
13483      *
13484      * @param startDelay the delay, in milliseconds, after which the animation
13485      *        should start; when the delay is 0, the animation starts
13486      *        immediately
13487      *
13488      * @param invalidate Whether this method should call invalidate
13489      *
13490      * @return true if the animation is played, false otherwise
13491      *
13492      * @see #scrollBy(int, int)
13493      * @see #scrollTo(int, int)
13494      * @see #isHorizontalScrollBarEnabled()
13495      * @see #isVerticalScrollBarEnabled()
13496      * @see #setHorizontalScrollBarEnabled(boolean)
13497      * @see #setVerticalScrollBarEnabled(boolean)
13498      */
13499     protected boolean awakenScrollBars(int startDelay, boolean invalidate) {
13500         final ScrollabilityCache scrollCache = mScrollCache;
13501
13502         if (scrollCache == null || !scrollCache.fadeScrollBars) {
13503             return false;
13504         }
13505
13506         if (scrollCache.scrollBar == null) {
13507             scrollCache.scrollBar = new ScrollBarDrawable();
13508             scrollCache.scrollBar.setState(getDrawableState());
13509             scrollCache.scrollBar.setCallback(this);
13510         }
13511
13512         if (isHorizontalScrollBarEnabled() || isVerticalScrollBarEnabled()) {
13513
13514             if (invalidate) {
13515                 // Invalidate to show the scrollbars
13516                 postInvalidateOnAnimation();
13517             }
13518
13519             if (scrollCache.state == ScrollabilityCache.OFF) {
13520                 // FIXME: this is copied from WindowManagerService.
13521                 // We should get this value from the system when it
13522                 // is possible to do so.
13523                 final int KEY_REPEAT_FIRST_DELAY = 750;
13524                 startDelay = Math.max(KEY_REPEAT_FIRST_DELAY, startDelay);
13525             }
13526
13527             // Tell mScrollCache when we should start fading. This may
13528             // extend the fade start time if one was already scheduled
13529             long fadeStartTime = AnimationUtils.currentAnimationTimeMillis() + startDelay;
13530             scrollCache.fadeStartTime = fadeStartTime;
13531             scrollCache.state = ScrollabilityCache.ON;
13532
13533             // Schedule our fader to run, unscheduling any old ones first
13534             if (mAttachInfo != null) {
13535                 mAttachInfo.mHandler.removeCallbacks(scrollCache);
13536                 mAttachInfo.mHandler.postAtTime(scrollCache, fadeStartTime);
13537             }
13538
13539             return true;
13540         }
13541
13542         return false;
13543     }
13544
13545     /**
13546      * Do not invalidate views which are not visible and which are not running an animation. They
13547      * will not get drawn and they should not set dirty flags as if they will be drawn
13548      */
13549     private boolean skipInvalidate() {
13550         return (mViewFlags & VISIBILITY_MASK) != VISIBLE && mCurrentAnimation == null &&
13551                 (!(mParent instanceof ViewGroup) ||
13552                         !((ViewGroup) mParent).isViewTransitioning(this));
13553     }
13554
13555     /**
13556      * Mark the area defined by dirty as needing to be drawn. If the view is
13557      * visible, {@link #onDraw(android.graphics.Canvas)} will be called at some
13558      * point in the future.
13559      * <p>
13560      * This must be called from a UI thread. To call from a non-UI thread, call
13561      * {@link #postInvalidate()}.
13562      * <p>
13563      * <b>WARNING:</b> In API 19 and below, this method may be destructive to
13564      * {@code dirty}.
13565      *
13566      * @param dirty the rectangle representing the bounds of the dirty region
13567      */
13568     public void invalidate(Rect dirty) {
13569         final int scrollX = mScrollX;
13570         final int scrollY = mScrollY;
13571         invalidateInternal(dirty.left - scrollX, dirty.top - scrollY,
13572                 dirty.right - scrollX, dirty.bottom - scrollY, true, false);
13573     }
13574
13575     /**
13576      * Mark the area defined by the rect (l,t,r,b) as needing to be drawn. The
13577      * coordinates of the dirty rect are relative to the view. If the view is
13578      * visible, {@link #onDraw(android.graphics.Canvas)} will be called at some
13579      * point in the future.
13580      * <p>
13581      * This must be called from a UI thread. To call from a non-UI thread, call
13582      * {@link #postInvalidate()}.
13583      *
13584      * @param l the left position of the dirty region
13585      * @param t the top position of the dirty region
13586      * @param r the right position of the dirty region
13587      * @param b the bottom position of the dirty region
13588      */
13589     public void invalidate(int l, int t, int r, int b) {
13590         final int scrollX = mScrollX;
13591         final int scrollY = mScrollY;
13592         invalidateInternal(l - scrollX, t - scrollY, r - scrollX, b - scrollY, true, false);
13593     }
13594
13595     /**
13596      * Invalidate the whole view. If the view is visible,
13597      * {@link #onDraw(android.graphics.Canvas)} will be called at some point in
13598      * the future.
13599      * <p>
13600      * This must be called from a UI thread. To call from a non-UI thread, call
13601      * {@link #postInvalidate()}.
13602      */
13603     public void invalidate() {
13604         invalidate(true);
13605     }
13606
13607     /**
13608      * This is where the invalidate() work actually happens. A full invalidate()
13609      * causes the drawing cache to be invalidated, but this function can be
13610      * called with invalidateCache set to false to skip that invalidation step
13611      * for cases that do not need it (for example, a component that remains at
13612      * the same dimensions with the same content).
13613      *
13614      * @param invalidateCache Whether the drawing cache for this view should be
13615      *            invalidated as well. This is usually true for a full
13616      *            invalidate, but may be set to false if the View's contents or
13617      *            dimensions have not changed.
13618      */
13619     void invalidate(boolean invalidateCache) {
13620         invalidateInternal(0, 0, mRight - mLeft, mBottom - mTop, invalidateCache, true);
13621     }
13622
13623     void invalidateInternal(int l, int t, int r, int b, boolean invalidateCache,
13624             boolean fullInvalidate) {
13625         if (mGhostView != null) {
13626             mGhostView.invalidate(true);
13627             return;
13628         }
13629
13630         if (skipInvalidate()) {
13631             return;
13632         }
13633
13634         if ((mPrivateFlags & (PFLAG_DRAWN | PFLAG_HAS_BOUNDS)) == (PFLAG_DRAWN | PFLAG_HAS_BOUNDS)
13635                 || (invalidateCache && (mPrivateFlags & PFLAG_DRAWING_CACHE_VALID) == PFLAG_DRAWING_CACHE_VALID)
13636                 || (mPrivateFlags & PFLAG_INVALIDATED) != PFLAG_INVALIDATED
13637                 || (fullInvalidate && isOpaque() != mLastIsOpaque)) {
13638             if (fullInvalidate) {
13639                 mLastIsOpaque = isOpaque();
13640                 mPrivateFlags &= ~PFLAG_DRAWN;
13641             }
13642
13643             mPrivateFlags |= PFLAG_DIRTY;
13644
13645             if (invalidateCache) {
13646                 mPrivateFlags |= PFLAG_INVALIDATED;
13647                 mPrivateFlags &= ~PFLAG_DRAWING_CACHE_VALID;
13648             }
13649
13650             // Propagate the damage rectangle to the parent view.
13651             final AttachInfo ai = mAttachInfo;
13652             final ViewParent p = mParent;
13653             if (p != null && ai != null && l < r && t < b) {
13654                 final Rect damage = ai.mTmpInvalRect;
13655                 damage.set(l, t, r, b);
13656                 p.invalidateChild(this, damage);
13657             }
13658
13659             // Damage the entire projection receiver, if necessary.
13660             if (mBackground != null && mBackground.isProjected()) {
13661                 final View receiver = getProjectionReceiver();
13662                 if (receiver != null) {
13663                     receiver.damageInParent();
13664                 }
13665             }
13666
13667             // Damage the entire IsolatedZVolume receiving this view's shadow.
13668             if (isHardwareAccelerated() && getZ() != 0) {
13669                 damageShadowReceiver();
13670             }
13671         }
13672     }
13673
13674     /**
13675      * @return this view's projection receiver, or {@code null} if none exists
13676      */
13677     private View getProjectionReceiver() {
13678         ViewParent p = getParent();
13679         while (p != null && p instanceof View) {
13680             final View v = (View) p;
13681             if (v.isProjectionReceiver()) {
13682                 return v;
13683             }
13684             p = p.getParent();
13685         }
13686
13687         return null;
13688     }
13689
13690     /**
13691      * @return whether the view is a projection receiver
13692      */
13693     private boolean isProjectionReceiver() {
13694         return mBackground != null;
13695     }
13696
13697     /**
13698      * Damage area of the screen that can be covered by this View's shadow.
13699      *
13700      * This method will guarantee that any changes to shadows cast by a View
13701      * are damaged on the screen for future redraw.
13702      */
13703     private void damageShadowReceiver() {
13704         final AttachInfo ai = mAttachInfo;
13705         if (ai != null) {
13706             ViewParent p = getParent();
13707             if (p != null && p instanceof ViewGroup) {
13708                 final ViewGroup vg = (ViewGroup) p;
13709                 vg.damageInParent();
13710             }
13711         }
13712     }
13713
13714     /**
13715      * Quick invalidation for View property changes (alpha, translationXY, etc.). We don't want to
13716      * set any flags or handle all of the cases handled by the default invalidation methods.
13717      * Instead, we just want to schedule a traversal in ViewRootImpl with the appropriate
13718      * dirty rect. This method calls into fast invalidation methods in ViewGroup that
13719      * walk up the hierarchy, transforming the dirty rect as necessary.
13720      *
13721      * The method also handles normal invalidation logic if display list properties are not
13722      * being used in this view. The invalidateParent and forceRedraw flags are used by that
13723      * backup approach, to handle these cases used in the various property-setting methods.
13724      *
13725      * @param invalidateParent Force a call to invalidateParentCaches() if display list properties
13726      * are not being used in this view
13727      * @param forceRedraw Mark the view as DRAWN to force the invalidation to propagate, if display
13728      * list properties are not being used in this view
13729      */
13730     void invalidateViewProperty(boolean invalidateParent, boolean forceRedraw) {
13731         if (!isHardwareAccelerated()
13732                 || !mRenderNode.isValid()
13733                 || (mPrivateFlags & PFLAG_DRAW_ANIMATION) != 0) {
13734             if (invalidateParent) {
13735                 invalidateParentCaches();
13736             }
13737             if (forceRedraw) {
13738                 mPrivateFlags |= PFLAG_DRAWN; // force another invalidation with the new orientation
13739             }
13740             invalidate(false);
13741         } else {
13742             damageInParent();
13743         }
13744         if (isHardwareAccelerated() && invalidateParent && getZ() != 0) {
13745             damageShadowReceiver();
13746         }
13747     }
13748
13749     /**
13750      * Tells the parent view to damage this view's bounds.
13751      *
13752      * @hide
13753      */
13754     protected void damageInParent() {
13755         final AttachInfo ai = mAttachInfo;
13756         final ViewParent p = mParent;
13757         if (p != null && ai != null) {
13758             final Rect r = ai.mTmpInvalRect;
13759             r.set(0, 0, mRight - mLeft, mBottom - mTop);
13760             if (mParent instanceof ViewGroup) {
13761                 ((ViewGroup) mParent).damageChild(this, r);
13762             } else {
13763                 mParent.invalidateChild(this, r);
13764             }
13765         }
13766     }
13767
13768     /**
13769      * Utility method to transform a given Rect by the current matrix of this view.
13770      */
13771     void transformRect(final Rect rect) {
13772         if (!getMatrix().isIdentity()) {
13773             RectF boundingRect = mAttachInfo.mTmpTransformRect;
13774             boundingRect.set(rect);
13775             getMatrix().mapRect(boundingRect);
13776             rect.set((int) Math.floor(boundingRect.left),
13777                     (int) Math.floor(boundingRect.top),
13778                     (int) Math.ceil(boundingRect.right),
13779                     (int) Math.ceil(boundingRect.bottom));
13780         }
13781     }
13782
13783     /**
13784      * Used to indicate that the parent of this view should clear its caches. This functionality
13785      * is used to force the parent to rebuild its display list (when hardware-accelerated),
13786      * which is necessary when various parent-managed properties of the view change, such as
13787      * alpha, translationX/Y, scrollX/Y, scaleX/Y, and rotation/X/Y. This method only
13788      * clears the parent caches and does not causes an invalidate event.
13789      *
13790      * @hide
13791      */
13792     protected void invalidateParentCaches() {
13793         if (mParent instanceof View) {
13794             ((View) mParent).mPrivateFlags |= PFLAG_INVALIDATED;
13795         }
13796     }
13797
13798     /**
13799      * Used to indicate that the parent of this view should be invalidated. This functionality
13800      * is used to force the parent to rebuild its display list (when hardware-accelerated),
13801      * which is necessary when various parent-managed properties of the view change, such as
13802      * alpha, translationX/Y, scrollX/Y, scaleX/Y, and rotation/X/Y. This method will propagate
13803      * an invalidation event to the parent.
13804      *
13805      * @hide
13806      */
13807     protected void invalidateParentIfNeeded() {
13808         if (isHardwareAccelerated() && mParent instanceof View) {
13809             ((View) mParent).invalidate(true);
13810         }
13811     }
13812
13813     /**
13814      * @hide
13815      */
13816     protected void invalidateParentIfNeededAndWasQuickRejected() {
13817         if ((mPrivateFlags2 & PFLAG2_VIEW_QUICK_REJECTED) != 0) {
13818             // View was rejected last time it was drawn by its parent; this may have changed
13819             invalidateParentIfNeeded();
13820         }
13821     }
13822
13823     /**
13824      * Indicates whether this View is opaque. An opaque View guarantees that it will
13825      * draw all the pixels overlapping its bounds using a fully opaque color.
13826      *
13827      * Subclasses of View should override this method whenever possible to indicate
13828      * whether an instance is opaque. Opaque Views are treated in a special way by
13829      * the View hierarchy, possibly allowing it to perform optimizations during
13830      * invalidate/draw passes.
13831      *
13832      * @return True if this View is guaranteed to be fully opaque, false otherwise.
13833      */
13834     @ViewDebug.ExportedProperty(category = "drawing")
13835     public boolean isOpaque() {
13836         return (mPrivateFlags & PFLAG_OPAQUE_MASK) == PFLAG_OPAQUE_MASK &&
13837                 getFinalAlpha() >= 1.0f;
13838     }
13839
13840     /**
13841      * @hide
13842      */
13843     protected void computeOpaqueFlags() {
13844         // Opaque if:
13845         //   - Has a background
13846         //   - Background is opaque
13847         //   - Doesn't have scrollbars or scrollbars overlay
13848
13849         if (mBackground != null && mBackground.getOpacity() == PixelFormat.OPAQUE) {
13850             mPrivateFlags |= PFLAG_OPAQUE_BACKGROUND;
13851         } else {
13852             mPrivateFlags &= ~PFLAG_OPAQUE_BACKGROUND;
13853         }
13854
13855         final int flags = mViewFlags;
13856         if (((flags & SCROLLBARS_VERTICAL) == 0 && (flags & SCROLLBARS_HORIZONTAL) == 0) ||
13857                 (flags & SCROLLBARS_STYLE_MASK) == SCROLLBARS_INSIDE_OVERLAY ||
13858                 (flags & SCROLLBARS_STYLE_MASK) == SCROLLBARS_OUTSIDE_OVERLAY) {
13859             mPrivateFlags |= PFLAG_OPAQUE_SCROLLBARS;
13860         } else {
13861             mPrivateFlags &= ~PFLAG_OPAQUE_SCROLLBARS;
13862         }
13863     }
13864
13865     /**
13866      * @hide
13867      */
13868     protected boolean hasOpaqueScrollbars() {
13869         return (mPrivateFlags & PFLAG_OPAQUE_SCROLLBARS) == PFLAG_OPAQUE_SCROLLBARS;
13870     }
13871
13872     /**
13873      * @return A handler associated with the thread running the View. This
13874      * handler can be used to pump events in the UI events queue.
13875      */
13876     public Handler getHandler() {
13877         final AttachInfo attachInfo = mAttachInfo;
13878         if (attachInfo != null) {
13879             return attachInfo.mHandler;
13880         }
13881         return null;
13882     }
13883
13884     /**
13885      * Returns the queue of runnable for this view.
13886      *
13887      * @return the queue of runnables for this view
13888      */
13889     private HandlerActionQueue getRunQueue() {
13890         if (mRunQueue == null) {
13891             mRunQueue = new HandlerActionQueue();
13892         }
13893         return mRunQueue;
13894     }
13895
13896     /**
13897      * Gets the view root associated with the View.
13898      * @return The view root, or null if none.
13899      * @hide
13900      */
13901     public ViewRootImpl getViewRootImpl() {
13902         if (mAttachInfo != null) {
13903             return mAttachInfo.mViewRootImpl;
13904         }
13905         return null;
13906     }
13907
13908     /**
13909      * @hide
13910      */
13911     public ThreadedRenderer getHardwareRenderer() {
13912         return mAttachInfo != null ? mAttachInfo.mHardwareRenderer : null;
13913     }
13914
13915     /**
13916      * <p>Causes the Runnable to be added to the message queue.
13917      * The runnable will be run on the user interface thread.</p>
13918      *
13919      * @param action The Runnable that will be executed.
13920      *
13921      * @return Returns true if the Runnable was successfully placed in to the
13922      *         message queue.  Returns false on failure, usually because the
13923      *         looper processing the message queue is exiting.
13924      *
13925      * @see #postDelayed
13926      * @see #removeCallbacks
13927      */
13928     public boolean post(Runnable action) {
13929         final AttachInfo attachInfo = mAttachInfo;
13930         if (attachInfo != null) {
13931             return attachInfo.mHandler.post(action);
13932         }
13933
13934         // Postpone the runnable until we know on which thread it needs to run.
13935         // Assume that the runnable will be successfully placed after attach.
13936         getRunQueue().post(action);
13937         return true;
13938     }
13939
13940     /**
13941      * <p>Causes the Runnable to be added to the message queue, to be run
13942      * after the specified amount of time elapses.
13943      * The runnable will be run on the user interface thread.</p>
13944      *
13945      * @param action The Runnable that will be executed.
13946      * @param delayMillis The delay (in milliseconds) until the Runnable
13947      *        will be executed.
13948      *
13949      * @return true if the Runnable was successfully placed in to the
13950      *         message queue.  Returns false on failure, usually because the
13951      *         looper processing the message queue is exiting.  Note that a
13952      *         result of true does not mean the Runnable will be processed --
13953      *         if the looper is quit before the delivery time of the message
13954      *         occurs then the message will be dropped.
13955      *
13956      * @see #post
13957      * @see #removeCallbacks
13958      */
13959     public boolean postDelayed(Runnable action, long delayMillis) {
13960         final AttachInfo attachInfo = mAttachInfo;
13961         if (attachInfo != null) {
13962             return attachInfo.mHandler.postDelayed(action, delayMillis);
13963         }
13964
13965         // Postpone the runnable until we know on which thread it needs to run.
13966         // Assume that the runnable will be successfully placed after attach.
13967         getRunQueue().postDelayed(action, delayMillis);
13968         return true;
13969     }
13970
13971     /**
13972      * <p>Causes the Runnable to execute on the next animation time step.
13973      * The runnable will be run on the user interface thread.</p>
13974      *
13975      * @param action The Runnable that will be executed.
13976      *
13977      * @see #postOnAnimationDelayed
13978      * @see #removeCallbacks
13979      */
13980     public void postOnAnimation(Runnable action) {
13981         final AttachInfo attachInfo = mAttachInfo;
13982         if (attachInfo != null) {
13983             attachInfo.mViewRootImpl.mChoreographer.postCallback(
13984                     Choreographer.CALLBACK_ANIMATION, action, null);
13985         } else {
13986             // Postpone the runnable until we know
13987             // on which thread it needs to run.
13988             getRunQueue().post(action);
13989         }
13990     }
13991
13992     /**
13993      * <p>Causes the Runnable to execute on the next animation time step,
13994      * after the specified amount of time elapses.
13995      * The runnable will be run on the user interface thread.</p>
13996      *
13997      * @param action The Runnable that will be executed.
13998      * @param delayMillis The delay (in milliseconds) until the Runnable
13999      *        will be executed.
14000      *
14001      * @see #postOnAnimation
14002      * @see #removeCallbacks
14003      */
14004     public void postOnAnimationDelayed(Runnable action, long delayMillis) {
14005         final AttachInfo attachInfo = mAttachInfo;
14006         if (attachInfo != null) {
14007             attachInfo.mViewRootImpl.mChoreographer.postCallbackDelayed(
14008                     Choreographer.CALLBACK_ANIMATION, action, null, delayMillis);
14009         } else {
14010             // Postpone the runnable until we know
14011             // on which thread it needs to run.
14012             getRunQueue().postDelayed(action, delayMillis);
14013         }
14014     }
14015
14016     /**
14017      * <p>Removes the specified Runnable from the message queue.</p>
14018      *
14019      * @param action The Runnable to remove from the message handling queue
14020      *
14021      * @return true if this view could ask the Handler to remove the Runnable,
14022      *         false otherwise. When the returned value is true, the Runnable
14023      *         may or may not have been actually removed from the message queue
14024      *         (for instance, if the Runnable was not in the queue already.)
14025      *
14026      * @see #post
14027      * @see #postDelayed
14028      * @see #postOnAnimation
14029      * @see #postOnAnimationDelayed
14030      */
14031     public boolean removeCallbacks(Runnable action) {
14032         if (action != null) {
14033             final AttachInfo attachInfo = mAttachInfo;
14034             if (attachInfo != null) {
14035                 attachInfo.mHandler.removeCallbacks(action);
14036                 attachInfo.mViewRootImpl.mChoreographer.removeCallbacks(
14037                         Choreographer.CALLBACK_ANIMATION, action, null);
14038             }
14039             getRunQueue().removeCallbacks(action);
14040         }
14041         return true;
14042     }
14043
14044     /**
14045      * <p>Cause an invalidate to happen on a subsequent cycle through the event loop.
14046      * Use this to invalidate the View from a non-UI thread.</p>
14047      *
14048      * <p>This method can be invoked from outside of the UI thread
14049      * only when this View is attached to a window.</p>
14050      *
14051      * @see #invalidate()
14052      * @see #postInvalidateDelayed(long)
14053      */
14054     public void postInvalidate() {
14055         postInvalidateDelayed(0);
14056     }
14057
14058     /**
14059      * <p>Cause an invalidate of the specified area to happen on a subsequent cycle
14060      * through the event loop. Use this to invalidate the View from a non-UI thread.</p>
14061      *
14062      * <p>This method can be invoked from outside of the UI thread
14063      * only when this View is attached to a window.</p>
14064      *
14065      * @param left The left coordinate of the rectangle to invalidate.
14066      * @param top The top coordinate of the rectangle to invalidate.
14067      * @param right The right coordinate of the rectangle to invalidate.
14068      * @param bottom The bottom coordinate of the rectangle to invalidate.
14069      *
14070      * @see #invalidate(int, int, int, int)
14071      * @see #invalidate(Rect)
14072      * @see #postInvalidateDelayed(long, int, int, int, int)
14073      */
14074     public void postInvalidate(int left, int top, int right, int bottom) {
14075         postInvalidateDelayed(0, left, top, right, bottom);
14076     }
14077
14078     /**
14079      * <p>Cause an invalidate to happen on a subsequent cycle through the event
14080      * loop. Waits for the specified amount of time.</p>
14081      *
14082      * <p>This method can be invoked from outside of the UI thread
14083      * only when this View is attached to a window.</p>
14084      *
14085      * @param delayMilliseconds the duration in milliseconds to delay the
14086      *         invalidation by
14087      *
14088      * @see #invalidate()
14089      * @see #postInvalidate()
14090      */
14091     public void postInvalidateDelayed(long delayMilliseconds) {
14092         // We try only with the AttachInfo because there's no point in invalidating
14093         // if we are not attached to our window
14094         final AttachInfo attachInfo = mAttachInfo;
14095         if (attachInfo != null) {
14096             attachInfo.mViewRootImpl.dispatchInvalidateDelayed(this, delayMilliseconds);
14097         }
14098     }
14099
14100     /**
14101      * <p>Cause an invalidate of the specified area to happen on a subsequent cycle
14102      * through the event loop. Waits for the specified amount of time.</p>
14103      *
14104      * <p>This method can be invoked from outside of the UI thread
14105      * only when this View is attached to a window.</p>
14106      *
14107      * @param delayMilliseconds the duration in milliseconds to delay the
14108      *         invalidation by
14109      * @param left The left coordinate of the rectangle to invalidate.
14110      * @param top The top coordinate of the rectangle to invalidate.
14111      * @param right The right coordinate of the rectangle to invalidate.
14112      * @param bottom The bottom coordinate of the rectangle to invalidate.
14113      *
14114      * @see #invalidate(int, int, int, int)
14115      * @see #invalidate(Rect)
14116      * @see #postInvalidate(int, int, int, int)
14117      */
14118     public void postInvalidateDelayed(long delayMilliseconds, int left, int top,
14119             int right, int bottom) {
14120
14121         // We try only with the AttachInfo because there's no point in invalidating
14122         // if we are not attached to our window
14123         final AttachInfo attachInfo = mAttachInfo;
14124         if (attachInfo != null) {
14125             final AttachInfo.InvalidateInfo info = AttachInfo.InvalidateInfo.obtain();
14126             info.target = this;
14127             info.left = left;
14128             info.top = top;
14129             info.right = right;
14130             info.bottom = bottom;
14131
14132             attachInfo.mViewRootImpl.dispatchInvalidateRectDelayed(info, delayMilliseconds);
14133         }
14134     }
14135
14136     /**
14137      * <p>Cause an invalidate to happen on the next animation time step, typically the
14138      * next display frame.</p>
14139      *
14140      * <p>This method can be invoked from outside of the UI thread
14141      * only when this View is attached to a window.</p>
14142      *
14143      * @see #invalidate()
14144      */
14145     public void postInvalidateOnAnimation() {
14146         // We try only with the AttachInfo because there's no point in invalidating
14147         // if we are not attached to our window
14148         final AttachInfo attachInfo = mAttachInfo;
14149         if (attachInfo != null) {
14150             attachInfo.mViewRootImpl.dispatchInvalidateOnAnimation(this);
14151         }
14152     }
14153
14154     /**
14155      * <p>Cause an invalidate of the specified area to happen on the next animation
14156      * time step, typically the next display frame.</p>
14157      *
14158      * <p>This method can be invoked from outside of the UI thread
14159      * only when this View is attached to a window.</p>
14160      *
14161      * @param left The left coordinate of the rectangle to invalidate.
14162      * @param top The top coordinate of the rectangle to invalidate.
14163      * @param right The right coordinate of the rectangle to invalidate.
14164      * @param bottom The bottom coordinate of the rectangle to invalidate.
14165      *
14166      * @see #invalidate(int, int, int, int)
14167      * @see #invalidate(Rect)
14168      */
14169     public void postInvalidateOnAnimation(int left, int top, int right, int bottom) {
14170         // We try only with the AttachInfo because there's no point in invalidating
14171         // if we are not attached to our window
14172         final AttachInfo attachInfo = mAttachInfo;
14173         if (attachInfo != null) {
14174             final AttachInfo.InvalidateInfo info = AttachInfo.InvalidateInfo.obtain();
14175             info.target = this;
14176             info.left = left;
14177             info.top = top;
14178             info.right = right;
14179             info.bottom = bottom;
14180
14181             attachInfo.mViewRootImpl.dispatchInvalidateRectOnAnimation(info);
14182         }
14183     }
14184
14185     /**
14186      * Post a callback to send a {@link AccessibilityEvent#TYPE_VIEW_SCROLLED} event.
14187      * This event is sent at most once every
14188      * {@link ViewConfiguration#getSendRecurringAccessibilityEventsInterval()}.
14189      */
14190     private void postSendViewScrolledAccessibilityEventCallback() {
14191         if (mSendViewScrolledAccessibilityEvent == null) {
14192             mSendViewScrolledAccessibilityEvent = new SendViewScrolledAccessibilityEvent();
14193         }
14194         if (!mSendViewScrolledAccessibilityEvent.mIsPending) {
14195             mSendViewScrolledAccessibilityEvent.mIsPending = true;
14196             postDelayed(mSendViewScrolledAccessibilityEvent,
14197                     ViewConfiguration.getSendRecurringAccessibilityEventsInterval());
14198         }
14199     }
14200
14201     /**
14202      * Called by a parent to request that a child update its values for mScrollX
14203      * and mScrollY if necessary. This will typically be done if the child is
14204      * animating a scroll using a {@link android.widget.Scroller Scroller}
14205      * object.
14206      */
14207     public void computeScroll() {
14208     }
14209
14210     /**
14211      * <p>Indicate whether the horizontal edges are faded when the view is
14212      * scrolled horizontally.</p>
14213      *
14214      * @return true if the horizontal edges should are faded on scroll, false
14215      *         otherwise
14216      *
14217      * @see #setHorizontalFadingEdgeEnabled(boolean)
14218      *
14219      * @attr ref android.R.styleable#View_requiresFadingEdge
14220      */
14221     public boolean isHorizontalFadingEdgeEnabled() {
14222         return (mViewFlags & FADING_EDGE_HORIZONTAL) == FADING_EDGE_HORIZONTAL;
14223     }
14224
14225     /**
14226      * <p>Define whether the horizontal edges should be faded when this view
14227      * is scrolled horizontally.</p>
14228      *
14229      * @param horizontalFadingEdgeEnabled true if the horizontal edges should
14230      *                                    be faded when the view is scrolled
14231      *                                    horizontally
14232      *
14233      * @see #isHorizontalFadingEdgeEnabled()
14234      *
14235      * @attr ref android.R.styleable#View_requiresFadingEdge
14236      */
14237     public void setHorizontalFadingEdgeEnabled(boolean horizontalFadingEdgeEnabled) {
14238         if (isHorizontalFadingEdgeEnabled() != horizontalFadingEdgeEnabled) {
14239             if (horizontalFadingEdgeEnabled) {
14240                 initScrollCache();
14241             }
14242
14243             mViewFlags ^= FADING_EDGE_HORIZONTAL;
14244         }
14245     }
14246
14247     /**
14248      * <p>Indicate whether the vertical edges are faded when the view is
14249      * scrolled horizontally.</p>
14250      *
14251      * @return true if the vertical edges should are faded on scroll, false
14252      *         otherwise
14253      *
14254      * @see #setVerticalFadingEdgeEnabled(boolean)
14255      *
14256      * @attr ref android.R.styleable#View_requiresFadingEdge
14257      */
14258     public boolean isVerticalFadingEdgeEnabled() {
14259         return (mViewFlags & FADING_EDGE_VERTICAL) == FADING_EDGE_VERTICAL;
14260     }
14261
14262     /**
14263      * <p>Define whether the vertical edges should be faded when this view
14264      * is scrolled vertically.</p>
14265      *
14266      * @param verticalFadingEdgeEnabled true if the vertical edges should
14267      *                                  be faded when the view is scrolled
14268      *                                  vertically
14269      *
14270      * @see #isVerticalFadingEdgeEnabled()
14271      *
14272      * @attr ref android.R.styleable#View_requiresFadingEdge
14273      */
14274     public void setVerticalFadingEdgeEnabled(boolean verticalFadingEdgeEnabled) {
14275         if (isVerticalFadingEdgeEnabled() != verticalFadingEdgeEnabled) {
14276             if (verticalFadingEdgeEnabled) {
14277                 initScrollCache();
14278             }
14279
14280             mViewFlags ^= FADING_EDGE_VERTICAL;
14281         }
14282     }
14283
14284     /**
14285      * Returns the strength, or intensity, of the top faded edge. The strength is
14286      * a value between 0.0 (no fade) and 1.0 (full fade). The default implementation
14287      * returns 0.0 or 1.0 but no value in between.
14288      *
14289      * Subclasses should override this method to provide a smoother fade transition
14290      * when scrolling occurs.
14291      *
14292      * @return the intensity of the top fade as a float between 0.0f and 1.0f
14293      */
14294     protected float getTopFadingEdgeStrength() {
14295         return computeVerticalScrollOffset() > 0 ? 1.0f : 0.0f;
14296     }
14297
14298     /**
14299      * Returns the strength, or intensity, of the bottom faded edge. The strength is
14300      * a value between 0.0 (no fade) and 1.0 (full fade). The default implementation
14301      * returns 0.0 or 1.0 but no value in between.
14302      *
14303      * Subclasses should override this method to provide a smoother fade transition
14304      * when scrolling occurs.
14305      *
14306      * @return the intensity of the bottom fade as a float between 0.0f and 1.0f
14307      */
14308     protected float getBottomFadingEdgeStrength() {
14309         return computeVerticalScrollOffset() + computeVerticalScrollExtent() <
14310                 computeVerticalScrollRange() ? 1.0f : 0.0f;
14311     }
14312
14313     /**
14314      * Returns the strength, or intensity, of the left faded edge. The strength is
14315      * a value between 0.0 (no fade) and 1.0 (full fade). The default implementation
14316      * returns 0.0 or 1.0 but no value in between.
14317      *
14318      * Subclasses should override this method to provide a smoother fade transition
14319      * when scrolling occurs.
14320      *
14321      * @return the intensity of the left fade as a float between 0.0f and 1.0f
14322      */
14323     protected float getLeftFadingEdgeStrength() {
14324         return computeHorizontalScrollOffset() > 0 ? 1.0f : 0.0f;
14325     }
14326
14327     /**
14328      * Returns the strength, or intensity, of the right faded edge. The strength is
14329      * a value between 0.0 (no fade) and 1.0 (full fade). The default implementation
14330      * returns 0.0 or 1.0 but no value in between.
14331      *
14332      * Subclasses should override this method to provide a smoother fade transition
14333      * when scrolling occurs.
14334      *
14335      * @return the intensity of the right fade as a float between 0.0f and 1.0f
14336      */
14337     protected float getRightFadingEdgeStrength() {
14338         return computeHorizontalScrollOffset() + computeHorizontalScrollExtent() <
14339                 computeHorizontalScrollRange() ? 1.0f : 0.0f;
14340     }
14341
14342     /**
14343      * <p>Indicate whether the horizontal scrollbar should be drawn or not. The
14344      * scrollbar is not drawn by default.</p>
14345      *
14346      * @return true if the horizontal scrollbar should be painted, false
14347      *         otherwise
14348      *
14349      * @see #setHorizontalScrollBarEnabled(boolean)
14350      */
14351     public boolean isHorizontalScrollBarEnabled() {
14352         return (mViewFlags & SCROLLBARS_HORIZONTAL) == SCROLLBARS_HORIZONTAL;
14353     }
14354
14355     /**
14356      * <p>Define whether the horizontal scrollbar should be drawn or not. The
14357      * scrollbar is not drawn by default.</p>
14358      *
14359      * @param horizontalScrollBarEnabled true if the horizontal scrollbar should
14360      *                                   be painted
14361      *
14362      * @see #isHorizontalScrollBarEnabled()
14363      */
14364     public void setHorizontalScrollBarEnabled(boolean horizontalScrollBarEnabled) {
14365         if (isHorizontalScrollBarEnabled() != horizontalScrollBarEnabled) {
14366             mViewFlags ^= SCROLLBARS_HORIZONTAL;
14367             computeOpaqueFlags();
14368             resolvePadding();
14369         }
14370     }
14371
14372     /**
14373      * <p>Indicate whether the vertical scrollbar should be drawn or not. The
14374      * scrollbar is not drawn by default.</p>
14375      *
14376      * @return true if the vertical scrollbar should be painted, false
14377      *         otherwise
14378      *
14379      * @see #setVerticalScrollBarEnabled(boolean)
14380      */
14381     public boolean isVerticalScrollBarEnabled() {
14382         return (mViewFlags & SCROLLBARS_VERTICAL) == SCROLLBARS_VERTICAL;
14383     }
14384
14385     /**
14386      * <p>Define whether the vertical scrollbar should be drawn or not. The
14387      * scrollbar is not drawn by default.</p>
14388      *
14389      * @param verticalScrollBarEnabled true if the vertical scrollbar should
14390      *                                 be painted
14391      *
14392      * @see #isVerticalScrollBarEnabled()
14393      */
14394     public void setVerticalScrollBarEnabled(boolean verticalScrollBarEnabled) {
14395         if (isVerticalScrollBarEnabled() != verticalScrollBarEnabled) {
14396             mViewFlags ^= SCROLLBARS_VERTICAL;
14397             computeOpaqueFlags();
14398             resolvePadding();
14399         }
14400     }
14401
14402     /**
14403      * @hide
14404      */
14405     protected void recomputePadding() {
14406         internalSetPadding(mUserPaddingLeft, mPaddingTop, mUserPaddingRight, mUserPaddingBottom);
14407     }
14408
14409     /**
14410      * Define whether scrollbars will fade when the view is not scrolling.
14411      *
14412      * @param fadeScrollbars whether to enable fading
14413      *
14414      * @attr ref android.R.styleable#View_fadeScrollbars
14415      */
14416     public void setScrollbarFadingEnabled(boolean fadeScrollbars) {
14417         initScrollCache();
14418         final ScrollabilityCache scrollabilityCache = mScrollCache;
14419         scrollabilityCache.fadeScrollBars = fadeScrollbars;
14420         if (fadeScrollbars) {
14421             scrollabilityCache.state = ScrollabilityCache.OFF;
14422         } else {
14423             scrollabilityCache.state = ScrollabilityCache.ON;
14424         }
14425     }
14426
14427     /**
14428      *
14429      * Returns true if scrollbars will fade when this view is not scrolling
14430      *
14431      * @return true if scrollbar fading is enabled
14432      *
14433      * @attr ref android.R.styleable#View_fadeScrollbars
14434      */
14435     public boolean isScrollbarFadingEnabled() {
14436         return mScrollCache != null && mScrollCache.fadeScrollBars;
14437     }
14438
14439     /**
14440      *
14441      * Returns the delay before scrollbars fade.
14442      *
14443      * @return the delay before scrollbars fade
14444      *
14445      * @attr ref android.R.styleable#View_scrollbarDefaultDelayBeforeFade
14446      */
14447     public int getScrollBarDefaultDelayBeforeFade() {
14448         return mScrollCache == null ? ViewConfiguration.getScrollDefaultDelay() :
14449                 mScrollCache.scrollBarDefaultDelayBeforeFade;
14450     }
14451
14452     /**
14453      * Define the delay before scrollbars fade.
14454      *
14455      * @param scrollBarDefaultDelayBeforeFade - the delay before scrollbars fade
14456      *
14457      * @attr ref android.R.styleable#View_scrollbarDefaultDelayBeforeFade
14458      */
14459     public void setScrollBarDefaultDelayBeforeFade(int scrollBarDefaultDelayBeforeFade) {
14460         getScrollCache().scrollBarDefaultDelayBeforeFade = scrollBarDefaultDelayBeforeFade;
14461     }
14462
14463     /**
14464      *
14465      * Returns the scrollbar fade duration.
14466      *
14467      * @return the scrollbar fade duration
14468      *
14469      * @attr ref android.R.styleable#View_scrollbarFadeDuration
14470      */
14471     public int getScrollBarFadeDuration() {
14472         return mScrollCache == null ? ViewConfiguration.getScrollBarFadeDuration() :
14473                 mScrollCache.scrollBarFadeDuration;
14474     }
14475
14476     /**
14477      * Define the scrollbar fade duration.
14478      *
14479      * @param scrollBarFadeDuration - the scrollbar fade duration
14480      *
14481      * @attr ref android.R.styleable#View_scrollbarFadeDuration
14482      */
14483     public void setScrollBarFadeDuration(int scrollBarFadeDuration) {
14484         getScrollCache().scrollBarFadeDuration = scrollBarFadeDuration;
14485     }
14486
14487     /**
14488      *
14489      * Returns the scrollbar size.
14490      *
14491      * @return the scrollbar size
14492      *
14493      * @attr ref android.R.styleable#View_scrollbarSize
14494      */
14495     public int getScrollBarSize() {
14496         return mScrollCache == null ? ViewConfiguration.get(mContext).getScaledScrollBarSize() :
14497                 mScrollCache.scrollBarSize;
14498     }
14499
14500     /**
14501      * Define the scrollbar size.
14502      *
14503      * @param scrollBarSize - the scrollbar size
14504      *
14505      * @attr ref android.R.styleable#View_scrollbarSize
14506      */
14507     public void setScrollBarSize(int scrollBarSize) {
14508         getScrollCache().scrollBarSize = scrollBarSize;
14509     }
14510
14511     /**
14512      * <p>Specify the style of the scrollbars. The scrollbars can be overlaid or
14513      * inset. When inset, they add to the padding of the view. And the scrollbars
14514      * can be drawn inside the padding area or on the edge of the view. For example,
14515      * if a view has a background drawable and you want to draw the scrollbars
14516      * inside the padding specified by the drawable, you can use
14517      * SCROLLBARS_INSIDE_OVERLAY or SCROLLBARS_INSIDE_INSET. If you want them to
14518      * appear at the edge of the view, ignoring the padding, then you can use
14519      * SCROLLBARS_OUTSIDE_OVERLAY or SCROLLBARS_OUTSIDE_INSET.</p>
14520      * @param style the style of the scrollbars. Should be one of
14521      * SCROLLBARS_INSIDE_OVERLAY, SCROLLBARS_INSIDE_INSET,
14522      * SCROLLBARS_OUTSIDE_OVERLAY or SCROLLBARS_OUTSIDE_INSET.
14523      * @see #SCROLLBARS_INSIDE_OVERLAY
14524      * @see #SCROLLBARS_INSIDE_INSET
14525      * @see #SCROLLBARS_OUTSIDE_OVERLAY
14526      * @see #SCROLLBARS_OUTSIDE_INSET
14527      *
14528      * @attr ref android.R.styleable#View_scrollbarStyle
14529      */
14530     public void setScrollBarStyle(@ScrollBarStyle int style) {
14531         if (style != (mViewFlags & SCROLLBARS_STYLE_MASK)) {
14532             mViewFlags = (mViewFlags & ~SCROLLBARS_STYLE_MASK) | (style & SCROLLBARS_STYLE_MASK);
14533             computeOpaqueFlags();
14534             resolvePadding();
14535         }
14536     }
14537
14538     /**
14539      * <p>Returns the current scrollbar style.</p>
14540      * @return the current scrollbar style
14541      * @see #SCROLLBARS_INSIDE_OVERLAY
14542      * @see #SCROLLBARS_INSIDE_INSET
14543      * @see #SCROLLBARS_OUTSIDE_OVERLAY
14544      * @see #SCROLLBARS_OUTSIDE_INSET
14545      *
14546      * @attr ref android.R.styleable#View_scrollbarStyle
14547      */
14548     @ViewDebug.ExportedProperty(mapping = {
14549             @ViewDebug.IntToString(from = SCROLLBARS_INSIDE_OVERLAY, to = "INSIDE_OVERLAY"),
14550             @ViewDebug.IntToString(from = SCROLLBARS_INSIDE_INSET, to = "INSIDE_INSET"),
14551             @ViewDebug.IntToString(from = SCROLLBARS_OUTSIDE_OVERLAY, to = "OUTSIDE_OVERLAY"),
14552             @ViewDebug.IntToString(from = SCROLLBARS_OUTSIDE_INSET, to = "OUTSIDE_INSET")
14553     })
14554     @ScrollBarStyle
14555     public int getScrollBarStyle() {
14556         return mViewFlags & SCROLLBARS_STYLE_MASK;
14557     }
14558
14559     /**
14560      * <p>Compute the horizontal range that the horizontal scrollbar
14561      * represents.</p>
14562      *
14563      * <p>The range is expressed in arbitrary units that must be the same as the
14564      * units used by {@link #computeHorizontalScrollExtent()} and
14565      * {@link #computeHorizontalScrollOffset()}.</p>
14566      *
14567      * <p>The default range is the drawing width of this view.</p>
14568      *
14569      * @return the total horizontal range represented by the horizontal
14570      *         scrollbar
14571      *
14572      * @see #computeHorizontalScrollExtent()
14573      * @see #computeHorizontalScrollOffset()
14574      * @see android.widget.ScrollBarDrawable
14575      */
14576     protected int computeHorizontalScrollRange() {
14577         return getWidth();
14578     }
14579
14580     /**
14581      * <p>Compute the horizontal offset of the horizontal scrollbar's thumb
14582      * within the horizontal range. This value is used to compute the position
14583      * of the thumb within the scrollbar's track.</p>
14584      *
14585      * <p>The range is expressed in arbitrary units that must be the same as the
14586      * units used by {@link #computeHorizontalScrollRange()} and
14587      * {@link #computeHorizontalScrollExtent()}.</p>
14588      *
14589      * <p>The default offset is the scroll offset of this view.</p>
14590      *
14591      * @return the horizontal offset of the scrollbar's thumb
14592      *
14593      * @see #computeHorizontalScrollRange()
14594      * @see #computeHorizontalScrollExtent()
14595      * @see android.widget.ScrollBarDrawable
14596      */
14597     protected int computeHorizontalScrollOffset() {
14598         return mScrollX;
14599     }
14600
14601     /**
14602      * <p>Compute the horizontal extent of the horizontal scrollbar's thumb
14603      * within the horizontal range. This value is used to compute the length
14604      * of the thumb within the scrollbar's track.</p>
14605      *
14606      * <p>The range is expressed in arbitrary units that must be the same as the
14607      * units used by {@link #computeHorizontalScrollRange()} and
14608      * {@link #computeHorizontalScrollOffset()}.</p>
14609      *
14610      * <p>The default extent is the drawing width of this view.</p>
14611      *
14612      * @return the horizontal extent of the scrollbar's thumb
14613      *
14614      * @see #computeHorizontalScrollRange()
14615      * @see #computeHorizontalScrollOffset()
14616      * @see android.widget.ScrollBarDrawable
14617      */
14618     protected int computeHorizontalScrollExtent() {
14619         return getWidth();
14620     }
14621
14622     /**
14623      * <p>Compute the vertical range that the vertical scrollbar represents.</p>
14624      *
14625      * <p>The range is expressed in arbitrary units that must be the same as the
14626      * units used by {@link #computeVerticalScrollExtent()} and
14627      * {@link #computeVerticalScrollOffset()}.</p>
14628      *
14629      * @return the total vertical range represented by the vertical scrollbar
14630      *
14631      * <p>The default range is the drawing height of this view.</p>
14632      *
14633      * @see #computeVerticalScrollExtent()
14634      * @see #computeVerticalScrollOffset()
14635      * @see android.widget.ScrollBarDrawable
14636      */
14637     protected int computeVerticalScrollRange() {
14638         return getHeight();
14639     }
14640
14641     /**
14642      * <p>Compute the vertical offset of the vertical scrollbar's thumb
14643      * within the horizontal range. This value is used to compute the position
14644      * of the thumb within the scrollbar's track.</p>
14645      *
14646      * <p>The range is expressed in arbitrary units that must be the same as the
14647      * units used by {@link #computeVerticalScrollRange()} and
14648      * {@link #computeVerticalScrollExtent()}.</p>
14649      *
14650      * <p>The default offset is the scroll offset of this view.</p>
14651      *
14652      * @return the vertical offset of the scrollbar's thumb
14653      *
14654      * @see #computeVerticalScrollRange()
14655      * @see #computeVerticalScrollExtent()
14656      * @see android.widget.ScrollBarDrawable
14657      */
14658     protected int computeVerticalScrollOffset() {
14659         return mScrollY;
14660     }
14661
14662     /**
14663      * <p>Compute the vertical extent of the vertical scrollbar's thumb
14664      * within the vertical range. This value is used to compute the length
14665      * of the thumb within the scrollbar's track.</p>
14666      *
14667      * <p>The range is expressed in arbitrary units that must be the same as the
14668      * units used by {@link #computeVerticalScrollRange()} and
14669      * {@link #computeVerticalScrollOffset()}.</p>
14670      *
14671      * <p>The default extent is the drawing height of this view.</p>
14672      *
14673      * @return the vertical extent of the scrollbar's thumb
14674      *
14675      * @see #computeVerticalScrollRange()
14676      * @see #computeVerticalScrollOffset()
14677      * @see android.widget.ScrollBarDrawable
14678      */
14679     protected int computeVerticalScrollExtent() {
14680         return getHeight();
14681     }
14682
14683     /**
14684      * Check if this view can be scrolled horizontally in a certain direction.
14685      *
14686      * @param direction Negative to check scrolling left, positive to check scrolling right.
14687      * @return true if this view can be scrolled in the specified direction, false otherwise.
14688      */
14689     public boolean canScrollHorizontally(int direction) {
14690         final int offset = computeHorizontalScrollOffset();
14691         final int range = computeHorizontalScrollRange() - computeHorizontalScrollExtent();
14692         if (range == 0) return false;
14693         if (direction < 0) {
14694             return offset > 0;
14695         } else {
14696             return offset < range - 1;
14697         }
14698     }
14699
14700     /**
14701      * Check if this view can be scrolled vertically in a certain direction.
14702      *
14703      * @param direction Negative to check scrolling up, positive to check scrolling down.
14704      * @return true if this view can be scrolled in the specified direction, false otherwise.
14705      */
14706     public boolean canScrollVertically(int direction) {
14707         final int offset = computeVerticalScrollOffset();
14708         final int range = computeVerticalScrollRange() - computeVerticalScrollExtent();
14709         if (range == 0) return false;
14710         if (direction < 0) {
14711             return offset > 0;
14712         } else {
14713             return offset < range - 1;
14714         }
14715     }
14716
14717     void getScrollIndicatorBounds(@NonNull Rect out) {
14718         out.left = mScrollX;
14719         out.right = mScrollX + mRight - mLeft;
14720         out.top = mScrollY;
14721         out.bottom = mScrollY + mBottom - mTop;
14722     }
14723
14724     private void onDrawScrollIndicators(Canvas c) {
14725         if ((mPrivateFlags3 & SCROLL_INDICATORS_PFLAG3_MASK) == 0) {
14726             // No scroll indicators enabled.
14727             return;
14728         }
14729
14730         final Drawable dr = mScrollIndicatorDrawable;
14731         if (dr == null) {
14732             // Scroll indicators aren't supported here.
14733             return;
14734         }
14735
14736         final int h = dr.getIntrinsicHeight();
14737         final int w = dr.getIntrinsicWidth();
14738         final Rect rect = mAttachInfo.mTmpInvalRect;
14739         getScrollIndicatorBounds(rect);
14740
14741         if ((mPrivateFlags3 & PFLAG3_SCROLL_INDICATOR_TOP) != 0) {
14742             final boolean canScrollUp = canScrollVertically(-1);
14743             if (canScrollUp) {
14744                 dr.setBounds(rect.left, rect.top, rect.right, rect.top + h);
14745                 dr.draw(c);
14746             }
14747         }
14748
14749         if ((mPrivateFlags3 & PFLAG3_SCROLL_INDICATOR_BOTTOM) != 0) {
14750             final boolean canScrollDown = canScrollVertically(1);
14751             if (canScrollDown) {
14752                 dr.setBounds(rect.left, rect.bottom - h, rect.right, rect.bottom);
14753                 dr.draw(c);
14754             }
14755         }
14756
14757         final int leftRtl;
14758         final int rightRtl;
14759         if (getLayoutDirection() == LAYOUT_DIRECTION_RTL) {
14760             leftRtl = PFLAG3_SCROLL_INDICATOR_END;
14761             rightRtl = PFLAG3_SCROLL_INDICATOR_START;
14762         } else {
14763             leftRtl = PFLAG3_SCROLL_INDICATOR_START;
14764             rightRtl = PFLAG3_SCROLL_INDICATOR_END;
14765         }
14766
14767         final int leftMask = PFLAG3_SCROLL_INDICATOR_LEFT | leftRtl;
14768         if ((mPrivateFlags3 & leftMask) != 0) {
14769             final boolean canScrollLeft = canScrollHorizontally(-1);
14770             if (canScrollLeft) {
14771                 dr.setBounds(rect.left, rect.top, rect.left + w, rect.bottom);
14772                 dr.draw(c);
14773             }
14774         }
14775
14776         final int rightMask = PFLAG3_SCROLL_INDICATOR_RIGHT | rightRtl;
14777         if ((mPrivateFlags3 & rightMask) != 0) {
14778             final boolean canScrollRight = canScrollHorizontally(1);
14779             if (canScrollRight) {
14780                 dr.setBounds(rect.right - w, rect.top, rect.right, rect.bottom);
14781                 dr.draw(c);
14782             }
14783         }
14784     }
14785
14786     private void getHorizontalScrollBarBounds(Rect bounds) {
14787         final int inside = (mViewFlags & SCROLLBARS_OUTSIDE_MASK) == 0 ? ~0 : 0;
14788         final boolean drawVerticalScrollBar = isVerticalScrollBarEnabled()
14789                 && !isVerticalScrollBarHidden();
14790         final int size = getHorizontalScrollbarHeight();
14791         final int verticalScrollBarGap = drawVerticalScrollBar ?
14792                 getVerticalScrollbarWidth() : 0;
14793         final int width = mRight - mLeft;
14794         final int height = mBottom - mTop;
14795         bounds.top = mScrollY + height - size - (mUserPaddingBottom & inside);
14796         bounds.left = mScrollX + (mPaddingLeft & inside);
14797         bounds.right = mScrollX + width - (mUserPaddingRight & inside) - verticalScrollBarGap;
14798         bounds.bottom = bounds.top + size;
14799     }
14800
14801     private void getVerticalScrollBarBounds(Rect bounds) {
14802         if (mRoundScrollbarRenderer == null) {
14803             getStraightVerticalScrollBarBounds(bounds);
14804         } else {
14805             getRoundVerticalScrollBarBounds(bounds);
14806         }
14807     }
14808
14809     private void getRoundVerticalScrollBarBounds(Rect bounds) {
14810         final int width = mRight - mLeft;
14811         final int height = mBottom - mTop;
14812         // Do not take padding into account as we always want the scrollbars
14813         // to hug the screen for round wearable devices.
14814         bounds.left = mScrollX;
14815         bounds.top = mScrollY;
14816         bounds.right = bounds.left + width;
14817         bounds.bottom = mScrollY + height;
14818     }
14819
14820     private void getStraightVerticalScrollBarBounds(Rect bounds) {
14821         final int inside = (mViewFlags & SCROLLBARS_OUTSIDE_MASK) == 0 ? ~0 : 0;
14822         final int size = getVerticalScrollbarWidth();
14823         int verticalScrollbarPosition = mVerticalScrollbarPosition;
14824         if (verticalScrollbarPosition == SCROLLBAR_POSITION_DEFAULT) {
14825             verticalScrollbarPosition = isLayoutRtl() ?
14826                     SCROLLBAR_POSITION_LEFT : SCROLLBAR_POSITION_RIGHT;
14827         }
14828         final int width = mRight - mLeft;
14829         final int height = mBottom - mTop;
14830         switch (verticalScrollbarPosition) {
14831             default:
14832             case SCROLLBAR_POSITION_RIGHT:
14833                 bounds.left = mScrollX + width - size - (mUserPaddingRight & inside);
14834                 break;
14835             case SCROLLBAR_POSITION_LEFT:
14836                 bounds.left = mScrollX + (mUserPaddingLeft & inside);
14837                 break;
14838         }
14839         bounds.top = mScrollY + (mPaddingTop & inside);
14840         bounds.right = bounds.left + size;
14841         bounds.bottom = mScrollY + height - (mUserPaddingBottom & inside);
14842     }
14843
14844     /**
14845      * <p>Request the drawing of the horizontal and the vertical scrollbar. The
14846      * scrollbars are painted only if they have been awakened first.</p>
14847      *
14848      * @param canvas the canvas on which to draw the scrollbars
14849      *
14850      * @see #awakenScrollBars(int)
14851      */
14852     protected final void onDrawScrollBars(Canvas canvas) {
14853         // scrollbars are drawn only when the animation is running
14854         final ScrollabilityCache cache = mScrollCache;
14855
14856         if (cache != null) {
14857
14858             int state = cache.state;
14859
14860             if (state == ScrollabilityCache.OFF) {
14861                 return;
14862             }
14863
14864             boolean invalidate = false;
14865
14866             if (state == ScrollabilityCache.FADING) {
14867                 // We're fading -- get our fade interpolation
14868                 if (cache.interpolatorValues == null) {
14869                     cache.interpolatorValues = new float[1];
14870                 }
14871
14872                 float[] values = cache.interpolatorValues;
14873
14874                 // Stops the animation if we're done
14875                 if (cache.scrollBarInterpolator.timeToValues(values) ==
14876                         Interpolator.Result.FREEZE_END) {
14877                     cache.state = ScrollabilityCache.OFF;
14878                 } else {
14879                     cache.scrollBar.mutate().setAlpha(Math.round(values[0]));
14880                 }
14881
14882                 // This will make the scroll bars inval themselves after
14883                 // drawing. We only want this when we're fading so that
14884                 // we prevent excessive redraws
14885                 invalidate = true;
14886             } else {
14887                 // We're just on -- but we may have been fading before so
14888                 // reset alpha
14889                 cache.scrollBar.mutate().setAlpha(255);
14890             }
14891
14892             final boolean drawHorizontalScrollBar = isHorizontalScrollBarEnabled();
14893             final boolean drawVerticalScrollBar = isVerticalScrollBarEnabled()
14894                     && !isVerticalScrollBarHidden();
14895
14896             // Fork out the scroll bar drawing for round wearable devices.
14897             if (mRoundScrollbarRenderer != null) {
14898                 if (drawVerticalScrollBar) {
14899                     final Rect bounds = cache.mScrollBarBounds;
14900                     getVerticalScrollBarBounds(bounds);
14901                     mRoundScrollbarRenderer.drawRoundScrollbars(
14902                             canvas, (float) cache.scrollBar.getAlpha() / 255f, bounds);
14903                     if (invalidate) {
14904                         invalidate();
14905                     }
14906                 }
14907                 // Do not draw horizontal scroll bars for round wearable devices.
14908             } else if (drawVerticalScrollBar || drawHorizontalScrollBar) {
14909                 final ScrollBarDrawable scrollBar = cache.scrollBar;
14910
14911                 if (drawHorizontalScrollBar) {
14912                     scrollBar.setParameters(computeHorizontalScrollRange(),
14913                             computeHorizontalScrollOffset(),
14914                             computeHorizontalScrollExtent(), false);
14915                     final Rect bounds = cache.mScrollBarBounds;
14916                     getHorizontalScrollBarBounds(bounds);
14917                     onDrawHorizontalScrollBar(canvas, scrollBar, bounds.left, bounds.top,
14918                             bounds.right, bounds.bottom);
14919                     if (invalidate) {
14920                         invalidate(bounds);
14921                     }
14922                 }
14923
14924                 if (drawVerticalScrollBar) {
14925                     scrollBar.setParameters(computeVerticalScrollRange(),
14926                             computeVerticalScrollOffset(),
14927                             computeVerticalScrollExtent(), true);
14928                     final Rect bounds = cache.mScrollBarBounds;
14929                     getVerticalScrollBarBounds(bounds);
14930                     onDrawVerticalScrollBar(canvas, scrollBar, bounds.left, bounds.top,
14931                             bounds.right, bounds.bottom);
14932                     if (invalidate) {
14933                         invalidate(bounds);
14934                     }
14935                 }
14936             }
14937         }
14938     }
14939
14940     /**
14941      * Override this if the vertical scrollbar needs to be hidden in a subclass, like when
14942      * FastScroller is visible.
14943      * @return whether to temporarily hide the vertical scrollbar
14944      * @hide
14945      */
14946     protected boolean isVerticalScrollBarHidden() {
14947         return false;
14948     }
14949
14950     /**
14951      * <p>Draw the horizontal scrollbar if
14952      * {@link #isHorizontalScrollBarEnabled()} returns true.</p>
14953      *
14954      * @param canvas the canvas on which to draw the scrollbar
14955      * @param scrollBar the scrollbar's drawable
14956      *
14957      * @see #isHorizontalScrollBarEnabled()
14958      * @see #computeHorizontalScrollRange()
14959      * @see #computeHorizontalScrollExtent()
14960      * @see #computeHorizontalScrollOffset()
14961      * @see android.widget.ScrollBarDrawable
14962      * @hide
14963      */
14964     protected void onDrawHorizontalScrollBar(Canvas canvas, Drawable scrollBar,
14965             int l, int t, int r, int b) {
14966         scrollBar.setBounds(l, t, r, b);
14967         scrollBar.draw(canvas);
14968     }
14969
14970     /**
14971      * <p>Draw the vertical scrollbar if {@link #isVerticalScrollBarEnabled()}
14972      * returns true.</p>
14973      *
14974      * @param canvas the canvas on which to draw the scrollbar
14975      * @param scrollBar the scrollbar's drawable
14976      *
14977      * @see #isVerticalScrollBarEnabled()
14978      * @see #computeVerticalScrollRange()
14979      * @see #computeVerticalScrollExtent()
14980      * @see #computeVerticalScrollOffset()
14981      * @see android.widget.ScrollBarDrawable
14982      * @hide
14983      */
14984     protected void onDrawVerticalScrollBar(Canvas canvas, Drawable scrollBar,
14985             int l, int t, int r, int b) {
14986         scrollBar.setBounds(l, t, r, b);
14987         scrollBar.draw(canvas);
14988     }
14989
14990     /**
14991      * Implement this to do your drawing.
14992      *
14993      * @param canvas the canvas on which the background will be drawn
14994      */
14995     protected void onDraw(Canvas canvas) {
14996     }
14997
14998     /*
14999      * Caller is responsible for calling requestLayout if necessary.
15000      * (This allows addViewInLayout to not request a new layout.)
15001      */
15002     void assignParent(ViewParent parent) {
15003         if (mParent == null) {
15004             mParent = parent;
15005         } else if (parent == null) {
15006             mParent = null;
15007         } else {
15008             throw new RuntimeException("view " + this + " being added, but"
15009                     + " it already has a parent");
15010         }
15011     }
15012
15013     /**
15014      * This is called when the view is attached to a window.  At this point it
15015      * has a Surface and will start drawing.  Note that this function is
15016      * guaranteed to be called before {@link #onDraw(android.graphics.Canvas)},
15017      * however it may be called any time before the first onDraw -- including
15018      * before or after {@link #onMeasure(int, int)}.
15019      *
15020      * @see #onDetachedFromWindow()
15021      */
15022     @CallSuper
15023     protected void onAttachedToWindow() {
15024         if ((mPrivateFlags & PFLAG_REQUEST_TRANSPARENT_REGIONS) != 0) {
15025             mParent.requestTransparentRegion(this);
15026         }
15027
15028         mPrivateFlags3 &= ~PFLAG3_IS_LAID_OUT;
15029
15030         jumpDrawablesToCurrentState();
15031
15032         resetSubtreeAccessibilityStateChanged();
15033
15034         // rebuild, since Outline not maintained while View is detached
15035         rebuildOutline();
15036
15037         if (isFocused()) {
15038             InputMethodManager imm = InputMethodManager.peekInstance();
15039             if (imm != null) {
15040                 imm.focusIn(this);
15041             }
15042         }
15043     }
15044
15045     /**
15046      * Resolve all RTL related properties.
15047      *
15048      * @return true if resolution of RTL properties has been done
15049      *
15050      * @hide
15051      */
15052     public boolean resolveRtlPropertiesIfNeeded() {
15053         if (!needRtlPropertiesResolution()) return false;
15054
15055         // Order is important here: LayoutDirection MUST be resolved first
15056         if (!isLayoutDirectionResolved()) {
15057             resolveLayoutDirection();
15058             resolveLayoutParams();
15059         }
15060         // ... then we can resolve the others properties depending on the resolved LayoutDirection.
15061         if (!isTextDirectionResolved()) {
15062             resolveTextDirection();
15063         }
15064         if (!isTextAlignmentResolved()) {
15065             resolveTextAlignment();
15066         }
15067         // Should resolve Drawables before Padding because we need the layout direction of the
15068         // Drawable to correctly resolve Padding.
15069         if (!areDrawablesResolved()) {
15070             resolveDrawables();
15071         }
15072         if (!isPaddingResolved()) {
15073             resolvePadding();
15074         }
15075         onRtlPropertiesChanged(getLayoutDirection());
15076         return true;
15077     }
15078
15079     /**
15080      * Reset resolution of all RTL related properties.
15081      *
15082      * @hide
15083      */
15084     public void resetRtlProperties() {
15085         resetResolvedLayoutDirection();
15086         resetResolvedTextDirection();
15087         resetResolvedTextAlignment();
15088         resetResolvedPadding();
15089         resetResolvedDrawables();
15090     }
15091
15092     /**
15093      * @see #onScreenStateChanged(int)
15094      */
15095     void dispatchScreenStateChanged(int screenState) {
15096         onScreenStateChanged(screenState);
15097     }
15098
15099     /**
15100      * This method is called whenever the state of the screen this view is
15101      * attached to changes. A state change will usually occurs when the screen
15102      * turns on or off (whether it happens automatically or the user does it
15103      * manually.)
15104      *
15105      * @param screenState The new state of the screen. Can be either
15106      *                    {@link #SCREEN_STATE_ON} or {@link #SCREEN_STATE_OFF}
15107      */
15108     public void onScreenStateChanged(int screenState) {
15109     }
15110
15111     /**
15112      * Return true if the application tag in the AndroidManifest has set "supportRtl" to true
15113      */
15114     private boolean hasRtlSupport() {
15115         return mContext.getApplicationInfo().hasRtlSupport();
15116     }
15117
15118     /**
15119      * Return true if we are in RTL compatibility mode (either before Jelly Bean MR1 or
15120      * RTL not supported)
15121      */
15122     private boolean isRtlCompatibilityMode() {
15123         final int targetSdkVersion = getContext().getApplicationInfo().targetSdkVersion;
15124         return targetSdkVersion < JELLY_BEAN_MR1 || !hasRtlSupport();
15125     }
15126
15127     /**
15128      * @return true if RTL properties need resolution.
15129      *
15130      */
15131     private boolean needRtlPropertiesResolution() {
15132         return (mPrivateFlags2 & ALL_RTL_PROPERTIES_RESOLVED) != ALL_RTL_PROPERTIES_RESOLVED;
15133     }
15134
15135     /**
15136      * Called when any RTL property (layout direction or text direction or text alignment) has
15137      * been changed.
15138      *
15139      * Subclasses need to override this method to take care of cached information that depends on the
15140      * resolved layout direction, or to inform child views that inherit their layout direction.
15141      *
15142      * The default implementation does nothing.
15143      *
15144      * @param layoutDirection the direction of the layout
15145      *
15146      * @see #LAYOUT_DIRECTION_LTR
15147      * @see #LAYOUT_DIRECTION_RTL
15148      */
15149     public void onRtlPropertiesChanged(@ResolvedLayoutDir int layoutDirection) {
15150     }
15151
15152     /**
15153      * Resolve and cache the layout direction. LTR is set initially. This is implicitly supposing
15154      * that the parent directionality can and will be resolved before its children.
15155      *
15156      * @return true if resolution has been done, false otherwise.
15157      *
15158      * @hide
15159      */
15160     public boolean resolveLayoutDirection() {
15161         // Clear any previous layout direction resolution
15162         mPrivateFlags2 &= ~PFLAG2_LAYOUT_DIRECTION_RESOLVED_MASK;
15163
15164         if (hasRtlSupport()) {
15165             // Set resolved depending on layout direction
15166             switch ((mPrivateFlags2 & PFLAG2_LAYOUT_DIRECTION_MASK) >>
15167                     PFLAG2_LAYOUT_DIRECTION_MASK_SHIFT) {
15168                 case LAYOUT_DIRECTION_INHERIT:
15169                     // We cannot resolve yet. LTR is by default and let the resolution happen again
15170                     // later to get the correct resolved value
15171                     if (!canResolveLayoutDirection()) return false;
15172
15173                     // Parent has not yet resolved, LTR is still the default
15174                     try {
15175                         if (!mParent.isLayoutDirectionResolved()) return false;
15176
15177                         if (mParent.getLayoutDirection() == LAYOUT_DIRECTION_RTL) {
15178                             mPrivateFlags2 |= PFLAG2_LAYOUT_DIRECTION_RESOLVED_RTL;
15179                         }
15180                     } catch (AbstractMethodError e) {
15181                         Log.e(VIEW_LOG_TAG, mParent.getClass().getSimpleName() +
15182                                 " does not fully implement ViewParent", e);
15183                     }
15184                     break;
15185                 case LAYOUT_DIRECTION_RTL:
15186                     mPrivateFlags2 |= PFLAG2_LAYOUT_DIRECTION_RESOLVED_RTL;
15187                     break;
15188                 case LAYOUT_DIRECTION_LOCALE:
15189                     if((LAYOUT_DIRECTION_RTL ==
15190                             TextUtils.getLayoutDirectionFromLocale(Locale.getDefault()))) {
15191                         mPrivateFlags2 |= PFLAG2_LAYOUT_DIRECTION_RESOLVED_RTL;
15192                     }
15193                     break;
15194                 default:
15195                     // Nothing to do, LTR by default
15196             }
15197         }
15198
15199         // Set to resolved
15200         mPrivateFlags2 |= PFLAG2_LAYOUT_DIRECTION_RESOLVED;
15201         return true;
15202     }
15203
15204     /**
15205      * Check if layout direction resolution can be done.
15206      *
15207      * @return true if layout direction resolution can be done otherwise return false.
15208      */
15209     public boolean canResolveLayoutDirection() {
15210         switch (getRawLayoutDirection()) {
15211             case LAYOUT_DIRECTION_INHERIT:
15212                 if (mParent != null) {
15213                     try {
15214                         return mParent.canResolveLayoutDirection();
15215                     } catch (AbstractMethodError e) {
15216                         Log.e(VIEW_LOG_TAG, mParent.getClass().getSimpleName() +
15217                                 " does not fully implement ViewParent", e);
15218                     }
15219                 }
15220                 return false;
15221
15222             default:
15223                 return true;
15224         }
15225     }
15226
15227     /**
15228      * Reset the resolved layout direction. Layout direction will be resolved during a call to
15229      * {@link #onMeasure(int, int)}.
15230      *
15231      * @hide
15232      */
15233     public void resetResolvedLayoutDirection() {
15234         // Reset the current resolved bits
15235         mPrivateFlags2 &= ~PFLAG2_LAYOUT_DIRECTION_RESOLVED_MASK;
15236     }
15237
15238     /**
15239      * @return true if the layout direction is inherited.
15240      *
15241      * @hide
15242      */
15243     public boolean isLayoutDirectionInherited() {
15244         return (getRawLayoutDirection() == LAYOUT_DIRECTION_INHERIT);
15245     }
15246
15247     /**
15248      * @return true if layout direction has been resolved.
15249      */
15250     public boolean isLayoutDirectionResolved() {
15251         return (mPrivateFlags2 & PFLAG2_LAYOUT_DIRECTION_RESOLVED) == PFLAG2_LAYOUT_DIRECTION_RESOLVED;
15252     }
15253
15254     /**
15255      * Return if padding has been resolved
15256      *
15257      * @hide
15258      */
15259     boolean isPaddingResolved() {
15260         return (mPrivateFlags2 & PFLAG2_PADDING_RESOLVED) == PFLAG2_PADDING_RESOLVED;
15261     }
15262
15263     /**
15264      * Resolves padding depending on layout direction, if applicable, and
15265      * recomputes internal padding values to adjust for scroll bars.
15266      *
15267      * @hide
15268      */
15269     public void resolvePadding() {
15270         final int resolvedLayoutDirection = getLayoutDirection();
15271
15272         if (!isRtlCompatibilityMode()) {
15273             // Post Jelly Bean MR1 case: we need to take the resolved layout direction into account.
15274             // If start / end padding are defined, they will be resolved (hence overriding) to
15275             // left / right or right / left depending on the resolved layout direction.
15276             // If start / end padding are not defined, use the left / right ones.
15277             if (mBackground != null && (!mLeftPaddingDefined || !mRightPaddingDefined)) {
15278                 Rect padding = sThreadLocal.get();
15279                 if (padding == null) {
15280                     padding = new Rect();
15281                     sThreadLocal.set(padding);
15282                 }
15283                 mBackground.getPadding(padding);
15284                 if (!mLeftPaddingDefined) {
15285                     mUserPaddingLeftInitial = padding.left;
15286                 }
15287                 if (!mRightPaddingDefined) {
15288                     mUserPaddingRightInitial = padding.right;
15289                 }
15290             }
15291             switch (resolvedLayoutDirection) {
15292                 case LAYOUT_DIRECTION_RTL:
15293                     if (mUserPaddingStart != UNDEFINED_PADDING) {
15294                         mUserPaddingRight = mUserPaddingStart;
15295                     } else {
15296                         mUserPaddingRight = mUserPaddingRightInitial;
15297                     }
15298                     if (mUserPaddingEnd != UNDEFINED_PADDING) {
15299                         mUserPaddingLeft = mUserPaddingEnd;
15300                     } else {
15301                         mUserPaddingLeft = mUserPaddingLeftInitial;
15302                     }
15303                     break;
15304                 case LAYOUT_DIRECTION_LTR:
15305                 default:
15306                     if (mUserPaddingStart != UNDEFINED_PADDING) {
15307                         mUserPaddingLeft = mUserPaddingStart;
15308                     } else {
15309                         mUserPaddingLeft = mUserPaddingLeftInitial;
15310                     }
15311                     if (mUserPaddingEnd != UNDEFINED_PADDING) {
15312                         mUserPaddingRight = mUserPaddingEnd;
15313                     } else {
15314                         mUserPaddingRight = mUserPaddingRightInitial;
15315                     }
15316             }
15317
15318             mUserPaddingBottom = (mUserPaddingBottom >= 0) ? mUserPaddingBottom : mPaddingBottom;
15319         }
15320
15321         internalSetPadding(mUserPaddingLeft, mPaddingTop, mUserPaddingRight, mUserPaddingBottom);
15322         onRtlPropertiesChanged(resolvedLayoutDirection);
15323
15324         mPrivateFlags2 |= PFLAG2_PADDING_RESOLVED;
15325     }
15326
15327     /**
15328      * Reset the resolved layout direction.
15329      *
15330      * @hide
15331      */
15332     public void resetResolvedPadding() {
15333         resetResolvedPaddingInternal();
15334     }
15335
15336     /**
15337      * Used when we only want to reset *this* view's padding and not trigger overrides
15338      * in ViewGroup that reset children too.
15339      */
15340     void resetResolvedPaddingInternal() {
15341         mPrivateFlags2 &= ~PFLAG2_PADDING_RESOLVED;
15342     }
15343
15344     /**
15345      * This is called when the view is detached from a window.  At this point it
15346      * no longer has a surface for drawing.
15347      *
15348      * @see #onAttachedToWindow()
15349      */
15350     @CallSuper
15351     protected void onDetachedFromWindow() {
15352     }
15353
15354     /**
15355      * This is a framework-internal mirror of onDetachedFromWindow() that's called
15356      * after onDetachedFromWindow().
15357      *
15358      * If you override this you *MUST* call super.onDetachedFromWindowInternal()!
15359      * The super method should be called at the end of the overridden method to ensure
15360      * subclasses are destroyed first
15361      *
15362      * @hide
15363      */
15364     @CallSuper
15365     protected void onDetachedFromWindowInternal() {
15366         mPrivateFlags &= ~PFLAG_CANCEL_NEXT_UP_EVENT;
15367         mPrivateFlags3 &= ~PFLAG3_IS_LAID_OUT;
15368         mPrivateFlags3 &= ~PFLAG3_TEMPORARY_DETACH;
15369
15370         removeUnsetPressCallback();
15371         removeLongPressCallback();
15372         removePerformClickCallback();
15373         removeSendViewScrolledAccessibilityEventCallback();
15374         stopNestedScroll();
15375
15376         // Anything that started animating right before detach should already
15377         // be in its final state when re-attached.
15378         jumpDrawablesToCurrentState();
15379
15380         destroyDrawingCache();
15381
15382         cleanupDraw();
15383         mCurrentAnimation = null;
15384     }
15385
15386     private void cleanupDraw() {
15387         resetDisplayList();
15388         if (mAttachInfo != null) {
15389             mAttachInfo.mViewRootImpl.cancelInvalidate(this);
15390         }
15391     }
15392
15393     void invalidateInheritedLayoutMode(int layoutModeOfRoot) {
15394     }
15395
15396     /**
15397      * @return The number of times this view has been attached to a window
15398      */
15399     protected int getWindowAttachCount() {
15400         return mWindowAttachCount;
15401     }
15402
15403     /**
15404      * Retrieve a unique token identifying the window this view is attached to.
15405      * @return Return the window's token for use in
15406      * {@link WindowManager.LayoutParams#token WindowManager.LayoutParams.token}.
15407      */
15408     public IBinder getWindowToken() {
15409         return mAttachInfo != null ? mAttachInfo.mWindowToken : null;
15410     }
15411
15412     /**
15413      * Retrieve the {@link WindowId} for the window this view is
15414      * currently attached to.
15415      */
15416     public WindowId getWindowId() {
15417         if (mAttachInfo == null) {
15418             return null;
15419         }
15420         if (mAttachInfo.mWindowId == null) {
15421             try {
15422                 mAttachInfo.mIWindowId = mAttachInfo.mSession.getWindowId(
15423                         mAttachInfo.mWindowToken);
15424                 mAttachInfo.mWindowId = new WindowId(
15425                         mAttachInfo.mIWindowId);
15426             } catch (RemoteException e) {
15427             }
15428         }
15429         return mAttachInfo.mWindowId;
15430     }
15431
15432     /**
15433      * Retrieve a unique token identifying the top-level "real" window of
15434      * the window that this view is attached to.  That is, this is like
15435      * {@link #getWindowToken}, except if the window this view in is a panel
15436      * window (attached to another containing window), then the token of
15437      * the containing window is returned instead.
15438      *
15439      * @return Returns the associated window token, either
15440      * {@link #getWindowToken()} or the containing window's token.
15441      */
15442     public IBinder getApplicationWindowToken() {
15443         AttachInfo ai = mAttachInfo;
15444         if (ai != null) {
15445             IBinder appWindowToken = ai.mPanelParentWindowToken;
15446             if (appWindowToken == null) {
15447                 appWindowToken = ai.mWindowToken;
15448             }
15449             return appWindowToken;
15450         }
15451         return null;
15452     }
15453
15454     /**
15455      * Gets the logical display to which the view's window has been attached.
15456      *
15457      * @return The logical display, or null if the view is not currently attached to a window.
15458      */
15459     public Display getDisplay() {
15460         return mAttachInfo != null ? mAttachInfo.mDisplay : null;
15461     }
15462
15463     /**
15464      * Retrieve private session object this view hierarchy is using to
15465      * communicate with the window manager.
15466      * @return the session object to communicate with the window manager
15467      */
15468     /*package*/ IWindowSession getWindowSession() {
15469         return mAttachInfo != null ? mAttachInfo.mSession : null;
15470     }
15471
15472     /**
15473      * Return the visibility value of the least visible component passed.
15474      */
15475     int combineVisibility(int vis1, int vis2) {
15476         // This works because VISIBLE < INVISIBLE < GONE.
15477         return Math.max(vis1, vis2);
15478     }
15479
15480     /**
15481      * @param info the {@link android.view.View.AttachInfo} to associated with
15482      *        this view
15483      */
15484     void dispatchAttachedToWindow(AttachInfo info, int visibility) {
15485         mAttachInfo = info;
15486         if (mOverlay != null) {
15487             mOverlay.getOverlayView().dispatchAttachedToWindow(info, visibility);
15488         }
15489         mWindowAttachCount++;
15490         // We will need to evaluate the drawable state at least once.
15491         mPrivateFlags |= PFLAG_DRAWABLE_STATE_DIRTY;
15492         if (mFloatingTreeObserver != null) {
15493             info.mTreeObserver.merge(mFloatingTreeObserver);
15494             mFloatingTreeObserver = null;
15495         }
15496
15497         registerPendingFrameMetricsObservers();
15498
15499         if ((mPrivateFlags&PFLAG_SCROLL_CONTAINER) != 0) {
15500             mAttachInfo.mScrollContainers.add(this);
15501             mPrivateFlags |= PFLAG_SCROLL_CONTAINER_ADDED;
15502         }
15503         // Transfer all pending runnables.
15504         if (mRunQueue != null) {
15505             mRunQueue.executeActions(info.mHandler);
15506             mRunQueue = null;
15507         }
15508         performCollectViewAttributes(mAttachInfo, visibility);
15509         onAttachedToWindow();
15510
15511         ListenerInfo li = mListenerInfo;
15512         final CopyOnWriteArrayList<OnAttachStateChangeListener> listeners =
15513                 li != null ? li.mOnAttachStateChangeListeners : null;
15514         if (listeners != null && listeners.size() > 0) {
15515             // NOTE: because of the use of CopyOnWriteArrayList, we *must* use an iterator to
15516             // perform the dispatching. The iterator is a safe guard against listeners that
15517             // could mutate the list by calling the various add/remove methods. This prevents
15518             // the array from being modified while we iterate it.
15519             for (OnAttachStateChangeListener listener : listeners) {
15520                 listener.onViewAttachedToWindow(this);
15521             }
15522         }
15523
15524         int vis = info.mWindowVisibility;
15525         if (vis != GONE) {
15526             onWindowVisibilityChanged(vis);
15527             if (isShown()) {
15528                 // Calling onVisibilityAggregated directly here since the subtree will also
15529                 // receive dispatchAttachedToWindow and this same call
15530                 onVisibilityAggregated(vis == VISIBLE);
15531             }
15532         }
15533
15534         // Send onVisibilityChanged directly instead of dispatchVisibilityChanged.
15535         // As all views in the subtree will already receive dispatchAttachedToWindow
15536         // traversing the subtree again here is not desired.
15537         onVisibilityChanged(this, visibility);
15538
15539         if ((mPrivateFlags&PFLAG_DRAWABLE_STATE_DIRTY) != 0) {
15540             // If nobody has evaluated the drawable state yet, then do it now.
15541             refreshDrawableState();
15542         }
15543         needGlobalAttributesUpdate(false);
15544     }
15545
15546     void dispatchDetachedFromWindow() {
15547         AttachInfo info = mAttachInfo;
15548         if (info != null) {
15549             int vis = info.mWindowVisibility;
15550             if (vis != GONE) {
15551                 onWindowVisibilityChanged(GONE);
15552                 if (isShown()) {
15553                     // Invoking onVisibilityAggregated directly here since the subtree
15554                     // will also receive detached from window
15555                     onVisibilityAggregated(false);
15556                 }
15557             }
15558         }
15559
15560         onDetachedFromWindow();
15561         onDetachedFromWindowInternal();
15562
15563         InputMethodManager imm = InputMethodManager.peekInstance();
15564         if (imm != null) {
15565             imm.onViewDetachedFromWindow(this);
15566         }
15567
15568         ListenerInfo li = mListenerInfo;
15569         final CopyOnWriteArrayList<OnAttachStateChangeListener> listeners =
15570                 li != null ? li.mOnAttachStateChangeListeners : null;
15571         if (listeners != null && listeners.size() > 0) {
15572             // NOTE: because of the use of CopyOnWriteArrayList, we *must* use an iterator to
15573             // perform the dispatching. The iterator is a safe guard against listeners that
15574             // could mutate the list by calling the various add/remove methods. This prevents
15575             // the array from being modified while we iterate it.
15576             for (OnAttachStateChangeListener listener : listeners) {
15577                 listener.onViewDetachedFromWindow(this);
15578             }
15579         }
15580
15581         if ((mPrivateFlags & PFLAG_SCROLL_CONTAINER_ADDED) != 0) {
15582             mAttachInfo.mScrollContainers.remove(this);
15583             mPrivateFlags &= ~PFLAG_SCROLL_CONTAINER_ADDED;
15584         }
15585
15586         mAttachInfo = null;
15587         if (mOverlay != null) {
15588             mOverlay.getOverlayView().dispatchDetachedFromWindow();
15589         }
15590     }
15591
15592     /**
15593      * Cancel any deferred high-level input events that were previously posted to the event queue.
15594      *
15595      * <p>Many views post high-level events such as click handlers to the event queue
15596      * to run deferred in order to preserve a desired user experience - clearing visible
15597      * pressed states before executing, etc. This method will abort any events of this nature
15598      * that are currently in flight.</p>
15599      *
15600      * <p>Custom views that generate their own high-level deferred input events should override
15601      * {@link #onCancelPendingInputEvents()} and remove those pending events from the queue.</p>
15602      *
15603      * <p>This will also cancel pending input events for any child views.</p>
15604      *
15605      * <p>Note that this may not be sufficient as a debouncing strategy for clicks in all cases.
15606      * This will not impact newer events posted after this call that may occur as a result of
15607      * lower-level input events still waiting in the queue. If you are trying to prevent
15608      * double-submitted  events for the duration of some sort of asynchronous transaction
15609      * you should also take other steps to protect against unexpected double inputs e.g. calling
15610      * {@link #setEnabled(boolean) setEnabled(false)} and re-enabling the view when
15611      * the transaction completes, tracking already submitted transaction IDs, etc.</p>
15612      */
15613     public final void cancelPendingInputEvents() {
15614         dispatchCancelPendingInputEvents();
15615     }
15616
15617     /**
15618      * Called by {@link #cancelPendingInputEvents()} to cancel input events in flight.
15619      * Overridden by ViewGroup to dispatch. Package scoped to prevent app-side meddling.
15620      */
15621     void dispatchCancelPendingInputEvents() {
15622         mPrivateFlags3 &= ~PFLAG3_CALLED_SUPER;
15623         onCancelPendingInputEvents();
15624         if ((mPrivateFlags3 & PFLAG3_CALLED_SUPER) != PFLAG3_CALLED_SUPER) {
15625             throw new SuperNotCalledException("View " + getClass().getSimpleName() +
15626                     " did not call through to super.onCancelPendingInputEvents()");
15627         }
15628     }
15629
15630     /**
15631      * Called as the result of a call to {@link #cancelPendingInputEvents()} on this view or
15632      * a parent view.
15633      *
15634      * <p>This method is responsible for removing any pending high-level input events that were
15635      * posted to the event queue to run later. Custom view classes that post their own deferred
15636      * high-level events via {@link #post(Runnable)}, {@link #postDelayed(Runnable, long)} or
15637      * {@link android.os.Handler} should override this method, call
15638      * <code>super.onCancelPendingInputEvents()</code> and remove those callbacks as appropriate.
15639      * </p>
15640      */
15641     public void onCancelPendingInputEvents() {
15642         removePerformClickCallback();
15643         cancelLongPress();
15644         mPrivateFlags3 |= PFLAG3_CALLED_SUPER;
15645     }
15646
15647     /**
15648      * Store this view hierarchy's frozen state into the given container.
15649      *
15650      * @param container The SparseArray in which to save the view's state.
15651      *
15652      * @see #restoreHierarchyState(android.util.SparseArray)
15653      * @see #dispatchSaveInstanceState(android.util.SparseArray)
15654      * @see #onSaveInstanceState()
15655      */
15656     public void saveHierarchyState(SparseArray<Parcelable> container) {
15657         dispatchSaveInstanceState(container);
15658     }
15659
15660     /**
15661      * Called by {@link #saveHierarchyState(android.util.SparseArray)} to store the state for
15662      * this view and its children. May be overridden to modify how freezing happens to a
15663      * view's children; for example, some views may want to not store state for their children.
15664      *
15665      * @param container The SparseArray in which to save the view's state.
15666      *
15667      * @see #dispatchRestoreInstanceState(android.util.SparseArray)
15668      * @see #saveHierarchyState(android.util.SparseArray)
15669      * @see #onSaveInstanceState()
15670      */
15671     protected void dispatchSaveInstanceState(SparseArray<Parcelable> container) {
15672         if (mID != NO_ID && (mViewFlags & SAVE_DISABLED_MASK) == 0) {
15673             mPrivateFlags &= ~PFLAG_SAVE_STATE_CALLED;
15674             Parcelable state = onSaveInstanceState();
15675             if ((mPrivateFlags & PFLAG_SAVE_STATE_CALLED) == 0) {
15676                 throw new IllegalStateException(
15677                         "Derived class did not call super.onSaveInstanceState()");
15678             }
15679             if (state != null) {
15680                 // Log.i("View", "Freezing #" + Integer.toHexString(mID)
15681                 // + ": " + state);
15682                 container.put(mID, state);
15683             }
15684         }
15685     }
15686
15687     /**
15688      * Hook allowing a view to generate a representation of its internal state
15689      * that can later be used to create a new instance with that same state.
15690      * This state should only contain information that is not persistent or can
15691      * not be reconstructed later. For example, you will never store your
15692      * current position on screen because that will be computed again when a
15693      * new instance of the view is placed in its view hierarchy.
15694      * <p>
15695      * Some examples of things you may store here: the current cursor position
15696      * in a text view (but usually not the text itself since that is stored in a
15697      * content provider or other persistent storage), the currently selected
15698      * item in a list view.
15699      *
15700      * @return Returns a Parcelable object containing the view's current dynamic
15701      *         state, or null if there is nothing interesting to save. The
15702      *         default implementation returns null.
15703      * @see #onRestoreInstanceState(android.os.Parcelable)
15704      * @see #saveHierarchyState(android.util.SparseArray)
15705      * @see #dispatchSaveInstanceState(android.util.SparseArray)
15706      * @see #setSaveEnabled(boolean)
15707      */
15708     @CallSuper
15709     protected Parcelable onSaveInstanceState() {
15710         mPrivateFlags |= PFLAG_SAVE_STATE_CALLED;
15711         if (mStartActivityRequestWho != null) {
15712             BaseSavedState state = new BaseSavedState(AbsSavedState.EMPTY_STATE);
15713             state.mStartActivityRequestWhoSaved = mStartActivityRequestWho;
15714             return state;
15715         }
15716         return BaseSavedState.EMPTY_STATE;
15717     }
15718
15719     /**
15720      * Restore this view hierarchy's frozen state from the given container.
15721      *
15722      * @param container The SparseArray which holds previously frozen states.
15723      *
15724      * @see #saveHierarchyState(android.util.SparseArray)
15725      * @see #dispatchRestoreInstanceState(android.util.SparseArray)
15726      * @see #onRestoreInstanceState(android.os.Parcelable)
15727      */
15728     public void restoreHierarchyState(SparseArray<Parcelable> container) {
15729         dispatchRestoreInstanceState(container);
15730     }
15731
15732     /**
15733      * Called by {@link #restoreHierarchyState(android.util.SparseArray)} to retrieve the
15734      * state for this view and its children. May be overridden to modify how restoring
15735      * happens to a view's children; for example, some views may want to not store state
15736      * for their children.
15737      *
15738      * @param container The SparseArray which holds previously saved state.
15739      *
15740      * @see #dispatchSaveInstanceState(android.util.SparseArray)
15741      * @see #restoreHierarchyState(android.util.SparseArray)
15742      * @see #onRestoreInstanceState(android.os.Parcelable)
15743      */
15744     protected void dispatchRestoreInstanceState(SparseArray<Parcelable> container) {
15745         if (mID != NO_ID) {
15746             Parcelable state = container.get(mID);
15747             if (state != null) {
15748                 // Log.i("View", "Restoreing #" + Integer.toHexString(mID)
15749                 // + ": " + state);
15750                 mPrivateFlags &= ~PFLAG_SAVE_STATE_CALLED;
15751                 onRestoreInstanceState(state);
15752                 if ((mPrivateFlags & PFLAG_SAVE_STATE_CALLED) == 0) {
15753                     throw new IllegalStateException(
15754                             "Derived class did not call super.onRestoreInstanceState()");
15755                 }
15756             }
15757         }
15758     }
15759
15760     /**
15761      * Hook allowing a view to re-apply a representation of its internal state that had previously
15762      * been generated by {@link #onSaveInstanceState}. This function will never be called with a
15763      * null state.
15764      *
15765      * @param state The frozen state that had previously been returned by
15766      *        {@link #onSaveInstanceState}.
15767      *
15768      * @see #onSaveInstanceState()
15769      * @see #restoreHierarchyState(android.util.SparseArray)
15770      * @see #dispatchRestoreInstanceState(android.util.SparseArray)
15771      */
15772     @CallSuper
15773     protected void onRestoreInstanceState(Parcelable state) {
15774         mPrivateFlags |= PFLAG_SAVE_STATE_CALLED;
15775         if (state != null && !(state instanceof AbsSavedState)) {
15776             throw new IllegalArgumentException("Wrong state class, expecting View State but "
15777                     + "received " + state.getClass().toString() + " instead. This usually happens "
15778                     + "when two views of different type have the same id in the same hierarchy. "
15779                     + "This view's id is " + ViewDebug.resolveId(mContext, getId()) + ". Make sure "
15780                     + "other views do not use the same id.");
15781         }
15782         if (state != null && state instanceof BaseSavedState) {
15783             mStartActivityRequestWho = ((BaseSavedState) state).mStartActivityRequestWhoSaved;
15784         }
15785     }
15786
15787     /**
15788      * <p>Return the time at which the drawing of the view hierarchy started.</p>
15789      *
15790      * @return the drawing start time in milliseconds
15791      */
15792     public long getDrawingTime() {
15793         return mAttachInfo != null ? mAttachInfo.mDrawingTime : 0;
15794     }
15795
15796     /**
15797      * <p>Enables or disables the duplication of the parent's state into this view. When
15798      * duplication is enabled, this view gets its drawable state from its parent rather
15799      * than from its own internal properties.</p>
15800      *
15801      * <p>Note: in the current implementation, setting this property to true after the
15802      * view was added to a ViewGroup might have no effect at all. This property should
15803      * always be used from XML or set to true before adding this view to a ViewGroup.</p>
15804      *
15805      * <p>Note: if this view's parent addStateFromChildren property is enabled and this
15806      * property is enabled, an exception will be thrown.</p>
15807      *
15808      * <p>Note: if the child view uses and updates additional states which are unknown to the
15809      * parent, these states should not be affected by this method.</p>
15810      *
15811      * @param enabled True to enable duplication of the parent's drawable state, false
15812      *                to disable it.
15813      *
15814      * @see #getDrawableState()
15815      * @see #isDuplicateParentStateEnabled()
15816      */
15817     public void setDuplicateParentStateEnabled(boolean enabled) {
15818         setFlags(enabled ? DUPLICATE_PARENT_STATE : 0, DUPLICATE_PARENT_STATE);
15819     }
15820
15821     /**
15822      * <p>Indicates whether this duplicates its drawable state from its parent.</p>
15823      *
15824      * @return True if this view's drawable state is duplicated from the parent,
15825      *         false otherwise
15826      *
15827      * @see #getDrawableState()
15828      * @see #setDuplicateParentStateEnabled(boolean)
15829      */
15830     public boolean isDuplicateParentStateEnabled() {
15831         return (mViewFlags & DUPLICATE_PARENT_STATE) == DUPLICATE_PARENT_STATE;
15832     }
15833
15834     /**
15835      * <p>Specifies the type of layer backing this view. The layer can be
15836      * {@link #LAYER_TYPE_NONE}, {@link #LAYER_TYPE_SOFTWARE} or
15837      * {@link #LAYER_TYPE_HARDWARE}.</p>
15838      *
15839      * <p>A layer is associated with an optional {@link android.graphics.Paint}
15840      * instance that controls how the layer is composed on screen. The following
15841      * properties of the paint are taken into account when composing the layer:</p>
15842      * <ul>
15843      * <li>{@link android.graphics.Paint#getAlpha() Translucency (alpha)}</li>
15844      * <li>{@link android.graphics.Paint#getXfermode() Blending mode}</li>
15845      * <li>{@link android.graphics.Paint#getColorFilter() Color filter}</li>
15846      * </ul>
15847      *
15848      * <p>If this view has an alpha value set to < 1.0 by calling
15849      * {@link #setAlpha(float)}, the alpha value of the layer's paint is superseded
15850      * by this view's alpha value.</p>
15851      *
15852      * <p>Refer to the documentation of {@link #LAYER_TYPE_NONE},
15853      * {@link #LAYER_TYPE_SOFTWARE} and {@link #LAYER_TYPE_HARDWARE}
15854      * for more information on when and how to use layers.</p>
15855      *
15856      * @param layerType The type of layer to use with this view, must be one of
15857      *        {@link #LAYER_TYPE_NONE}, {@link #LAYER_TYPE_SOFTWARE} or
15858      *        {@link #LAYER_TYPE_HARDWARE}
15859      * @param paint The paint used to compose the layer. This argument is optional
15860      *        and can be null. It is ignored when the layer type is
15861      *        {@link #LAYER_TYPE_NONE}
15862      *
15863      * @see #getLayerType()
15864      * @see #LAYER_TYPE_NONE
15865      * @see #LAYER_TYPE_SOFTWARE
15866      * @see #LAYER_TYPE_HARDWARE
15867      * @see #setAlpha(float)
15868      *
15869      * @attr ref android.R.styleable#View_layerType
15870      */
15871     public void setLayerType(int layerType, @Nullable Paint paint) {
15872         if (layerType < LAYER_TYPE_NONE || layerType > LAYER_TYPE_HARDWARE) {
15873             throw new IllegalArgumentException("Layer type can only be one of: LAYER_TYPE_NONE, "
15874                     + "LAYER_TYPE_SOFTWARE or LAYER_TYPE_HARDWARE");
15875         }
15876
15877         boolean typeChanged = mRenderNode.setLayerType(layerType);
15878
15879         if (!typeChanged) {
15880             setLayerPaint(paint);
15881             return;
15882         }
15883
15884         if (layerType != LAYER_TYPE_SOFTWARE) {
15885             // Destroy any previous software drawing cache if present
15886             // NOTE: even if previous layer type is HW, we do this to ensure we've cleaned up
15887             // drawing cache created in View#draw when drawing to a SW canvas.
15888             destroyDrawingCache();
15889         }
15890
15891         mLayerType = layerType;
15892         mLayerPaint = mLayerType == LAYER_TYPE_NONE ? null : paint;
15893         mRenderNode.setLayerPaint(mLayerPaint);
15894
15895         // draw() behaves differently if we are on a layer, so we need to
15896         // invalidate() here
15897         invalidateParentCaches();
15898         invalidate(true);
15899     }
15900
15901     /**
15902      * Updates the {@link Paint} object used with the current layer (used only if the current
15903      * layer type is not set to {@link #LAYER_TYPE_NONE}). Changed properties of the Paint
15904      * provided to {@link #setLayerType(int, android.graphics.Paint)} will be used the next time
15905      * the View is redrawn, but {@link #setLayerPaint(android.graphics.Paint)} must be called to
15906      * ensure that the view gets redrawn immediately.
15907      *
15908      * <p>A layer is associated with an optional {@link android.graphics.Paint}
15909      * instance that controls how the layer is composed on screen. The following
15910      * properties of the paint are taken into account when composing the layer:</p>
15911      * <ul>
15912      * <li>{@link android.graphics.Paint#getAlpha() Translucency (alpha)}</li>
15913      * <li>{@link android.graphics.Paint#getXfermode() Blending mode}</li>
15914      * <li>{@link android.graphics.Paint#getColorFilter() Color filter}</li>
15915      * </ul>
15916      *
15917      * <p>If this view has an alpha value set to < 1.0 by calling {@link #setAlpha(float)}, the
15918      * alpha value of the layer's paint is superseded by this view's alpha value.</p>
15919      *
15920      * @param paint The paint used to compose the layer. This argument is optional
15921      *        and can be null. It is ignored when the layer type is
15922      *        {@link #LAYER_TYPE_NONE}
15923      *
15924      * @see #setLayerType(int, android.graphics.Paint)
15925      */
15926     public void setLayerPaint(@Nullable Paint paint) {
15927         int layerType = getLayerType();
15928         if (layerType != LAYER_TYPE_NONE) {
15929             mLayerPaint = paint;
15930             if (layerType == LAYER_TYPE_HARDWARE) {
15931                 if (mRenderNode.setLayerPaint(paint)) {
15932                     invalidateViewProperty(false, false);
15933                 }
15934             } else {
15935                 invalidate();
15936             }
15937         }
15938     }
15939
15940     /**
15941      * Indicates what type of layer is currently associated with this view. By default
15942      * a view does not have a layer, and the layer type is {@link #LAYER_TYPE_NONE}.
15943      * Refer to the documentation of {@link #setLayerType(int, android.graphics.Paint)}
15944      * for more information on the different types of layers.
15945      *
15946      * @return {@link #LAYER_TYPE_NONE}, {@link #LAYER_TYPE_SOFTWARE} or
15947      *         {@link #LAYER_TYPE_HARDWARE}
15948      *
15949      * @see #setLayerType(int, android.graphics.Paint)
15950      * @see #buildLayer()
15951      * @see #LAYER_TYPE_NONE
15952      * @see #LAYER_TYPE_SOFTWARE
15953      * @see #LAYER_TYPE_HARDWARE
15954      */
15955     public int getLayerType() {
15956         return mLayerType;
15957     }
15958
15959     /**
15960      * Forces this view's layer to be created and this view to be rendered
15961      * into its layer. If this view's layer type is set to {@link #LAYER_TYPE_NONE},
15962      * invoking this method will have no effect.
15963      *
15964      * This method can for instance be used to render a view into its layer before
15965      * starting an animation. If this view is complex, rendering into the layer
15966      * before starting the animation will avoid skipping frames.
15967      *
15968      * @throws IllegalStateException If this view is not attached to a window
15969      *
15970      * @see #setLayerType(int, android.graphics.Paint)
15971      */
15972     public void buildLayer() {
15973         if (mLayerType == LAYER_TYPE_NONE) return;
15974
15975         final AttachInfo attachInfo = mAttachInfo;
15976         if (attachInfo == null) {
15977             throw new IllegalStateException("This view must be attached to a window first");
15978         }
15979
15980         if (getWidth() == 0 || getHeight() == 0) {
15981             return;
15982         }
15983
15984         switch (mLayerType) {
15985             case LAYER_TYPE_HARDWARE:
15986                 updateDisplayListIfDirty();
15987                 if (attachInfo.mHardwareRenderer != null && mRenderNode.isValid()) {
15988                     attachInfo.mHardwareRenderer.buildLayer(mRenderNode);
15989                 }
15990                 break;
15991             case LAYER_TYPE_SOFTWARE:
15992                 buildDrawingCache(true);
15993                 break;
15994         }
15995     }
15996
15997     /**
15998      * Destroys all hardware rendering resources. This method is invoked
15999      * when the system needs to reclaim resources. Upon execution of this
16000      * method, you should free any OpenGL resources created by the view.
16001      *
16002      * Note: you <strong>must</strong> call
16003      * <code>super.destroyHardwareResources()</code> when overriding
16004      * this method.
16005      *
16006      * @hide
16007      */
16008     @CallSuper
16009     protected void destroyHardwareResources() {
16010         // Although the Layer will be destroyed by RenderNode, we want to release
16011         // the staging display list, which is also a signal to RenderNode that it's
16012         // safe to free its copy of the display list as it knows that we will
16013         // push an updated DisplayList if we try to draw again
16014         resetDisplayList();
16015     }
16016
16017     /**
16018      * <p>Enables or disables the drawing cache. When the drawing cache is enabled, the next call
16019      * to {@link #getDrawingCache()} or {@link #buildDrawingCache()} will draw the view in a
16020      * bitmap. Calling {@link #draw(android.graphics.Canvas)} will not draw from the cache when
16021      * the cache is enabled. To benefit from the cache, you must request the drawing cache by
16022      * calling {@link #getDrawingCache()} and draw it on screen if the returned bitmap is not
16023      * null.</p>
16024      *
16025      * <p>Enabling the drawing cache is similar to
16026      * {@link #setLayerType(int, android.graphics.Paint) setting a layer} when hardware
16027      * acceleration is turned off. When hardware acceleration is turned on, enabling the
16028      * drawing cache has no effect on rendering because the system uses a different mechanism
16029      * for acceleration which ignores the flag. If you want to use a Bitmap for the view, even
16030      * when hardware acceleration is enabled, see {@link #setLayerType(int, android.graphics.Paint)}
16031      * for information on how to enable software and hardware layers.</p>
16032      *
16033      * <p>This API can be used to manually generate
16034      * a bitmap copy of this view, by setting the flag to <code>true</code> and calling
16035      * {@link #getDrawingCache()}.</p>
16036      *
16037      * @param enabled true to enable the drawing cache, false otherwise
16038      *
16039      * @see #isDrawingCacheEnabled()
16040      * @see #getDrawingCache()
16041      * @see #buildDrawingCache()
16042      * @see #setLayerType(int, android.graphics.Paint)
16043      */
16044     public void setDrawingCacheEnabled(boolean enabled) {
16045         mCachingFailed = false;
16046         setFlags(enabled ? DRAWING_CACHE_ENABLED : 0, DRAWING_CACHE_ENABLED);
16047     }
16048
16049     /**
16050      * <p>Indicates whether the drawing cache is enabled for this view.</p>
16051      *
16052      * @return true if the drawing cache is enabled
16053      *
16054      * @see #setDrawingCacheEnabled(boolean)
16055      * @see #getDrawingCache()
16056      */
16057     @ViewDebug.ExportedProperty(category = "drawing")
16058     public boolean isDrawingCacheEnabled() {
16059         return (mViewFlags & DRAWING_CACHE_ENABLED) == DRAWING_CACHE_ENABLED;
16060     }
16061
16062     /**
16063      * Debugging utility which recursively outputs the dirty state of a view and its
16064      * descendants.
16065      *
16066      * @hide
16067      */
16068     @SuppressWarnings({"UnusedDeclaration"})
16069     public void outputDirtyFlags(String indent, boolean clear, int clearMask) {
16070         Log.d("View", indent + this + "             DIRTY(" + (mPrivateFlags & View.PFLAG_DIRTY_MASK) +
16071                 ") DRAWN(" + (mPrivateFlags & PFLAG_DRAWN) + ")" + " CACHE_VALID(" +
16072                 (mPrivateFlags & View.PFLAG_DRAWING_CACHE_VALID) +
16073                 ") INVALIDATED(" + (mPrivateFlags & PFLAG_INVALIDATED) + ")");
16074         if (clear) {
16075             mPrivateFlags &= clearMask;
16076         }
16077         if (this instanceof ViewGroup) {
16078             ViewGroup parent = (ViewGroup) this;
16079             final int count = parent.getChildCount();
16080             for (int i = 0; i < count; i++) {
16081                 final View child = parent.getChildAt(i);
16082                 child.outputDirtyFlags(indent + "  ", clear, clearMask);
16083             }
16084         }
16085     }
16086
16087     /**
16088      * This method is used by ViewGroup to cause its children to restore or recreate their
16089      * display lists. It is called by getDisplayList() when the parent ViewGroup does not need
16090      * to recreate its own display list, which would happen if it went through the normal
16091      * draw/dispatchDraw mechanisms.
16092      *
16093      * @hide
16094      */
16095     protected void dispatchGetDisplayList() {}
16096
16097     /**
16098      * A view that is not attached or hardware accelerated cannot create a display list.
16099      * This method checks these conditions and returns the appropriate result.
16100      *
16101      * @return true if view has the ability to create a display list, false otherwise.
16102      *
16103      * @hide
16104      */
16105     public boolean canHaveDisplayList() {
16106         return !(mAttachInfo == null || mAttachInfo.mHardwareRenderer == null);
16107     }
16108
16109     /**
16110      * Gets the RenderNode for the view, and updates its DisplayList (if needed and supported)
16111      * @hide
16112      */
16113     @NonNull
16114     public RenderNode updateDisplayListIfDirty() {
16115         final RenderNode renderNode = mRenderNode;
16116         if (!canHaveDisplayList()) {
16117             // can't populate RenderNode, don't try
16118             return renderNode;
16119         }
16120
16121         if ((mPrivateFlags & PFLAG_DRAWING_CACHE_VALID) == 0
16122                 || !renderNode.isValid()
16123                 || (mRecreateDisplayList)) {
16124             // Don't need to recreate the display list, just need to tell our
16125             // children to restore/recreate theirs
16126             if (renderNode.isValid()
16127                     && !mRecreateDisplayList) {
16128                 mPrivateFlags |= PFLAG_DRAWN | PFLAG_DRAWING_CACHE_VALID;
16129                 mPrivateFlags &= ~PFLAG_DIRTY_MASK;
16130                 dispatchGetDisplayList();
16131
16132                 return renderNode; // no work needed
16133             }
16134
16135             // If we got here, we're recreating it. Mark it as such to ensure that
16136             // we copy in child display lists into ours in drawChild()
16137             mRecreateDisplayList = true;
16138
16139             int width = mRight - mLeft;
16140             int height = mBottom - mTop;
16141             int layerType = getLayerType();
16142
16143             final DisplayListCanvas canvas = renderNode.start(width, height);
16144             canvas.setHighContrastText(mAttachInfo.mHighContrastText);
16145
16146             try {
16147                 if (layerType == LAYER_TYPE_SOFTWARE) {
16148                     buildDrawingCache(true);
16149                     Bitmap cache = getDrawingCache(true);
16150                     if (cache != null) {
16151                         canvas.drawBitmap(cache, 0, 0, mLayerPaint);
16152                     }
16153                 } else {
16154                     computeScroll();
16155
16156                     canvas.translate(-mScrollX, -mScrollY);
16157                     mPrivateFlags |= PFLAG_DRAWN | PFLAG_DRAWING_CACHE_VALID;
16158                     mPrivateFlags &= ~PFLAG_DIRTY_MASK;
16159
16160                     // Fast path for layouts with no backgrounds
16161                     if ((mPrivateFlags & PFLAG_SKIP_DRAW) == PFLAG_SKIP_DRAW) {
16162                         dispatchDraw(canvas);
16163                         if (mOverlay != null && !mOverlay.isEmpty()) {
16164                             mOverlay.getOverlayView().draw(canvas);
16165                         }
16166                     } else {
16167                         draw(canvas);
16168                     }
16169                 }
16170             } finally {
16171                 renderNode.end(canvas);
16172                 setDisplayListProperties(renderNode);
16173             }
16174         } else {
16175             mPrivateFlags |= PFLAG_DRAWN | PFLAG_DRAWING_CACHE_VALID;
16176             mPrivateFlags &= ~PFLAG_DIRTY_MASK;
16177         }
16178         return renderNode;
16179     }
16180
16181     private void resetDisplayList() {
16182         if (mRenderNode.isValid()) {
16183             mRenderNode.discardDisplayList();
16184         }
16185
16186         if (mBackgroundRenderNode != null && mBackgroundRenderNode.isValid()) {
16187             mBackgroundRenderNode.discardDisplayList();
16188         }
16189     }
16190
16191     /**
16192      * Called when the passed RenderNode is removed from the draw tree
16193      * @hide
16194      */
16195     public void onRenderNodeDetached(RenderNode renderNode) {
16196     }
16197
16198     /**
16199      * <p>Calling this method is equivalent to calling <code>getDrawingCache(false)</code>.</p>
16200      *
16201      * @return A non-scaled bitmap representing this view or null if cache is disabled.
16202      *
16203      * @see #getDrawingCache(boolean)
16204      */
16205     public Bitmap getDrawingCache() {
16206         return getDrawingCache(false);
16207     }
16208
16209     /**
16210      * <p>Returns the bitmap in which this view drawing is cached. The returned bitmap
16211      * is null when caching is disabled. If caching is enabled and the cache is not ready,
16212      * this method will create it. Calling {@link #draw(android.graphics.Canvas)} will not
16213      * draw from the cache when the cache is enabled. To benefit from the cache, you must
16214      * request the drawing cache by calling this method and draw it on screen if the
16215      * returned bitmap is not null.</p>
16216      *
16217      * <p>Note about auto scaling in compatibility mode: When auto scaling is not enabled,
16218      * this method will create a bitmap of the same size as this view. Because this bitmap
16219      * will be drawn scaled by the parent ViewGroup, the result on screen might show
16220      * scaling artifacts. To avoid such artifacts, you should call this method by setting
16221      * the auto scaling to true. Doing so, however, will generate a bitmap of a different
16222      * size than the view. This implies that your application must be able to handle this
16223      * size.</p>
16224      *
16225      * @param autoScale Indicates whether the generated bitmap should be scaled based on
16226      *        the current density of the screen when the application is in compatibility
16227      *        mode.
16228      *
16229      * @return A bitmap representing this view or null if cache is disabled.
16230      *
16231      * @see #setDrawingCacheEnabled(boolean)
16232      * @see #isDrawingCacheEnabled()
16233      * @see #buildDrawingCache(boolean)
16234      * @see #destroyDrawingCache()
16235      */
16236     public Bitmap getDrawingCache(boolean autoScale) {
16237         if ((mViewFlags & WILL_NOT_CACHE_DRAWING) == WILL_NOT_CACHE_DRAWING) {
16238             return null;
16239         }
16240         if ((mViewFlags & DRAWING_CACHE_ENABLED) == DRAWING_CACHE_ENABLED) {
16241             buildDrawingCache(autoScale);
16242         }
16243         return autoScale ? mDrawingCache : mUnscaledDrawingCache;
16244     }
16245
16246     /**
16247      * <p>Frees the resources used by the drawing cache. If you call
16248      * {@link #buildDrawingCache()} manually without calling
16249      * {@link #setDrawingCacheEnabled(boolean) setDrawingCacheEnabled(true)}, you
16250      * should cleanup the cache with this method afterwards.</p>
16251      *
16252      * @see #setDrawingCacheEnabled(boolean)
16253      * @see #buildDrawingCache()
16254      * @see #getDrawingCache()
16255      */
16256     public void destroyDrawingCache() {
16257         if (mDrawingCache != null) {
16258             mDrawingCache.recycle();
16259             mDrawingCache = null;
16260         }
16261         if (mUnscaledDrawingCache != null) {
16262             mUnscaledDrawingCache.recycle();
16263             mUnscaledDrawingCache = null;
16264         }
16265     }
16266
16267     /**
16268      * Setting a solid background color for the drawing cache's bitmaps will improve
16269      * performance and memory usage. Note, though that this should only be used if this
16270      * view will always be drawn on top of a solid color.
16271      *
16272      * @param color The background color to use for the drawing cache's bitmap
16273      *
16274      * @see #setDrawingCacheEnabled(boolean)
16275      * @see #buildDrawingCache()
16276      * @see #getDrawingCache()
16277      */
16278     public void setDrawingCacheBackgroundColor(@ColorInt int color) {
16279         if (color != mDrawingCacheBackgroundColor) {
16280             mDrawingCacheBackgroundColor = color;
16281             mPrivateFlags &= ~PFLAG_DRAWING_CACHE_VALID;
16282         }
16283     }
16284
16285     /**
16286      * @see #setDrawingCacheBackgroundColor(int)
16287      *
16288      * @return The background color to used for the drawing cache's bitmap
16289      */
16290     @ColorInt
16291     public int getDrawingCacheBackgroundColor() {
16292         return mDrawingCacheBackgroundColor;
16293     }
16294
16295     /**
16296      * <p>Calling this method is equivalent to calling <code>buildDrawingCache(false)</code>.</p>
16297      *
16298      * @see #buildDrawingCache(boolean)
16299      */
16300     public void buildDrawingCache() {
16301         buildDrawingCache(false);
16302     }
16303
16304     /**
16305      * <p>Forces the drawing cache to be built if the drawing cache is invalid.</p>
16306      *
16307      * <p>If you call {@link #buildDrawingCache()} manually without calling
16308      * {@link #setDrawingCacheEnabled(boolean) setDrawingCacheEnabled(true)}, you
16309      * should cleanup the cache by calling {@link #destroyDrawingCache()} afterwards.</p>
16310      *
16311      * <p>Note about auto scaling in compatibility mode: When auto scaling is not enabled,
16312      * this method will create a bitmap of the same size as this view. Because this bitmap
16313      * will be drawn scaled by the parent ViewGroup, the result on screen might show
16314      * scaling artifacts. To avoid such artifacts, you should call this method by setting
16315      * the auto scaling to true. Doing so, however, will generate a bitmap of a different
16316      * size than the view. This implies that your application must be able to handle this
16317      * size.</p>
16318      *
16319      * <p>You should avoid calling this method when hardware acceleration is enabled. If
16320      * you do not need the drawing cache bitmap, calling this method will increase memory
16321      * usage and cause the view to be rendered in software once, thus negatively impacting
16322      * performance.</p>
16323      *
16324      * @see #getDrawingCache()
16325      * @see #destroyDrawingCache()
16326      */
16327     public void buildDrawingCache(boolean autoScale) {
16328         if ((mPrivateFlags & PFLAG_DRAWING_CACHE_VALID) == 0 || (autoScale ?
16329                 mDrawingCache == null : mUnscaledDrawingCache == null)) {
16330             if (Trace.isTagEnabled(Trace.TRACE_TAG_VIEW)) {
16331                 Trace.traceBegin(Trace.TRACE_TAG_VIEW,
16332                         "buildDrawingCache/SW Layer for " + getClass().getSimpleName());
16333             }
16334             try {
16335                 buildDrawingCacheImpl(autoScale);
16336             } finally {
16337                 Trace.traceEnd(Trace.TRACE_TAG_VIEW);
16338             }
16339         }
16340     }
16341
16342     /**
16343      * private, internal implementation of buildDrawingCache, used to enable tracing
16344      */
16345     private void buildDrawingCacheImpl(boolean autoScale) {
16346         mCachingFailed = false;
16347
16348         int width = mRight - mLeft;
16349         int height = mBottom - mTop;
16350
16351         final AttachInfo attachInfo = mAttachInfo;
16352         final boolean scalingRequired = attachInfo != null && attachInfo.mScalingRequired;
16353
16354         if (autoScale && scalingRequired) {
16355             width = (int) ((width * attachInfo.mApplicationScale) + 0.5f);
16356             height = (int) ((height * attachInfo.mApplicationScale) + 0.5f);
16357         }
16358
16359         final int drawingCacheBackgroundColor = mDrawingCacheBackgroundColor;
16360         final boolean opaque = drawingCacheBackgroundColor != 0 || isOpaque();
16361         final boolean use32BitCache = attachInfo != null && attachInfo.mUse32BitDrawingCache;
16362
16363         final long projectedBitmapSize = width * height * (opaque && !use32BitCache ? 2 : 4);
16364         final long drawingCacheSize =
16365                 ViewConfiguration.get(mContext).getScaledMaximumDrawingCacheSize();
16366         if (width <= 0 || height <= 0 || projectedBitmapSize > drawingCacheSize) {
16367             if (width > 0 && height > 0) {
16368                 Log.w(VIEW_LOG_TAG, getClass().getSimpleName() + " not displayed because it is"
16369                         + " too large to fit into a software layer (or drawing cache), needs "
16370                         + projectedBitmapSize + " bytes, only "
16371                         + drawingCacheSize + " available");
16372             }
16373             destroyDrawingCache();
16374             mCachingFailed = true;
16375             return;
16376         }
16377
16378         boolean clear = true;
16379         Bitmap bitmap = autoScale ? mDrawingCache : mUnscaledDrawingCache;
16380
16381         if (bitmap == null || bitmap.getWidth() != width || bitmap.getHeight() != height) {
16382             Bitmap.Config quality;
16383             if (!opaque) {
16384                 // Never pick ARGB_4444 because it looks awful
16385                 // Keep the DRAWING_CACHE_QUALITY_LOW flag just in case
16386                 switch (mViewFlags & DRAWING_CACHE_QUALITY_MASK) {
16387                     case DRAWING_CACHE_QUALITY_AUTO:
16388                     case DRAWING_CACHE_QUALITY_LOW:
16389                     case DRAWING_CACHE_QUALITY_HIGH:
16390                     default:
16391                         quality = Bitmap.Config.ARGB_8888;
16392                         break;
16393                 }
16394             } else {
16395                 // Optimization for translucent windows
16396                 // If the window is translucent, use a 32 bits bitmap to benefit from memcpy()
16397                 quality = use32BitCache ? Bitmap.Config.ARGB_8888 : Bitmap.Config.RGB_565;
16398             }
16399
16400             // Try to cleanup memory
16401             if (bitmap != null) bitmap.recycle();
16402
16403             try {
16404                 bitmap = Bitmap.createBitmap(mResources.getDisplayMetrics(),
16405                         width, height, quality);
16406                 bitmap.setDensity(getResources().getDisplayMetrics().densityDpi);
16407                 if (autoScale) {
16408                     mDrawingCache = bitmap;
16409                 } else {
16410                     mUnscaledDrawingCache = bitmap;
16411                 }
16412                 if (opaque && use32BitCache) bitmap.setHasAlpha(false);
16413             } catch (OutOfMemoryError e) {
16414                 // If there is not enough memory to create the bitmap cache, just
16415                 // ignore the issue as bitmap caches are not required to draw the
16416                 // view hierarchy
16417                 if (autoScale) {
16418                     mDrawingCache = null;
16419                 } else {
16420                     mUnscaledDrawingCache = null;
16421                 }
16422                 mCachingFailed = true;
16423                 return;
16424             }
16425
16426             clear = drawingCacheBackgroundColor != 0;
16427         }
16428
16429         Canvas canvas;
16430         if (attachInfo != null) {
16431             canvas = attachInfo.mCanvas;
16432             if (canvas == null) {
16433                 canvas = new Canvas();
16434             }
16435             canvas.setBitmap(bitmap);
16436             // Temporarily clobber the cached Canvas in case one of our children
16437             // is also using a drawing cache. Without this, the children would
16438             // steal the canvas by attaching their own bitmap to it and bad, bad
16439             // thing would happen (invisible views, corrupted drawings, etc.)
16440             attachInfo.mCanvas = null;
16441         } else {
16442             // This case should hopefully never or seldom happen
16443             canvas = new Canvas(bitmap);
16444         }
16445
16446         if (clear) {
16447             bitmap.eraseColor(drawingCacheBackgroundColor);
16448         }
16449
16450         computeScroll();
16451         final int restoreCount = canvas.save();
16452
16453         if (autoScale && scalingRequired) {
16454             final float scale = attachInfo.mApplicationScale;
16455             canvas.scale(scale, scale);
16456         }
16457
16458         canvas.translate(-mScrollX, -mScrollY);
16459
16460         mPrivateFlags |= PFLAG_DRAWN;
16461         if (mAttachInfo == null || !mAttachInfo.mHardwareAccelerated ||
16462                 mLayerType != LAYER_TYPE_NONE) {
16463             mPrivateFlags |= PFLAG_DRAWING_CACHE_VALID;
16464         }
16465
16466         // Fast path for layouts with no backgrounds
16467         if ((mPrivateFlags & PFLAG_SKIP_DRAW) == PFLAG_SKIP_DRAW) {
16468             mPrivateFlags &= ~PFLAG_DIRTY_MASK;
16469             dispatchDraw(canvas);
16470             if (mOverlay != null && !mOverlay.isEmpty()) {
16471                 mOverlay.getOverlayView().draw(canvas);
16472             }
16473         } else {
16474             draw(canvas);
16475         }
16476
16477         canvas.restoreToCount(restoreCount);
16478         canvas.setBitmap(null);
16479
16480         if (attachInfo != null) {
16481             // Restore the cached Canvas for our siblings
16482             attachInfo.mCanvas = canvas;
16483         }
16484     }
16485
16486     /**
16487      * Create a snapshot of the view into a bitmap.  We should probably make
16488      * some form of this public, but should think about the API.
16489      *
16490      * @hide
16491      */
16492     public Bitmap createSnapshot(Bitmap.Config quality, int backgroundColor, boolean skipChildren) {
16493         int width = mRight - mLeft;
16494         int height = mBottom - mTop;
16495
16496         final AttachInfo attachInfo = mAttachInfo;
16497         final float scale = attachInfo != null ? attachInfo.mApplicationScale : 1.0f;
16498         width = (int) ((width * scale) + 0.5f);
16499         height = (int) ((height * scale) + 0.5f);
16500
16501         Bitmap bitmap = Bitmap.createBitmap(mResources.getDisplayMetrics(),
16502                 width > 0 ? width : 1, height > 0 ? height : 1, quality);
16503         if (bitmap == null) {
16504             throw new OutOfMemoryError();
16505         }
16506
16507         Resources resources = getResources();
16508         if (resources != null) {
16509             bitmap.setDensity(resources.getDisplayMetrics().densityDpi);
16510         }
16511
16512         Canvas canvas;
16513         if (attachInfo != null) {
16514             canvas = attachInfo.mCanvas;
16515             if (canvas == null) {
16516                 canvas = new Canvas();
16517             }
16518             canvas.setBitmap(bitmap);
16519             // Temporarily clobber the cached Canvas in case one of our children
16520             // is also using a drawing cache. Without this, the children would
16521             // steal the canvas by attaching their own bitmap to it and bad, bad
16522             // things would happen (invisible views, corrupted drawings, etc.)
16523             attachInfo.mCanvas = null;
16524         } else {
16525             // This case should hopefully never or seldom happen
16526             canvas = new Canvas(bitmap);
16527         }
16528
16529         if ((backgroundColor & 0xff000000) != 0) {
16530             bitmap.eraseColor(backgroundColor);
16531         }
16532
16533         computeScroll();
16534         final int restoreCount = canvas.save();
16535         canvas.scale(scale, scale);
16536         canvas.translate(-mScrollX, -mScrollY);
16537
16538         // Temporarily remove the dirty mask
16539         int flags = mPrivateFlags;
16540         mPrivateFlags &= ~PFLAG_DIRTY_MASK;
16541
16542         // Fast path for layouts with no backgrounds
16543         if ((mPrivateFlags & PFLAG_SKIP_DRAW) == PFLAG_SKIP_DRAW) {
16544             dispatchDraw(canvas);
16545             if (mOverlay != null && !mOverlay.isEmpty()) {
16546                 mOverlay.getOverlayView().draw(canvas);
16547             }
16548         } else {
16549             draw(canvas);
16550         }
16551
16552         mPrivateFlags = flags;
16553
16554         canvas.restoreToCount(restoreCount);
16555         canvas.setBitmap(null);
16556
16557         if (attachInfo != null) {
16558             // Restore the cached Canvas for our siblings
16559             attachInfo.mCanvas = canvas;
16560         }
16561
16562         return bitmap;
16563     }
16564
16565     /**
16566      * Indicates whether this View is currently in edit mode. A View is usually
16567      * in edit mode when displayed within a developer tool. For instance, if
16568      * this View is being drawn by a visual user interface builder, this method
16569      * should return true.
16570      *
16571      * Subclasses should check the return value of this method to provide
16572      * different behaviors if their normal behavior might interfere with the
16573      * host environment. For instance: the class spawns a thread in its
16574      * constructor, the drawing code relies on device-specific features, etc.
16575      *
16576      * This method is usually checked in the drawing code of custom widgets.
16577      *
16578      * @return True if this View is in edit mode, false otherwise.
16579      */
16580     public boolean isInEditMode() {
16581         return false;
16582     }
16583
16584     /**
16585      * If the View draws content inside its padding and enables fading edges,
16586      * it needs to support padding offsets. Padding offsets are added to the
16587      * fading edges to extend the length of the fade so that it covers pixels
16588      * drawn inside the padding.
16589      *
16590      * Subclasses of this class should override this method if they need
16591      * to draw content inside the padding.
16592      *
16593      * @return True if padding offset must be applied, false otherwise.
16594      *
16595      * @see #getLeftPaddingOffset()
16596      * @see #getRightPaddingOffset()
16597      * @see #getTopPaddingOffset()
16598      * @see #getBottomPaddingOffset()
16599      *
16600      * @since CURRENT
16601      */
16602     protected boolean isPaddingOffsetRequired() {
16603         return false;
16604     }
16605
16606     /**
16607      * Amount by which to extend the left fading region. Called only when
16608      * {@link #isPaddingOffsetRequired()} returns true.
16609      *
16610      * @return The left padding offset in pixels.
16611      *
16612      * @see #isPaddingOffsetRequired()
16613      *
16614      * @since CURRENT
16615      */
16616     protected int getLeftPaddingOffset() {
16617         return 0;
16618     }
16619
16620     /**
16621      * Amount by which to extend the right fading region. Called only when
16622      * {@link #isPaddingOffsetRequired()} returns true.
16623      *
16624      * @return The right padding offset in pixels.
16625      *
16626      * @see #isPaddingOffsetRequired()
16627      *
16628      * @since CURRENT
16629      */
16630     protected int getRightPaddingOffset() {
16631         return 0;
16632     }
16633
16634     /**
16635      * Amount by which to extend the top fading region. Called only when
16636      * {@link #isPaddingOffsetRequired()} returns true.
16637      *
16638      * @return The top padding offset in pixels.
16639      *
16640      * @see #isPaddingOffsetRequired()
16641      *
16642      * @since CURRENT
16643      */
16644     protected int getTopPaddingOffset() {
16645         return 0;
16646     }
16647
16648     /**
16649      * Amount by which to extend the bottom fading region. Called only when
16650      * {@link #isPaddingOffsetRequired()} returns true.
16651      *
16652      * @return The bottom padding offset in pixels.
16653      *
16654      * @see #isPaddingOffsetRequired()
16655      *
16656      * @since CURRENT
16657      */
16658     protected int getBottomPaddingOffset() {
16659         return 0;
16660     }
16661
16662     /**
16663      * @hide
16664      * @param offsetRequired
16665      */
16666     protected int getFadeTop(boolean offsetRequired) {
16667         int top = mPaddingTop;
16668         if (offsetRequired) top += getTopPaddingOffset();
16669         return top;
16670     }
16671
16672     /**
16673      * @hide
16674      * @param offsetRequired
16675      */
16676     protected int getFadeHeight(boolean offsetRequired) {
16677         int padding = mPaddingTop;
16678         if (offsetRequired) padding += getTopPaddingOffset();
16679         return mBottom - mTop - mPaddingBottom - padding;
16680     }
16681
16682     /**
16683      * <p>Indicates whether this view is attached to a hardware accelerated
16684      * window or not.</p>
16685      *
16686      * <p>Even if this method returns true, it does not mean that every call
16687      * to {@link #draw(android.graphics.Canvas)} will be made with an hardware
16688      * accelerated {@link android.graphics.Canvas}. For instance, if this view
16689      * is drawn onto an offscreen {@link android.graphics.Bitmap} and its
16690      * window is hardware accelerated,
16691      * {@link android.graphics.Canvas#isHardwareAccelerated()} will likely
16692      * return false, and this method will return true.</p>
16693      *
16694      * @return True if the view is attached to a window and the window is
16695      *         hardware accelerated; false in any other case.
16696      */
16697     @ViewDebug.ExportedProperty(category = "drawing")
16698     public boolean isHardwareAccelerated() {
16699         return mAttachInfo != null && mAttachInfo.mHardwareAccelerated;
16700     }
16701
16702     /**
16703      * Sets a rectangular area on this view to which the view will be clipped
16704      * when it is drawn. Setting the value to null will remove the clip bounds
16705      * and the view will draw normally, using its full bounds.
16706      *
16707      * @param clipBounds The rectangular area, in the local coordinates of
16708      * this view, to which future drawing operations will be clipped.
16709      */
16710     public void setClipBounds(Rect clipBounds) {
16711         if (clipBounds == mClipBounds
16712                 || (clipBounds != null && clipBounds.equals(mClipBounds))) {
16713             return;
16714         }
16715         if (clipBounds != null) {
16716             if (mClipBounds == null) {
16717                 mClipBounds = new Rect(clipBounds);
16718             } else {
16719                 mClipBounds.set(clipBounds);
16720             }
16721         } else {
16722             mClipBounds = null;
16723         }
16724         mRenderNode.setClipBounds(mClipBounds);
16725         invalidateViewProperty(false, false);
16726     }
16727
16728     /**
16729      * Returns a copy of the current {@link #setClipBounds(Rect) clipBounds}.
16730      *
16731      * @return A copy of the current clip bounds if clip bounds are set,
16732      * otherwise null.
16733      */
16734     public Rect getClipBounds() {
16735         return (mClipBounds != null) ? new Rect(mClipBounds) : null;
16736     }
16737
16738
16739     /**
16740      * Populates an output rectangle with the clip bounds of the view,
16741      * returning {@code true} if successful or {@code false} if the view's
16742      * clip bounds are {@code null}.
16743      *
16744      * @param outRect rectangle in which to place the clip bounds of the view
16745      * @return {@code true} if successful or {@code false} if the view's
16746      *         clip bounds are {@code null}
16747      */
16748     public boolean getClipBounds(Rect outRect) {
16749         if (mClipBounds != null) {
16750             outRect.set(mClipBounds);
16751             return true;
16752         }
16753         return false;
16754     }
16755
16756     /**
16757      * Utility function, called by draw(canvas, parent, drawingTime) to handle the less common
16758      * case of an active Animation being run on the view.
16759      */
16760     private boolean applyLegacyAnimation(ViewGroup parent, long drawingTime,
16761             Animation a, boolean scalingRequired) {
16762         Transformation invalidationTransform;
16763         final int flags = parent.mGroupFlags;
16764         final boolean initialized = a.isInitialized();
16765         if (!initialized) {
16766             a.initialize(mRight - mLeft, mBottom - mTop, parent.getWidth(), parent.getHeight());
16767             a.initializeInvalidateRegion(0, 0, mRight - mLeft, mBottom - mTop);
16768             if (mAttachInfo != null) a.setListenerHandler(mAttachInfo.mHandler);
16769             onAnimationStart();
16770         }
16771
16772         final Transformation t = parent.getChildTransformation();
16773         boolean more = a.getTransformation(drawingTime, t, 1f);
16774         if (scalingRequired && mAttachInfo.mApplicationScale != 1f) {
16775             if (parent.mInvalidationTransformation == null) {
16776                 parent.mInvalidationTransformation = new Transformation();
16777             }
16778             invalidationTransform = parent.mInvalidationTransformation;
16779             a.getTransformation(drawingTime, invalidationTransform, 1f);
16780         } else {
16781             invalidationTransform = t;
16782         }
16783
16784         if (more) {
16785             if (!a.willChangeBounds()) {
16786                 if ((flags & (ViewGroup.FLAG_OPTIMIZE_INVALIDATE | ViewGroup.FLAG_ANIMATION_DONE)) ==
16787                         ViewGroup.FLAG_OPTIMIZE_INVALIDATE) {
16788                     parent.mGroupFlags |= ViewGroup.FLAG_INVALIDATE_REQUIRED;
16789                 } else if ((flags & ViewGroup.FLAG_INVALIDATE_REQUIRED) == 0) {
16790                     // The child need to draw an animation, potentially offscreen, so
16791                     // make sure we do not cancel invalidate requests
16792                     parent.mPrivateFlags |= PFLAG_DRAW_ANIMATION;
16793                     parent.invalidate(mLeft, mTop, mRight, mBottom);
16794                 }
16795             } else {
16796                 if (parent.mInvalidateRegion == null) {
16797                     parent.mInvalidateRegion = new RectF();
16798                 }
16799                 final RectF region = parent.mInvalidateRegion;
16800                 a.getInvalidateRegion(0, 0, mRight - mLeft, mBottom - mTop, region,
16801                         invalidationTransform);
16802
16803                 // The child need to draw an animation, potentially offscreen, so
16804                 // make sure we do not cancel invalidate requests
16805                 parent.mPrivateFlags |= PFLAG_DRAW_ANIMATION;
16806
16807                 final int left = mLeft + (int) region.left;
16808                 final int top = mTop + (int) region.top;
16809                 parent.invalidate(left, top, left + (int) (region.width() + .5f),
16810                         top + (int) (region.height() + .5f));
16811             }
16812         }
16813         return more;
16814     }
16815
16816     /**
16817      * This method is called by getDisplayList() when a display list is recorded for a View.
16818      * It pushes any properties to the RenderNode that aren't managed by the RenderNode.
16819      */
16820     void setDisplayListProperties(RenderNode renderNode) {
16821         if (renderNode != null) {
16822             renderNode.setHasOverlappingRendering(getHasOverlappingRendering());
16823             renderNode.setClipToBounds(mParent instanceof ViewGroup
16824                     && ((ViewGroup) mParent).getClipChildren());
16825
16826             float alpha = 1;
16827             if (mParent instanceof ViewGroup && (((ViewGroup) mParent).mGroupFlags &
16828                     ViewGroup.FLAG_SUPPORT_STATIC_TRANSFORMATIONS) != 0) {
16829                 ViewGroup parentVG = (ViewGroup) mParent;
16830                 final Transformation t = parentVG.getChildTransformation();
16831                 if (parentVG.getChildStaticTransformation(this, t)) {
16832                     final int transformType = t.getTransformationType();
16833                     if (transformType != Transformation.TYPE_IDENTITY) {
16834                         if ((transformType & Transformation.TYPE_ALPHA) != 0) {
16835                             alpha = t.getAlpha();
16836                         }
16837                         if ((transformType & Transformation.TYPE_MATRIX) != 0) {
16838                             renderNode.setStaticMatrix(t.getMatrix());
16839                         }
16840                     }
16841                 }
16842             }
16843             if (mTransformationInfo != null) {
16844                 alpha *= getFinalAlpha();
16845                 if (alpha < 1) {
16846                     final int multipliedAlpha = (int) (255 * alpha);
16847                     if (onSetAlpha(multipliedAlpha)) {
16848                         alpha = 1;
16849                     }
16850                 }
16851                 renderNode.setAlpha(alpha);
16852             } else if (alpha < 1) {
16853                 renderNode.setAlpha(alpha);
16854             }
16855         }
16856     }
16857
16858     /**
16859      * This method is called by ViewGroup.drawChild() to have each child view draw itself.
16860      *
16861      * This is where the View specializes rendering behavior based on layer type,
16862      * and hardware acceleration.
16863      */
16864     boolean draw(Canvas canvas, ViewGroup parent, long drawingTime) {
16865         final boolean hardwareAcceleratedCanvas = canvas.isHardwareAccelerated();
16866         /* If an attached view draws to a HW canvas, it may use its RenderNode + DisplayList.
16867          *
16868          * If a view is dettached, its DisplayList shouldn't exist. If the canvas isn't
16869          * HW accelerated, it can't handle drawing RenderNodes.
16870          */
16871         boolean drawingWithRenderNode = mAttachInfo != null
16872                 && mAttachInfo.mHardwareAccelerated
16873                 && hardwareAcceleratedCanvas;
16874
16875         boolean more = false;
16876         final boolean childHasIdentityMatrix = hasIdentityMatrix();
16877         final int parentFlags = parent.mGroupFlags;
16878
16879         if ((parentFlags & ViewGroup.FLAG_CLEAR_TRANSFORMATION) != 0) {
16880             parent.getChildTransformation().clear();
16881             parent.mGroupFlags &= ~ViewGroup.FLAG_CLEAR_TRANSFORMATION;
16882         }
16883
16884         Transformation transformToApply = null;
16885         boolean concatMatrix = false;
16886         final boolean scalingRequired = mAttachInfo != null && mAttachInfo.mScalingRequired;
16887         final Animation a = getAnimation();
16888         if (a != null) {
16889             more = applyLegacyAnimation(parent, drawingTime, a, scalingRequired);
16890             concatMatrix = a.willChangeTransformationMatrix();
16891             if (concatMatrix) {
16892                 mPrivateFlags3 |= PFLAG3_VIEW_IS_ANIMATING_TRANSFORM;
16893             }
16894             transformToApply = parent.getChildTransformation();
16895         } else {
16896             if ((mPrivateFlags3 & PFLAG3_VIEW_IS_ANIMATING_TRANSFORM) != 0) {
16897                 // No longer animating: clear out old animation matrix
16898                 mRenderNode.setAnimationMatrix(null);
16899                 mPrivateFlags3 &= ~PFLAG3_VIEW_IS_ANIMATING_TRANSFORM;
16900             }
16901             if (!drawingWithRenderNode
16902                     && (parentFlags & ViewGroup.FLAG_SUPPORT_STATIC_TRANSFORMATIONS) != 0) {
16903                 final Transformation t = parent.getChildTransformation();
16904                 final boolean hasTransform = parent.getChildStaticTransformation(this, t);
16905                 if (hasTransform) {
16906                     final int transformType = t.getTransformationType();
16907                     transformToApply = transformType != Transformation.TYPE_IDENTITY ? t : null;
16908                     concatMatrix = (transformType & Transformation.TYPE_MATRIX) != 0;
16909                 }
16910             }
16911         }
16912
16913         concatMatrix |= !childHasIdentityMatrix;
16914
16915         // Sets the flag as early as possible to allow draw() implementations
16916         // to call invalidate() successfully when doing animations
16917         mPrivateFlags |= PFLAG_DRAWN;
16918
16919         if (!concatMatrix &&
16920                 (parentFlags & (ViewGroup.FLAG_SUPPORT_STATIC_TRANSFORMATIONS |
16921                         ViewGroup.FLAG_CLIP_CHILDREN)) == ViewGroup.FLAG_CLIP_CHILDREN &&
16922                 canvas.quickReject(mLeft, mTop, mRight, mBottom, Canvas.EdgeType.BW) &&
16923                 (mPrivateFlags & PFLAG_DRAW_ANIMATION) == 0) {
16924             mPrivateFlags2 |= PFLAG2_VIEW_QUICK_REJECTED;
16925             return more;
16926         }
16927         mPrivateFlags2 &= ~PFLAG2_VIEW_QUICK_REJECTED;
16928
16929         if (hardwareAcceleratedCanvas) {
16930             // Clear INVALIDATED flag to allow invalidation to occur during rendering, but
16931             // retain the flag's value temporarily in the mRecreateDisplayList flag
16932             mRecreateDisplayList = (mPrivateFlags & PFLAG_INVALIDATED) != 0;
16933             mPrivateFlags &= ~PFLAG_INVALIDATED;
16934         }
16935
16936         RenderNode renderNode = null;
16937         Bitmap cache = null;
16938         int layerType = getLayerType(); // TODO: signify cache state with just 'cache' local
16939         if (layerType == LAYER_TYPE_SOFTWARE || !drawingWithRenderNode) {
16940              if (layerType != LAYER_TYPE_NONE) {
16941                  // If not drawing with RenderNode, treat HW layers as SW
16942                  layerType = LAYER_TYPE_SOFTWARE;
16943                  buildDrawingCache(true);
16944             }
16945             cache = getDrawingCache(true);
16946         }
16947
16948         if (drawingWithRenderNode) {
16949             // Delay getting the display list until animation-driven alpha values are
16950             // set up and possibly passed on to the view
16951             renderNode = updateDisplayListIfDirty();
16952             if (!renderNode.isValid()) {
16953                 // Uncommon, but possible. If a view is removed from the hierarchy during the call
16954                 // to getDisplayList(), the display list will be marked invalid and we should not
16955                 // try to use it again.
16956                 renderNode = null;
16957                 drawingWithRenderNode = false;
16958             }
16959         }
16960
16961         int sx = 0;
16962         int sy = 0;
16963         if (!drawingWithRenderNode) {
16964             computeScroll();
16965             sx = mScrollX;
16966             sy = mScrollY;
16967         }
16968
16969         final boolean drawingWithDrawingCache = cache != null && !drawingWithRenderNode;
16970         final boolean offsetForScroll = cache == null && !drawingWithRenderNode;
16971
16972         int restoreTo = -1;
16973         if (!drawingWithRenderNode || transformToApply != null) {
16974             restoreTo = canvas.save();
16975         }
16976         if (offsetForScroll) {
16977             canvas.translate(mLeft - sx, mTop - sy);
16978         } else {
16979             if (!drawingWithRenderNode) {
16980                 canvas.translate(mLeft, mTop);
16981             }
16982             if (scalingRequired) {
16983                 if (drawingWithRenderNode) {
16984                     // TODO: Might not need this if we put everything inside the DL
16985                     restoreTo = canvas.save();
16986                 }
16987                 // mAttachInfo cannot be null, otherwise scalingRequired == false
16988                 final float scale = 1.0f / mAttachInfo.mApplicationScale;
16989                 canvas.scale(scale, scale);
16990             }
16991         }
16992
16993         float alpha = drawingWithRenderNode ? 1 : (getAlpha() * getTransitionAlpha());
16994         if (transformToApply != null
16995                 || alpha < 1
16996                 || !hasIdentityMatrix()
16997                 || (mPrivateFlags3 & PFLAG3_VIEW_IS_ANIMATING_ALPHA) != 0) {
16998             if (transformToApply != null || !childHasIdentityMatrix) {
16999                 int transX = 0;
17000                 int transY = 0;
17001
17002                 if (offsetForScroll) {
17003                     transX = -sx;
17004                     transY = -sy;
17005                 }
17006
17007                 if (transformToApply != null) {
17008                     if (concatMatrix) {
17009                         if (drawingWithRenderNode) {
17010                             renderNode.setAnimationMatrix(transformToApply.getMatrix());
17011                         } else {
17012                             // Undo the scroll translation, apply the transformation matrix,
17013                             // then redo the scroll translate to get the correct result.
17014                             canvas.translate(-transX, -transY);
17015                             canvas.concat(transformToApply.getMatrix());
17016                             canvas.translate(transX, transY);
17017                         }
17018                         parent.mGroupFlags |= ViewGroup.FLAG_CLEAR_TRANSFORMATION;
17019                     }
17020
17021                     float transformAlpha = transformToApply.getAlpha();
17022                     if (transformAlpha < 1) {
17023                         alpha *= transformAlpha;
17024                         parent.mGroupFlags |= ViewGroup.FLAG_CLEAR_TRANSFORMATION;
17025                     }
17026                 }
17027
17028                 if (!childHasIdentityMatrix && !drawingWithRenderNode) {
17029                     canvas.translate(-transX, -transY);
17030                     canvas.concat(getMatrix());
17031                     canvas.translate(transX, transY);
17032                 }
17033             }
17034
17035             // Deal with alpha if it is or used to be <1
17036             if (alpha < 1 || (mPrivateFlags3 & PFLAG3_VIEW_IS_ANIMATING_ALPHA) != 0) {
17037                 if (alpha < 1) {
17038                     mPrivateFlags3 |= PFLAG3_VIEW_IS_ANIMATING_ALPHA;
17039                 } else {
17040                     mPrivateFlags3 &= ~PFLAG3_VIEW_IS_ANIMATING_ALPHA;
17041                 }
17042                 parent.mGroupFlags |= ViewGroup.FLAG_CLEAR_TRANSFORMATION;
17043                 if (!drawingWithDrawingCache) {
17044                     final int multipliedAlpha = (int) (255 * alpha);
17045                     if (!onSetAlpha(multipliedAlpha)) {
17046                         if (drawingWithRenderNode) {
17047                             renderNode.setAlpha(alpha * getAlpha() * getTransitionAlpha());
17048                         } else if (layerType == LAYER_TYPE_NONE) {
17049                             canvas.saveLayerAlpha(sx, sy, sx + getWidth(), sy + getHeight(),
17050                                     multipliedAlpha);
17051                         }
17052                     } else {
17053                         // Alpha is handled by the child directly, clobber the layer's alpha
17054                         mPrivateFlags |= PFLAG_ALPHA_SET;
17055                     }
17056                 }
17057             }
17058         } else if ((mPrivateFlags & PFLAG_ALPHA_SET) == PFLAG_ALPHA_SET) {
17059             onSetAlpha(255);
17060             mPrivateFlags &= ~PFLAG_ALPHA_SET;
17061         }
17062
17063         if (!drawingWithRenderNode) {
17064             // apply clips directly, since RenderNode won't do it for this draw
17065             if ((parentFlags & ViewGroup.FLAG_CLIP_CHILDREN) != 0 && cache == null) {
17066                 if (offsetForScroll) {
17067                     canvas.clipRect(sx, sy, sx + getWidth(), sy + getHeight());
17068                 } else {
17069                     if (!scalingRequired || cache == null) {
17070                         canvas.clipRect(0, 0, getWidth(), getHeight());
17071                     } else {
17072                         canvas.clipRect(0, 0, cache.getWidth(), cache.getHeight());
17073                     }
17074                 }
17075             }
17076
17077             if (mClipBounds != null) {
17078                 // clip bounds ignore scroll
17079                 canvas.clipRect(mClipBounds);
17080             }
17081         }
17082
17083         if (!drawingWithDrawingCache) {
17084             if (drawingWithRenderNode) {
17085                 mPrivateFlags &= ~PFLAG_DIRTY_MASK;
17086                 ((DisplayListCanvas) canvas).drawRenderNode(renderNode);
17087             } else {
17088                 // Fast path for layouts with no backgrounds
17089                 if ((mPrivateFlags & PFLAG_SKIP_DRAW) == PFLAG_SKIP_DRAW) {
17090                     mPrivateFlags &= ~PFLAG_DIRTY_MASK;
17091                     dispatchDraw(canvas);
17092                 } else {
17093                     draw(canvas);
17094                 }
17095             }
17096         } else if (cache != null) {
17097             mPrivateFlags &= ~PFLAG_DIRTY_MASK;
17098             if (layerType == LAYER_TYPE_NONE || mLayerPaint == null) {
17099                 // no layer paint, use temporary paint to draw bitmap
17100                 Paint cachePaint = parent.mCachePaint;
17101                 if (cachePaint == null) {
17102                     cachePaint = new Paint();
17103                     cachePaint.setDither(false);
17104                     parent.mCachePaint = cachePaint;
17105                 }
17106                 cachePaint.setAlpha((int) (alpha * 255));
17107                 canvas.drawBitmap(cache, 0.0f, 0.0f, cachePaint);
17108             } else {
17109                 // use layer paint to draw the bitmap, merging the two alphas, but also restore
17110                 int layerPaintAlpha = mLayerPaint.getAlpha();
17111                 if (alpha < 1) {
17112                     mLayerPaint.setAlpha((int) (alpha * layerPaintAlpha));
17113                 }
17114                 canvas.drawBitmap(cache, 0.0f, 0.0f, mLayerPaint);
17115                 if (alpha < 1) {
17116                     mLayerPaint.setAlpha(layerPaintAlpha);
17117                 }
17118             }
17119         }
17120
17121         if (restoreTo >= 0) {
17122             canvas.restoreToCount(restoreTo);
17123         }
17124
17125         if (a != null && !more) {
17126             if (!hardwareAcceleratedCanvas && !a.getFillAfter()) {
17127                 onSetAlpha(255);
17128             }
17129             parent.finishAnimatingView(this, a);
17130         }
17131
17132         if (more && hardwareAcceleratedCanvas) {
17133             if (a.hasAlpha() && (mPrivateFlags & PFLAG_ALPHA_SET) == PFLAG_ALPHA_SET) {
17134                 // alpha animations should cause the child to recreate its display list
17135                 invalidate(true);
17136             }
17137         }
17138
17139         mRecreateDisplayList = false;
17140
17141         return more;
17142     }
17143
17144     /**
17145      * Manually render this view (and all of its children) to the given Canvas.
17146      * The view must have already done a full layout before this function is
17147      * called.  When implementing a view, implement
17148      * {@link #onDraw(android.graphics.Canvas)} instead of overriding this method.
17149      * If you do need to override this method, call the superclass version.
17150      *
17151      * @param canvas The Canvas to which the View is rendered.
17152      */
17153     @CallSuper
17154     public void draw(Canvas canvas) {
17155         final int privateFlags = mPrivateFlags;
17156         final boolean dirtyOpaque = (privateFlags & PFLAG_DIRTY_MASK) == PFLAG_DIRTY_OPAQUE &&
17157                 (mAttachInfo == null || !mAttachInfo.mIgnoreDirtyState);
17158         mPrivateFlags = (privateFlags & ~PFLAG_DIRTY_MASK) | PFLAG_DRAWN;
17159
17160         /*
17161          * Draw traversal performs several drawing steps which must be executed
17162          * in the appropriate order:
17163          *
17164          *      1. Draw the background
17165          *      2. If necessary, save the canvas' layers to prepare for fading
17166          *      3. Draw view's content
17167          *      4. Draw children
17168          *      5. If necessary, draw the fading edges and restore layers
17169          *      6. Draw decorations (scrollbars for instance)
17170          */
17171
17172         // Step 1, draw the background, if needed
17173         int saveCount;
17174
17175         if (!dirtyOpaque) {
17176             drawBackground(canvas);
17177         }
17178
17179         // skip step 2 & 5 if possible (common case)
17180         final int viewFlags = mViewFlags;
17181         boolean horizontalEdges = (viewFlags & FADING_EDGE_HORIZONTAL) != 0;
17182         boolean verticalEdges = (viewFlags & FADING_EDGE_VERTICAL) != 0;
17183         if (!verticalEdges && !horizontalEdges) {
17184             // Step 3, draw the content
17185             if (!dirtyOpaque) onDraw(canvas);
17186
17187             // Step 4, draw the children
17188             dispatchDraw(canvas);
17189
17190             // Overlay is part of the content and draws beneath Foreground
17191             if (mOverlay != null && !mOverlay.isEmpty()) {
17192                 mOverlay.getOverlayView().dispatchDraw(canvas);
17193             }
17194
17195             // Step 6, draw decorations (foreground, scrollbars)
17196             onDrawForeground(canvas);
17197
17198             // we're done...
17199             return;
17200         }
17201
17202         /*
17203          * Here we do the full fledged routine...
17204          * (this is an uncommon case where speed matters less,
17205          * this is why we repeat some of the tests that have been
17206          * done above)
17207          */
17208
17209         boolean drawTop = false;
17210         boolean drawBottom = false;
17211         boolean drawLeft = false;
17212         boolean drawRight = false;
17213
17214         float topFadeStrength = 0.0f;
17215         float bottomFadeStrength = 0.0f;
17216         float leftFadeStrength = 0.0f;
17217         float rightFadeStrength = 0.0f;
17218
17219         // Step 2, save the canvas' layers
17220         int paddingLeft = mPaddingLeft;
17221
17222         final boolean offsetRequired = isPaddingOffsetRequired();
17223         if (offsetRequired) {
17224             paddingLeft += getLeftPaddingOffset();
17225         }
17226
17227         int left = mScrollX + paddingLeft;
17228         int right = left + mRight - mLeft - mPaddingRight - paddingLeft;
17229         int top = mScrollY + getFadeTop(offsetRequired);
17230         int bottom = top + getFadeHeight(offsetRequired);
17231
17232         if (offsetRequired) {
17233             right += getRightPaddingOffset();
17234             bottom += getBottomPaddingOffset();
17235         }
17236
17237         final ScrollabilityCache scrollabilityCache = mScrollCache;
17238         final float fadeHeight = scrollabilityCache.fadingEdgeLength;
17239         int length = (int) fadeHeight;
17240
17241         // clip the fade length if top and bottom fades overlap
17242         // overlapping fades produce odd-looking artifacts
17243         if (verticalEdges && (top + length > bottom - length)) {
17244             length = (bottom - top) / 2;
17245         }
17246
17247         // also clip horizontal fades if necessary
17248         if (horizontalEdges && (left + length > right - length)) {
17249             length = (right - left) / 2;
17250         }
17251
17252         if (verticalEdges) {
17253             topFadeStrength = Math.max(0.0f, Math.min(1.0f, getTopFadingEdgeStrength()));
17254             drawTop = topFadeStrength * fadeHeight > 1.0f;
17255             bottomFadeStrength = Math.max(0.0f, Math.min(1.0f, getBottomFadingEdgeStrength()));
17256             drawBottom = bottomFadeStrength * fadeHeight > 1.0f;
17257         }
17258
17259         if (horizontalEdges) {
17260             leftFadeStrength = Math.max(0.0f, Math.min(1.0f, getLeftFadingEdgeStrength()));
17261             drawLeft = leftFadeStrength * fadeHeight > 1.0f;
17262             rightFadeStrength = Math.max(0.0f, Math.min(1.0f, getRightFadingEdgeStrength()));
17263             drawRight = rightFadeStrength * fadeHeight > 1.0f;
17264         }
17265
17266         saveCount = canvas.getSaveCount();
17267
17268         int solidColor = getSolidColor();
17269         if (solidColor == 0) {
17270             final int flags = Canvas.HAS_ALPHA_LAYER_SAVE_FLAG;
17271
17272             if (drawTop) {
17273                 canvas.saveLayer(left, top, right, top + length, null, flags);
17274             }
17275
17276             if (drawBottom) {
17277                 canvas.saveLayer(left, bottom - length, right, bottom, null, flags);
17278             }
17279
17280             if (drawLeft) {
17281                 canvas.saveLayer(left, top, left + length, bottom, null, flags);
17282             }
17283
17284             if (drawRight) {
17285                 canvas.saveLayer(right - length, top, right, bottom, null, flags);
17286             }
17287         } else {
17288             scrollabilityCache.setFadeColor(solidColor);
17289         }
17290
17291         // Step 3, draw the content
17292         if (!dirtyOpaque) onDraw(canvas);
17293
17294         // Step 4, draw the children
17295         dispatchDraw(canvas);
17296
17297         // Step 5, draw the fade effect and restore layers
17298         final Paint p = scrollabilityCache.paint;
17299         final Matrix matrix = scrollabilityCache.matrix;
17300         final Shader fade = scrollabilityCache.shader;
17301
17302         if (drawTop) {
17303             matrix.setScale(1, fadeHeight * topFadeStrength);
17304             matrix.postTranslate(left, top);
17305             fade.setLocalMatrix(matrix);
17306             p.setShader(fade);
17307             canvas.drawRect(left, top, right, top + length, p);
17308         }
17309
17310         if (drawBottom) {
17311             matrix.setScale(1, fadeHeight * bottomFadeStrength);
17312             matrix.postRotate(180);
17313             matrix.postTranslate(left, bottom);
17314             fade.setLocalMatrix(matrix);
17315             p.setShader(fade);
17316             canvas.drawRect(left, bottom - length, right, bottom, p);
17317         }
17318
17319         if (drawLeft) {
17320             matrix.setScale(1, fadeHeight * leftFadeStrength);
17321             matrix.postRotate(-90);
17322             matrix.postTranslate(left, top);
17323             fade.setLocalMatrix(matrix);
17324             p.setShader(fade);
17325             canvas.drawRect(left, top, left + length, bottom, p);
17326         }
17327
17328         if (drawRight) {
17329             matrix.setScale(1, fadeHeight * rightFadeStrength);
17330             matrix.postRotate(90);
17331             matrix.postTranslate(right, top);
17332             fade.setLocalMatrix(matrix);
17333             p.setShader(fade);
17334             canvas.drawRect(right - length, top, right, bottom, p);
17335         }
17336
17337         canvas.restoreToCount(saveCount);
17338
17339         // Overlay is part of the content and draws beneath Foreground
17340         if (mOverlay != null && !mOverlay.isEmpty()) {
17341             mOverlay.getOverlayView().dispatchDraw(canvas);
17342         }
17343
17344         // Step 6, draw decorations (foreground, scrollbars)
17345         onDrawForeground(canvas);
17346     }
17347
17348     /**
17349      * Draws the background onto the specified canvas.
17350      *
17351      * @param canvas Canvas on which to draw the background
17352      */
17353     private void drawBackground(Canvas canvas) {
17354         final Drawable background = mBackground;
17355         if (background == null) {
17356             return;
17357         }
17358
17359         setBackgroundBounds();
17360
17361         // Attempt to use a display list if requested.
17362         if (canvas.isHardwareAccelerated() && mAttachInfo != null
17363                 && mAttachInfo.mHardwareRenderer != null) {
17364             mBackgroundRenderNode = getDrawableRenderNode(background, mBackgroundRenderNode);
17365
17366             final RenderNode renderNode = mBackgroundRenderNode;
17367             if (renderNode != null && renderNode.isValid()) {
17368                 setBackgroundRenderNodeProperties(renderNode);
17369                 ((DisplayListCanvas) canvas).drawRenderNode(renderNode);
17370                 return;
17371             }
17372         }
17373
17374         final int scrollX = mScrollX;
17375         final int scrollY = mScrollY;
17376         if ((scrollX | scrollY) == 0) {
17377             background.draw(canvas);
17378         } else {
17379             canvas.translate(scrollX, scrollY);
17380             background.draw(canvas);
17381             canvas.translate(-scrollX, -scrollY);
17382         }
17383     }
17384
17385     /**
17386      * Sets the correct background bounds and rebuilds the outline, if needed.
17387      * <p/>
17388      * This is called by LayoutLib.
17389      */
17390     void setBackgroundBounds() {
17391         if (mBackgroundSizeChanged && mBackground != null) {
17392             mBackground.setBounds(0, 0, mRight - mLeft, mBottom - mTop);
17393             mBackgroundSizeChanged = false;
17394             rebuildOutline();
17395         }
17396     }
17397
17398     private void setBackgroundRenderNodeProperties(RenderNode renderNode) {
17399         renderNode.setTranslationX(mScrollX);
17400         renderNode.setTranslationY(mScrollY);
17401     }
17402
17403     /**
17404      * Creates a new display list or updates the existing display list for the
17405      * specified Drawable.
17406      *
17407      * @param drawable Drawable for which to create a display list
17408      * @param renderNode Existing RenderNode, or {@code null}
17409      * @return A valid display list for the specified drawable
17410      */
17411     private RenderNode getDrawableRenderNode(Drawable drawable, RenderNode renderNode) {
17412         if (renderNode == null) {
17413             renderNode = RenderNode.create(drawable.getClass().getName(), this);
17414         }
17415
17416         final Rect bounds = drawable.getBounds();
17417         final int width = bounds.width();
17418         final int height = bounds.height();
17419         final DisplayListCanvas canvas = renderNode.start(width, height);
17420
17421         // Reverse left/top translation done by drawable canvas, which will
17422         // instead be applied by rendernode's LTRB bounds below. This way, the
17423         // drawable's bounds match with its rendernode bounds and its content
17424         // will lie within those bounds in the rendernode tree.
17425         canvas.translate(-bounds.left, -bounds.top);
17426
17427         try {
17428             drawable.draw(canvas);
17429         } finally {
17430             renderNode.end(canvas);
17431         }
17432
17433         // Set up drawable properties that are view-independent.
17434         renderNode.setLeftTopRightBottom(bounds.left, bounds.top, bounds.right, bounds.bottom);
17435         renderNode.setProjectBackwards(drawable.isProjected());
17436         renderNode.setProjectionReceiver(true);
17437         renderNode.setClipToBounds(false);
17438         return renderNode;
17439     }
17440
17441     /**
17442      * Returns the overlay for this view, creating it if it does not yet exist.
17443      * Adding drawables to the overlay will cause them to be displayed whenever
17444      * the view itself is redrawn. Objects in the overlay should be actively
17445      * managed: remove them when they should not be displayed anymore. The
17446      * overlay will always have the same size as its host view.
17447      *
17448      * <p>Note: Overlays do not currently work correctly with {@link
17449      * SurfaceView} or {@link TextureView}; contents in overlays for these
17450      * types of views may not display correctly.</p>
17451      *
17452      * @return The ViewOverlay object for this view.
17453      * @see ViewOverlay
17454      */
17455     public ViewOverlay getOverlay() {
17456         if (mOverlay == null) {
17457             mOverlay = new ViewOverlay(mContext, this);
17458         }
17459         return mOverlay;
17460     }
17461
17462     /**
17463      * Override this if your view is known to always be drawn on top of a solid color background,
17464      * and needs to draw fading edges. Returning a non-zero color enables the view system to
17465      * optimize the drawing of the fading edges. If you do return a non-zero color, the alpha
17466      * should be set to 0xFF.
17467      *
17468      * @see #setVerticalFadingEdgeEnabled(boolean)
17469      * @see #setHorizontalFadingEdgeEnabled(boolean)
17470      *
17471      * @return The known solid color background for this view, or 0 if the color may vary
17472      */
17473     @ViewDebug.ExportedProperty(category = "drawing")
17474     @ColorInt
17475     public int getSolidColor() {
17476         return 0;
17477     }
17478
17479     /**
17480      * Build a human readable string representation of the specified view flags.
17481      *
17482      * @param flags the view flags to convert to a string
17483      * @return a String representing the supplied flags
17484      */
17485     private static String printFlags(int flags) {
17486         String output = "";
17487         int numFlags = 0;
17488         if ((flags & FOCUSABLE_MASK) == FOCUSABLE) {
17489             output += "TAKES_FOCUS";
17490             numFlags++;
17491         }
17492
17493         switch (flags & VISIBILITY_MASK) {
17494         case INVISIBLE:
17495             if (numFlags > 0) {
17496                 output += " ";
17497             }
17498             output += "INVISIBLE";
17499             // USELESS HERE numFlags++;
17500             break;
17501         case GONE:
17502             if (numFlags > 0) {
17503                 output += " ";
17504             }
17505             output += "GONE";
17506             // USELESS HERE numFlags++;
17507             break;
17508         default:
17509             break;
17510         }
17511         return output;
17512     }
17513
17514     /**
17515      * Build a human readable string representation of the specified private
17516      * view flags.
17517      *
17518      * @param privateFlags the private view flags to convert to a string
17519      * @return a String representing the supplied flags
17520      */
17521     private static String printPrivateFlags(int privateFlags) {
17522         String output = "";
17523         int numFlags = 0;
17524
17525         if ((privateFlags & PFLAG_WANTS_FOCUS) == PFLAG_WANTS_FOCUS) {
17526             output += "WANTS_FOCUS";
17527             numFlags++;
17528         }
17529
17530         if ((privateFlags & PFLAG_FOCUSED) == PFLAG_FOCUSED) {
17531             if (numFlags > 0) {
17532                 output += " ";
17533             }
17534             output += "FOCUSED";
17535             numFlags++;
17536         }
17537
17538         if ((privateFlags & PFLAG_SELECTED) == PFLAG_SELECTED) {
17539             if (numFlags > 0) {
17540                 output += " ";
17541             }
17542             output += "SELECTED";
17543             numFlags++;
17544         }
17545
17546         if ((privateFlags & PFLAG_IS_ROOT_NAMESPACE) == PFLAG_IS_ROOT_NAMESPACE) {
17547             if (numFlags > 0) {
17548                 output += " ";
17549             }
17550             output += "IS_ROOT_NAMESPACE";
17551             numFlags++;
17552         }
17553
17554         if ((privateFlags & PFLAG_HAS_BOUNDS) == PFLAG_HAS_BOUNDS) {
17555             if (numFlags > 0) {
17556                 output += " ";
17557             }
17558             output += "HAS_BOUNDS";
17559             numFlags++;
17560         }
17561
17562         if ((privateFlags & PFLAG_DRAWN) == PFLAG_DRAWN) {
17563             if (numFlags > 0) {
17564                 output += " ";
17565             }
17566             output += "DRAWN";
17567             // USELESS HERE numFlags++;
17568         }
17569         return output;
17570     }
17571
17572     /**
17573      * <p>Indicates whether or not this view's layout will be requested during
17574      * the next hierarchy layout pass.</p>
17575      *
17576      * @return true if the layout will be forced during next layout pass
17577      */
17578     public boolean isLayoutRequested() {
17579         return (mPrivateFlags & PFLAG_FORCE_LAYOUT) == PFLAG_FORCE_LAYOUT;
17580     }
17581
17582     /**
17583      * Return true if o is a ViewGroup that is laying out using optical bounds.
17584      * @hide
17585      */
17586     public static boolean isLayoutModeOptical(Object o) {
17587         return o instanceof ViewGroup && ((ViewGroup) o).isLayoutModeOptical();
17588     }
17589
17590     private boolean setOpticalFrame(int left, int top, int right, int bottom) {
17591         Insets parentInsets = mParent instanceof View ?
17592                 ((View) mParent).getOpticalInsets() : Insets.NONE;
17593         Insets childInsets = getOpticalInsets();
17594         return setFrame(
17595                 left   + parentInsets.left - childInsets.left,
17596                 top    + parentInsets.top  - childInsets.top,
17597                 right  + parentInsets.left + childInsets.right,
17598                 bottom + parentInsets.top  + childInsets.bottom);
17599     }
17600
17601     /**
17602      * Assign a size and position to a view and all of its
17603      * descendants
17604      *
17605      * <p>This is the second phase of the layout mechanism.
17606      * (The first is measuring). In this phase, each parent calls
17607      * layout on all of its children to position them.
17608      * This is typically done using the child measurements
17609      * that were stored in the measure pass().</p>
17610      *
17611      * <p>Derived classes should not override this method.
17612      * Derived classes with children should override
17613      * onLayout. In that method, they should
17614      * call layout on each of their children.</p>
17615      *
17616      * @param l Left position, relative to parent
17617      * @param t Top position, relative to parent
17618      * @param r Right position, relative to parent
17619      * @param b Bottom position, relative to parent
17620      */
17621     @SuppressWarnings({"unchecked"})
17622     public void layout(int l, int t, int r, int b) {
17623         if ((mPrivateFlags3 & PFLAG3_MEASURE_NEEDED_BEFORE_LAYOUT) != 0) {
17624             onMeasure(mOldWidthMeasureSpec, mOldHeightMeasureSpec);
17625             mPrivateFlags3 &= ~PFLAG3_MEASURE_NEEDED_BEFORE_LAYOUT;
17626         }
17627
17628         int oldL = mLeft;
17629         int oldT = mTop;
17630         int oldB = mBottom;
17631         int oldR = mRight;
17632
17633         boolean changed = isLayoutModeOptical(mParent) ?
17634                 setOpticalFrame(l, t, r, b) : setFrame(l, t, r, b);
17635
17636         if (changed || (mPrivateFlags & PFLAG_LAYOUT_REQUIRED) == PFLAG_LAYOUT_REQUIRED) {
17637             onLayout(changed, l, t, r, b);
17638
17639             if (shouldDrawRoundScrollbar()) {
17640                 if(mRoundScrollbarRenderer == null) {
17641                     mRoundScrollbarRenderer = new RoundScrollbarRenderer(this);
17642                 }
17643             } else {
17644                 mRoundScrollbarRenderer = null;
17645             }
17646
17647             mPrivateFlags &= ~PFLAG_LAYOUT_REQUIRED;
17648
17649             ListenerInfo li = mListenerInfo;
17650             if (li != null && li.mOnLayoutChangeListeners != null) {
17651                 ArrayList<OnLayoutChangeListener> listenersCopy =
17652                         (ArrayList<OnLayoutChangeListener>)li.mOnLayoutChangeListeners.clone();
17653                 int numListeners = listenersCopy.size();
17654                 for (int i = 0; i < numListeners; ++i) {
17655                     listenersCopy.get(i).onLayoutChange(this, l, t, r, b, oldL, oldT, oldR, oldB);
17656                 }
17657             }
17658         }
17659
17660         mPrivateFlags &= ~PFLAG_FORCE_LAYOUT;
17661         mPrivateFlags3 |= PFLAG3_IS_LAID_OUT;
17662     }
17663
17664     /**
17665      * Called from layout when this view should
17666      * assign a size and position to each of its children.
17667      *
17668      * Derived classes with children should override
17669      * this method and call layout on each of
17670      * their children.
17671      * @param changed This is a new size or position for this view
17672      * @param left Left position, relative to parent
17673      * @param top Top position, relative to parent
17674      * @param right Right position, relative to parent
17675      * @param bottom Bottom position, relative to parent
17676      */
17677     protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
17678     }
17679
17680     /**
17681      * Assign a size and position to this view.
17682      *
17683      * This is called from layout.
17684      *
17685      * @param left Left position, relative to parent
17686      * @param top Top position, relative to parent
17687      * @param right Right position, relative to parent
17688      * @param bottom Bottom position, relative to parent
17689      * @return true if the new size and position are different than the
17690      *         previous ones
17691      * {@hide}
17692      */
17693     protected boolean setFrame(int left, int top, int right, int bottom) {
17694         boolean changed = false;
17695
17696         if (DBG) {
17697             Log.d("View", this + " View.setFrame(" + left + "," + top + ","
17698                     + right + "," + bottom + ")");
17699         }
17700
17701         if (mLeft != left || mRight != right || mTop != top || mBottom != bottom) {
17702             changed = true;
17703
17704             // Remember our drawn bit
17705             int drawn = mPrivateFlags & PFLAG_DRAWN;
17706
17707             int oldWidth = mRight - mLeft;
17708             int oldHeight = mBottom - mTop;
17709             int newWidth = right - left;
17710             int newHeight = bottom - top;
17711             boolean sizeChanged = (newWidth != oldWidth) || (newHeight != oldHeight);
17712
17713             // Invalidate our old position
17714             invalidate(sizeChanged);
17715
17716             mLeft = left;
17717             mTop = top;
17718             mRight = right;
17719             mBottom = bottom;
17720             mRenderNode.setLeftTopRightBottom(mLeft, mTop, mRight, mBottom);
17721
17722             mPrivateFlags |= PFLAG_HAS_BOUNDS;
17723
17724
17725             if (sizeChanged) {
17726                 sizeChange(newWidth, newHeight, oldWidth, oldHeight);
17727             }
17728
17729             if ((mViewFlags & VISIBILITY_MASK) == VISIBLE || mGhostView != null) {
17730                 // If we are visible, force the DRAWN bit to on so that
17731                 // this invalidate will go through (at least to our parent).
17732                 // This is because someone may have invalidated this view
17733                 // before this call to setFrame came in, thereby clearing
17734                 // the DRAWN bit.
17735                 mPrivateFlags |= PFLAG_DRAWN;
17736                 invalidate(sizeChanged);
17737                 // parent display list may need to be recreated based on a change in the bounds
17738                 // of any child
17739                 invalidateParentCaches();
17740             }
17741
17742             // Reset drawn bit to original value (invalidate turns it off)
17743             mPrivateFlags |= drawn;
17744
17745             mBackgroundSizeChanged = true;
17746             if (mForegroundInfo != null) {
17747                 mForegroundInfo.mBoundsChanged = true;
17748             }
17749
17750             notifySubtreeAccessibilityStateChangedIfNeeded();
17751         }
17752         return changed;
17753     }
17754
17755     /**
17756      * Same as setFrame, but public and hidden. For use in {@link android.transition.ChangeBounds}.
17757      * @hide
17758      */
17759     public void setLeftTopRightBottom(int left, int top, int right, int bottom) {
17760         setFrame(left, top, right, bottom);
17761     }
17762
17763     private void sizeChange(int newWidth, int newHeight, int oldWidth, int oldHeight) {
17764         onSizeChanged(newWidth, newHeight, oldWidth, oldHeight);
17765         if (mOverlay != null) {
17766             mOverlay.getOverlayView().setRight(newWidth);
17767             mOverlay.getOverlayView().setBottom(newHeight);
17768         }
17769         rebuildOutline();
17770     }
17771
17772     /**
17773      * Finalize inflating a view from XML.  This is called as the last phase
17774      * of inflation, after all child views have been added.
17775      *
17776      * <p>Even if the subclass overrides onFinishInflate, they should always be
17777      * sure to call the super method, so that we get called.
17778      */
17779     @CallSuper
17780     protected void onFinishInflate() {
17781     }
17782
17783     /**
17784      * Returns the resources associated with this view.
17785      *
17786      * @return Resources object.
17787      */
17788     public Resources getResources() {
17789         return mResources;
17790     }
17791
17792     /**
17793      * Invalidates the specified Drawable.
17794      *
17795      * @param drawable the drawable to invalidate
17796      */
17797     @Override
17798     public void invalidateDrawable(@NonNull Drawable drawable) {
17799         if (verifyDrawable(drawable)) {
17800             final Rect dirty = drawable.getDirtyBounds();
17801             final int scrollX = mScrollX;
17802             final int scrollY = mScrollY;
17803
17804             invalidate(dirty.left + scrollX, dirty.top + scrollY,
17805                     dirty.right + scrollX, dirty.bottom + scrollY);
17806             rebuildOutline();
17807         }
17808     }
17809
17810     /**
17811      * Schedules an action on a drawable to occur at a specified time.
17812      *
17813      * @param who the recipient of the action
17814      * @param what the action to run on the drawable
17815      * @param when the time at which the action must occur. Uses the
17816      *        {@link SystemClock#uptimeMillis} timebase.
17817      */
17818     @Override
17819     public void scheduleDrawable(@NonNull Drawable who, @NonNull Runnable what, long when) {
17820         if (verifyDrawable(who) && what != null) {
17821             final long delay = when - SystemClock.uptimeMillis();
17822             if (mAttachInfo != null) {
17823                 mAttachInfo.mViewRootImpl.mChoreographer.postCallbackDelayed(
17824                         Choreographer.CALLBACK_ANIMATION, what, who,
17825                         Choreographer.subtractFrameDelay(delay));
17826             } else {
17827                 // Postpone the runnable until we know
17828                 // on which thread it needs to run.
17829                 getRunQueue().postDelayed(what, delay);
17830             }
17831         }
17832     }
17833
17834     /**
17835      * Cancels a scheduled action on a drawable.
17836      *
17837      * @param who the recipient of the action
17838      * @param what the action to cancel
17839      */
17840     @Override
17841     public void unscheduleDrawable(@NonNull Drawable who, @NonNull Runnable what) {
17842         if (verifyDrawable(who) && what != null) {
17843             if (mAttachInfo != null) {
17844                 mAttachInfo.mViewRootImpl.mChoreographer.removeCallbacks(
17845                         Choreographer.CALLBACK_ANIMATION, what, who);
17846             }
17847             getRunQueue().removeCallbacks(what);
17848         }
17849     }
17850
17851     /**
17852      * Unschedule any events associated with the given Drawable.  This can be
17853      * used when selecting a new Drawable into a view, so that the previous
17854      * one is completely unscheduled.
17855      *
17856      * @param who The Drawable to unschedule.
17857      *
17858      * @see #drawableStateChanged
17859      */
17860     public void unscheduleDrawable(Drawable who) {
17861         if (mAttachInfo != null && who != null) {
17862             mAttachInfo.mViewRootImpl.mChoreographer.removeCallbacks(
17863                     Choreographer.CALLBACK_ANIMATION, null, who);
17864         }
17865     }
17866
17867     /**
17868      * Resolve the Drawables depending on the layout direction. This is implicitly supposing
17869      * that the View directionality can and will be resolved before its Drawables.
17870      *
17871      * Will call {@link View#onResolveDrawables} when resolution is done.
17872      *
17873      * @hide
17874      */
17875     protected void resolveDrawables() {
17876         // Drawables resolution may need to happen before resolving the layout direction (which is
17877         // done only during the measure() call).
17878         // If the layout direction is not resolved yet, we cannot resolve the Drawables except in
17879         // one case: when the raw layout direction has not been defined as LAYOUT_DIRECTION_INHERIT.
17880         // So, if the raw layout direction is LAYOUT_DIRECTION_LTR or LAYOUT_DIRECTION_RTL or
17881         // LAYOUT_DIRECTION_LOCALE, we can "cheat" and we don't need to wait for the layout
17882         // direction to be resolved as its resolved value will be the same as its raw value.
17883         if (!isLayoutDirectionResolved() &&
17884                 getRawLayoutDirection() == View.LAYOUT_DIRECTION_INHERIT) {
17885             return;
17886         }
17887
17888         final int layoutDirection = isLayoutDirectionResolved() ?
17889                 getLayoutDirection() : getRawLayoutDirection();
17890
17891         if (mBackground != null) {
17892             mBackground.setLayoutDirection(layoutDirection);
17893         }
17894         if (mForegroundInfo != null && mForegroundInfo.mDrawable != null) {
17895             mForegroundInfo.mDrawable.setLayoutDirection(layoutDirection);
17896         }
17897         mPrivateFlags2 |= PFLAG2_DRAWABLE_RESOLVED;
17898         onResolveDrawables(layoutDirection);
17899     }
17900
17901     boolean areDrawablesResolved() {
17902         return (mPrivateFlags2 & PFLAG2_DRAWABLE_RESOLVED) == PFLAG2_DRAWABLE_RESOLVED;
17903     }
17904
17905     /**
17906      * Called when layout direction has been resolved.
17907      *
17908      * The default implementation does nothing.
17909      *
17910      * @param layoutDirection The resolved layout direction.
17911      *
17912      * @see #LAYOUT_DIRECTION_LTR
17913      * @see #LAYOUT_DIRECTION_RTL
17914      *
17915      * @hide
17916      */
17917     public void onResolveDrawables(@ResolvedLayoutDir int layoutDirection) {
17918     }
17919
17920     /**
17921      * @hide
17922      */
17923     protected void resetResolvedDrawables() {
17924         resetResolvedDrawablesInternal();
17925     }
17926
17927     void resetResolvedDrawablesInternal() {
17928         mPrivateFlags2 &= ~PFLAG2_DRAWABLE_RESOLVED;
17929     }
17930
17931     /**
17932      * If your view subclass is displaying its own Drawable objects, it should
17933      * override this function and return true for any Drawable it is
17934      * displaying.  This allows animations for those drawables to be
17935      * scheduled.
17936      *
17937      * <p>Be sure to call through to the super class when overriding this
17938      * function.
17939      *
17940      * @param who The Drawable to verify.  Return true if it is one you are
17941      *            displaying, else return the result of calling through to the
17942      *            super class.
17943      *
17944      * @return boolean If true than the Drawable is being displayed in the
17945      *         view; else false and it is not allowed to animate.
17946      *
17947      * @see #unscheduleDrawable(android.graphics.drawable.Drawable)
17948      * @see #drawableStateChanged()
17949      */
17950     @CallSuper
17951     protected boolean verifyDrawable(@NonNull Drawable who) {
17952         // Avoid verifying the scroll bar drawable so that we don't end up in
17953         // an invalidation loop. This effectively prevents the scroll bar
17954         // drawable from triggering invalidations and scheduling runnables.
17955         return who == mBackground || (mForegroundInfo != null && mForegroundInfo.mDrawable == who);
17956     }
17957
17958     /**
17959      * This function is called whenever the state of the view changes in such
17960      * a way that it impacts the state of drawables being shown.
17961      * <p>
17962      * If the View has a StateListAnimator, it will also be called to run necessary state
17963      * change animations.
17964      * <p>
17965      * Be sure to call through to the superclass when overriding this function.
17966      *
17967      * @see Drawable#setState(int[])
17968      */
17969     @CallSuper
17970     protected void drawableStateChanged() {
17971         final int[] state = getDrawableState();
17972         boolean changed = false;
17973
17974         final Drawable bg = mBackground;
17975         if (bg != null && bg.isStateful()) {
17976             changed |= bg.setState(state);
17977         }
17978
17979         final Drawable fg = mForegroundInfo != null ? mForegroundInfo.mDrawable : null;
17980         if (fg != null && fg.isStateful()) {
17981             changed |= fg.setState(state);
17982         }
17983
17984         if (mScrollCache != null) {
17985             final Drawable scrollBar = mScrollCache.scrollBar;
17986             if (scrollBar != null && scrollBar.isStateful()) {
17987                 changed |= scrollBar.setState(state)
17988                         && mScrollCache.state != ScrollabilityCache.OFF;
17989             }
17990         }
17991
17992         if (mStateListAnimator != null) {
17993             mStateListAnimator.setState(state);
17994         }
17995
17996         if (changed) {
17997             invalidate();
17998         }
17999     }
18000
18001     /**
18002      * This function is called whenever the view hotspot changes and needs to
18003      * be propagated to drawables or child views managed by the view.
18004      * <p>
18005      * Dispatching to child views is handled by
18006      * {@link #dispatchDrawableHotspotChanged(float, float)}.
18007      * <p>
18008      * Be sure to call through to the superclass when overriding this function.
18009      *
18010      * @param x hotspot x coordinate
18011      * @param y hotspot y coordinate
18012      */
18013     @CallSuper
18014     public void drawableHotspotChanged(float x, float y) {
18015         if (mBackground != null) {
18016             mBackground.setHotspot(x, y);
18017         }
18018         if (mForegroundInfo != null && mForegroundInfo.mDrawable != null) {
18019             mForegroundInfo.mDrawable.setHotspot(x, y);
18020         }
18021
18022         dispatchDrawableHotspotChanged(x, y);
18023     }
18024
18025     /**
18026      * Dispatches drawableHotspotChanged to all of this View's children.
18027      *
18028      * @param x hotspot x coordinate
18029      * @param y hotspot y coordinate
18030      * @see #drawableHotspotChanged(float, float)
18031      */
18032     public void dispatchDrawableHotspotChanged(float x, float y) {
18033     }
18034
18035     /**
18036      * Call this to force a view to update its drawable state. This will cause
18037      * drawableStateChanged to be called on this view. Views that are interested
18038      * in the new state should call getDrawableState.
18039      *
18040      * @see #drawableStateChanged
18041      * @see #getDrawableState
18042      */
18043     public void refreshDrawableState() {
18044         mPrivateFlags |= PFLAG_DRAWABLE_STATE_DIRTY;
18045         drawableStateChanged();
18046
18047         ViewParent parent = mParent;
18048         if (parent != null) {
18049             parent.childDrawableStateChanged(this);
18050         }
18051     }
18052
18053     /**
18054      * Return an array of resource IDs of the drawable states representing the
18055      * current state of the view.
18056      *
18057      * @return The current drawable state
18058      *
18059      * @see Drawable#setState(int[])
18060      * @see #drawableStateChanged()
18061      * @see #onCreateDrawableState(int)
18062      */
18063     public final int[] getDrawableState() {
18064         if ((mDrawableState != null) && ((mPrivateFlags & PFLAG_DRAWABLE_STATE_DIRTY) == 0)) {
18065             return mDrawableState;
18066         } else {
18067             mDrawableState = onCreateDrawableState(0);
18068             mPrivateFlags &= ~PFLAG_DRAWABLE_STATE_DIRTY;
18069             return mDrawableState;
18070         }
18071     }
18072
18073     /**
18074      * Generate the new {@link android.graphics.drawable.Drawable} state for
18075      * this view. This is called by the view
18076      * system when the cached Drawable state is determined to be invalid.  To
18077      * retrieve the current state, you should use {@link #getDrawableState}.
18078      *
18079      * @param extraSpace if non-zero, this is the number of extra entries you
18080      * would like in the returned array in which you can place your own
18081      * states.
18082      *
18083      * @return Returns an array holding the current {@link Drawable} state of
18084      * the view.
18085      *
18086      * @see #mergeDrawableStates(int[], int[])
18087      */
18088     protected int[] onCreateDrawableState(int extraSpace) {
18089         if ((mViewFlags & DUPLICATE_PARENT_STATE) == DUPLICATE_PARENT_STATE &&
18090                 mParent instanceof View) {
18091             return ((View) mParent).onCreateDrawableState(extraSpace);
18092         }
18093
18094         int[] drawableState;
18095
18096         int privateFlags = mPrivateFlags;
18097
18098         int viewStateIndex = 0;
18099         if ((privateFlags & PFLAG_PRESSED) != 0) viewStateIndex |= StateSet.VIEW_STATE_PRESSED;
18100         if ((mViewFlags & ENABLED_MASK) == ENABLED) viewStateIndex |= StateSet.VIEW_STATE_ENABLED;
18101         if (isFocused()) viewStateIndex |= StateSet.VIEW_STATE_FOCUSED;
18102         if ((privateFlags & PFLAG_SELECTED) != 0) viewStateIndex |= StateSet.VIEW_STATE_SELECTED;
18103         if (hasWindowFocus()) viewStateIndex |= StateSet.VIEW_STATE_WINDOW_FOCUSED;
18104         if ((privateFlags & PFLAG_ACTIVATED) != 0) viewStateIndex |= StateSet.VIEW_STATE_ACTIVATED;
18105         if (mAttachInfo != null && mAttachInfo.mHardwareAccelerationRequested &&
18106                 ThreadedRenderer.isAvailable()) {
18107             // This is set if HW acceleration is requested, even if the current
18108             // process doesn't allow it.  This is just to allow app preview
18109             // windows to better match their app.
18110             viewStateIndex |= StateSet.VIEW_STATE_ACCELERATED;
18111         }
18112         if ((privateFlags & PFLAG_HOVERED) != 0) viewStateIndex |= StateSet.VIEW_STATE_HOVERED;
18113
18114         final int privateFlags2 = mPrivateFlags2;
18115         if ((privateFlags2 & PFLAG2_DRAG_CAN_ACCEPT) != 0) {
18116             viewStateIndex |= StateSet.VIEW_STATE_DRAG_CAN_ACCEPT;
18117         }
18118         if ((privateFlags2 & PFLAG2_DRAG_HOVERED) != 0) {
18119             viewStateIndex |= StateSet.VIEW_STATE_DRAG_HOVERED;
18120         }
18121
18122         drawableState = StateSet.get(viewStateIndex);
18123
18124         //noinspection ConstantIfStatement
18125         if (false) {
18126             Log.i("View", "drawableStateIndex=" + viewStateIndex);
18127             Log.i("View", toString()
18128                     + " pressed=" + ((privateFlags & PFLAG_PRESSED) != 0)
18129                     + " en=" + ((mViewFlags & ENABLED_MASK) == ENABLED)
18130                     + " fo=" + hasFocus()
18131                     + " sl=" + ((privateFlags & PFLAG_SELECTED) != 0)
18132                     + " wf=" + hasWindowFocus()
18133                     + ": " + Arrays.toString(drawableState));
18134         }
18135
18136         if (extraSpace == 0) {
18137             return drawableState;
18138         }
18139
18140         final int[] fullState;
18141         if (drawableState != null) {
18142             fullState = new int[drawableState.length + extraSpace];
18143             System.arraycopy(drawableState, 0, fullState, 0, drawableState.length);
18144         } else {
18145             fullState = new int[extraSpace];
18146         }
18147
18148         return fullState;
18149     }
18150
18151     /**
18152      * Merge your own state values in <var>additionalState</var> into the base
18153      * state values <var>baseState</var> that were returned by
18154      * {@link #onCreateDrawableState(int)}.
18155      *
18156      * @param baseState The base state values returned by
18157      * {@link #onCreateDrawableState(int)}, which will be modified to also hold your
18158      * own additional state values.
18159      *
18160      * @param additionalState The additional state values you would like
18161      * added to <var>baseState</var>; this array is not modified.
18162      *
18163      * @return As a convenience, the <var>baseState</var> array you originally
18164      * passed into the function is returned.
18165      *
18166      * @see #onCreateDrawableState(int)
18167      */
18168     protected static int[] mergeDrawableStates(int[] baseState, int[] additionalState) {
18169         final int N = baseState.length;
18170         int i = N - 1;
18171         while (i >= 0 && baseState[i] == 0) {
18172             i--;
18173         }
18174         System.arraycopy(additionalState, 0, baseState, i + 1, additionalState.length);
18175         return baseState;
18176     }
18177
18178     /**
18179      * Call {@link Drawable#jumpToCurrentState() Drawable.jumpToCurrentState()}
18180      * on all Drawable objects associated with this view.
18181      * <p>
18182      * Also calls {@link StateListAnimator#jumpToCurrentState()} if there is a StateListAnimator
18183      * attached to this view.
18184      */
18185     @CallSuper
18186     public void jumpDrawablesToCurrentState() {
18187         if (mBackground != null) {
18188             mBackground.jumpToCurrentState();
18189         }
18190         if (mStateListAnimator != null) {
18191             mStateListAnimator.jumpToCurrentState();
18192         }
18193         if (mForegroundInfo != null && mForegroundInfo.mDrawable != null) {
18194             mForegroundInfo.mDrawable.jumpToCurrentState();
18195         }
18196     }
18197
18198     /**
18199      * Sets the background color for this view.
18200      * @param color the color of the background
18201      */
18202     @RemotableViewMethod
18203     public void setBackgroundColor(@ColorInt int color) {
18204         if (mBackground instanceof ColorDrawable) {
18205             ((ColorDrawable) mBackground.mutate()).setColor(color);
18206             computeOpaqueFlags();
18207             mBackgroundResource = 0;
18208         } else {
18209             setBackground(new ColorDrawable(color));
18210         }
18211     }
18212
18213     /**
18214      * Set the background to a given resource. The resource should refer to
18215      * a Drawable object or 0 to remove the background.
18216      * @param resid The identifier of the resource.
18217      *
18218      * @attr ref android.R.styleable#View_background
18219      */
18220     @RemotableViewMethod
18221     public void setBackgroundResource(@DrawableRes int resid) {
18222         if (resid != 0 && resid == mBackgroundResource) {
18223             return;
18224         }
18225
18226         Drawable d = null;
18227         if (resid != 0) {
18228             d = mContext.getDrawable(resid);
18229         }
18230         setBackground(d);
18231
18232         mBackgroundResource = resid;
18233     }
18234
18235     /**
18236      * Set the background to a given Drawable, or remove the background. If the
18237      * background has padding, this View's padding is set to the background's
18238      * padding. However, when a background is removed, this View's padding isn't
18239      * touched. If setting the padding is desired, please use
18240      * {@link #setPadding(int, int, int, int)}.
18241      *
18242      * @param background The Drawable to use as the background, or null to remove the
18243      *        background
18244      */
18245     public void setBackground(Drawable background) {
18246         //noinspection deprecation
18247         setBackgroundDrawable(background);
18248     }
18249
18250     /**
18251      * @deprecated use {@link #setBackground(Drawable)} instead
18252      */
18253     @Deprecated
18254     public void setBackgroundDrawable(Drawable background) {
18255         computeOpaqueFlags();
18256
18257         if (background == mBackground) {
18258             return;
18259         }
18260
18261         boolean requestLayout = false;
18262
18263         mBackgroundResource = 0;
18264
18265         /*
18266          * Regardless of whether we're setting a new background or not, we want
18267          * to clear the previous drawable. setVisible first while we still have the callback set.
18268          */
18269         if (mBackground != null) {
18270             if (isAttachedToWindow()) {
18271                 mBackground.setVisible(false, false);
18272             }
18273             mBackground.setCallback(null);
18274             unscheduleDrawable(mBackground);
18275         }
18276
18277         if (background != null) {
18278             Rect padding = sThreadLocal.get();
18279             if (padding == null) {
18280                 padding = new Rect();
18281                 sThreadLocal.set(padding);
18282             }
18283             resetResolvedDrawablesInternal();
18284             background.setLayoutDirection(getLayoutDirection());
18285             if (background.getPadding(padding)) {
18286                 resetResolvedPaddingInternal();
18287                 switch (background.getLayoutDirection()) {
18288                     case LAYOUT_DIRECTION_RTL:
18289                         mUserPaddingLeftInitial = padding.right;
18290                         mUserPaddingRightInitial = padding.left;
18291                         internalSetPadding(padding.right, padding.top, padding.left, padding.bottom);
18292                         break;
18293                     case LAYOUT_DIRECTION_LTR:
18294                     default:
18295                         mUserPaddingLeftInitial = padding.left;
18296                         mUserPaddingRightInitial = padding.right;
18297                         internalSetPadding(padding.left, padding.top, padding.right, padding.bottom);
18298                 }
18299                 mLeftPaddingDefined = false;
18300                 mRightPaddingDefined = false;
18301             }
18302
18303             // Compare the minimum sizes of the old Drawable and the new.  If there isn't an old or
18304             // if it has a different minimum size, we should layout again
18305             if (mBackground == null
18306                     || mBackground.getMinimumHeight() != background.getMinimumHeight()
18307                     || mBackground.getMinimumWidth() != background.getMinimumWidth()) {
18308                 requestLayout = true;
18309             }
18310
18311             // Set mBackground before we set this as the callback and start making other
18312             // background drawable state change calls. In particular, the setVisible call below
18313             // can result in drawables attempting to start animations or otherwise invalidate,
18314             // which requires the view set as the callback (us) to recognize the drawable as
18315             // belonging to it as per verifyDrawable.
18316             mBackground = background;
18317             if (background.isStateful()) {
18318                 background.setState(getDrawableState());
18319             }
18320             if (isAttachedToWindow()) {
18321                 background.setVisible(getWindowVisibility() == VISIBLE && isShown(), false);
18322             }
18323
18324             applyBackgroundTint();
18325
18326             // Set callback last, since the view may still be initializing.
18327             background.setCallback(this);
18328
18329             if ((mPrivateFlags & PFLAG_SKIP_DRAW) != 0) {
18330                 mPrivateFlags &= ~PFLAG_SKIP_DRAW;
18331                 requestLayout = true;
18332             }
18333         } else {
18334             /* Remove the background */
18335             mBackground = null;
18336             if ((mViewFlags & WILL_NOT_DRAW) != 0
18337                     && (mForegroundInfo == null || mForegroundInfo.mDrawable == null)) {
18338                 mPrivateFlags |= PFLAG_SKIP_DRAW;
18339             }
18340
18341             /*
18342              * When the background is set, we try to apply its padding to this
18343              * View. When the background is removed, we don't touch this View's
18344              * padding. This is noted in the Javadocs. Hence, we don't need to
18345              * requestLayout(), the invalidate() below is sufficient.
18346              */
18347
18348             // The old background's minimum size could have affected this
18349             // View's layout, so let's requestLayout
18350             requestLayout = true;
18351         }
18352
18353         computeOpaqueFlags();
18354
18355         if (requestLayout) {
18356             requestLayout();
18357         }
18358
18359         mBackgroundSizeChanged = true;
18360         invalidate(true);
18361         invalidateOutline();
18362     }
18363
18364     /**
18365      * Gets the background drawable
18366      *
18367      * @return The drawable used as the background for this view, if any.
18368      *
18369      * @see #setBackground(Drawable)
18370      *
18371      * @attr ref android.R.styleable#View_background
18372      */
18373     public Drawable getBackground() {
18374         return mBackground;
18375     }
18376
18377     /**
18378      * Applies a tint to the background drawable. Does not modify the current tint
18379      * mode, which is {@link PorterDuff.Mode#SRC_IN} by default.
18380      * <p>
18381      * Subsequent calls to {@link #setBackground(Drawable)} will automatically
18382      * mutate the drawable and apply the specified tint and tint mode using
18383      * {@link Drawable#setTintList(ColorStateList)}.
18384      *
18385      * @param tint the tint to apply, may be {@code null} to clear tint
18386      *
18387      * @attr ref android.R.styleable#View_backgroundTint
18388      * @see #getBackgroundTintList()
18389      * @see Drawable#setTintList(ColorStateList)
18390      */
18391     public void setBackgroundTintList(@Nullable ColorStateList tint) {
18392         if (mBackgroundTint == null) {
18393             mBackgroundTint = new TintInfo();
18394         }
18395         mBackgroundTint.mTintList = tint;
18396         mBackgroundTint.mHasTintList = true;
18397
18398         applyBackgroundTint();
18399     }
18400
18401     /**
18402      * Return the tint applied to the background drawable, if specified.
18403      *
18404      * @return the tint applied to the background drawable
18405      * @attr ref android.R.styleable#View_backgroundTint
18406      * @see #setBackgroundTintList(ColorStateList)
18407      */
18408     @Nullable
18409     public ColorStateList getBackgroundTintList() {
18410         return mBackgroundTint != null ? mBackgroundTint.mTintList : null;
18411     }
18412
18413     /**
18414      * Specifies the blending mode used to apply the tint specified by
18415      * {@link #setBackgroundTintList(ColorStateList)}} to the background
18416      * drawable. The default mode is {@link PorterDuff.Mode#SRC_IN}.
18417      *
18418      * @param tintMode the blending mode used to apply the tint, may be
18419      *                 {@code null} to clear tint
18420      * @attr ref android.R.styleable#View_backgroundTintMode
18421      * @see #getBackgroundTintMode()
18422      * @see Drawable#setTintMode(PorterDuff.Mode)
18423      */
18424     public void setBackgroundTintMode(@Nullable PorterDuff.Mode tintMode) {
18425         if (mBackgroundTint == null) {
18426             mBackgroundTint = new TintInfo();
18427         }
18428         mBackgroundTint.mTintMode = tintMode;
18429         mBackgroundTint.mHasTintMode = true;
18430
18431         applyBackgroundTint();
18432     }
18433
18434     /**
18435      * Return the blending mode used to apply the tint to the background
18436      * drawable, if specified.
18437      *
18438      * @return the blending mode used to apply the tint to the background
18439      *         drawable
18440      * @attr ref android.R.styleable#View_backgroundTintMode
18441      * @see #setBackgroundTintMode(PorterDuff.Mode)
18442      */
18443     @Nullable
18444     public PorterDuff.Mode getBackgroundTintMode() {
18445         return mBackgroundTint != null ? mBackgroundTint.mTintMode : null;
18446     }
18447
18448     private void applyBackgroundTint() {
18449         if (mBackground != null && mBackgroundTint != null) {
18450             final TintInfo tintInfo = mBackgroundTint;
18451             if (tintInfo.mHasTintList || tintInfo.mHasTintMode) {
18452                 mBackground = mBackground.mutate();
18453
18454                 if (tintInfo.mHasTintList) {
18455                     mBackground.setTintList(tintInfo.mTintList);
18456                 }
18457
18458                 if (tintInfo.mHasTintMode) {
18459                     mBackground.setTintMode(tintInfo.mTintMode);
18460                 }
18461
18462                 // The drawable (or one of its children) may not have been
18463                 // stateful before applying the tint, so let's try again.
18464                 if (mBackground.isStateful()) {
18465                     mBackground.setState(getDrawableState());
18466                 }
18467             }
18468         }
18469     }
18470
18471     /**
18472      * Returns the drawable used as the foreground of this View. The
18473      * foreground drawable, if non-null, is always drawn on top of the view's content.
18474      *
18475      * @return a Drawable or null if no foreground was set
18476      *
18477      * @see #onDrawForeground(Canvas)
18478      */
18479     public Drawable getForeground() {
18480         return mForegroundInfo != null ? mForegroundInfo.mDrawable : null;
18481     }
18482
18483     /**
18484      * Supply a Drawable that is to be rendered on top of all of the content in the view.
18485      *
18486      * @param foreground the Drawable to be drawn on top of the children
18487      *
18488      * @attr ref android.R.styleable#View_foreground
18489      */
18490     public void setForeground(Drawable foreground) {
18491         if (mForegroundInfo == null) {
18492             if (foreground == null) {
18493                 // Nothing to do.
18494                 return;
18495             }
18496             mForegroundInfo = new ForegroundInfo();
18497         }
18498
18499         if (foreground == mForegroundInfo.mDrawable) {
18500             // Nothing to do
18501             return;
18502         }
18503
18504         if (mForegroundInfo.mDrawable != null) {
18505             if (isAttachedToWindow()) {
18506                 mForegroundInfo.mDrawable.setVisible(false, false);
18507             }
18508             mForegroundInfo.mDrawable.setCallback(null);
18509             unscheduleDrawable(mForegroundInfo.mDrawable);
18510         }
18511
18512         mForegroundInfo.mDrawable = foreground;
18513         mForegroundInfo.mBoundsChanged = true;
18514         if (foreground != null) {
18515             if ((mPrivateFlags & PFLAG_SKIP_DRAW) != 0) {
18516                 mPrivateFlags &= ~PFLAG_SKIP_DRAW;
18517             }
18518             foreground.setLayoutDirection(getLayoutDirection());
18519             if (foreground.isStateful()) {
18520                 foreground.setState(getDrawableState());
18521             }
18522             applyForegroundTint();
18523             if (isAttachedToWindow()) {
18524                 foreground.setVisible(getWindowVisibility() == VISIBLE && isShown(), false);
18525             }
18526             // Set callback last, since the view may still be initializing.
18527             foreground.setCallback(this);
18528         } else if ((mViewFlags & WILL_NOT_DRAW) != 0 && mBackground == null) {
18529             mPrivateFlags |= PFLAG_SKIP_DRAW;
18530         }
18531         requestLayout();
18532         invalidate();
18533     }
18534
18535     /**
18536      * Magic bit used to support features of framework-internal window decor implementation details.
18537      * This used to live exclusively in FrameLayout.
18538      *
18539      * @return true if the foreground should draw inside the padding region or false
18540      *         if it should draw inset by the view's padding
18541      * @hide internal use only; only used by FrameLayout and internal screen layouts.
18542      */
18543     public boolean isForegroundInsidePadding() {
18544         return mForegroundInfo != null ? mForegroundInfo.mInsidePadding : true;
18545     }
18546
18547     /**
18548      * Describes how the foreground is positioned.
18549      *
18550      * @return foreground gravity.
18551      *
18552      * @see #setForegroundGravity(int)
18553      *
18554      * @attr ref android.R.styleable#View_foregroundGravity
18555      */
18556     public int getForegroundGravity() {
18557         return mForegroundInfo != null ? mForegroundInfo.mGravity
18558                 : Gravity.START | Gravity.TOP;
18559     }
18560
18561     /**
18562      * Describes how the foreground is positioned. Defaults to START and TOP.
18563      *
18564      * @param gravity see {@link android.view.Gravity}
18565      *
18566      * @see #getForegroundGravity()
18567      *
18568      * @attr ref android.R.styleable#View_foregroundGravity
18569      */
18570     public void setForegroundGravity(int gravity) {
18571         if (mForegroundInfo == null) {
18572             mForegroundInfo = new ForegroundInfo();
18573         }
18574
18575         if (mForegroundInfo.mGravity != gravity) {
18576             if ((gravity & Gravity.RELATIVE_HORIZONTAL_GRAVITY_MASK) == 0) {
18577                 gravity |= Gravity.START;
18578             }
18579
18580             if ((gravity & Gravity.VERTICAL_GRAVITY_MASK) == 0) {
18581                 gravity |= Gravity.TOP;
18582             }
18583
18584             mForegroundInfo.mGravity = gravity;
18585             requestLayout();
18586         }
18587     }
18588
18589     /**
18590      * Applies a tint to the foreground drawable. Does not modify the current tint
18591      * mode, which is {@link PorterDuff.Mode#SRC_IN} by default.
18592      * <p>
18593      * Subsequent calls to {@link #setForeground(Drawable)} will automatically
18594      * mutate the drawable and apply the specified tint and tint mode using
18595      * {@link Drawable#setTintList(ColorStateList)}.
18596      *
18597      * @param tint the tint to apply, may be {@code null} to clear tint
18598      *
18599      * @attr ref android.R.styleable#View_foregroundTint
18600      * @see #getForegroundTintList()
18601      * @see Drawable#setTintList(ColorStateList)
18602      */
18603     public void setForegroundTintList(@Nullable ColorStateList tint) {
18604         if (mForegroundInfo == null) {
18605             mForegroundInfo = new ForegroundInfo();
18606         }
18607         if (mForegroundInfo.mTintInfo == null) {
18608             mForegroundInfo.mTintInfo = new TintInfo();
18609         }
18610         mForegroundInfo.mTintInfo.mTintList = tint;
18611         mForegroundInfo.mTintInfo.mHasTintList = true;
18612
18613         applyForegroundTint();
18614     }
18615
18616     /**
18617      * Return the tint applied to the foreground drawable, if specified.
18618      *
18619      * @return the tint applied to the foreground drawable
18620      * @attr ref android.R.styleable#View_foregroundTint
18621      * @see #setForegroundTintList(ColorStateList)
18622      */
18623     @Nullable
18624     public ColorStateList getForegroundTintList() {
18625         return mForegroundInfo != null && mForegroundInfo.mTintInfo != null
18626                 ? mForegroundInfo.mTintInfo.mTintList : null;
18627     }
18628
18629     /**
18630      * Specifies the blending mode used to apply the tint specified by
18631      * {@link #setForegroundTintList(ColorStateList)}} to the background
18632      * drawable. The default mode is {@link PorterDuff.Mode#SRC_IN}.
18633      *
18634      * @param tintMode the blending mode used to apply the tint, may be
18635      *                 {@code null} to clear tint
18636      * @attr ref android.R.styleable#View_foregroundTintMode
18637      * @see #getForegroundTintMode()
18638      * @see Drawable#setTintMode(PorterDuff.Mode)
18639      */
18640     public void setForegroundTintMode(@Nullable PorterDuff.Mode tintMode) {
18641         if (mForegroundInfo == null) {
18642             mForegroundInfo = new ForegroundInfo();
18643         }
18644         if (mForegroundInfo.mTintInfo == null) {
18645             mForegroundInfo.mTintInfo = new TintInfo();
18646         }
18647         mForegroundInfo.mTintInfo.mTintMode = tintMode;
18648         mForegroundInfo.mTintInfo.mHasTintMode = true;
18649
18650         applyForegroundTint();
18651     }
18652
18653     /**
18654      * Return the blending mode used to apply the tint to the foreground
18655      * drawable, if specified.
18656      *
18657      * @return the blending mode used to apply the tint to the foreground
18658      *         drawable
18659      * @attr ref android.R.styleable#View_foregroundTintMode
18660      * @see #setForegroundTintMode(PorterDuff.Mode)
18661      */
18662     @Nullable
18663     public PorterDuff.Mode getForegroundTintMode() {
18664         return mForegroundInfo != null && mForegroundInfo.mTintInfo != null
18665                 ? mForegroundInfo.mTintInfo.mTintMode : null;
18666     }
18667
18668     private void applyForegroundTint() {
18669         if (mForegroundInfo != null && mForegroundInfo.mDrawable != null
18670                 && mForegroundInfo.mTintInfo != null) {
18671             final TintInfo tintInfo = mForegroundInfo.mTintInfo;
18672             if (tintInfo.mHasTintList || tintInfo.mHasTintMode) {
18673                 mForegroundInfo.mDrawable = mForegroundInfo.mDrawable.mutate();
18674
18675                 if (tintInfo.mHasTintList) {
18676                     mForegroundInfo.mDrawable.setTintList(tintInfo.mTintList);
18677                 }
18678
18679                 if (tintInfo.mHasTintMode) {
18680                     mForegroundInfo.mDrawable.setTintMode(tintInfo.mTintMode);
18681                 }
18682
18683                 // The drawable (or one of its children) may not have been
18684                 // stateful before applying the tint, so let's try again.
18685                 if (mForegroundInfo.mDrawable.isStateful()) {
18686                     mForegroundInfo.mDrawable.setState(getDrawableState());
18687                 }
18688             }
18689         }
18690     }
18691
18692     /**
18693      * Draw any foreground content for this view.
18694      *
18695      * <p>Foreground content may consist of scroll bars, a {@link #setForeground foreground}
18696      * drawable or other view-specific decorations. The foreground is drawn on top of the
18697      * primary view content.</p>
18698      *
18699      * @param canvas canvas to draw into
18700      */
18701     public void onDrawForeground(Canvas canvas) {
18702         onDrawScrollIndicators(canvas);
18703         onDrawScrollBars(canvas);
18704
18705         final Drawable foreground = mForegroundInfo != null ? mForegroundInfo.mDrawable : null;
18706         if (foreground != null) {
18707             if (mForegroundInfo.mBoundsChanged) {
18708                 mForegroundInfo.mBoundsChanged = false;
18709                 final Rect selfBounds = mForegroundInfo.mSelfBounds;
18710                 final Rect overlayBounds = mForegroundInfo.mOverlayBounds;
18711
18712                 if (mForegroundInfo.mInsidePadding) {
18713                     selfBounds.set(0, 0, getWidth(), getHeight());
18714                 } else {
18715                     selfBounds.set(getPaddingLeft(), getPaddingTop(),
18716                             getWidth() - getPaddingRight(), getHeight() - getPaddingBottom());
18717                 }
18718
18719                 final int ld = getLayoutDirection();
18720                 Gravity.apply(mForegroundInfo.mGravity, foreground.getIntrinsicWidth(),
18721                         foreground.getIntrinsicHeight(), selfBounds, overlayBounds, ld);
18722                 foreground.setBounds(overlayBounds);
18723             }
18724
18725             foreground.draw(canvas);
18726         }
18727     }
18728
18729     /**
18730      * Sets the padding. The view may add on the space required to display
18731      * the scrollbars, depending on the style and visibility of the scrollbars.
18732      * So the values returned from {@link #getPaddingLeft}, {@link #getPaddingTop},
18733      * {@link #getPaddingRight} and {@link #getPaddingBottom} may be different
18734      * from the values set in this call.
18735      *
18736      * @attr ref android.R.styleable#View_padding
18737      * @attr ref android.R.styleable#View_paddingBottom
18738      * @attr ref android.R.styleable#View_paddingLeft
18739      * @attr ref android.R.styleable#View_paddingRight
18740      * @attr ref android.R.styleable#View_paddingTop
18741      * @param left the left padding in pixels
18742      * @param top the top padding in pixels
18743      * @param right the right padding in pixels
18744      * @param bottom the bottom padding in pixels
18745      */
18746     public void setPadding(int left, int top, int right, int bottom) {
18747         resetResolvedPaddingInternal();
18748
18749         mUserPaddingStart = UNDEFINED_PADDING;
18750         mUserPaddingEnd = UNDEFINED_PADDING;
18751
18752         mUserPaddingLeftInitial = left;
18753         mUserPaddingRightInitial = right;
18754
18755         mLeftPaddingDefined = true;
18756         mRightPaddingDefined = true;
18757
18758         internalSetPadding(left, top, right, bottom);
18759     }
18760
18761     /**
18762      * @hide
18763      */
18764     protected void internalSetPadding(int left, int top, int right, int bottom) {
18765         mUserPaddingLeft = left;
18766         mUserPaddingRight = right;
18767         mUserPaddingBottom = bottom;
18768
18769         final int viewFlags = mViewFlags;
18770         boolean changed = false;
18771
18772         // Common case is there are no scroll bars.
18773         if ((viewFlags & (SCROLLBARS_VERTICAL|SCROLLBARS_HORIZONTAL)) != 0) {
18774             if ((viewFlags & SCROLLBARS_VERTICAL) != 0) {
18775                 final int offset = (viewFlags & SCROLLBARS_INSET_MASK) == 0
18776                         ? 0 : getVerticalScrollbarWidth();
18777                 switch (mVerticalScrollbarPosition) {
18778                     case SCROLLBAR_POSITION_DEFAULT:
18779                         if (isLayoutRtl()) {
18780                             left += offset;
18781                         } else {
18782                             right += offset;
18783                         }
18784                         break;
18785                     case SCROLLBAR_POSITION_RIGHT:
18786                         right += offset;
18787                         break;
18788                     case SCROLLBAR_POSITION_LEFT:
18789                         left += offset;
18790                         break;
18791                 }
18792             }
18793             if ((viewFlags & SCROLLBARS_HORIZONTAL) != 0) {
18794                 bottom += (viewFlags & SCROLLBARS_INSET_MASK) == 0
18795                         ? 0 : getHorizontalScrollbarHeight();
18796             }
18797         }
18798
18799         if (mPaddingLeft != left) {
18800             changed = true;
18801             mPaddingLeft = left;
18802         }
18803         if (mPaddingTop != top) {
18804             changed = true;
18805             mPaddingTop = top;
18806         }
18807         if (mPaddingRight != right) {
18808             changed = true;
18809             mPaddingRight = right;
18810         }
18811         if (mPaddingBottom != bottom) {
18812             changed = true;
18813             mPaddingBottom = bottom;
18814         }
18815
18816         if (changed) {
18817             requestLayout();
18818             invalidateOutline();
18819         }
18820     }
18821
18822     /**
18823      * Sets the relative padding. The view may add on the space required to display
18824      * the scrollbars, depending on the style and visibility of the scrollbars.
18825      * So the values returned from {@link #getPaddingStart}, {@link #getPaddingTop},
18826      * {@link #getPaddingEnd} and {@link #getPaddingBottom} may be different
18827      * from the values set in this call.
18828      *
18829      * @attr ref android.R.styleable#View_padding
18830      * @attr ref android.R.styleable#View_paddingBottom
18831      * @attr ref android.R.styleable#View_paddingStart
18832      * @attr ref android.R.styleable#View_paddingEnd
18833      * @attr ref android.R.styleable#View_paddingTop
18834      * @param start the start padding in pixels
18835      * @param top the top padding in pixels
18836      * @param end the end padding in pixels
18837      * @param bottom the bottom padding in pixels
18838      */
18839     public void setPaddingRelative(int start, int top, int end, int bottom) {
18840         resetResolvedPaddingInternal();
18841
18842         mUserPaddingStart = start;
18843         mUserPaddingEnd = end;
18844         mLeftPaddingDefined = true;
18845         mRightPaddingDefined = true;
18846
18847         switch(getLayoutDirection()) {
18848             case LAYOUT_DIRECTION_RTL:
18849                 mUserPaddingLeftInitial = end;
18850                 mUserPaddingRightInitial = start;
18851                 internalSetPadding(end, top, start, bottom);
18852                 break;
18853             case LAYOUT_DIRECTION_LTR:
18854             default:
18855                 mUserPaddingLeftInitial = start;
18856                 mUserPaddingRightInitial = end;
18857                 internalSetPadding(start, top, end, bottom);
18858         }
18859     }
18860
18861     /**
18862      * Returns the top padding of this view.
18863      *
18864      * @return the top padding in pixels
18865      */
18866     public int getPaddingTop() {
18867         return mPaddingTop;
18868     }
18869
18870     /**
18871      * Returns the bottom padding of this view. If there are inset and enabled
18872      * scrollbars, this value may include the space required to display the
18873      * scrollbars as well.
18874      *
18875      * @return the bottom padding in pixels
18876      */
18877     public int getPaddingBottom() {
18878         return mPaddingBottom;
18879     }
18880
18881     /**
18882      * Returns the left padding of this view. If there are inset and enabled
18883      * scrollbars, this value may include the space required to display the
18884      * scrollbars as well.
18885      *
18886      * @return the left padding in pixels
18887      */
18888     public int getPaddingLeft() {
18889         if (!isPaddingResolved()) {
18890             resolvePadding();
18891         }
18892         return mPaddingLeft;
18893     }
18894
18895     /**
18896      * Returns the start padding of this view depending on its resolved layout direction.
18897      * If there are inset and enabled scrollbars, this value may include the space
18898      * required to display the scrollbars as well.
18899      *
18900      * @return the start padding in pixels
18901      */
18902     public int getPaddingStart() {
18903         if (!isPaddingResolved()) {
18904             resolvePadding();
18905         }
18906         return (getLayoutDirection() == LAYOUT_DIRECTION_RTL) ?
18907                 mPaddingRight : mPaddingLeft;
18908     }
18909
18910     /**
18911      * Returns the right padding of this view. If there are inset and enabled
18912      * scrollbars, this value may include the space required to display the
18913      * scrollbars as well.
18914      *
18915      * @return the right padding in pixels
18916      */
18917     public int getPaddingRight() {
18918         if (!isPaddingResolved()) {
18919             resolvePadding();
18920         }
18921         return mPaddingRight;
18922     }
18923
18924     /**
18925      * Returns the end padding of this view depending on its resolved layout direction.
18926      * If there are inset and enabled scrollbars, this value may include the space
18927      * required to display the scrollbars as well.
18928      *
18929      * @return the end padding in pixels
18930      */
18931     public int getPaddingEnd() {
18932         if (!isPaddingResolved()) {
18933             resolvePadding();
18934         }
18935         return (getLayoutDirection() == LAYOUT_DIRECTION_RTL) ?
18936                 mPaddingLeft : mPaddingRight;
18937     }
18938
18939     /**
18940      * Return if the padding has been set through relative values
18941      * {@link #setPaddingRelative(int, int, int, int)} or through
18942      * @attr ref android.R.styleable#View_paddingStart or
18943      * @attr ref android.R.styleable#View_paddingEnd
18944      *
18945      * @return true if the padding is relative or false if it is not.
18946      */
18947     public boolean isPaddingRelative() {
18948         return (mUserPaddingStart != UNDEFINED_PADDING || mUserPaddingEnd != UNDEFINED_PADDING);
18949     }
18950
18951     Insets computeOpticalInsets() {
18952         return (mBackground == null) ? Insets.NONE : mBackground.getOpticalInsets();
18953     }
18954
18955     /**
18956      * @hide
18957      */
18958     public void resetPaddingToInitialValues() {
18959         if (isRtlCompatibilityMode()) {
18960             mPaddingLeft = mUserPaddingLeftInitial;
18961             mPaddingRight = mUserPaddingRightInitial;
18962             return;
18963         }
18964         if (isLayoutRtl()) {
18965             mPaddingLeft = (mUserPaddingEnd >= 0) ? mUserPaddingEnd : mUserPaddingLeftInitial;
18966             mPaddingRight = (mUserPaddingStart >= 0) ? mUserPaddingStart : mUserPaddingRightInitial;
18967         } else {
18968             mPaddingLeft = (mUserPaddingStart >= 0) ? mUserPaddingStart : mUserPaddingLeftInitial;
18969             mPaddingRight = (mUserPaddingEnd >= 0) ? mUserPaddingEnd : mUserPaddingRightInitial;
18970         }
18971     }
18972
18973     /**
18974      * @hide
18975      */
18976     public Insets getOpticalInsets() {
18977         if (mLayoutInsets == null) {
18978             mLayoutInsets = computeOpticalInsets();
18979         }
18980         return mLayoutInsets;
18981     }
18982
18983     /**
18984      * Set this view's optical insets.
18985      *
18986      * <p>This method should be treated similarly to setMeasuredDimension and not as a general
18987      * property. Views that compute their own optical insets should call it as part of measurement.
18988      * This method does not request layout. If you are setting optical insets outside of
18989      * measure/layout itself you will want to call requestLayout() yourself.
18990      * </p>
18991      * @hide
18992      */
18993     public void setOpticalInsets(Insets insets) {
18994         mLayoutInsets = insets;
18995     }
18996
18997     /**
18998      * Changes the selection state of this view. A view can be selected or not.
18999      * Note that selection is not the same as focus. Views are typically
19000      * selected in the context of an AdapterView like ListView or GridView;
19001      * the selected view is the view that is highlighted.
19002      *
19003      * @param selected true if the view must be selected, false otherwise
19004      */
19005     public void setSelected(boolean selected) {
19006         //noinspection DoubleNegation
19007         if (((mPrivateFlags & PFLAG_SELECTED) != 0) != selected) {
19008             mPrivateFlags = (mPrivateFlags & ~PFLAG_SELECTED) | (selected ? PFLAG_SELECTED : 0);
19009             if (!selected) resetPressedState();
19010             invalidate(true);
19011             refreshDrawableState();
19012             dispatchSetSelected(selected);
19013             if (selected) {
19014                 sendAccessibilityEvent(AccessibilityEvent.TYPE_VIEW_SELECTED);
19015             } else {
19016                 notifyViewAccessibilityStateChangedIfNeeded(
19017                         AccessibilityEvent.CONTENT_CHANGE_TYPE_UNDEFINED);
19018             }
19019         }
19020     }
19021
19022     /**
19023      * Dispatch setSelected to all of this View's children.
19024      *
19025      * @see #setSelected(boolean)
19026      *
19027      * @param selected The new selected state
19028      */
19029     protected void dispatchSetSelected(boolean selected) {
19030     }
19031
19032     /**
19033      * Indicates the selection state of this view.
19034      *
19035      * @return true if the view is selected, false otherwise
19036      */
19037     @ViewDebug.ExportedProperty
19038     public boolean isSelected() {
19039         return (mPrivateFlags & PFLAG_SELECTED) != 0;
19040     }
19041
19042     /**
19043      * Changes the activated state of this view. A view can be activated or not.
19044      * Note that activation is not the same as selection.  Selection is
19045      * a transient property, representing the view (hierarchy) the user is
19046      * currently interacting with.  Activation is a longer-term state that the
19047      * user can move views in and out of.  For example, in a list view with
19048      * single or multiple selection enabled, the views in the current selection
19049      * set are activated.  (Um, yeah, we are deeply sorry about the terminology
19050      * here.)  The activated state is propagated down to children of the view it
19051      * is set on.
19052      *
19053      * @param activated true if the view must be activated, false otherwise
19054      */
19055     public void setActivated(boolean activated) {
19056         //noinspection DoubleNegation
19057         if (((mPrivateFlags & PFLAG_ACTIVATED) != 0) != activated) {
19058             mPrivateFlags = (mPrivateFlags & ~PFLAG_ACTIVATED) | (activated ? PFLAG_ACTIVATED : 0);
19059             invalidate(true);
19060             refreshDrawableState();
19061             dispatchSetActivated(activated);
19062         }
19063     }
19064
19065     /**
19066      * Dispatch setActivated to all of this View's children.
19067      *
19068      * @see #setActivated(boolean)
19069      *
19070      * @param activated The new activated state
19071      */
19072     protected void dispatchSetActivated(boolean activated) {
19073     }
19074
19075     /**
19076      * Indicates the activation state of this view.
19077      *
19078      * @return true if the view is activated, false otherwise
19079      */
19080     @ViewDebug.ExportedProperty
19081     public boolean isActivated() {
19082         return (mPrivateFlags & PFLAG_ACTIVATED) != 0;
19083     }
19084
19085     /**
19086      * Returns the ViewTreeObserver for this view's hierarchy. The view tree
19087      * observer can be used to get notifications when global events, like
19088      * layout, happen.
19089      *
19090      * The returned ViewTreeObserver observer is not guaranteed to remain
19091      * valid for the lifetime of this View. If the caller of this method keeps
19092      * a long-lived reference to ViewTreeObserver, it should always check for
19093      * the return value of {@link ViewTreeObserver#isAlive()}.
19094      *
19095      * @return The ViewTreeObserver for this view's hierarchy.
19096      */
19097     public ViewTreeObserver getViewTreeObserver() {
19098         if (mAttachInfo != null) {
19099             return mAttachInfo.mTreeObserver;
19100         }
19101         if (mFloatingTreeObserver == null) {
19102             mFloatingTreeObserver = new ViewTreeObserver();
19103         }
19104         return mFloatingTreeObserver;
19105     }
19106
19107     /**
19108      * <p>Finds the topmost view in the current view hierarchy.</p>
19109      *
19110      * @return the topmost view containing this view
19111      */
19112     public View getRootView() {
19113         if (mAttachInfo != null) {
19114             final View v = mAttachInfo.mRootView;
19115             if (v != null) {
19116                 return v;
19117             }
19118         }
19119
19120         View parent = this;
19121
19122         while (parent.mParent != null && parent.mParent instanceof View) {
19123             parent = (View) parent.mParent;
19124         }
19125
19126         return parent;
19127     }
19128
19129     /**
19130      * Transforms a motion event from view-local coordinates to on-screen
19131      * coordinates.
19132      *
19133      * @param ev the view-local motion event
19134      * @return false if the transformation could not be applied
19135      * @hide
19136      */
19137     public boolean toGlobalMotionEvent(MotionEvent ev) {
19138         final AttachInfo info = mAttachInfo;
19139         if (info == null) {
19140             return false;
19141         }
19142
19143         final Matrix m = info.mTmpMatrix;
19144         m.set(Matrix.IDENTITY_MATRIX);
19145         transformMatrixToGlobal(m);
19146         ev.transform(m);
19147         return true;
19148     }
19149
19150     /**
19151      * Transforms a motion event from on-screen coordinates to view-local
19152      * coordinates.
19153      *
19154      * @param ev the on-screen motion event
19155      * @return false if the transformation could not be applied
19156      * @hide
19157      */
19158     public boolean toLocalMotionEvent(MotionEvent ev) {
19159         final AttachInfo info = mAttachInfo;
19160         if (info == null) {
19161             return false;
19162         }
19163
19164         final Matrix m = info.mTmpMatrix;
19165         m.set(Matrix.IDENTITY_MATRIX);
19166         transformMatrixToLocal(m);
19167         ev.transform(m);
19168         return true;
19169     }
19170
19171     /**
19172      * Modifies the input matrix such that it maps view-local coordinates to
19173      * on-screen coordinates.
19174      *
19175      * @param m input matrix to modify
19176      * @hide
19177      */
19178     public void transformMatrixToGlobal(Matrix m) {
19179         final ViewParent parent = mParent;
19180         if (parent instanceof View) {
19181             final View vp = (View) parent;
19182             vp.transformMatrixToGlobal(m);
19183             m.preTranslate(-vp.mScrollX, -vp.mScrollY);
19184         } else if (parent instanceof ViewRootImpl) {
19185             final ViewRootImpl vr = (ViewRootImpl) parent;
19186             vr.transformMatrixToGlobal(m);
19187             m.preTranslate(0, -vr.mCurScrollY);
19188         }
19189
19190         m.preTranslate(mLeft, mTop);
19191
19192         if (!hasIdentityMatrix()) {
19193             m.preConcat(getMatrix());
19194         }
19195     }
19196
19197     /**
19198      * Modifies the input matrix such that it maps on-screen coordinates to
19199      * view-local coordinates.
19200      *
19201      * @param m input matrix to modify
19202      * @hide
19203      */
19204     public void transformMatrixToLocal(Matrix m) {
19205         final ViewParent parent = mParent;
19206         if (parent instanceof View) {
19207             final View vp = (View) parent;
19208             vp.transformMatrixToLocal(m);
19209             m.postTranslate(vp.mScrollX, vp.mScrollY);
19210         } else if (parent instanceof ViewRootImpl) {
19211             final ViewRootImpl vr = (ViewRootImpl) parent;
19212             vr.transformMatrixToLocal(m);
19213             m.postTranslate(0, vr.mCurScrollY);
19214         }
19215
19216         m.postTranslate(-mLeft, -mTop);
19217
19218         if (!hasIdentityMatrix()) {
19219             m.postConcat(getInverseMatrix());
19220         }
19221     }
19222
19223     /**
19224      * @hide
19225      */
19226     @ViewDebug.ExportedProperty(category = "layout", indexMapping = {
19227             @ViewDebug.IntToString(from = 0, to = "x"),
19228             @ViewDebug.IntToString(from = 1, to = "y")
19229     })
19230     public int[] getLocationOnScreen() {
19231         int[] location = new int[2];
19232         getLocationOnScreen(location);
19233         return location;
19234     }
19235
19236     /**
19237      * <p>Computes the coordinates of this view on the screen. The argument
19238      * must be an array of two integers. After the method returns, the array
19239      * contains the x and y location in that order.</p>
19240      *
19241      * @param outLocation an array of two integers in which to hold the coordinates
19242      */
19243     public void getLocationOnScreen(@Size(2) int[] outLocation) {
19244         getLocationInWindow(outLocation);
19245
19246         final AttachInfo info = mAttachInfo;
19247         if (info != null) {
19248             outLocation[0] += info.mWindowLeft;
19249             outLocation[1] += info.mWindowTop;
19250         }
19251     }
19252
19253     /**
19254      * <p>Computes the coordinates of this view in its window. The argument
19255      * must be an array of two integers. After the method returns, the array
19256      * contains the x and y location in that order.</p>
19257      *
19258      * @param outLocation an array of two integers in which to hold the coordinates
19259      */
19260     public void getLocationInWindow(@Size(2) int[] outLocation) {
19261         if (outLocation == null || outLocation.length < 2) {
19262             throw new IllegalArgumentException("outLocation must be an array of two integers");
19263         }
19264
19265         outLocation[0] = 0;
19266         outLocation[1] = 0;
19267
19268         transformFromViewToWindowSpace(outLocation);
19269     }
19270
19271     /** @hide */
19272     public void transformFromViewToWindowSpace(@Size(2) int[] inOutLocation) {
19273         if (inOutLocation == null || inOutLocation.length < 2) {
19274             throw new IllegalArgumentException("inOutLocation must be an array of two integers");
19275         }
19276
19277         if (mAttachInfo == null) {
19278             // When the view is not attached to a window, this method does not make sense
19279             inOutLocation[0] = inOutLocation[1] = 0;
19280             return;
19281         }
19282
19283         float position[] = mAttachInfo.mTmpTransformLocation;
19284         position[0] = inOutLocation[0];
19285         position[1] = inOutLocation[1];
19286
19287         if (!hasIdentityMatrix()) {
19288             getMatrix().mapPoints(position);
19289         }
19290
19291         position[0] += mLeft;
19292         position[1] += mTop;
19293
19294         ViewParent viewParent = mParent;
19295         while (viewParent instanceof View) {
19296             final View view = (View) viewParent;
19297
19298             position[0] -= view.mScrollX;
19299             position[1] -= view.mScrollY;
19300
19301             if (!view.hasIdentityMatrix()) {
19302                 view.getMatrix().mapPoints(position);
19303             }
19304
19305             position[0] += view.mLeft;
19306             position[1] += view.mTop;
19307
19308             viewParent = view.mParent;
19309          }
19310
19311         if (viewParent instanceof ViewRootImpl) {
19312             // *cough*
19313             final ViewRootImpl vr = (ViewRootImpl) viewParent;
19314             position[1] -= vr.mCurScrollY;
19315         }
19316
19317         inOutLocation[0] = Math.round(position[0]);
19318         inOutLocation[1] = Math.round(position[1]);
19319     }
19320
19321     /**
19322      * {@hide}
19323      * @param id the id of the view to be found
19324      * @return the view of the specified id, null if cannot be found
19325      */
19326     protected View findViewTraversal(@IdRes int id) {
19327         if (id == mID) {
19328             return this;
19329         }
19330         return null;
19331     }
19332
19333     /**
19334      * {@hide}
19335      * @param tag the tag of the view to be found
19336      * @return the view of specified tag, null if cannot be found
19337      */
19338     protected View findViewWithTagTraversal(Object tag) {
19339         if (tag != null && tag.equals(mTag)) {
19340             return this;
19341         }
19342         return null;
19343     }
19344
19345     /**
19346      * {@hide}
19347      * @param predicate The predicate to evaluate.
19348      * @param childToSkip If not null, ignores this child during the recursive traversal.
19349      * @return The first view that matches the predicate or null.
19350      */
19351     protected View findViewByPredicateTraversal(Predicate<View> predicate, View childToSkip) {
19352         if (predicate.apply(this)) {
19353             return this;
19354         }
19355         return null;
19356     }
19357
19358     /**
19359      * Look for a child view with the given id.  If this view has the given
19360      * id, return this view.
19361      *
19362      * @param id The id to search for.
19363      * @return The view that has the given id in the hierarchy or null
19364      */
19365     @Nullable
19366     public final View findViewById(@IdRes int id) {
19367         if (id < 0) {
19368             return null;
19369         }
19370         return findViewTraversal(id);
19371     }
19372
19373     /**
19374      * Finds a view by its unuque and stable accessibility id.
19375      *
19376      * @param accessibilityId The searched accessibility id.
19377      * @return The found view.
19378      */
19379     final View findViewByAccessibilityId(int accessibilityId) {
19380         if (accessibilityId < 0) {
19381             return null;
19382         }
19383         View view = findViewByAccessibilityIdTraversal(accessibilityId);
19384         if (view != null) {
19385             return view.includeForAccessibility() ? view : null;
19386         }
19387         return null;
19388     }
19389
19390     /**
19391      * Performs the traversal to find a view by its unuque and stable accessibility id.
19392      *
19393      * <strong>Note:</strong>This method does not stop at the root namespace
19394      * boundary since the user can touch the screen at an arbitrary location
19395      * potentially crossing the root namespace bounday which will send an
19396      * accessibility event to accessibility services and they should be able
19397      * to obtain the event source. Also accessibility ids are guaranteed to be
19398      * unique in the window.
19399      *
19400      * @param accessibilityId The accessibility id.
19401      * @return The found view.
19402      *
19403      * @hide
19404      */
19405     public View findViewByAccessibilityIdTraversal(int accessibilityId) {
19406         if (getAccessibilityViewId() == accessibilityId) {
19407             return this;
19408         }
19409         return null;
19410     }
19411
19412     /**
19413      * Look for a child view with the given tag.  If this view has the given
19414      * tag, return this view.
19415      *
19416      * @param tag The tag to search for, using "tag.equals(getTag())".
19417      * @return The View that has the given tag in the hierarchy or null
19418      */
19419     public final View findViewWithTag(Object tag) {
19420         if (tag == null) {
19421             return null;
19422         }
19423         return findViewWithTagTraversal(tag);
19424     }
19425
19426     /**
19427      * {@hide}
19428      * Look for a child view that matches the specified predicate.
19429      * If this view matches the predicate, return this view.
19430      *
19431      * @param predicate The predicate to evaluate.
19432      * @return The first view that matches the predicate or null.
19433      */
19434     public final View findViewByPredicate(Predicate<View> predicate) {
19435         return findViewByPredicateTraversal(predicate, null);
19436     }
19437
19438     /**
19439      * {@hide}
19440      * Look for a child view that matches the specified predicate,
19441      * starting with the specified view and its descendents and then
19442      * recusively searching the ancestors and siblings of that view
19443      * until this view is reached.
19444      *
19445      * This method is useful in cases where the predicate does not match
19446      * a single unique view (perhaps multiple views use the same id)
19447      * and we are trying to find the view that is "closest" in scope to the
19448      * starting view.
19449      *
19450      * @param start The view to start from.
19451      * @param predicate The predicate to evaluate.
19452      * @return The first view that matches the predicate or null.
19453      */
19454     public final View findViewByPredicateInsideOut(View start, Predicate<View> predicate) {
19455         View childToSkip = null;
19456         for (;;) {
19457             View view = start.findViewByPredicateTraversal(predicate, childToSkip);
19458             if (view != null || start == this) {
19459                 return view;
19460             }
19461
19462             ViewParent parent = start.getParent();
19463             if (parent == null || !(parent instanceof View)) {
19464                 return null;
19465             }
19466
19467             childToSkip = start;
19468             start = (View) parent;
19469         }
19470     }
19471
19472     /**
19473      * Sets the identifier for this view. The identifier does not have to be
19474      * unique in this view's hierarchy. The identifier should be a positive
19475      * number.
19476      *
19477      * @see #NO_ID
19478      * @see #getId()
19479      * @see #findViewById(int)
19480      *
19481      * @param id a number used to identify the view
19482      *
19483      * @attr ref android.R.styleable#View_id
19484      */
19485     public void setId(@IdRes int id) {
19486         mID = id;
19487         if (mID == View.NO_ID && mLabelForId != View.NO_ID) {
19488             mID = generateViewId();
19489         }
19490     }
19491
19492     /**
19493      * {@hide}
19494      *
19495      * @param isRoot true if the view belongs to the root namespace, false
19496      *        otherwise
19497      */
19498     public void setIsRootNamespace(boolean isRoot) {
19499         if (isRoot) {
19500             mPrivateFlags |= PFLAG_IS_ROOT_NAMESPACE;
19501         } else {
19502             mPrivateFlags &= ~PFLAG_IS_ROOT_NAMESPACE;
19503         }
19504     }
19505
19506     /**
19507      * {@hide}
19508      *
19509      * @return true if the view belongs to the root namespace, false otherwise
19510      */
19511     public boolean isRootNamespace() {
19512         return (mPrivateFlags&PFLAG_IS_ROOT_NAMESPACE) != 0;
19513     }
19514
19515     /**
19516      * Returns this view's identifier.
19517      *
19518      * @return a positive integer used to identify the view or {@link #NO_ID}
19519      *         if the view has no ID
19520      *
19521      * @see #setId(int)
19522      * @see #findViewById(int)
19523      * @attr ref android.R.styleable#View_id
19524      */
19525     @IdRes
19526     @ViewDebug.CapturedViewProperty
19527     public int getId() {
19528         return mID;
19529     }
19530
19531     /**
19532      * Returns this view's tag.
19533      *
19534      * @return the Object stored in this view as a tag, or {@code null} if not
19535      *         set
19536      *
19537      * @see #setTag(Object)
19538      * @see #getTag(int)
19539      */
19540     @ViewDebug.ExportedProperty
19541     public Object getTag() {
19542         return mTag;
19543     }
19544
19545     /**
19546      * Sets the tag associated with this view. A tag can be used to mark
19547      * a view in its hierarchy and does not have to be unique within the
19548      * hierarchy. Tags can also be used to store data within a view without
19549      * resorting to another data structure.
19550      *
19551      * @param tag an Object to tag the view with
19552      *
19553      * @see #getTag()
19554      * @see #setTag(int, Object)
19555      */
19556     public void setTag(final Object tag) {
19557         mTag = tag;
19558     }
19559
19560     /**
19561      * Returns the tag associated with this view and the specified key.
19562      *
19563      * @param key The key identifying the tag
19564      *
19565      * @return the Object stored in this view as a tag, or {@code null} if not
19566      *         set
19567      *
19568      * @see #setTag(int, Object)
19569      * @see #getTag()
19570      */
19571     public Object getTag(int key) {
19572         if (mKeyedTags != null) return mKeyedTags.get(key);
19573         return null;
19574     }
19575
19576     /**
19577      * Sets a tag associated with this view and a key. A tag can be used
19578      * to mark a view in its hierarchy and does not have to be unique within
19579      * the hierarchy. Tags can also be used to store data within a view
19580      * without resorting to another data structure.
19581      *
19582      * The specified key should be an id declared in the resources of the
19583      * application to ensure it is unique (see the <a
19584      * href="{@docRoot}guide/topics/resources/more-resources.html#Id">ID resource type</a>).
19585      * Keys identified as belonging to
19586      * the Android framework or not associated with any package will cause
19587      * an {@link IllegalArgumentException} to be thrown.
19588      *
19589      * @param key The key identifying the tag
19590      * @param tag An Object to tag the view with
19591      *
19592      * @throws IllegalArgumentException If they specified key is not valid
19593      *
19594      * @see #setTag(Object)
19595      * @see #getTag(int)
19596      */
19597     public void setTag(int key, final Object tag) {
19598         // If the package id is 0x00 or 0x01, it's either an undefined package
19599         // or a framework id
19600         if ((key >>> 24) < 2) {
19601             throw new IllegalArgumentException("The key must be an application-specific "
19602                     + "resource id.");
19603         }
19604
19605         setKeyedTag(key, tag);
19606     }
19607
19608     /**
19609      * Variation of {@link #setTag(int, Object)} that enforces the key to be a
19610      * framework id.
19611      *
19612      * @hide
19613      */
19614     public void setTagInternal(int key, Object tag) {
19615         if ((key >>> 24) != 0x1) {
19616             throw new IllegalArgumentException("The key must be a framework-specific "
19617                     + "resource id.");
19618         }
19619
19620         setKeyedTag(key, tag);
19621     }
19622
19623     private void setKeyedTag(int key, Object tag) {
19624         if (mKeyedTags == null) {
19625             mKeyedTags = new SparseArray<Object>(2);
19626         }
19627
19628         mKeyedTags.put(key, tag);
19629     }
19630
19631     /**
19632      * Prints information about this view in the log output, with the tag
19633      * {@link #VIEW_LOG_TAG}.
19634      *
19635      * @hide
19636      */
19637     public void debug() {
19638         debug(0);
19639     }
19640
19641     /**
19642      * Prints information about this view in the log output, with the tag
19643      * {@link #VIEW_LOG_TAG}. Each line in the output is preceded with an
19644      * indentation defined by the <code>depth</code>.
19645      *
19646      * @param depth the indentation level
19647      *
19648      * @hide
19649      */
19650     protected void debug(int depth) {
19651         String output = debugIndent(depth - 1);
19652
19653         output += "+ " + this;
19654         int id = getId();
19655         if (id != -1) {
19656             output += " (id=" + id + ")";
19657         }
19658         Object tag = getTag();
19659         if (tag != null) {
19660             output += " (tag=" + tag + ")";
19661         }
19662         Log.d(VIEW_LOG_TAG, output);
19663
19664         if ((mPrivateFlags & PFLAG_FOCUSED) != 0) {
19665             output = debugIndent(depth) + " FOCUSED";
19666             Log.d(VIEW_LOG_TAG, output);
19667         }
19668
19669         output = debugIndent(depth);
19670         output += "frame={" + mLeft + ", " + mTop + ", " + mRight
19671                 + ", " + mBottom + "} scroll={" + mScrollX + ", " + mScrollY
19672                 + "} ";
19673         Log.d(VIEW_LOG_TAG, output);
19674
19675         if (mPaddingLeft != 0 || mPaddingTop != 0 || mPaddingRight != 0
19676                 || mPaddingBottom != 0) {
19677             output = debugIndent(depth);
19678             output += "padding={" + mPaddingLeft + ", " + mPaddingTop
19679                     + ", " + mPaddingRight + ", " + mPaddingBottom + "}";
19680             Log.d(VIEW_LOG_TAG, output);
19681         }
19682
19683         output = debugIndent(depth);
19684         output += "mMeasureWidth=" + mMeasuredWidth +
19685                 " mMeasureHeight=" + mMeasuredHeight;
19686         Log.d(VIEW_LOG_TAG, output);
19687
19688         output = debugIndent(depth);
19689         if (mLayoutParams == null) {
19690             output += "BAD! no layout params";
19691         } else {
19692             output = mLayoutParams.debug(output);
19693         }
19694         Log.d(VIEW_LOG_TAG, output);
19695
19696         output = debugIndent(depth);
19697         output += "flags={";
19698         output += View.printFlags(mViewFlags);
19699         output += "}";
19700         Log.d(VIEW_LOG_TAG, output);
19701
19702         output = debugIndent(depth);
19703         output += "privateFlags={";
19704         output += View.printPrivateFlags(mPrivateFlags);
19705         output += "}";
19706         Log.d(VIEW_LOG_TAG, output);
19707     }
19708
19709     /**
19710      * Creates a string of whitespaces used for indentation.
19711      *
19712      * @param depth the indentation level
19713      * @return a String containing (depth * 2 + 3) * 2 white spaces
19714      *
19715      * @hide
19716      */
19717     protected static String debugIndent(int depth) {
19718         StringBuilder spaces = new StringBuilder((depth * 2 + 3) * 2);
19719         for (int i = 0; i < (depth * 2) + 3; i++) {
19720             spaces.append(' ').append(' ');
19721         }
19722         return spaces.toString();
19723     }
19724
19725     /**
19726      * <p>Return the offset of the widget's text baseline from the widget's top
19727      * boundary. If this widget does not support baseline alignment, this
19728      * method returns -1. </p>
19729      *
19730      * @return the offset of the baseline within the widget's bounds or -1
19731      *         if baseline alignment is not supported
19732      */
19733     @ViewDebug.ExportedProperty(category = "layout")
19734     public int getBaseline() {
19735         return -1;
19736     }
19737
19738     /**
19739      * Returns whether the view hierarchy is currently undergoing a layout pass. This
19740      * information is useful to avoid situations such as calling {@link #requestLayout()} during
19741      * a layout pass.
19742      *
19743      * @return whether the view hierarchy is currently undergoing a layout pass
19744      */
19745     public boolean isInLayout() {
19746         ViewRootImpl viewRoot = getViewRootImpl();
19747         return (viewRoot != null && viewRoot.isInLayout());
19748     }
19749
19750     /**
19751      * Call this when something has changed which has invalidated the
19752      * layout of this view. This will schedule a layout pass of the view
19753      * tree. This should not be called while the view hierarchy is currently in a layout
19754      * pass ({@link #isInLayout()}. If layout is happening, the request may be honored at the
19755      * end of the current layout pass (and then layout will run again) or after the current
19756      * frame is drawn and the next layout occurs.
19757      *
19758      * <p>Subclasses which override this method should call the superclass method to
19759      * handle possible request-during-layout errors correctly.</p>
19760      */
19761     @CallSuper
19762     public void requestLayout() {
19763         if (mMeasureCache != null) mMeasureCache.clear();
19764
19765         if (mAttachInfo != null && mAttachInfo.mViewRequestingLayout == null) {
19766             // Only trigger request-during-layout logic if this is the view requesting it,
19767             // not the views in its parent hierarchy
19768             ViewRootImpl viewRoot = getViewRootImpl();
19769             if (viewRoot != null && viewRoot.isInLayout()) {
19770                 if (!viewRoot.requestLayoutDuringLayout(this)) {
19771                     return;
19772                 }
19773             }
19774             mAttachInfo.mViewRequestingLayout = this;
19775         }
19776
19777         mPrivateFlags |= PFLAG_FORCE_LAYOUT;
19778         mPrivateFlags |= PFLAG_INVALIDATED;
19779
19780         if (mParent != null && !mParent.isLayoutRequested()) {
19781             mParent.requestLayout();
19782         }
19783         if (mAttachInfo != null && mAttachInfo.mViewRequestingLayout == this) {
19784             mAttachInfo.mViewRequestingLayout = null;
19785         }
19786     }
19787
19788     /**
19789      * Forces this view to be laid out during the next layout pass.
19790      * This method does not call requestLayout() or forceLayout()
19791      * on the parent.
19792      */
19793     public void forceLayout() {
19794         if (mMeasureCache != null) mMeasureCache.clear();
19795
19796         mPrivateFlags |= PFLAG_FORCE_LAYOUT;
19797         mPrivateFlags |= PFLAG_INVALIDATED;
19798     }
19799
19800     /**
19801      * <p>
19802      * This is called to find out how big a view should be. The parent
19803      * supplies constraint information in the width and height parameters.
19804      * </p>
19805      *
19806      * <p>
19807      * The actual measurement work of a view is performed in
19808      * {@link #onMeasure(int, int)}, called by this method. Therefore, only
19809      * {@link #onMeasure(int, int)} can and must be overridden by subclasses.
19810      * </p>
19811      *
19812      *
19813      * @param widthMeasureSpec Horizontal space requirements as imposed by the
19814      *        parent
19815      * @param heightMeasureSpec Vertical space requirements as imposed by the
19816      *        parent
19817      *
19818      * @see #onMeasure(int, int)
19819      */
19820     public final void measure(int widthMeasureSpec, int heightMeasureSpec) {
19821         boolean optical = isLayoutModeOptical(this);
19822         if (optical != isLayoutModeOptical(mParent)) {
19823             Insets insets = getOpticalInsets();
19824             int oWidth  = insets.left + insets.right;
19825             int oHeight = insets.top  + insets.bottom;
19826             widthMeasureSpec  = MeasureSpec.adjust(widthMeasureSpec,  optical ? -oWidth  : oWidth);
19827             heightMeasureSpec = MeasureSpec.adjust(heightMeasureSpec, optical ? -oHeight : oHeight);
19828         }
19829
19830         // Suppress sign extension for the low bytes
19831         long key = (long) widthMeasureSpec << 32 | (long) heightMeasureSpec & 0xffffffffL;
19832         if (mMeasureCache == null) mMeasureCache = new LongSparseLongArray(2);
19833
19834         final boolean forceLayout = (mPrivateFlags & PFLAG_FORCE_LAYOUT) == PFLAG_FORCE_LAYOUT;
19835
19836         // Optimize layout by avoiding an extra EXACTLY pass when the view is
19837         // already measured as the correct size. In API 23 and below, this
19838         // extra pass is required to make LinearLayout re-distribute weight.
19839         final boolean specChanged = widthMeasureSpec != mOldWidthMeasureSpec
19840                 || heightMeasureSpec != mOldHeightMeasureSpec;
19841         final boolean isSpecExactly = MeasureSpec.getMode(widthMeasureSpec) == MeasureSpec.EXACTLY
19842                 && MeasureSpec.getMode(heightMeasureSpec) == MeasureSpec.EXACTLY;
19843         final boolean matchesSpecSize = getMeasuredWidth() == MeasureSpec.getSize(widthMeasureSpec)
19844                 && getMeasuredHeight() == MeasureSpec.getSize(heightMeasureSpec);
19845         final boolean needsLayout = specChanged
19846                 && (sAlwaysRemeasureExactly || !isSpecExactly || !matchesSpecSize);
19847
19848         if (forceLayout || needsLayout) {
19849             // first clears the measured dimension flag
19850             mPrivateFlags &= ~PFLAG_MEASURED_DIMENSION_SET;
19851
19852             resolveRtlPropertiesIfNeeded();
19853
19854             int cacheIndex = forceLayout ? -1 : mMeasureCache.indexOfKey(key);
19855             if (cacheIndex < 0 || sIgnoreMeasureCache) {
19856                 // measure ourselves, this should set the measured dimension flag back
19857                 onMeasure(widthMeasureSpec, heightMeasureSpec);
19858                 mPrivateFlags3 &= ~PFLAG3_MEASURE_NEEDED_BEFORE_LAYOUT;
19859             } else {
19860                 long value = mMeasureCache.valueAt(cacheIndex);
19861                 // Casting a long to int drops the high 32 bits, no mask needed
19862                 setMeasuredDimensionRaw((int) (value >> 32), (int) value);
19863                 mPrivateFlags3 |= PFLAG3_MEASURE_NEEDED_BEFORE_LAYOUT;
19864             }
19865
19866             // flag not set, setMeasuredDimension() was not invoked, we raise
19867             // an exception to warn the developer
19868             if ((mPrivateFlags & PFLAG_MEASURED_DIMENSION_SET) != PFLAG_MEASURED_DIMENSION_SET) {
19869                 throw new IllegalStateException("View with id " + getId() + ": "
19870                         + getClass().getName() + "#onMeasure() did not set the"
19871                         + " measured dimension by calling"
19872                         + " setMeasuredDimension()");
19873             }
19874
19875             mPrivateFlags |= PFLAG_LAYOUT_REQUIRED;
19876         }
19877
19878         mOldWidthMeasureSpec = widthMeasureSpec;
19879         mOldHeightMeasureSpec = heightMeasureSpec;
19880
19881         mMeasureCache.put(key, ((long) mMeasuredWidth) << 32 |
19882                 (long) mMeasuredHeight & 0xffffffffL); // suppress sign extension
19883     }
19884
19885     /**
19886      * <p>
19887      * Measure the view and its content to determine the measured width and the
19888      * measured height. This method is invoked by {@link #measure(int, int)} and
19889      * should be overridden by subclasses to provide accurate and efficient
19890      * measurement of their contents.
19891      * </p>
19892      *
19893      * <p>
19894      * <strong>CONTRACT:</strong> When overriding this method, you
19895      * <em>must</em> call {@link #setMeasuredDimension(int, int)} to store the
19896      * measured width and height of this view. Failure to do so will trigger an
19897      * <code>IllegalStateException</code>, thrown by
19898      * {@link #measure(int, int)}. Calling the superclass'
19899      * {@link #onMeasure(int, int)} is a valid use.
19900      * </p>
19901      *
19902      * <p>
19903      * The base class implementation of measure defaults to the background size,
19904      * unless a larger size is allowed by the MeasureSpec. Subclasses should
19905      * override {@link #onMeasure(int, int)} to provide better measurements of
19906      * their content.
19907      * </p>
19908      *
19909      * <p>
19910      * If this method is overridden, it is the subclass's responsibility to make
19911      * sure the measured height and width are at least the view's minimum height
19912      * and width ({@link #getSuggestedMinimumHeight()} and
19913      * {@link #getSuggestedMinimumWidth()}).
19914      * </p>
19915      *
19916      * @param widthMeasureSpec horizontal space requirements as imposed by the parent.
19917      *                         The requirements are encoded with
19918      *                         {@link android.view.View.MeasureSpec}.
19919      * @param heightMeasureSpec vertical space requirements as imposed by the parent.
19920      *                         The requirements are encoded with
19921      *                         {@link android.view.View.MeasureSpec}.
19922      *
19923      * @see #getMeasuredWidth()
19924      * @see #getMeasuredHeight()
19925      * @see #setMeasuredDimension(int, int)
19926      * @see #getSuggestedMinimumHeight()
19927      * @see #getSuggestedMinimumWidth()
19928      * @see android.view.View.MeasureSpec#getMode(int)
19929      * @see android.view.View.MeasureSpec#getSize(int)
19930      */
19931     protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
19932         setMeasuredDimension(getDefaultSize(getSuggestedMinimumWidth(), widthMeasureSpec),
19933                 getDefaultSize(getSuggestedMinimumHeight(), heightMeasureSpec));
19934     }
19935
19936     /**
19937      * <p>This method must be called by {@link #onMeasure(int, int)} to store the
19938      * measured width and measured height. Failing to do so will trigger an
19939      * exception at measurement time.</p>
19940      *
19941      * @param measuredWidth The measured width of this view.  May be a complex
19942      * bit mask as defined by {@link #MEASURED_SIZE_MASK} and
19943      * {@link #MEASURED_STATE_TOO_SMALL}.
19944      * @param measuredHeight The measured height of this view.  May be a complex
19945      * bit mask as defined by {@link #MEASURED_SIZE_MASK} and
19946      * {@link #MEASURED_STATE_TOO_SMALL}.
19947      */
19948     protected final void setMeasuredDimension(int measuredWidth, int measuredHeight) {
19949         boolean optical = isLayoutModeOptical(this);
19950         if (optical != isLayoutModeOptical(mParent)) {
19951             Insets insets = getOpticalInsets();
19952             int opticalWidth  = insets.left + insets.right;
19953             int opticalHeight = insets.top  + insets.bottom;
19954
19955             measuredWidth  += optical ? opticalWidth  : -opticalWidth;
19956             measuredHeight += optical ? opticalHeight : -opticalHeight;
19957         }
19958         setMeasuredDimensionRaw(measuredWidth, measuredHeight);
19959     }
19960
19961     /**
19962      * Sets the measured dimension without extra processing for things like optical bounds.
19963      * Useful for reapplying consistent values that have already been cooked with adjustments
19964      * for optical bounds, etc. such as those from the measurement cache.
19965      *
19966      * @param measuredWidth The measured width of this view.  May be a complex
19967      * bit mask as defined by {@link #MEASURED_SIZE_MASK} and
19968      * {@link #MEASURED_STATE_TOO_SMALL}.
19969      * @param measuredHeight The measured height of this view.  May be a complex
19970      * bit mask as defined by {@link #MEASURED_SIZE_MASK} and
19971      * {@link #MEASURED_STATE_TOO_SMALL}.
19972      */
19973     private void setMeasuredDimensionRaw(int measuredWidth, int measuredHeight) {
19974         mMeasuredWidth = measuredWidth;
19975         mMeasuredHeight = measuredHeight;
19976
19977         mPrivateFlags |= PFLAG_MEASURED_DIMENSION_SET;
19978     }
19979
19980     /**
19981      * Merge two states as returned by {@link #getMeasuredState()}.
19982      * @param curState The current state as returned from a view or the result
19983      * of combining multiple views.
19984      * @param newState The new view state to combine.
19985      * @return Returns a new integer reflecting the combination of the two
19986      * states.
19987      */
19988     public static int combineMeasuredStates(int curState, int newState) {
19989         return curState | newState;
19990     }
19991
19992     /**
19993      * Version of {@link #resolveSizeAndState(int, int, int)}
19994      * returning only the {@link #MEASURED_SIZE_MASK} bits of the result.
19995      */
19996     public static int resolveSize(int size, int measureSpec) {
19997         return resolveSizeAndState(size, measureSpec, 0) & MEASURED_SIZE_MASK;
19998     }
19999
20000     /**
20001      * Utility to reconcile a desired size and state, with constraints imposed
20002      * by a MeasureSpec. Will take the desired size, unless a different size
20003      * is imposed by the constraints. The returned value is a compound integer,
20004      * with the resolved size in the {@link #MEASURED_SIZE_MASK} bits and
20005      * optionally the bit {@link #MEASURED_STATE_TOO_SMALL} set if the
20006      * resulting size is smaller than the size the view wants to be.
20007      *
20008      * @param size How big the view wants to be.
20009      * @param measureSpec Constraints imposed by the parent.
20010      * @param childMeasuredState Size information bit mask for the view's
20011      *                           children.
20012      * @return Size information bit mask as defined by
20013      *         {@link #MEASURED_SIZE_MASK} and
20014      *         {@link #MEASURED_STATE_TOO_SMALL}.
20015      */
20016     public static int resolveSizeAndState(int size, int measureSpec, int childMeasuredState) {
20017         final int specMode = MeasureSpec.getMode(measureSpec);
20018         final int specSize = MeasureSpec.getSize(measureSpec);
20019         final int result;
20020         switch (specMode) {
20021             case MeasureSpec.AT_MOST:
20022                 if (specSize < size) {
20023                     result = specSize | MEASURED_STATE_TOO_SMALL;
20024                 } else {
20025                     result = size;
20026                 }
20027                 break;
20028             case MeasureSpec.EXACTLY:
20029                 result = specSize;
20030                 break;
20031             case MeasureSpec.UNSPECIFIED:
20032             default:
20033                 result = size;
20034         }
20035         return result | (childMeasuredState & MEASURED_STATE_MASK);
20036     }
20037
20038     /**
20039      * Utility to return a default size. Uses the supplied size if the
20040      * MeasureSpec imposed no constraints. Will get larger if allowed
20041      * by the MeasureSpec.
20042      *
20043      * @param size Default size for this view
20044      * @param measureSpec Constraints imposed by the parent
20045      * @return The size this view should be.
20046      */
20047     public static int getDefaultSize(int size, int measureSpec) {
20048         int result = size;
20049         int specMode = MeasureSpec.getMode(measureSpec);
20050         int specSize = MeasureSpec.getSize(measureSpec);
20051
20052         switch (specMode) {
20053         case MeasureSpec.UNSPECIFIED:
20054             result = size;
20055             break;
20056         case MeasureSpec.AT_MOST:
20057         case MeasureSpec.EXACTLY:
20058             result = specSize;
20059             break;
20060         }
20061         return result;
20062     }
20063
20064     /**
20065      * Returns the suggested minimum height that the view should use. This
20066      * returns the maximum of the view's minimum height
20067      * and the background's minimum height
20068      * ({@link android.graphics.drawable.Drawable#getMinimumHeight()}).
20069      * <p>
20070      * When being used in {@link #onMeasure(int, int)}, the caller should still
20071      * ensure the returned height is within the requirements of the parent.
20072      *
20073      * @return The suggested minimum height of the view.
20074      */
20075     protected int getSuggestedMinimumHeight() {
20076         return (mBackground == null) ? mMinHeight : max(mMinHeight, mBackground.getMinimumHeight());
20077
20078     }
20079
20080     /**
20081      * Returns the suggested minimum width that the view should use. This
20082      * returns the maximum of the view's minimum width
20083      * and the background's minimum width
20084      *  ({@link android.graphics.drawable.Drawable#getMinimumWidth()}).
20085      * <p>
20086      * When being used in {@link #onMeasure(int, int)}, the caller should still
20087      * ensure the returned width is within the requirements of the parent.
20088      *
20089      * @return The suggested minimum width of the view.
20090      */
20091     protected int getSuggestedMinimumWidth() {
20092         return (mBackground == null) ? mMinWidth : max(mMinWidth, mBackground.getMinimumWidth());
20093     }
20094
20095     /**
20096      * Returns the minimum height of the view.
20097      *
20098      * @return the minimum height the view will try to be.
20099      *
20100      * @see #setMinimumHeight(int)
20101      *
20102      * @attr ref android.R.styleable#View_minHeight
20103      */
20104     public int getMinimumHeight() {
20105         return mMinHeight;
20106     }
20107
20108     /**
20109      * Sets the minimum height of the view. It is not guaranteed the view will
20110      * be able to achieve this minimum height (for example, if its parent layout
20111      * constrains it with less available height).
20112      *
20113      * @param minHeight The minimum height the view will try to be.
20114      *
20115      * @see #getMinimumHeight()
20116      *
20117      * @attr ref android.R.styleable#View_minHeight
20118      */
20119     @RemotableViewMethod
20120     public void setMinimumHeight(int minHeight) {
20121         mMinHeight = minHeight;
20122         requestLayout();
20123     }
20124
20125     /**
20126      * Returns the minimum width of the view.
20127      *
20128      * @return the minimum width the view will try to be.
20129      *
20130      * @see #setMinimumWidth(int)
20131      *
20132      * @attr ref android.R.styleable#View_minWidth
20133      */
20134     public int getMinimumWidth() {
20135         return mMinWidth;
20136     }
20137
20138     /**
20139      * Sets the minimum width of the view. It is not guaranteed the view will
20140      * be able to achieve this minimum width (for example, if its parent layout
20141      * constrains it with less available width).
20142      *
20143      * @param minWidth The minimum width the view will try to be.
20144      *
20145      * @see #getMinimumWidth()
20146      *
20147      * @attr ref android.R.styleable#View_minWidth
20148      */
20149     public void setMinimumWidth(int minWidth) {
20150         mMinWidth = minWidth;
20151         requestLayout();
20152
20153     }
20154
20155     /**
20156      * Get the animation currently associated with this view.
20157      *
20158      * @return The animation that is currently playing or
20159      *         scheduled to play for this view.
20160      */
20161     public Animation getAnimation() {
20162         return mCurrentAnimation;
20163     }
20164
20165     /**
20166      * Start the specified animation now.
20167      *
20168      * @param animation the animation to start now
20169      */
20170     public void startAnimation(Animation animation) {
20171         animation.setStartTime(Animation.START_ON_FIRST_FRAME);
20172         setAnimation(animation);
20173         invalidateParentCaches();
20174         invalidate(true);
20175     }
20176
20177     /**
20178      * Cancels any animations for this view.
20179      */
20180     public void clearAnimation() {
20181         if (mCurrentAnimation != null) {
20182             mCurrentAnimation.detach();
20183         }
20184         mCurrentAnimation = null;
20185         invalidateParentIfNeeded();
20186     }
20187
20188     /**
20189      * Sets the next animation to play for this view.
20190      * If you want the animation to play immediately, use
20191      * {@link #startAnimation(android.view.animation.Animation)} instead.
20192      * This method provides allows fine-grained
20193      * control over the start time and invalidation, but you
20194      * must make sure that 1) the animation has a start time set, and
20195      * 2) the view's parent (which controls animations on its children)
20196      * will be invalidated when the animation is supposed to
20197      * start.
20198      *
20199      * @param animation The next animation, or null.
20200      */
20201     public void setAnimation(Animation animation) {
20202         mCurrentAnimation = animation;
20203
20204         if (animation != null) {
20205             // If the screen is off assume the animation start time is now instead of
20206             // the next frame we draw. Keeping the START_ON_FIRST_FRAME start time
20207             // would cause the animation to start when the screen turns back on
20208             if (mAttachInfo != null && mAttachInfo.mDisplayState == Display.STATE_OFF
20209                     && animation.getStartTime() == Animation.START_ON_FIRST_FRAME) {
20210                 animation.setStartTime(AnimationUtils.currentAnimationTimeMillis());
20211             }
20212             animation.reset();
20213         }
20214     }
20215
20216     /**
20217      * Invoked by a parent ViewGroup to notify the start of the animation
20218      * currently associated with this view. If you override this method,
20219      * always call super.onAnimationStart();
20220      *
20221      * @see #setAnimation(android.view.animation.Animation)
20222      * @see #getAnimation()
20223      */
20224     @CallSuper
20225     protected void onAnimationStart() {
20226         mPrivateFlags |= PFLAG_ANIMATION_STARTED;
20227     }
20228
20229     /**
20230      * Invoked by a parent ViewGroup to notify the end of the animation
20231      * currently associated with this view. If you override this method,
20232      * always call super.onAnimationEnd();
20233      *
20234      * @see #setAnimation(android.view.animation.Animation)
20235      * @see #getAnimation()
20236      */
20237     @CallSuper
20238     protected void onAnimationEnd() {
20239         mPrivateFlags &= ~PFLAG_ANIMATION_STARTED;
20240     }
20241
20242     /**
20243      * Invoked if there is a Transform that involves alpha. Subclass that can
20244      * draw themselves with the specified alpha should return true, and then
20245      * respect that alpha when their onDraw() is called. If this returns false
20246      * then the view may be redirected to draw into an offscreen buffer to
20247      * fulfill the request, which will look fine, but may be slower than if the
20248      * subclass handles it internally. The default implementation returns false.
20249      *
20250      * @param alpha The alpha (0..255) to apply to the view's drawing
20251      * @return true if the view can draw with the specified alpha.
20252      */
20253     protected boolean onSetAlpha(int alpha) {
20254         return false;
20255     }
20256
20257     /**
20258      * This is used by the RootView to perform an optimization when
20259      * the view hierarchy contains one or several SurfaceView.
20260      * SurfaceView is always considered transparent, but its children are not,
20261      * therefore all View objects remove themselves from the global transparent
20262      * region (passed as a parameter to this function).
20263      *
20264      * @param region The transparent region for this ViewAncestor (window).
20265      *
20266      * @return Returns true if the effective visibility of the view at this
20267      * point is opaque, regardless of the transparent region; returns false
20268      * if it is possible for underlying windows to be seen behind the view.
20269      *
20270      * {@hide}
20271      */
20272     public boolean gatherTransparentRegion(Region region) {
20273         final AttachInfo attachInfo = mAttachInfo;
20274         if (region != null && attachInfo != null) {
20275             final int pflags = mPrivateFlags;
20276             if ((pflags & PFLAG_SKIP_DRAW) == 0) {
20277                 // The SKIP_DRAW flag IS NOT set, so this view draws. We need to
20278                 // remove it from the transparent region.
20279                 final int[] location = attachInfo.mTransparentLocation;
20280                 getLocationInWindow(location);
20281                 // When a view has Z value, then it will be better to leave some area below the view
20282                 // for drawing shadow. The shadow outset is proportional to the Z value. Note that
20283                 // the bottom part needs more offset than the left, top and right parts due to the
20284                 // spot light effects.
20285                 int shadowOffset = getZ() > 0 ? (int) getZ() : 0;
20286                 region.op(location[0] - shadowOffset, location[1] - shadowOffset,
20287                         location[0] + mRight - mLeft + shadowOffset,
20288                         location[1] + mBottom - mTop + (shadowOffset * 3), Region.Op.DIFFERENCE);
20289             } else {
20290                 if (mBackground != null && mBackground.getOpacity() != PixelFormat.TRANSPARENT) {
20291                     // The SKIP_DRAW flag IS set and the background drawable exists, we remove
20292                     // the background drawable's non-transparent parts from this transparent region.
20293                     applyDrawableToTransparentRegion(mBackground, region);
20294                 }
20295                 if (mForegroundInfo != null && mForegroundInfo.mDrawable != null
20296                         && mForegroundInfo.mDrawable.getOpacity() != PixelFormat.TRANSPARENT) {
20297                     // Similarly, we remove the foreground drawable's non-transparent parts.
20298                     applyDrawableToTransparentRegion(mForegroundInfo.mDrawable, region);
20299                 }
20300             }
20301         }
20302         return true;
20303     }
20304
20305     /**
20306      * Play a sound effect for this view.
20307      *
20308      * <p>The framework will play sound effects for some built in actions, such as
20309      * clicking, but you may wish to play these effects in your widget,
20310      * for instance, for internal navigation.
20311      *
20312      * <p>The sound effect will only be played if sound effects are enabled by the user, and
20313      * {@link #isSoundEffectsEnabled()} is true.
20314      *
20315      * @param soundConstant One of the constants defined in {@link SoundEffectConstants}
20316      */
20317     public void playSoundEffect(int soundConstant) {
20318         if (mAttachInfo == null || mAttachInfo.mRootCallbacks == null || !isSoundEffectsEnabled()) {
20319             return;
20320         }
20321         mAttachInfo.mRootCallbacks.playSoundEffect(soundConstant);
20322     }
20323
20324     /**
20325      * BZZZTT!!1!
20326      *
20327      * <p>Provide haptic feedback to the user for this view.
20328      *
20329      * <p>The framework will provide haptic feedback for some built in actions,
20330      * such as long presses, but you may wish to provide feedback for your
20331      * own widget.
20332      *
20333      * <p>The feedback will only be performed if
20334      * {@link #isHapticFeedbackEnabled()} is true.
20335      *
20336      * @param feedbackConstant One of the constants defined in
20337      * {@link HapticFeedbackConstants}
20338      */
20339     public boolean performHapticFeedback(int feedbackConstant) {
20340         return performHapticFeedback(feedbackConstant, 0);
20341     }
20342
20343     /**
20344      * BZZZTT!!1!
20345      *
20346      * <p>Like {@link #performHapticFeedback(int)}, with additional options.
20347      *
20348      * @param feedbackConstant One of the constants defined in
20349      * {@link HapticFeedbackConstants}
20350      * @param flags Additional flags as per {@link HapticFeedbackConstants}.
20351      */
20352     public boolean performHapticFeedback(int feedbackConstant, int flags) {
20353         if (mAttachInfo == null) {
20354             return false;
20355         }
20356         //noinspection SimplifiableIfStatement
20357         if ((flags & HapticFeedbackConstants.FLAG_IGNORE_VIEW_SETTING) == 0
20358                 && !isHapticFeedbackEnabled()) {
20359             return false;
20360         }
20361         return mAttachInfo.mRootCallbacks.performHapticFeedback(feedbackConstant,
20362                 (flags & HapticFeedbackConstants.FLAG_IGNORE_GLOBAL_SETTING) != 0);
20363     }
20364
20365     /**
20366      * Request that the visibility of the status bar or other screen/window
20367      * decorations be changed.
20368      *
20369      * <p>This method is used to put the over device UI into temporary modes
20370      * where the user's attention is focused more on the application content,
20371      * by dimming or hiding surrounding system affordances.  This is typically
20372      * used in conjunction with {@link Window#FEATURE_ACTION_BAR_OVERLAY
20373      * Window.FEATURE_ACTION_BAR_OVERLAY}, allowing the applications content
20374      * to be placed behind the action bar (and with these flags other system
20375      * affordances) so that smooth transitions between hiding and showing them
20376      * can be done.
20377      *
20378      * <p>Two representative examples of the use of system UI visibility is
20379      * implementing a content browsing application (like a magazine reader)
20380      * and a video playing application.
20381      *
20382      * <p>The first code shows a typical implementation of a View in a content
20383      * browsing application.  In this implementation, the application goes
20384      * into a content-oriented mode by hiding the status bar and action bar,
20385      * and putting the navigation elements into lights out mode.  The user can
20386      * then interact with content while in this mode.  Such an application should
20387      * provide an easy way for the user to toggle out of the mode (such as to
20388      * check information in the status bar or access notifications).  In the
20389      * implementation here, this is done simply by tapping on the content.
20390      *
20391      * {@sample development/samples/ApiDemos/src/com/example/android/apis/view/ContentBrowserActivity.java
20392      *      content}
20393      *
20394      * <p>This second code sample shows a typical implementation of a View
20395      * in a video playing application.  In this situation, while the video is
20396      * playing the application would like to go into a complete full-screen mode,
20397      * to use as much of the display as possible for the video.  When in this state
20398      * the user can not interact with the application; the system intercepts
20399      * touching on the screen to pop the UI out of full screen mode.  See
20400      * {@link #fitSystemWindows(Rect)} for a sample layout that goes with this code.
20401      *
20402      * {@sample development/samples/ApiDemos/src/com/example/android/apis/view/VideoPlayerActivity.java
20403      *      content}
20404      *
20405      * @param visibility  Bitwise-or of flags {@link #SYSTEM_UI_FLAG_LOW_PROFILE},
20406      * {@link #SYSTEM_UI_FLAG_HIDE_NAVIGATION}, {@link #SYSTEM_UI_FLAG_FULLSCREEN},
20407      * {@link #SYSTEM_UI_FLAG_LAYOUT_STABLE}, {@link #SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION},
20408      * {@link #SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN}, {@link #SYSTEM_UI_FLAG_IMMERSIVE},
20409      * and {@link #SYSTEM_UI_FLAG_IMMERSIVE_STICKY}.
20410      */
20411     public void setSystemUiVisibility(int visibility) {
20412         if (visibility != mSystemUiVisibility) {
20413             mSystemUiVisibility = visibility;
20414             if (mParent != null && mAttachInfo != null && !mAttachInfo.mRecomputeGlobalAttributes) {
20415                 mParent.recomputeViewAttributes(this);
20416             }
20417         }
20418     }
20419
20420     /**
20421      * Returns the last {@link #setSystemUiVisibility(int)} that this view has requested.
20422      * @return  Bitwise-or of flags {@link #SYSTEM_UI_FLAG_LOW_PROFILE},
20423      * {@link #SYSTEM_UI_FLAG_HIDE_NAVIGATION}, {@link #SYSTEM_UI_FLAG_FULLSCREEN},
20424      * {@link #SYSTEM_UI_FLAG_LAYOUT_STABLE}, {@link #SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION},
20425      * {@link #SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN}, {@link #SYSTEM_UI_FLAG_IMMERSIVE},
20426      * and {@link #SYSTEM_UI_FLAG_IMMERSIVE_STICKY}.
20427      */
20428     public int getSystemUiVisibility() {
20429         return mSystemUiVisibility;
20430     }
20431
20432     /**
20433      * Returns the current system UI visibility that is currently set for
20434      * the entire window.  This is the combination of the
20435      * {@link #setSystemUiVisibility(int)} values supplied by all of the
20436      * views in the window.
20437      */
20438     public int getWindowSystemUiVisibility() {
20439         return mAttachInfo != null ? mAttachInfo.mSystemUiVisibility : 0;
20440     }
20441
20442     /**
20443      * Override to find out when the window's requested system UI visibility
20444      * has changed, that is the value returned by {@link #getWindowSystemUiVisibility()}.
20445      * This is different from the callbacks received through
20446      * {@link #setOnSystemUiVisibilityChangeListener(OnSystemUiVisibilityChangeListener)}
20447      * in that this is only telling you about the local request of the window,
20448      * not the actual values applied by the system.
20449      */
20450     public void onWindowSystemUiVisibilityChanged(int visible) {
20451     }
20452
20453     /**
20454      * Dispatch callbacks to {@link #onWindowSystemUiVisibilityChanged(int)} down
20455      * the view hierarchy.
20456      */
20457     public void dispatchWindowSystemUiVisiblityChanged(int visible) {
20458         onWindowSystemUiVisibilityChanged(visible);
20459     }
20460
20461     /**
20462      * Set a listener to receive callbacks when the visibility of the system bar changes.
20463      * @param l  The {@link OnSystemUiVisibilityChangeListener} to receive callbacks.
20464      */
20465     public void setOnSystemUiVisibilityChangeListener(OnSystemUiVisibilityChangeListener l) {
20466         getListenerInfo().mOnSystemUiVisibilityChangeListener = l;
20467         if (mParent != null && mAttachInfo != null && !mAttachInfo.mRecomputeGlobalAttributes) {
20468             mParent.recomputeViewAttributes(this);
20469         }
20470     }
20471
20472     /**
20473      * Dispatch callbacks to {@link #setOnSystemUiVisibilityChangeListener} down
20474      * the view hierarchy.
20475      */
20476     public void dispatchSystemUiVisibilityChanged(int visibility) {
20477         ListenerInfo li = mListenerInfo;
20478         if (li != null && li.mOnSystemUiVisibilityChangeListener != null) {
20479             li.mOnSystemUiVisibilityChangeListener.onSystemUiVisibilityChange(
20480                     visibility & PUBLIC_STATUS_BAR_VISIBILITY_MASK);
20481         }
20482     }
20483
20484     boolean updateLocalSystemUiVisibility(int localValue, int localChanges) {
20485         int val = (mSystemUiVisibility&~localChanges) | (localValue&localChanges);
20486         if (val != mSystemUiVisibility) {
20487             setSystemUiVisibility(val);
20488             return true;
20489         }
20490         return false;
20491     }
20492
20493     /** @hide */
20494     public void setDisabledSystemUiVisibility(int flags) {
20495         if (mAttachInfo != null) {
20496             if (mAttachInfo.mDisabledSystemUiVisibility != flags) {
20497                 mAttachInfo.mDisabledSystemUiVisibility = flags;
20498                 if (mParent != null) {
20499                     mParent.recomputeViewAttributes(this);
20500                 }
20501             }
20502         }
20503     }
20504
20505     /**
20506      * Creates an image that the system displays during the drag and drop
20507      * operation. This is called a &quot;drag shadow&quot;. The default implementation
20508      * for a DragShadowBuilder based on a View returns an image that has exactly the same
20509      * appearance as the given View. The default also positions the center of the drag shadow
20510      * directly under the touch point. If no View is provided (the constructor with no parameters
20511      * is used), and {@link #onProvideShadowMetrics(Point,Point) onProvideShadowMetrics()} and
20512      * {@link #onDrawShadow(Canvas) onDrawShadow()} are not overridden, then the
20513      * default is an invisible drag shadow.
20514      * <p>
20515      * You are not required to use the View you provide to the constructor as the basis of the
20516      * drag shadow. The {@link #onDrawShadow(Canvas) onDrawShadow()} method allows you to draw
20517      * anything you want as the drag shadow.
20518      * </p>
20519      * <p>
20520      *  You pass a DragShadowBuilder object to the system when you start the drag. The system
20521      *  calls {@link #onProvideShadowMetrics(Point,Point) onProvideShadowMetrics()} to get the
20522      *  size and position of the drag shadow. It uses this data to construct a
20523      *  {@link android.graphics.Canvas} object, then it calls {@link #onDrawShadow(Canvas) onDrawShadow()}
20524      *  so that your application can draw the shadow image in the Canvas.
20525      * </p>
20526      *
20527      * <div class="special reference">
20528      * <h3>Developer Guides</h3>
20529      * <p>For a guide to implementing drag and drop features, read the
20530      * <a href="{@docRoot}guide/topics/ui/drag-drop.html">Drag and Drop</a> developer guide.</p>
20531      * </div>
20532      */
20533     public static class DragShadowBuilder {
20534         private final WeakReference<View> mView;
20535
20536         /**
20537          * Constructs a shadow image builder based on a View. By default, the resulting drag
20538          * shadow will have the same appearance and dimensions as the View, with the touch point
20539          * over the center of the View.
20540          * @param view A View. Any View in scope can be used.
20541          */
20542         public DragShadowBuilder(View view) {
20543             mView = new WeakReference<View>(view);
20544         }
20545
20546         /**
20547          * Construct a shadow builder object with no associated View.  This
20548          * constructor variant is only useful when the {@link #onProvideShadowMetrics(Point, Point)}
20549          * and {@link #onDrawShadow(Canvas)} methods are also overridden in order
20550          * to supply the drag shadow's dimensions and appearance without
20551          * reference to any View object. If they are not overridden, then the result is an
20552          * invisible drag shadow.
20553          */
20554         public DragShadowBuilder() {
20555             mView = new WeakReference<View>(null);
20556         }
20557
20558         /**
20559          * Returns the View object that had been passed to the
20560          * {@link #View.DragShadowBuilder(View)}
20561          * constructor.  If that View parameter was {@code null} or if the
20562          * {@link #View.DragShadowBuilder()}
20563          * constructor was used to instantiate the builder object, this method will return
20564          * null.
20565          *
20566          * @return The View object associate with this builder object.
20567          */
20568         @SuppressWarnings({"JavadocReference"})
20569         final public View getView() {
20570             return mView.get();
20571         }
20572
20573         /**
20574          * Provides the metrics for the shadow image. These include the dimensions of
20575          * the shadow image, and the point within that shadow that should
20576          * be centered under the touch location while dragging.
20577          * <p>
20578          * The default implementation sets the dimensions of the shadow to be the
20579          * same as the dimensions of the View itself and centers the shadow under
20580          * the touch point.
20581          * </p>
20582          *
20583          * @param outShadowSize A {@link android.graphics.Point} containing the width and height
20584          * of the shadow image. Your application must set {@link android.graphics.Point#x} to the
20585          * desired width and must set {@link android.graphics.Point#y} to the desired height of the
20586          * image.
20587          *
20588          * @param outShadowTouchPoint A {@link android.graphics.Point} for the position within the
20589          * shadow image that should be underneath the touch point during the drag and drop
20590          * operation. Your application must set {@link android.graphics.Point#x} to the
20591          * X coordinate and {@link android.graphics.Point#y} to the Y coordinate of this position.
20592          */
20593         public void onProvideShadowMetrics(Point outShadowSize, Point outShadowTouchPoint) {
20594             final View view = mView.get();
20595             if (view != null) {
20596                 outShadowSize.set(view.getWidth(), view.getHeight());
20597                 outShadowTouchPoint.set(outShadowSize.x / 2, outShadowSize.y / 2);
20598             } else {
20599                 Log.e(View.VIEW_LOG_TAG, "Asked for drag thumb metrics but no view");
20600             }
20601         }
20602
20603         /**
20604          * Draws the shadow image. The system creates the {@link android.graphics.Canvas} object
20605          * based on the dimensions it received from the
20606          * {@link #onProvideShadowMetrics(Point, Point)} callback.
20607          *
20608          * @param canvas A {@link android.graphics.Canvas} object in which to draw the shadow image.
20609          */
20610         public void onDrawShadow(Canvas canvas) {
20611             final View view = mView.get();
20612             if (view != null) {
20613                 view.draw(canvas);
20614             } else {
20615                 Log.e(View.VIEW_LOG_TAG, "Asked to draw drag shadow but no view");
20616             }
20617         }
20618     }
20619
20620     /**
20621      * @deprecated Use {@link #startDragAndDrop(ClipData, DragShadowBuilder, Object, int)
20622      * startDragAndDrop()} for newer platform versions.
20623      */
20624     public final boolean startDrag(ClipData data, DragShadowBuilder shadowBuilder,
20625                                    Object myLocalState, int flags) {
20626         return startDragAndDrop(data, shadowBuilder, myLocalState, flags);
20627     }
20628
20629     /**
20630      * Starts a drag and drop operation. When your application calls this method, it passes a
20631      * {@link android.view.View.DragShadowBuilder} object to the system. The
20632      * system calls this object's {@link DragShadowBuilder#onProvideShadowMetrics(Point, Point)}
20633      * to get metrics for the drag shadow, and then calls the object's
20634      * {@link DragShadowBuilder#onDrawShadow(Canvas)} to draw the drag shadow itself.
20635      * <p>
20636      *  Once the system has the drag shadow, it begins the drag and drop operation by sending
20637      *  drag events to all the View objects in your application that are currently visible. It does
20638      *  this either by calling the View object's drag listener (an implementation of
20639      *  {@link android.view.View.OnDragListener#onDrag(View,DragEvent) onDrag()} or by calling the
20640      *  View object's {@link android.view.View#onDragEvent(DragEvent) onDragEvent()} method.
20641      *  Both are passed a {@link android.view.DragEvent} object that has a
20642      *  {@link android.view.DragEvent#getAction()} value of
20643      *  {@link android.view.DragEvent#ACTION_DRAG_STARTED}.
20644      * </p>
20645      * <p>
20646      * Your application can invoke {@link #startDragAndDrop(ClipData, DragShadowBuilder, Object,
20647      * int) startDragAndDrop()} on any attached View object. The View object does not need to be
20648      * the one used in {@link android.view.View.DragShadowBuilder}, nor does it need to be related
20649      * to the View the user selected for dragging.
20650      * </p>
20651      * @param data A {@link android.content.ClipData} object pointing to the data to be
20652      * transferred by the drag and drop operation.
20653      * @param shadowBuilder A {@link android.view.View.DragShadowBuilder} object for building the
20654      * drag shadow.
20655      * @param myLocalState An {@link java.lang.Object} containing local data about the drag and
20656      * drop operation. When dispatching drag events to views in the same activity this object
20657      * will be available through {@link android.view.DragEvent#getLocalState()}. Views in other
20658      * activities will not have access to this data ({@link android.view.DragEvent#getLocalState()}
20659      * will return null).
20660      * <p>
20661      * myLocalState is a lightweight mechanism for the sending information from the dragged View
20662      * to the target Views. For example, it can contain flags that differentiate between a
20663      * a copy operation and a move operation.
20664      * </p>
20665      * @param flags Flags that control the drag and drop operation. This can be set to 0 for no
20666      * flags, or any combination of the following:
20667      *     <ul>
20668      *         <li>{@link #DRAG_FLAG_GLOBAL}</li>
20669      *         <li>{@link #DRAG_FLAG_GLOBAL_PERSISTABLE_URI_PERMISSION}</li>
20670      *         <li>{@link #DRAG_FLAG_GLOBAL_PREFIX_URI_PERMISSION}</li>
20671      *         <li>{@link #DRAG_FLAG_GLOBAL_URI_READ}</li>
20672      *         <li>{@link #DRAG_FLAG_GLOBAL_URI_WRITE}</li>
20673      *         <li>{@link #DRAG_FLAG_OPAQUE}</li>
20674      *     </ul>
20675      * @return {@code true} if the method completes successfully, or
20676      * {@code false} if it fails anywhere. Returning {@code false} means the system was unable to
20677      * do a drag, and so no drag operation is in progress.
20678      */
20679     public final boolean startDragAndDrop(ClipData data, DragShadowBuilder shadowBuilder,
20680             Object myLocalState, int flags) {
20681         if (ViewDebug.DEBUG_DRAG) {
20682             Log.d(VIEW_LOG_TAG, "startDragAndDrop: data=" + data + " flags=" + flags);
20683         }
20684         if (mAttachInfo == null) {
20685             Log.w(VIEW_LOG_TAG, "startDragAndDrop called on a detached view.");
20686             return false;
20687         }
20688         boolean okay = false;
20689
20690         Point shadowSize = new Point();
20691         Point shadowTouchPoint = new Point();
20692         shadowBuilder.onProvideShadowMetrics(shadowSize, shadowTouchPoint);
20693
20694         if ((shadowSize.x < 0) || (shadowSize.y < 0) ||
20695                 (shadowTouchPoint.x < 0) || (shadowTouchPoint.y < 0)) {
20696             throw new IllegalStateException("Drag shadow dimensions must not be negative");
20697         }
20698
20699         if (ViewDebug.DEBUG_DRAG) {
20700             Log.d(VIEW_LOG_TAG, "drag shadow: width=" + shadowSize.x + " height=" + shadowSize.y
20701                     + " shadowX=" + shadowTouchPoint.x + " shadowY=" + shadowTouchPoint.y);
20702         }
20703         if (mAttachInfo.mDragSurface != null) {
20704             mAttachInfo.mDragSurface.release();
20705         }
20706         mAttachInfo.mDragSurface = new Surface();
20707         try {
20708             mAttachInfo.mDragToken = mAttachInfo.mSession.prepareDrag(mAttachInfo.mWindow,
20709                     flags, shadowSize.x, shadowSize.y, mAttachInfo.mDragSurface);
20710             if (ViewDebug.DEBUG_DRAG) Log.d(VIEW_LOG_TAG, "prepareDrag returned token="
20711                     + mAttachInfo.mDragToken + " surface=" + mAttachInfo.mDragSurface);
20712             if (mAttachInfo.mDragToken != null) {
20713                 Canvas canvas = mAttachInfo.mDragSurface.lockCanvas(null);
20714                 try {
20715                     canvas.drawColor(0, PorterDuff.Mode.CLEAR);
20716                     shadowBuilder.onDrawShadow(canvas);
20717                 } finally {
20718                     mAttachInfo.mDragSurface.unlockCanvasAndPost(canvas);
20719                 }
20720
20721                 final ViewRootImpl root = getViewRootImpl();
20722
20723                 // Cache the local state object for delivery with DragEvents
20724                 root.setLocalDragState(myLocalState);
20725
20726                 // repurpose 'shadowSize' for the last touch point
20727                 root.getLastTouchPoint(shadowSize);
20728
20729                 okay = mAttachInfo.mSession.performDrag(mAttachInfo.mWindow, mAttachInfo.mDragToken,
20730                         root.getLastTouchSource(), shadowSize.x, shadowSize.y,
20731                         shadowTouchPoint.x, shadowTouchPoint.y, data);
20732                 if (ViewDebug.DEBUG_DRAG) Log.d(VIEW_LOG_TAG, "performDrag returned " + okay);
20733             }
20734         } catch (Exception e) {
20735             Log.e(VIEW_LOG_TAG, "Unable to initiate drag", e);
20736             mAttachInfo.mDragSurface.destroy();
20737             mAttachInfo.mDragSurface = null;
20738         }
20739
20740         return okay;
20741     }
20742
20743     /**
20744      * Cancels an ongoing drag and drop operation.
20745      * <p>
20746      * A {@link android.view.DragEvent} object with
20747      * {@link android.view.DragEvent#getAction()} value of
20748      * {@link android.view.DragEvent#ACTION_DRAG_ENDED} and
20749      * {@link android.view.DragEvent#getResult()} value of {@code false}
20750      * will be sent to every
20751      * View that received {@link android.view.DragEvent#ACTION_DRAG_STARTED}
20752      * even if they are not currently visible.
20753      * </p>
20754      * <p>
20755      * This method can be called on any View in the same window as the View on which
20756      * {@link #startDragAndDrop(ClipData, DragShadowBuilder, Object, int) startDragAndDrop}
20757      * was called.
20758      * </p>
20759      */
20760     public final void cancelDragAndDrop() {
20761         if (ViewDebug.DEBUG_DRAG) {
20762             Log.d(VIEW_LOG_TAG, "cancelDragAndDrop");
20763         }
20764         if (mAttachInfo == null) {
20765             Log.w(VIEW_LOG_TAG, "cancelDragAndDrop called on a detached view.");
20766             return;
20767         }
20768         if (mAttachInfo.mDragToken != null) {
20769             try {
20770                 mAttachInfo.mSession.cancelDragAndDrop(mAttachInfo.mDragToken);
20771             } catch (Exception e) {
20772                 Log.e(VIEW_LOG_TAG, "Unable to cancel drag", e);
20773             }
20774             mAttachInfo.mDragToken = null;
20775         } else {
20776             Log.e(VIEW_LOG_TAG, "No active drag to cancel");
20777         }
20778     }
20779
20780     /**
20781      * Updates the drag shadow for the ongoing drag and drop operation.
20782      *
20783      * @param shadowBuilder A {@link android.view.View.DragShadowBuilder} object for building the
20784      * new drag shadow.
20785      */
20786     public final void updateDragShadow(DragShadowBuilder shadowBuilder) {
20787         if (ViewDebug.DEBUG_DRAG) {
20788             Log.d(VIEW_LOG_TAG, "updateDragShadow");
20789         }
20790         if (mAttachInfo == null) {
20791             Log.w(VIEW_LOG_TAG, "updateDragShadow called on a detached view.");
20792             return;
20793         }
20794         if (mAttachInfo.mDragToken != null) {
20795             try {
20796                 Canvas canvas = mAttachInfo.mDragSurface.lockCanvas(null);
20797                 try {
20798                     canvas.drawColor(0, PorterDuff.Mode.CLEAR);
20799                     shadowBuilder.onDrawShadow(canvas);
20800                 } finally {
20801                     mAttachInfo.mDragSurface.unlockCanvasAndPost(canvas);
20802                 }
20803             } catch (Exception e) {
20804                 Log.e(VIEW_LOG_TAG, "Unable to update drag shadow", e);
20805             }
20806         } else {
20807             Log.e(VIEW_LOG_TAG, "No active drag");
20808         }
20809     }
20810
20811     /**
20812      * Starts a move from {startX, startY}, the amount of the movement will be the offset
20813      * between {startX, startY} and the new cursor positon.
20814      * @param startX horizontal coordinate where the move started.
20815      * @param startY vertical coordinate where the move started.
20816      * @return whether moving was started successfully.
20817      * @hide
20818      */
20819     public final boolean startMovingTask(float startX, float startY) {
20820         if (ViewDebug.DEBUG_POSITIONING) {
20821             Log.d(VIEW_LOG_TAG, "startMovingTask: {" + startX + "," + startY + "}");
20822         }
20823         try {
20824             return mAttachInfo.mSession.startMovingTask(mAttachInfo.mWindow, startX, startY);
20825         } catch (RemoteException e) {
20826             Log.e(VIEW_LOG_TAG, "Unable to start moving", e);
20827         }
20828         return false;
20829     }
20830
20831     /**
20832      * Handles drag events sent by the system following a call to
20833      * {@link android.view.View#startDragAndDrop(ClipData,DragShadowBuilder,Object,int)
20834      * startDragAndDrop()}.
20835      *<p>
20836      * When the system calls this method, it passes a
20837      * {@link android.view.DragEvent} object. A call to
20838      * {@link android.view.DragEvent#getAction()} returns one of the action type constants defined
20839      * in DragEvent. The method uses these to determine what is happening in the drag and drop
20840      * operation.
20841      * @param event The {@link android.view.DragEvent} sent by the system.
20842      * The {@link android.view.DragEvent#getAction()} method returns an action type constant defined
20843      * in DragEvent, indicating the type of drag event represented by this object.
20844      * @return {@code true} if the method was successful, otherwise {@code false}.
20845      * <p>
20846      *  The method should return {@code true} in response to an action type of
20847      *  {@link android.view.DragEvent#ACTION_DRAG_STARTED} to receive drag events for the current
20848      *  operation.
20849      * </p>
20850      * <p>
20851      *  The method should also return {@code true} in response to an action type of
20852      *  {@link android.view.DragEvent#ACTION_DROP} if it consumed the drop, or
20853      *  {@code false} if it didn't.
20854      * </p>
20855      */
20856     public boolean onDragEvent(DragEvent event) {
20857         return false;
20858     }
20859
20860     // Dispatches ACTION_DRAG_ENTERED and ACTION_DRAG_EXITED events for pre-Nougat apps.
20861     boolean dispatchDragEnterExitInPreN(DragEvent event) {
20862         return callDragEventHandler(event);
20863     }
20864
20865     /**
20866      * Detects if this View is enabled and has a drag event listener.
20867      * If both are true, then it calls the drag event listener with the
20868      * {@link android.view.DragEvent} it received. If the drag event listener returns
20869      * {@code true}, then dispatchDragEvent() returns {@code true}.
20870      * <p>
20871      * For all other cases, the method calls the
20872      * {@link android.view.View#onDragEvent(DragEvent) onDragEvent()} drag event handler
20873      * method and returns its result.
20874      * </p>
20875      * <p>
20876      * This ensures that a drag event is always consumed, even if the View does not have a drag
20877      * event listener. However, if the View has a listener and the listener returns true, then
20878      * onDragEvent() is not called.
20879      * </p>
20880      */
20881     public boolean dispatchDragEvent(DragEvent event) {
20882         event.mEventHandlerWasCalled = true;
20883         if (event.mAction == DragEvent.ACTION_DRAG_LOCATION ||
20884             event.mAction == DragEvent.ACTION_DROP) {
20885             // About to deliver an event with coordinates to this view. Notify that now this view
20886             // has drag focus. This will send exit/enter events as needed.
20887             getViewRootImpl().setDragFocus(this, event);
20888         }
20889         return callDragEventHandler(event);
20890     }
20891
20892     final boolean callDragEventHandler(DragEvent event) {
20893         final boolean result;
20894
20895         ListenerInfo li = mListenerInfo;
20896         //noinspection SimplifiableIfStatement
20897         if (li != null && li.mOnDragListener != null && (mViewFlags & ENABLED_MASK) == ENABLED
20898                 && li.mOnDragListener.onDrag(this, event)) {
20899             result = true;
20900         } else {
20901             result = onDragEvent(event);
20902         }
20903
20904         switch (event.mAction) {
20905             case DragEvent.ACTION_DRAG_ENTERED: {
20906                 mPrivateFlags2 |= View.PFLAG2_DRAG_HOVERED;
20907                 refreshDrawableState();
20908             } break;
20909             case DragEvent.ACTION_DRAG_EXITED: {
20910                 mPrivateFlags2 &= ~View.PFLAG2_DRAG_HOVERED;
20911                 refreshDrawableState();
20912             } break;
20913             case DragEvent.ACTION_DRAG_ENDED: {
20914                 mPrivateFlags2 &= ~View.DRAG_MASK;
20915                 refreshDrawableState();
20916             } break;
20917         }
20918
20919         return result;
20920     }
20921
20922     boolean canAcceptDrag() {
20923         return (mPrivateFlags2 & PFLAG2_DRAG_CAN_ACCEPT) != 0;
20924     }
20925
20926     /**
20927      * This needs to be a better API (NOT ON VIEW) before it is exposed.  If
20928      * it is ever exposed at all.
20929      * @hide
20930      */
20931     public void onCloseSystemDialogs(String reason) {
20932     }
20933
20934     /**
20935      * Given a Drawable whose bounds have been set to draw into this view,
20936      * update a Region being computed for
20937      * {@link #gatherTransparentRegion(android.graphics.Region)} so
20938      * that any non-transparent parts of the Drawable are removed from the
20939      * given transparent region.
20940      *
20941      * @param dr The Drawable whose transparency is to be applied to the region.
20942      * @param region A Region holding the current transparency information,
20943      * where any parts of the region that are set are considered to be
20944      * transparent.  On return, this region will be modified to have the
20945      * transparency information reduced by the corresponding parts of the
20946      * Drawable that are not transparent.
20947      * {@hide}
20948      */
20949     public void applyDrawableToTransparentRegion(Drawable dr, Region region) {
20950         if (DBG) {
20951             Log.i("View", "Getting transparent region for: " + this);
20952         }
20953         final Region r = dr.getTransparentRegion();
20954         final Rect db = dr.getBounds();
20955         final AttachInfo attachInfo = mAttachInfo;
20956         if (r != null && attachInfo != null) {
20957             final int w = getRight()-getLeft();
20958             final int h = getBottom()-getTop();
20959             if (db.left > 0) {
20960                 //Log.i("VIEW", "Drawable left " + db.left + " > view 0");
20961                 r.op(0, 0, db.left, h, Region.Op.UNION);
20962             }
20963             if (db.right < w) {
20964                 //Log.i("VIEW", "Drawable right " + db.right + " < view " + w);
20965                 r.op(db.right, 0, w, h, Region.Op.UNION);
20966             }
20967             if (db.top > 0) {
20968                 //Log.i("VIEW", "Drawable top " + db.top + " > view 0");
20969                 r.op(0, 0, w, db.top, Region.Op.UNION);
20970             }
20971             if (db.bottom < h) {
20972                 //Log.i("VIEW", "Drawable bottom " + db.bottom + " < view " + h);
20973                 r.op(0, db.bottom, w, h, Region.Op.UNION);
20974             }
20975             final int[] location = attachInfo.mTransparentLocation;
20976             getLocationInWindow(location);
20977             r.translate(location[0], location[1]);
20978             region.op(r, Region.Op.INTERSECT);
20979         } else {
20980             region.op(db, Region.Op.DIFFERENCE);
20981         }
20982     }
20983
20984     private void checkForLongClick(int delayOffset, float x, float y) {
20985         if ((mViewFlags & LONG_CLICKABLE) == LONG_CLICKABLE) {
20986             mHasPerformedLongPress = false;
20987
20988             if (mPendingCheckForLongPress == null) {
20989                 mPendingCheckForLongPress = new CheckForLongPress();
20990             }
20991             mPendingCheckForLongPress.setAnchor(x, y);
20992             mPendingCheckForLongPress.rememberWindowAttachCount();
20993             postDelayed(mPendingCheckForLongPress,
20994                     ViewConfiguration.getLongPressTimeout() - delayOffset);
20995         }
20996     }
20997
20998     /**
20999      * Inflate a view from an XML resource.  This convenience method wraps the {@link
21000      * LayoutInflater} class, which provides a full range of options for view inflation.
21001      *
21002      * @param context The Context object for your activity or application.
21003      * @param resource The resource ID to inflate
21004      * @param root A view group that will be the parent.  Used to properly inflate the
21005      * layout_* parameters.
21006      * @see LayoutInflater
21007      */
21008     public static View inflate(Context context, @LayoutRes int resource, ViewGroup root) {
21009         LayoutInflater factory = LayoutInflater.from(context);
21010         return factory.inflate(resource, root);
21011     }
21012
21013     /**
21014      * Scroll the view with standard behavior for scrolling beyond the normal
21015      * content boundaries. Views that call this method should override
21016      * {@link #onOverScrolled(int, int, boolean, boolean)} to respond to the
21017      * results of an over-scroll operation.
21018      *
21019      * Views can use this method to handle any touch or fling-based scrolling.
21020      *
21021      * @param deltaX Change in X in pixels
21022      * @param deltaY Change in Y in pixels
21023      * @param scrollX Current X scroll value in pixels before applying deltaX
21024      * @param scrollY Current Y scroll value in pixels before applying deltaY
21025      * @param scrollRangeX Maximum content scroll range along the X axis
21026      * @param scrollRangeY Maximum content scroll range along the Y axis
21027      * @param maxOverScrollX Number of pixels to overscroll by in either direction
21028      *          along the X axis.
21029      * @param maxOverScrollY Number of pixels to overscroll by in either direction
21030      *          along the Y axis.
21031      * @param isTouchEvent true if this scroll operation is the result of a touch event.
21032      * @return true if scrolling was clamped to an over-scroll boundary along either
21033      *          axis, false otherwise.
21034      */
21035     @SuppressWarnings({"UnusedParameters"})
21036     protected boolean overScrollBy(int deltaX, int deltaY,
21037             int scrollX, int scrollY,
21038             int scrollRangeX, int scrollRangeY,
21039             int maxOverScrollX, int maxOverScrollY,
21040             boolean isTouchEvent) {
21041         final int overScrollMode = mOverScrollMode;
21042         final boolean canScrollHorizontal =
21043                 computeHorizontalScrollRange() > computeHorizontalScrollExtent();
21044         final boolean canScrollVertical =
21045                 computeVerticalScrollRange() > computeVerticalScrollExtent();
21046         final boolean overScrollHorizontal = overScrollMode == OVER_SCROLL_ALWAYS ||
21047                 (overScrollMode == OVER_SCROLL_IF_CONTENT_SCROLLS && canScrollHorizontal);
21048         final boolean overScrollVertical = overScrollMode == OVER_SCROLL_ALWAYS ||
21049                 (overScrollMode == OVER_SCROLL_IF_CONTENT_SCROLLS && canScrollVertical);
21050
21051         int newScrollX = scrollX + deltaX;
21052         if (!overScrollHorizontal) {
21053             maxOverScrollX = 0;
21054         }
21055
21056         int newScrollY = scrollY + deltaY;
21057         if (!overScrollVertical) {
21058             maxOverScrollY = 0;
21059         }
21060
21061         // Clamp values if at the limits and record
21062         final int left = -maxOverScrollX;
21063         final int right = maxOverScrollX + scrollRangeX;
21064         final int top = -maxOverScrollY;
21065         final int bottom = maxOverScrollY + scrollRangeY;
21066
21067         boolean clampedX = false;
21068         if (newScrollX > right) {
21069             newScrollX = right;
21070             clampedX = true;
21071         } else if (newScrollX < left) {
21072             newScrollX = left;
21073             clampedX = true;
21074         }
21075
21076         boolean clampedY = false;
21077         if (newScrollY > bottom) {
21078             newScrollY = bottom;
21079             clampedY = true;
21080         } else if (newScrollY < top) {
21081             newScrollY = top;
21082             clampedY = true;
21083         }
21084
21085         onOverScrolled(newScrollX, newScrollY, clampedX, clampedY);
21086
21087         return clampedX || clampedY;
21088     }
21089
21090     /**
21091      * Called by {@link #overScrollBy(int, int, int, int, int, int, int, int, boolean)} to
21092      * respond to the results of an over-scroll operation.
21093      *
21094      * @param scrollX New X scroll value in pixels
21095      * @param scrollY New Y scroll value in pixels
21096      * @param clampedX True if scrollX was clamped to an over-scroll boundary
21097      * @param clampedY True if scrollY was clamped to an over-scroll boundary
21098      */
21099     protected void onOverScrolled(int scrollX, int scrollY,
21100             boolean clampedX, boolean clampedY) {
21101         // Intentionally empty.
21102     }
21103
21104     /**
21105      * Returns the over-scroll mode for this view. The result will be
21106      * one of {@link #OVER_SCROLL_ALWAYS} (default), {@link #OVER_SCROLL_IF_CONTENT_SCROLLS}
21107      * (allow over-scrolling only if the view content is larger than the container),
21108      * or {@link #OVER_SCROLL_NEVER}.
21109      *
21110      * @return This view's over-scroll mode.
21111      */
21112     public int getOverScrollMode() {
21113         return mOverScrollMode;
21114     }
21115
21116     /**
21117      * Set the over-scroll mode for this view. Valid over-scroll modes are
21118      * {@link #OVER_SCROLL_ALWAYS} (default), {@link #OVER_SCROLL_IF_CONTENT_SCROLLS}
21119      * (allow over-scrolling only if the view content is larger than the container),
21120      * or {@link #OVER_SCROLL_NEVER}.
21121      *
21122      * Setting the over-scroll mode of a view will have an effect only if the
21123      * view is capable of scrolling.
21124      *
21125      * @param overScrollMode The new over-scroll mode for this view.
21126      */
21127     public void setOverScrollMode(int overScrollMode) {
21128         if (overScrollMode != OVER_SCROLL_ALWAYS &&
21129                 overScrollMode != OVER_SCROLL_IF_CONTENT_SCROLLS &&
21130                 overScrollMode != OVER_SCROLL_NEVER) {
21131             throw new IllegalArgumentException("Invalid overscroll mode " + overScrollMode);
21132         }
21133         mOverScrollMode = overScrollMode;
21134     }
21135
21136     /**
21137      * Enable or disable nested scrolling for this view.
21138      *
21139      * <p>If this property is set to true the view will be permitted to initiate nested
21140      * scrolling operations with a compatible parent view in the current hierarchy. If this
21141      * view does not implement nested scrolling this will have no effect. Disabling nested scrolling
21142      * while a nested scroll is in progress has the effect of {@link #stopNestedScroll() stopping}
21143      * the nested scroll.</p>
21144      *
21145      * @param enabled true to enable nested scrolling, false to disable
21146      *
21147      * @see #isNestedScrollingEnabled()
21148      */
21149     public void setNestedScrollingEnabled(boolean enabled) {
21150         if (enabled) {
21151             mPrivateFlags3 |= PFLAG3_NESTED_SCROLLING_ENABLED;
21152         } else {
21153             stopNestedScroll();
21154             mPrivateFlags3 &= ~PFLAG3_NESTED_SCROLLING_ENABLED;
21155         }
21156     }
21157
21158     /**
21159      * Returns true if nested scrolling is enabled for this view.
21160      *
21161      * <p>If nested scrolling is enabled and this View class implementation supports it,
21162      * this view will act as a nested scrolling child view when applicable, forwarding data
21163      * about the scroll operation in progress to a compatible and cooperating nested scrolling
21164      * parent.</p>
21165      *
21166      * @return true if nested scrolling is enabled
21167      *
21168      * @see #setNestedScrollingEnabled(boolean)
21169      */
21170     public boolean isNestedScrollingEnabled() {
21171         return (mPrivateFlags3 & PFLAG3_NESTED_SCROLLING_ENABLED) ==
21172                 PFLAG3_NESTED_SCROLLING_ENABLED;
21173     }
21174
21175     /**
21176      * Begin a nestable scroll operation along the given axes.
21177      *
21178      * <p>A view starting a nested scroll promises to abide by the following contract:</p>
21179      *
21180      * <p>The view will call startNestedScroll upon initiating a scroll operation. In the case
21181      * of a touch scroll this corresponds to the initial {@link MotionEvent#ACTION_DOWN}.
21182      * In the case of touch scrolling the nested scroll will be terminated automatically in
21183      * the same manner as {@link ViewParent#requestDisallowInterceptTouchEvent(boolean)}.
21184      * In the event of programmatic scrolling the caller must explicitly call
21185      * {@link #stopNestedScroll()} to indicate the end of the nested scroll.</p>
21186      *
21187      * <p>If <code>startNestedScroll</code> returns true, a cooperative parent was found.
21188      * If it returns false the caller may ignore the rest of this contract until the next scroll.
21189      * Calling startNestedScroll while a nested scroll is already in progress will return true.</p>
21190      *
21191      * <p>At each incremental step of the scroll the caller should invoke
21192      * {@link #dispatchNestedPreScroll(int, int, int[], int[]) dispatchNestedPreScroll}
21193      * once it has calculated the requested scrolling delta. If it returns true the nested scrolling
21194      * parent at least partially consumed the scroll and the caller should adjust the amount it
21195      * scrolls by.</p>
21196      *
21197      * <p>After applying the remainder of the scroll delta the caller should invoke
21198      * {@link #dispatchNestedScroll(int, int, int, int, int[]) dispatchNestedScroll}, passing
21199      * both the delta consumed and the delta unconsumed. A nested scrolling parent may treat
21200      * these values differently. See {@link ViewParent#onNestedScroll(View, int, int, int, int)}.
21201      * </p>
21202      *
21203      * @param axes Flags consisting of a combination of {@link #SCROLL_AXIS_HORIZONTAL} and/or
21204      *             {@link #SCROLL_AXIS_VERTICAL}.
21205      * @return true if a cooperative parent was found and nested scrolling has been enabled for
21206      *         the current gesture.
21207      *
21208      * @see #stopNestedScroll()
21209      * @see #dispatchNestedPreScroll(int, int, int[], int[])
21210      * @see #dispatchNestedScroll(int, int, int, int, int[])
21211      */
21212     public boolean startNestedScroll(int axes) {
21213         if (hasNestedScrollingParent()) {
21214             // Already in progress
21215             return true;
21216         }
21217         if (isNestedScrollingEnabled()) {
21218             ViewParent p = getParent();
21219             View child = this;
21220             while (p != null) {
21221                 try {
21222                     if (p.onStartNestedScroll(child, this, axes)) {
21223                         mNestedScrollingParent = p;
21224                         p.onNestedScrollAccepted(child, this, axes);
21225                         return true;
21226                     }
21227                 } catch (AbstractMethodError e) {
21228                     Log.e(VIEW_LOG_TAG, "ViewParent " + p + " does not implement interface " +
21229                             "method onStartNestedScroll", e);
21230                     // Allow the search upward to continue
21231                 }
21232                 if (p instanceof View) {
21233                     child = (View) p;
21234                 }
21235                 p = p.getParent();
21236             }
21237         }
21238         return false;
21239     }
21240
21241     /**
21242      * Stop a nested scroll in progress.
21243      *
21244      * <p>Calling this method when a nested scroll is not currently in progress is harmless.</p>
21245      *
21246      * @see #startNestedScroll(int)
21247      */
21248     public void stopNestedScroll() {
21249         if (mNestedScrollingParent != null) {
21250             mNestedScrollingParent.onStopNestedScroll(this);
21251             mNestedScrollingParent = null;
21252         }
21253     }
21254
21255     /**
21256      * Returns true if this view has a nested scrolling parent.
21257      *
21258      * <p>The presence of a nested scrolling parent indicates that this view has initiated
21259      * a nested scroll and it was accepted by an ancestor view further up the view hierarchy.</p>
21260      *
21261      * @return whether this view has a nested scrolling parent
21262      */
21263     public boolean hasNestedScrollingParent() {
21264         return mNestedScrollingParent != null;
21265     }
21266
21267     /**
21268      * Dispatch one step of a nested scroll in progress.
21269      *
21270      * <p>Implementations of views that support nested scrolling should call this to report
21271      * info about a scroll in progress to the current nested scrolling parent. If a nested scroll
21272      * is not currently in progress or nested scrolling is not
21273      * {@link #isNestedScrollingEnabled() enabled} for this view this method does nothing.</p>
21274      *
21275      * <p>Compatible View implementations should also call
21276      * {@link #dispatchNestedPreScroll(int, int, int[], int[]) dispatchNestedPreScroll} before
21277      * consuming a component of the scroll event themselves.</p>
21278      *
21279      * @param dxConsumed Horizontal distance in pixels consumed by this view during this scroll step
21280      * @param dyConsumed Vertical distance in pixels consumed by this view during this scroll step
21281      * @param dxUnconsumed Horizontal scroll distance in pixels not consumed by this view
21282      * @param dyUnconsumed Horizontal scroll distance in pixels not consumed by this view
21283      * @param offsetInWindow Optional. If not null, on return this will contain the offset
21284      *                       in local view coordinates of this view from before this operation
21285      *                       to after it completes. View implementations may use this to adjust
21286      *                       expected input coordinate tracking.
21287      * @return true if the event was dispatched, false if it could not be dispatched.
21288      * @see #dispatchNestedPreScroll(int, int, int[], int[])
21289      */
21290     public boolean dispatchNestedScroll(int dxConsumed, int dyConsumed,
21291             int dxUnconsumed, int dyUnconsumed, @Nullable @Size(2) int[] offsetInWindow) {
21292         if (isNestedScrollingEnabled() && mNestedScrollingParent != null) {
21293             if (dxConsumed != 0 || dyConsumed != 0 || dxUnconsumed != 0 || dyUnconsumed != 0) {
21294                 int startX = 0;
21295                 int startY = 0;
21296                 if (offsetInWindow != null) {
21297                     getLocationInWindow(offsetInWindow);
21298                     startX = offsetInWindow[0];
21299                     startY = offsetInWindow[1];
21300                 }
21301
21302                 mNestedScrollingParent.onNestedScroll(this, dxConsumed, dyConsumed,
21303                         dxUnconsumed, dyUnconsumed);
21304
21305                 if (offsetInWindow != null) {
21306                     getLocationInWindow(offsetInWindow);
21307                     offsetInWindow[0] -= startX;
21308                     offsetInWindow[1] -= startY;
21309                 }
21310                 return true;
21311             } else if (offsetInWindow != null) {
21312                 // No motion, no dispatch. Keep offsetInWindow up to date.
21313                 offsetInWindow[0] = 0;
21314                 offsetInWindow[1] = 0;
21315             }
21316         }
21317         return false;
21318     }
21319
21320     /**
21321      * Dispatch one step of a nested scroll in progress before this view consumes any portion of it.
21322      *
21323      * <p>Nested pre-scroll events are to nested scroll events what touch intercept is to touch.
21324      * <code>dispatchNestedPreScroll</code> offers an opportunity for the parent view in a nested
21325      * scrolling operation to consume some or all of the scroll operation before the child view
21326      * consumes it.</p>
21327      *
21328      * @param dx Horizontal scroll distance in pixels
21329      * @param dy Vertical scroll distance in pixels
21330      * @param consumed Output. If not null, consumed[0] will contain the consumed component of dx
21331      *                 and consumed[1] the consumed dy.
21332      * @param offsetInWindow Optional. If not null, on return this will contain the offset
21333      *                       in local view coordinates of this view from before this operation
21334      *                       to after it completes. View implementations may use this to adjust
21335      *                       expected input coordinate tracking.
21336      * @return true if the parent consumed some or all of the scroll delta
21337      * @see #dispatchNestedScroll(int, int, int, int, int[])
21338      */
21339     public boolean dispatchNestedPreScroll(int dx, int dy,
21340             @Nullable @Size(2) int[] consumed, @Nullable @Size(2) int[] offsetInWindow) {
21341         if (isNestedScrollingEnabled() && mNestedScrollingParent != null) {
21342             if (dx != 0 || dy != 0) {
21343                 int startX = 0;
21344                 int startY = 0;
21345                 if (offsetInWindow != null) {
21346                     getLocationInWindow(offsetInWindow);
21347                     startX = offsetInWindow[0];
21348                     startY = offsetInWindow[1];
21349                 }
21350
21351                 if (consumed == null) {
21352                     if (mTempNestedScrollConsumed == null) {
21353                         mTempNestedScrollConsumed = new int[2];
21354                     }
21355                     consumed = mTempNestedScrollConsumed;
21356                 }
21357                 consumed[0] = 0;
21358                 consumed[1] = 0;
21359                 mNestedScrollingParent.onNestedPreScroll(this, dx, dy, consumed);
21360
21361                 if (offsetInWindow != null) {
21362                     getLocationInWindow(offsetInWindow);
21363                     offsetInWindow[0] -= startX;
21364                     offsetInWindow[1] -= startY;
21365                 }
21366                 return consumed[0] != 0 || consumed[1] != 0;
21367             } else if (offsetInWindow != null) {
21368                 offsetInWindow[0] = 0;
21369                 offsetInWindow[1] = 0;
21370             }
21371         }
21372         return false;
21373     }
21374
21375     /**
21376      * Dispatch a fling to a nested scrolling parent.
21377      *
21378      * <p>This method should be used to indicate that a nested scrolling child has detected
21379      * suitable conditions for a fling. Generally this means that a touch scroll has ended with a
21380      * {@link VelocityTracker velocity} in the direction of scrolling that meets or exceeds
21381      * the {@link ViewConfiguration#getScaledMinimumFlingVelocity() minimum fling velocity}
21382      * along a scrollable axis.</p>
21383      *
21384      * <p>If a nested scrolling child view would normally fling but it is at the edge of
21385      * its own content, it can use this method to delegate the fling to its nested scrolling
21386      * parent instead. The parent may optionally consume the fling or observe a child fling.</p>
21387      *
21388      * @param velocityX Horizontal fling velocity in pixels per second
21389      * @param velocityY Vertical fling velocity in pixels per second
21390      * @param consumed true if the child consumed the fling, false otherwise
21391      * @return true if the nested scrolling parent consumed or otherwise reacted to the fling
21392      */
21393     public boolean dispatchNestedFling(float velocityX, float velocityY, boolean consumed) {
21394         if (isNestedScrollingEnabled() && mNestedScrollingParent != null) {
21395             return mNestedScrollingParent.onNestedFling(this, velocityX, velocityY, consumed);
21396         }
21397         return false;
21398     }
21399
21400     /**
21401      * Dispatch a fling to a nested scrolling parent before it is processed by this view.
21402      *
21403      * <p>Nested pre-fling events are to nested fling events what touch intercept is to touch
21404      * and what nested pre-scroll is to nested scroll. <code>dispatchNestedPreFling</code>
21405      * offsets an opportunity for the parent view in a nested fling to fully consume the fling
21406      * before the child view consumes it. If this method returns <code>true</code>, a nested
21407      * parent view consumed the fling and this view should not scroll as a result.</p>
21408      *
21409      * <p>For a better user experience, only one view in a nested scrolling chain should consume
21410      * the fling at a time. If a parent view consumed the fling this method will return false.
21411      * Custom view implementations should account for this in two ways:</p>
21412      *
21413      * <ul>
21414      *     <li>If a custom view is paged and needs to settle to a fixed page-point, do not
21415      *     call <code>dispatchNestedPreFling</code>; consume the fling and settle to a valid
21416      *     position regardless.</li>
21417      *     <li>If a nested parent does consume the fling, this view should not scroll at all,
21418      *     even to settle back to a valid idle position.</li>
21419      * </ul>
21420      *
21421      * <p>Views should also not offer fling velocities to nested parent views along an axis
21422      * where scrolling is not currently supported; a {@link android.widget.ScrollView ScrollView}
21423      * should not offer a horizontal fling velocity to its parents since scrolling along that
21424      * axis is not permitted and carrying velocity along that motion does not make sense.</p>
21425      *
21426      * @param velocityX Horizontal fling velocity in pixels per second
21427      * @param velocityY Vertical fling velocity in pixels per second
21428      * @return true if a nested scrolling parent consumed the fling
21429      */
21430     public boolean dispatchNestedPreFling(float velocityX, float velocityY) {
21431         if (isNestedScrollingEnabled() && mNestedScrollingParent != null) {
21432             return mNestedScrollingParent.onNestedPreFling(this, velocityX, velocityY);
21433         }
21434         return false;
21435     }
21436
21437     /**
21438      * Gets a scale factor that determines the distance the view should scroll
21439      * vertically in response to {@link MotionEvent#ACTION_SCROLL}.
21440      * @return The vertical scroll scale factor.
21441      * @hide
21442      */
21443     protected float getVerticalScrollFactor() {
21444         if (mVerticalScrollFactor == 0) {
21445             TypedValue outValue = new TypedValue();
21446             if (!mContext.getTheme().resolveAttribute(
21447                     com.android.internal.R.attr.listPreferredItemHeight, outValue, true)) {
21448                 throw new IllegalStateException(
21449                         "Expected theme to define listPreferredItemHeight.");
21450             }
21451             mVerticalScrollFactor = outValue.getDimension(
21452                     mContext.getResources().getDisplayMetrics());
21453         }
21454         return mVerticalScrollFactor;
21455     }
21456
21457     /**
21458      * Gets a scale factor that determines the distance the view should scroll
21459      * horizontally in response to {@link MotionEvent#ACTION_SCROLL}.
21460      * @return The horizontal scroll scale factor.
21461      * @hide
21462      */
21463     protected float getHorizontalScrollFactor() {
21464         // TODO: Should use something else.
21465         return getVerticalScrollFactor();
21466     }
21467
21468     /**
21469      * Return the value specifying the text direction or policy that was set with
21470      * {@link #setTextDirection(int)}.
21471      *
21472      * @return the defined text direction. It can be one of:
21473      *
21474      * {@link #TEXT_DIRECTION_INHERIT},
21475      * {@link #TEXT_DIRECTION_FIRST_STRONG},
21476      * {@link #TEXT_DIRECTION_ANY_RTL},
21477      * {@link #TEXT_DIRECTION_LTR},
21478      * {@link #TEXT_DIRECTION_RTL},
21479      * {@link #TEXT_DIRECTION_LOCALE},
21480      * {@link #TEXT_DIRECTION_FIRST_STRONG_LTR},
21481      * {@link #TEXT_DIRECTION_FIRST_STRONG_RTL}
21482      *
21483      * @attr ref android.R.styleable#View_textDirection
21484      *
21485      * @hide
21486      */
21487     @ViewDebug.ExportedProperty(category = "text", mapping = {
21488             @ViewDebug.IntToString(from = TEXT_DIRECTION_INHERIT, to = "INHERIT"),
21489             @ViewDebug.IntToString(from = TEXT_DIRECTION_FIRST_STRONG, to = "FIRST_STRONG"),
21490             @ViewDebug.IntToString(from = TEXT_DIRECTION_ANY_RTL, to = "ANY_RTL"),
21491             @ViewDebug.IntToString(from = TEXT_DIRECTION_LTR, to = "LTR"),
21492             @ViewDebug.IntToString(from = TEXT_DIRECTION_RTL, to = "RTL"),
21493             @ViewDebug.IntToString(from = TEXT_DIRECTION_LOCALE, to = "LOCALE"),
21494             @ViewDebug.IntToString(from = TEXT_DIRECTION_FIRST_STRONG_LTR, to = "FIRST_STRONG_LTR"),
21495             @ViewDebug.IntToString(from = TEXT_DIRECTION_FIRST_STRONG_RTL, to = "FIRST_STRONG_RTL")
21496     })
21497     public int getRawTextDirection() {
21498         return (mPrivateFlags2 & PFLAG2_TEXT_DIRECTION_MASK) >> PFLAG2_TEXT_DIRECTION_MASK_SHIFT;
21499     }
21500
21501     /**
21502      * Set the text direction.
21503      *
21504      * @param textDirection the direction to set. Should be one of:
21505      *
21506      * {@link #TEXT_DIRECTION_INHERIT},
21507      * {@link #TEXT_DIRECTION_FIRST_STRONG},
21508      * {@link #TEXT_DIRECTION_ANY_RTL},
21509      * {@link #TEXT_DIRECTION_LTR},
21510      * {@link #TEXT_DIRECTION_RTL},
21511      * {@link #TEXT_DIRECTION_LOCALE}
21512      * {@link #TEXT_DIRECTION_FIRST_STRONG_LTR},
21513      * {@link #TEXT_DIRECTION_FIRST_STRONG_RTL},
21514      *
21515      * Resolution will be done if the value is set to TEXT_DIRECTION_INHERIT. The resolution
21516      * proceeds up the parent chain of the view to get the value. If there is no parent, then it will
21517      * return the default {@link #TEXT_DIRECTION_FIRST_STRONG}.
21518      *
21519      * @attr ref android.R.styleable#View_textDirection
21520      */
21521     public void setTextDirection(int textDirection) {
21522         if (getRawTextDirection() != textDirection) {
21523             // Reset the current text direction and the resolved one
21524             mPrivateFlags2 &= ~PFLAG2_TEXT_DIRECTION_MASK;
21525             resetResolvedTextDirection();
21526             // Set the new text direction
21527             mPrivateFlags2 |= ((textDirection << PFLAG2_TEXT_DIRECTION_MASK_SHIFT) & PFLAG2_TEXT_DIRECTION_MASK);
21528             // Do resolution
21529             resolveTextDirection();
21530             // Notify change
21531             onRtlPropertiesChanged(getLayoutDirection());
21532             // Refresh
21533             requestLayout();
21534             invalidate(true);
21535         }
21536     }
21537
21538     /**
21539      * Return the resolved text direction.
21540      *
21541      * @return the resolved text direction. Returns one of:
21542      *
21543      * {@link #TEXT_DIRECTION_FIRST_STRONG},
21544      * {@link #TEXT_DIRECTION_ANY_RTL},
21545      * {@link #TEXT_DIRECTION_LTR},
21546      * {@link #TEXT_DIRECTION_RTL},
21547      * {@link #TEXT_DIRECTION_LOCALE},
21548      * {@link #TEXT_DIRECTION_FIRST_STRONG_LTR},
21549      * {@link #TEXT_DIRECTION_FIRST_STRONG_RTL}
21550      *
21551      * @attr ref android.R.styleable#View_textDirection
21552      */
21553     @ViewDebug.ExportedProperty(category = "text", mapping = {
21554             @ViewDebug.IntToString(from = TEXT_DIRECTION_INHERIT, to = "INHERIT"),
21555             @ViewDebug.IntToString(from = TEXT_DIRECTION_FIRST_STRONG, to = "FIRST_STRONG"),
21556             @ViewDebug.IntToString(from = TEXT_DIRECTION_ANY_RTL, to = "ANY_RTL"),
21557             @ViewDebug.IntToString(from = TEXT_DIRECTION_LTR, to = "LTR"),
21558             @ViewDebug.IntToString(from = TEXT_DIRECTION_RTL, to = "RTL"),
21559             @ViewDebug.IntToString(from = TEXT_DIRECTION_LOCALE, to = "LOCALE"),
21560             @ViewDebug.IntToString(from = TEXT_DIRECTION_FIRST_STRONG_LTR, to = "FIRST_STRONG_LTR"),
21561             @ViewDebug.IntToString(from = TEXT_DIRECTION_FIRST_STRONG_RTL, to = "FIRST_STRONG_RTL")
21562     })
21563     public int getTextDirection() {
21564         return (mPrivateFlags2 & PFLAG2_TEXT_DIRECTION_RESOLVED_MASK) >> PFLAG2_TEXT_DIRECTION_RESOLVED_MASK_SHIFT;
21565     }
21566
21567     /**
21568      * Resolve the text direction.
21569      *
21570      * @return true if resolution has been done, false otherwise.
21571      *
21572      * @hide
21573      */
21574     public boolean resolveTextDirection() {
21575         // Reset any previous text direction resolution
21576         mPrivateFlags2 &= ~(PFLAG2_TEXT_DIRECTION_RESOLVED | PFLAG2_TEXT_DIRECTION_RESOLVED_MASK);
21577
21578         if (hasRtlSupport()) {
21579             // Set resolved text direction flag depending on text direction flag
21580             final int textDirection = getRawTextDirection();
21581             switch(textDirection) {
21582                 case TEXT_DIRECTION_INHERIT:
21583                     if (!canResolveTextDirection()) {
21584                         // We cannot do the resolution if there is no parent, so use the default one
21585                         mPrivateFlags2 |= PFLAG2_TEXT_DIRECTION_RESOLVED_DEFAULT;
21586                         // Resolution will need to happen again later
21587                         return false;
21588                     }
21589
21590                     // Parent has not yet resolved, so we still return the default
21591                     try {
21592                         if (!mParent.isTextDirectionResolved()) {
21593                             mPrivateFlags2 |= PFLAG2_TEXT_DIRECTION_RESOLVED_DEFAULT;
21594                             // Resolution will need to happen again later
21595                             return false;
21596                         }
21597                     } catch (AbstractMethodError e) {
21598                         Log.e(VIEW_LOG_TAG, mParent.getClass().getSimpleName() +
21599                                 " does not fully implement ViewParent", e);
21600                         mPrivateFlags2 |= PFLAG2_TEXT_DIRECTION_RESOLVED |
21601                                 PFLAG2_TEXT_DIRECTION_RESOLVED_DEFAULT;
21602                         return true;
21603                     }
21604
21605                     // Set current resolved direction to the same value as the parent's one
21606                     int parentResolvedDirection;
21607                     try {
21608                         parentResolvedDirection = mParent.getTextDirection();
21609                     } catch (AbstractMethodError e) {
21610                         Log.e(VIEW_LOG_TAG, mParent.getClass().getSimpleName() +
21611                                 " does not fully implement ViewParent", e);
21612                         parentResolvedDirection = TEXT_DIRECTION_LTR;
21613                     }
21614                     switch (parentResolvedDirection) {
21615                         case TEXT_DIRECTION_FIRST_STRONG:
21616                         case TEXT_DIRECTION_ANY_RTL:
21617                         case TEXT_DIRECTION_LTR:
21618                         case TEXT_DIRECTION_RTL:
21619                         case TEXT_DIRECTION_LOCALE:
21620                         case TEXT_DIRECTION_FIRST_STRONG_LTR:
21621                         case TEXT_DIRECTION_FIRST_STRONG_RTL:
21622                             mPrivateFlags2 |=
21623                                     (parentResolvedDirection << PFLAG2_TEXT_DIRECTION_RESOLVED_MASK_SHIFT);
21624                             break;
21625                         default:
21626                             // Default resolved direction is "first strong" heuristic
21627                             mPrivateFlags2 |= PFLAG2_TEXT_DIRECTION_RESOLVED_DEFAULT;
21628                     }
21629                     break;
21630                 case TEXT_DIRECTION_FIRST_STRONG:
21631                 case TEXT_DIRECTION_ANY_RTL:
21632                 case TEXT_DIRECTION_LTR:
21633                 case TEXT_DIRECTION_RTL:
21634                 case TEXT_DIRECTION_LOCALE:
21635                 case TEXT_DIRECTION_FIRST_STRONG_LTR:
21636                 case TEXT_DIRECTION_FIRST_STRONG_RTL:
21637                     // Resolved direction is the same as text direction
21638                     mPrivateFlags2 |= (textDirection << PFLAG2_TEXT_DIRECTION_RESOLVED_MASK_SHIFT);
21639                     break;
21640                 default:
21641                     // Default resolved direction is "first strong" heuristic
21642                     mPrivateFlags2 |= PFLAG2_TEXT_DIRECTION_RESOLVED_DEFAULT;
21643             }
21644         } else {
21645             // Default resolved direction is "first strong" heuristic
21646             mPrivateFlags2 |= PFLAG2_TEXT_DIRECTION_RESOLVED_DEFAULT;
21647         }
21648
21649         // Set to resolved
21650         mPrivateFlags2 |= PFLAG2_TEXT_DIRECTION_RESOLVED;
21651         return true;
21652     }
21653
21654     /**
21655      * Check if text direction resolution can be done.
21656      *
21657      * @return true if text direction resolution can be done otherwise return false.
21658      */
21659     public boolean canResolveTextDirection() {
21660         switch (getRawTextDirection()) {
21661             case TEXT_DIRECTION_INHERIT:
21662                 if (mParent != null) {
21663                     try {
21664                         return mParent.canResolveTextDirection();
21665                     } catch (AbstractMethodError e) {
21666                         Log.e(VIEW_LOG_TAG, mParent.getClass().getSimpleName() +
21667                                 " does not fully implement ViewParent", e);
21668                     }
21669                 }
21670                 return false;
21671
21672             default:
21673                 return true;
21674         }
21675     }
21676
21677     /**
21678      * Reset resolved text direction. Text direction will be resolved during a call to
21679      * {@link #onMeasure(int, int)}.
21680      *
21681      * @hide
21682      */
21683     public void resetResolvedTextDirection() {
21684         // Reset any previous text direction resolution
21685         mPrivateFlags2 &= ~(PFLAG2_TEXT_DIRECTION_RESOLVED | PFLAG2_TEXT_DIRECTION_RESOLVED_MASK);
21686         // Set to default value
21687         mPrivateFlags2 |= PFLAG2_TEXT_DIRECTION_RESOLVED_DEFAULT;
21688     }
21689
21690     /**
21691      * @return true if text direction is inherited.
21692      *
21693      * @hide
21694      */
21695     public boolean isTextDirectionInherited() {
21696         return (getRawTextDirection() == TEXT_DIRECTION_INHERIT);
21697     }
21698
21699     /**
21700      * @return true if text direction is resolved.
21701      */
21702     public boolean isTextDirectionResolved() {
21703         return (mPrivateFlags2 & PFLAG2_TEXT_DIRECTION_RESOLVED) == PFLAG2_TEXT_DIRECTION_RESOLVED;
21704     }
21705
21706     /**
21707      * Return the value specifying the text alignment or policy that was set with
21708      * {@link #setTextAlignment(int)}.
21709      *
21710      * @return the defined text alignment. It can be one of:
21711      *
21712      * {@link #TEXT_ALIGNMENT_INHERIT},
21713      * {@link #TEXT_ALIGNMENT_GRAVITY},
21714      * {@link #TEXT_ALIGNMENT_CENTER},
21715      * {@link #TEXT_ALIGNMENT_TEXT_START},
21716      * {@link #TEXT_ALIGNMENT_TEXT_END},
21717      * {@link #TEXT_ALIGNMENT_VIEW_START},
21718      * {@link #TEXT_ALIGNMENT_VIEW_END}
21719      *
21720      * @attr ref android.R.styleable#View_textAlignment
21721      *
21722      * @hide
21723      */
21724     @ViewDebug.ExportedProperty(category = "text", mapping = {
21725             @ViewDebug.IntToString(from = TEXT_ALIGNMENT_INHERIT, to = "INHERIT"),
21726             @ViewDebug.IntToString(from = TEXT_ALIGNMENT_GRAVITY, to = "GRAVITY"),
21727             @ViewDebug.IntToString(from = TEXT_ALIGNMENT_TEXT_START, to = "TEXT_START"),
21728             @ViewDebug.IntToString(from = TEXT_ALIGNMENT_TEXT_END, to = "TEXT_END"),
21729             @ViewDebug.IntToString(from = TEXT_ALIGNMENT_CENTER, to = "CENTER"),
21730             @ViewDebug.IntToString(from = TEXT_ALIGNMENT_VIEW_START, to = "VIEW_START"),
21731             @ViewDebug.IntToString(from = TEXT_ALIGNMENT_VIEW_END, to = "VIEW_END")
21732     })
21733     @TextAlignment
21734     public int getRawTextAlignment() {
21735         return (mPrivateFlags2 & PFLAG2_TEXT_ALIGNMENT_MASK) >> PFLAG2_TEXT_ALIGNMENT_MASK_SHIFT;
21736     }
21737
21738     /**
21739      * Set the text alignment.
21740      *
21741      * @param textAlignment The text alignment to set. Should be one of
21742      *
21743      * {@link #TEXT_ALIGNMENT_INHERIT},
21744      * {@link #TEXT_ALIGNMENT_GRAVITY},
21745      * {@link #TEXT_ALIGNMENT_CENTER},
21746      * {@link #TEXT_ALIGNMENT_TEXT_START},
21747      * {@link #TEXT_ALIGNMENT_TEXT_END},
21748      * {@link #TEXT_ALIGNMENT_VIEW_START},
21749      * {@link #TEXT_ALIGNMENT_VIEW_END}
21750      *
21751      * Resolution will be done if the value is set to TEXT_ALIGNMENT_INHERIT. The resolution
21752      * proceeds up the parent chain of the view to get the value. If there is no parent, then it
21753      * will return the default {@link #TEXT_ALIGNMENT_GRAVITY}.
21754      *
21755      * @attr ref android.R.styleable#View_textAlignment
21756      */
21757     public void setTextAlignment(@TextAlignment int textAlignment) {
21758         if (textAlignment != getRawTextAlignment()) {
21759             // Reset the current and resolved text alignment
21760             mPrivateFlags2 &= ~PFLAG2_TEXT_ALIGNMENT_MASK;
21761             resetResolvedTextAlignment();
21762             // Set the new text alignment
21763             mPrivateFlags2 |=
21764                     ((textAlignment << PFLAG2_TEXT_ALIGNMENT_MASK_SHIFT) & PFLAG2_TEXT_ALIGNMENT_MASK);
21765             // Do resolution
21766             resolveTextAlignment();
21767             // Notify change
21768             onRtlPropertiesChanged(getLayoutDirection());
21769             // Refresh
21770             requestLayout();
21771             invalidate(true);
21772         }
21773     }
21774
21775     /**
21776      * Return the resolved text alignment.
21777      *
21778      * @return the resolved text alignment. Returns one of:
21779      *
21780      * {@link #TEXT_ALIGNMENT_GRAVITY},
21781      * {@link #TEXT_ALIGNMENT_CENTER},
21782      * {@link #TEXT_ALIGNMENT_TEXT_START},
21783      * {@link #TEXT_ALIGNMENT_TEXT_END},
21784      * {@link #TEXT_ALIGNMENT_VIEW_START},
21785      * {@link #TEXT_ALIGNMENT_VIEW_END}
21786      *
21787      * @attr ref android.R.styleable#View_textAlignment
21788      */
21789     @ViewDebug.ExportedProperty(category = "text", mapping = {
21790             @ViewDebug.IntToString(from = TEXT_ALIGNMENT_INHERIT, to = "INHERIT"),
21791             @ViewDebug.IntToString(from = TEXT_ALIGNMENT_GRAVITY, to = "GRAVITY"),
21792             @ViewDebug.IntToString(from = TEXT_ALIGNMENT_TEXT_START, to = "TEXT_START"),
21793             @ViewDebug.IntToString(from = TEXT_ALIGNMENT_TEXT_END, to = "TEXT_END"),
21794             @ViewDebug.IntToString(from = TEXT_ALIGNMENT_CENTER, to = "CENTER"),
21795             @ViewDebug.IntToString(from = TEXT_ALIGNMENT_VIEW_START, to = "VIEW_START"),
21796             @ViewDebug.IntToString(from = TEXT_ALIGNMENT_VIEW_END, to = "VIEW_END")
21797     })
21798     @TextAlignment
21799     public int getTextAlignment() {
21800         return (mPrivateFlags2 & PFLAG2_TEXT_ALIGNMENT_RESOLVED_MASK) >>
21801                 PFLAG2_TEXT_ALIGNMENT_RESOLVED_MASK_SHIFT;
21802     }
21803
21804     /**
21805      * Resolve the text alignment.
21806      *
21807      * @return true if resolution has been done, false otherwise.
21808      *
21809      * @hide
21810      */
21811     public boolean resolveTextAlignment() {
21812         // Reset any previous text alignment resolution
21813         mPrivateFlags2 &= ~(PFLAG2_TEXT_ALIGNMENT_RESOLVED | PFLAG2_TEXT_ALIGNMENT_RESOLVED_MASK);
21814
21815         if (hasRtlSupport()) {
21816             // Set resolved text alignment flag depending on text alignment flag
21817             final int textAlignment = getRawTextAlignment();
21818             switch (textAlignment) {
21819                 case TEXT_ALIGNMENT_INHERIT:
21820                     // Check if we can resolve the text alignment
21821                     if (!canResolveTextAlignment()) {
21822                         // We cannot do the resolution if there is no parent so use the default
21823                         mPrivateFlags2 |= PFLAG2_TEXT_ALIGNMENT_RESOLVED_DEFAULT;
21824                         // Resolution will need to happen again later
21825                         return false;
21826                     }
21827
21828                     // Parent has not yet resolved, so we still return the default
21829                     try {
21830                         if (!mParent.isTextAlignmentResolved()) {
21831                             mPrivateFlags2 |= PFLAG2_TEXT_ALIGNMENT_RESOLVED_DEFAULT;
21832                             // Resolution will need to happen again later
21833                             return false;
21834                         }
21835                     } catch (AbstractMethodError e) {
21836                         Log.e(VIEW_LOG_TAG, mParent.getClass().getSimpleName() +
21837                                 " does not fully implement ViewParent", e);
21838                         mPrivateFlags2 |= PFLAG2_TEXT_ALIGNMENT_RESOLVED |
21839                                 PFLAG2_TEXT_ALIGNMENT_RESOLVED_DEFAULT;
21840                         return true;
21841                     }
21842
21843                     int parentResolvedTextAlignment;
21844                     try {
21845                         parentResolvedTextAlignment = mParent.getTextAlignment();
21846                     } catch (AbstractMethodError e) {
21847                         Log.e(VIEW_LOG_TAG, mParent.getClass().getSimpleName() +
21848                                 " does not fully implement ViewParent", e);
21849                         parentResolvedTextAlignment = TEXT_ALIGNMENT_GRAVITY;
21850                     }
21851                     switch (parentResolvedTextAlignment) {
21852                         case TEXT_ALIGNMENT_GRAVITY:
21853                         case TEXT_ALIGNMENT_TEXT_START:
21854                         case TEXT_ALIGNMENT_TEXT_END:
21855                         case TEXT_ALIGNMENT_CENTER:
21856                         case TEXT_ALIGNMENT_VIEW_START:
21857                         case TEXT_ALIGNMENT_VIEW_END:
21858                             // Resolved text alignment is the same as the parent resolved
21859                             // text alignment
21860                             mPrivateFlags2 |=
21861                                     (parentResolvedTextAlignment << PFLAG2_TEXT_ALIGNMENT_RESOLVED_MASK_SHIFT);
21862                             break;
21863                         default:
21864                             // Use default resolved text alignment
21865                             mPrivateFlags2 |= PFLAG2_TEXT_ALIGNMENT_RESOLVED_DEFAULT;
21866                     }
21867                     break;
21868                 case TEXT_ALIGNMENT_GRAVITY:
21869                 case TEXT_ALIGNMENT_TEXT_START:
21870                 case TEXT_ALIGNMENT_TEXT_END:
21871                 case TEXT_ALIGNMENT_CENTER:
21872                 case TEXT_ALIGNMENT_VIEW_START:
21873                 case TEXT_ALIGNMENT_VIEW_END:
21874                     // Resolved text alignment is the same as text alignment
21875                     mPrivateFlags2 |= (textAlignment << PFLAG2_TEXT_ALIGNMENT_RESOLVED_MASK_SHIFT);
21876                     break;
21877                 default:
21878                     // Use default resolved text alignment
21879                     mPrivateFlags2 |= PFLAG2_TEXT_ALIGNMENT_RESOLVED_DEFAULT;
21880             }
21881         } else {
21882             // Use default resolved text alignment
21883             mPrivateFlags2 |= PFLAG2_TEXT_ALIGNMENT_RESOLVED_DEFAULT;
21884         }
21885
21886         // Set the resolved
21887         mPrivateFlags2 |= PFLAG2_TEXT_ALIGNMENT_RESOLVED;
21888         return true;
21889     }
21890
21891     /**
21892      * Check if text alignment resolution can be done.
21893      *
21894      * @return true if text alignment resolution can be done otherwise return false.
21895      */
21896     public boolean canResolveTextAlignment() {
21897         switch (getRawTextAlignment()) {
21898             case TEXT_DIRECTION_INHERIT:
21899                 if (mParent != null) {
21900                     try {
21901                         return mParent.canResolveTextAlignment();
21902                     } catch (AbstractMethodError e) {
21903                         Log.e(VIEW_LOG_TAG, mParent.getClass().getSimpleName() +
21904                                 " does not fully implement ViewParent", e);
21905                     }
21906                 }
21907                 return false;
21908
21909             default:
21910                 return true;
21911         }
21912     }
21913
21914     /**
21915      * Reset resolved text alignment. Text alignment will be resolved during a call to
21916      * {@link #onMeasure(int, int)}.
21917      *
21918      * @hide
21919      */
21920     public void resetResolvedTextAlignment() {
21921         // Reset any previous text alignment resolution
21922         mPrivateFlags2 &= ~(PFLAG2_TEXT_ALIGNMENT_RESOLVED | PFLAG2_TEXT_ALIGNMENT_RESOLVED_MASK);
21923         // Set to default
21924         mPrivateFlags2 |= PFLAG2_TEXT_ALIGNMENT_RESOLVED_DEFAULT;
21925     }
21926
21927     /**
21928      * @return true if text alignment is inherited.
21929      *
21930      * @hide
21931      */
21932     public boolean isTextAlignmentInherited() {
21933         return (getRawTextAlignment() == TEXT_ALIGNMENT_INHERIT);
21934     }
21935
21936     /**
21937      * @return true if text alignment is resolved.
21938      */
21939     public boolean isTextAlignmentResolved() {
21940         return (mPrivateFlags2 & PFLAG2_TEXT_ALIGNMENT_RESOLVED) == PFLAG2_TEXT_ALIGNMENT_RESOLVED;
21941     }
21942
21943     /**
21944      * Generate a value suitable for use in {@link #setId(int)}.
21945      * This value will not collide with ID values generated at build time by aapt for R.id.
21946      *
21947      * @return a generated ID value
21948      */
21949     public static int generateViewId() {
21950         for (;;) {
21951             final int result = sNextGeneratedId.get();
21952             // aapt-generated IDs have the high byte nonzero; clamp to the range under that.
21953             int newValue = result + 1;
21954             if (newValue > 0x00FFFFFF) newValue = 1; // Roll over to 1, not 0.
21955             if (sNextGeneratedId.compareAndSet(result, newValue)) {
21956                 return result;
21957             }
21958         }
21959     }
21960
21961     /**
21962      * Gets the Views in the hierarchy affected by entering and exiting Activity Scene transitions.
21963      * @param transitioningViews This View will be added to transitioningViews if it is VISIBLE and
21964      *                           a normal View or a ViewGroup with
21965      *                           {@link android.view.ViewGroup#isTransitionGroup()} true.
21966      * @hide
21967      */
21968     public void captureTransitioningViews(List<View> transitioningViews) {
21969         if (getVisibility() == View.VISIBLE) {
21970             transitioningViews.add(this);
21971         }
21972     }
21973
21974     /**
21975      * Adds all Views that have {@link #getTransitionName()} non-null to namedElements.
21976      * @param namedElements Will contain all Views in the hierarchy having a transitionName.
21977      * @hide
21978      */
21979     public void findNamedViews(Map<String, View> namedElements) {
21980         if (getVisibility() == VISIBLE || mGhostView != null) {
21981             String transitionName = getTransitionName();
21982             if (transitionName != null) {
21983                 namedElements.put(transitionName, this);
21984             }
21985         }
21986     }
21987
21988     /**
21989      * Returns the pointer icon for the motion event, or null if it doesn't specify the icon.
21990      * The default implementation does not care the location or event types, but some subclasses
21991      * may use it (such as WebViews).
21992      * @param event The MotionEvent from a mouse
21993      * @param pointerIndex The index of the pointer for which to retrieve the {@link PointerIcon}.
21994      *                     This will be between 0 and {@link MotionEvent#getPointerCount()}.
21995      * @see PointerIcon
21996      */
21997     public PointerIcon onResolvePointerIcon(MotionEvent event, int pointerIndex) {
21998         final float x = event.getX(pointerIndex);
21999         final float y = event.getY(pointerIndex);
22000         if (isDraggingScrollBar() || isOnScrollbarThumb(x, y)) {
22001             return PointerIcon.getSystemIcon(mContext, PointerIcon.TYPE_ARROW);
22002         }
22003         return mPointerIcon;
22004     }
22005
22006     /**
22007      * Set the pointer icon for the current view.
22008      * Passing {@code null} will restore the pointer icon to its default value.
22009      * @param pointerIcon A PointerIcon instance which will be shown when the mouse hovers.
22010      */
22011     public void setPointerIcon(PointerIcon pointerIcon) {
22012         mPointerIcon = pointerIcon;
22013         if (mAttachInfo == null || mAttachInfo.mHandlingPointerEvent) {
22014             return;
22015         }
22016         try {
22017             mAttachInfo.mSession.updatePointerIcon(mAttachInfo.mWindow);
22018         } catch (RemoteException e) {
22019         }
22020     }
22021
22022     /**
22023      * Gets the pointer icon for the current view.
22024      */
22025     public PointerIcon getPointerIcon() {
22026         return mPointerIcon;
22027     }
22028
22029     //
22030     // Properties
22031     //
22032     /**
22033      * A Property wrapper around the <code>alpha</code> functionality handled by the
22034      * {@link View#setAlpha(float)} and {@link View#getAlpha()} methods.
22035      */
22036     public static final Property<View, Float> ALPHA = new FloatProperty<View>("alpha") {
22037         @Override
22038         public void setValue(View object, float value) {
22039             object.setAlpha(value);
22040         }
22041
22042         @Override
22043         public Float get(View object) {
22044             return object.getAlpha();
22045         }
22046     };
22047
22048     /**
22049      * A Property wrapper around the <code>translationX</code> functionality handled by the
22050      * {@link View#setTranslationX(float)} and {@link View#getTranslationX()} methods.
22051      */
22052     public static final Property<View, Float> TRANSLATION_X = new FloatProperty<View>("translationX") {
22053         @Override
22054         public void setValue(View object, float value) {
22055             object.setTranslationX(value);
22056         }
22057
22058                 @Override
22059         public Float get(View object) {
22060             return object.getTranslationX();
22061         }
22062     };
22063
22064     /**
22065      * A Property wrapper around the <code>translationY</code> functionality handled by the
22066      * {@link View#setTranslationY(float)} and {@link View#getTranslationY()} methods.
22067      */
22068     public static final Property<View, Float> TRANSLATION_Y = new FloatProperty<View>("translationY") {
22069         @Override
22070         public void setValue(View object, float value) {
22071             object.setTranslationY(value);
22072         }
22073
22074         @Override
22075         public Float get(View object) {
22076             return object.getTranslationY();
22077         }
22078     };
22079
22080     /**
22081      * A Property wrapper around the <code>translationZ</code> functionality handled by the
22082      * {@link View#setTranslationZ(float)} and {@link View#getTranslationZ()} methods.
22083      */
22084     public static final Property<View, Float> TRANSLATION_Z = new FloatProperty<View>("translationZ") {
22085         @Override
22086         public void setValue(View object, float value) {
22087             object.setTranslationZ(value);
22088         }
22089
22090         @Override
22091         public Float get(View object) {
22092             return object.getTranslationZ();
22093         }
22094     };
22095
22096     /**
22097      * A Property wrapper around the <code>x</code> functionality handled by the
22098      * {@link View#setX(float)} and {@link View#getX()} methods.
22099      */
22100     public static final Property<View, Float> X = new FloatProperty<View>("x") {
22101         @Override
22102         public void setValue(View object, float value) {
22103             object.setX(value);
22104         }
22105
22106         @Override
22107         public Float get(View object) {
22108             return object.getX();
22109         }
22110     };
22111
22112     /**
22113      * A Property wrapper around the <code>y</code> functionality handled by the
22114      * {@link View#setY(float)} and {@link View#getY()} methods.
22115      */
22116     public static final Property<View, Float> Y = new FloatProperty<View>("y") {
22117         @Override
22118         public void setValue(View object, float value) {
22119             object.setY(value);
22120         }
22121
22122         @Override
22123         public Float get(View object) {
22124             return object.getY();
22125         }
22126     };
22127
22128     /**
22129      * A Property wrapper around the <code>z</code> functionality handled by the
22130      * {@link View#setZ(float)} and {@link View#getZ()} methods.
22131      */
22132     public static final Property<View, Float> Z = new FloatProperty<View>("z") {
22133         @Override
22134         public void setValue(View object, float value) {
22135             object.setZ(value);
22136         }
22137
22138         @Override
22139         public Float get(View object) {
22140             return object.getZ();
22141         }
22142     };
22143
22144     /**
22145      * A Property wrapper around the <code>rotation</code> functionality handled by the
22146      * {@link View#setRotation(float)} and {@link View#getRotation()} methods.
22147      */
22148     public static final Property<View, Float> ROTATION = new FloatProperty<View>("rotation") {
22149         @Override
22150         public void setValue(View object, float value) {
22151             object.setRotation(value);
22152         }
22153
22154         @Override
22155         public Float get(View object) {
22156             return object.getRotation();
22157         }
22158     };
22159
22160     /**
22161      * A Property wrapper around the <code>rotationX</code> functionality handled by the
22162      * {@link View#setRotationX(float)} and {@link View#getRotationX()} methods.
22163      */
22164     public static final Property<View, Float> ROTATION_X = new FloatProperty<View>("rotationX") {
22165         @Override
22166         public void setValue(View object, float value) {
22167             object.setRotationX(value);
22168         }
22169
22170         @Override
22171         public Float get(View object) {
22172             return object.getRotationX();
22173         }
22174     };
22175
22176     /**
22177      * A Property wrapper around the <code>rotationY</code> functionality handled by the
22178      * {@link View#setRotationY(float)} and {@link View#getRotationY()} methods.
22179      */
22180     public static final Property<View, Float> ROTATION_Y = new FloatProperty<View>("rotationY") {
22181         @Override
22182         public void setValue(View object, float value) {
22183             object.setRotationY(value);
22184         }
22185
22186         @Override
22187         public Float get(View object) {
22188             return object.getRotationY();
22189         }
22190     };
22191
22192     /**
22193      * A Property wrapper around the <code>scaleX</code> functionality handled by the
22194      * {@link View#setScaleX(float)} and {@link View#getScaleX()} methods.
22195      */
22196     public static final Property<View, Float> SCALE_X = new FloatProperty<View>("scaleX") {
22197         @Override
22198         public void setValue(View object, float value) {
22199             object.setScaleX(value);
22200         }
22201
22202         @Override
22203         public Float get(View object) {
22204             return object.getScaleX();
22205         }
22206     };
22207
22208     /**
22209      * A Property wrapper around the <code>scaleY</code> functionality handled by the
22210      * {@link View#setScaleY(float)} and {@link View#getScaleY()} methods.
22211      */
22212     public static final Property<View, Float> SCALE_Y = new FloatProperty<View>("scaleY") {
22213         @Override
22214         public void setValue(View object, float value) {
22215             object.setScaleY(value);
22216         }
22217
22218         @Override
22219         public Float get(View object) {
22220             return object.getScaleY();
22221         }
22222     };
22223
22224     /**
22225      * A MeasureSpec encapsulates the layout requirements passed from parent to child.
22226      * Each MeasureSpec represents a requirement for either the width or the height.
22227      * A MeasureSpec is comprised of a size and a mode. There are three possible
22228      * modes:
22229      * <dl>
22230      * <dt>UNSPECIFIED</dt>
22231      * <dd>
22232      * The parent has not imposed any constraint on the child. It can be whatever size
22233      * it wants.
22234      * </dd>
22235      *
22236      * <dt>EXACTLY</dt>
22237      * <dd>
22238      * The parent has determined an exact size for the child. The child is going to be
22239      * given those bounds regardless of how big it wants to be.
22240      * </dd>
22241      *
22242      * <dt>AT_MOST</dt>
22243      * <dd>
22244      * The child can be as large as it wants up to the specified size.
22245      * </dd>
22246      * </dl>
22247      *
22248      * MeasureSpecs are implemented as ints to reduce object allocation. This class
22249      * is provided to pack and unpack the &lt;size, mode&gt; tuple into the int.
22250      */
22251     public static class MeasureSpec {
22252         private static final int MODE_SHIFT = 30;
22253         private static final int MODE_MASK  = 0x3 << MODE_SHIFT;
22254
22255         /** @hide */
22256         @IntDef({UNSPECIFIED, EXACTLY, AT_MOST})
22257         @Retention(RetentionPolicy.SOURCE)
22258         public @interface MeasureSpecMode {}
22259
22260         /**
22261          * Measure specification mode: The parent has not imposed any constraint
22262          * on the child. It can be whatever size it wants.
22263          */
22264         public static final int UNSPECIFIED = 0 << MODE_SHIFT;
22265
22266         /**
22267          * Measure specification mode: The parent has determined an exact size
22268          * for the child. The child is going to be given those bounds regardless
22269          * of how big it wants to be.
22270          */
22271         public static final int EXACTLY     = 1 << MODE_SHIFT;
22272
22273         /**
22274          * Measure specification mode: The child can be as large as it wants up
22275          * to the specified size.
22276          */
22277         public static final int AT_MOST     = 2 << MODE_SHIFT;
22278
22279         /**
22280          * Creates a measure specification based on the supplied size and mode.
22281          *
22282          * The mode must always be one of the following:
22283          * <ul>
22284          *  <li>{@link android.view.View.MeasureSpec#UNSPECIFIED}</li>
22285          *  <li>{@link android.view.View.MeasureSpec#EXACTLY}</li>
22286          *  <li>{@link android.view.View.MeasureSpec#AT_MOST}</li>
22287          * </ul>
22288          *
22289          * <p><strong>Note:</strong> On API level 17 and lower, makeMeasureSpec's
22290          * implementation was such that the order of arguments did not matter
22291          * and overflow in either value could impact the resulting MeasureSpec.
22292          * {@link android.widget.RelativeLayout} was affected by this bug.
22293          * Apps targeting API levels greater than 17 will get the fixed, more strict
22294          * behavior.</p>
22295          *
22296          * @param size the size of the measure specification
22297          * @param mode the mode of the measure specification
22298          * @return the measure specification based on size and mode
22299          */
22300         public static int makeMeasureSpec(@IntRange(from = 0, to = (1 << MeasureSpec.MODE_SHIFT) - 1) int size,
22301                                           @MeasureSpecMode int mode) {
22302             if (sUseBrokenMakeMeasureSpec) {
22303                 return size + mode;
22304             } else {
22305                 return (size & ~MODE_MASK) | (mode & MODE_MASK);
22306             }
22307         }
22308
22309         /**
22310          * Like {@link #makeMeasureSpec(int, int)}, but any spec with a mode of UNSPECIFIED
22311          * will automatically get a size of 0. Older apps expect this.
22312          *
22313          * @hide internal use only for compatibility with system widgets and older apps
22314          */
22315         public static int makeSafeMeasureSpec(int size, int mode) {
22316             if (sUseZeroUnspecifiedMeasureSpec && mode == UNSPECIFIED) {
22317                 return 0;
22318             }
22319             return makeMeasureSpec(size, mode);
22320         }
22321
22322         /**
22323          * Extracts the mode from the supplied measure specification.
22324          *
22325          * @param measureSpec the measure specification to extract the mode from
22326          * @return {@link android.view.View.MeasureSpec#UNSPECIFIED},
22327          *         {@link android.view.View.MeasureSpec#AT_MOST} or
22328          *         {@link android.view.View.MeasureSpec#EXACTLY}
22329          */
22330         @MeasureSpecMode
22331         public static int getMode(int measureSpec) {
22332             //noinspection ResourceType
22333             return (measureSpec & MODE_MASK);
22334         }
22335
22336         /**
22337          * Extracts the size from the supplied measure specification.
22338          *
22339          * @param measureSpec the measure specification to extract the size from
22340          * @return the size in pixels defined in the supplied measure specification
22341          */
22342         public static int getSize(int measureSpec) {
22343             return (measureSpec & ~MODE_MASK);
22344         }
22345
22346         static int adjust(int measureSpec, int delta) {
22347             final int mode = getMode(measureSpec);
22348             int size = getSize(measureSpec);
22349             if (mode == UNSPECIFIED) {
22350                 // No need to adjust size for UNSPECIFIED mode.
22351                 return makeMeasureSpec(size, UNSPECIFIED);
22352             }
22353             size += delta;
22354             if (size < 0) {
22355                 Log.e(VIEW_LOG_TAG, "MeasureSpec.adjust: new size would be negative! (" + size +
22356                         ") spec: " + toString(measureSpec) + " delta: " + delta);
22357                 size = 0;
22358             }
22359             return makeMeasureSpec(size, mode);
22360         }
22361
22362         /**
22363          * Returns a String representation of the specified measure
22364          * specification.
22365          *
22366          * @param measureSpec the measure specification to convert to a String
22367          * @return a String with the following format: "MeasureSpec: MODE SIZE"
22368          */
22369         public static String toString(int measureSpec) {
22370             int mode = getMode(measureSpec);
22371             int size = getSize(measureSpec);
22372
22373             StringBuilder sb = new StringBuilder("MeasureSpec: ");
22374
22375             if (mode == UNSPECIFIED)
22376                 sb.append("UNSPECIFIED ");
22377             else if (mode == EXACTLY)
22378                 sb.append("EXACTLY ");
22379             else if (mode == AT_MOST)
22380                 sb.append("AT_MOST ");
22381             else
22382                 sb.append(mode).append(" ");
22383
22384             sb.append(size);
22385             return sb.toString();
22386         }
22387     }
22388
22389     private final class CheckForLongPress implements Runnable {
22390         private int mOriginalWindowAttachCount;
22391         private float mX;
22392         private float mY;
22393
22394         @Override
22395         public void run() {
22396             if (isPressed() && (mParent != null)
22397                     && mOriginalWindowAttachCount == mWindowAttachCount) {
22398                 if (performLongClick(mX, mY)) {
22399                     mHasPerformedLongPress = true;
22400                 }
22401             }
22402         }
22403
22404         public void setAnchor(float x, float y) {
22405             mX = x;
22406             mY = y;
22407         }
22408
22409         public void rememberWindowAttachCount() {
22410             mOriginalWindowAttachCount = mWindowAttachCount;
22411         }
22412     }
22413
22414     private final class CheckForTap implements Runnable {
22415         public float x;
22416         public float y;
22417
22418         @Override
22419         public void run() {
22420             mPrivateFlags &= ~PFLAG_PREPRESSED;
22421             setPressed(true, x, y);
22422             checkForLongClick(ViewConfiguration.getTapTimeout(), x, y);
22423         }
22424     }
22425
22426     private final class PerformClick implements Runnable {
22427         @Override
22428         public void run() {
22429             performClick();
22430         }
22431     }
22432
22433     /**
22434      * This method returns a ViewPropertyAnimator object, which can be used to animate
22435      * specific properties on this View.
22436      *
22437      * @return ViewPropertyAnimator The ViewPropertyAnimator associated with this View.
22438      */
22439     public ViewPropertyAnimator animate() {
22440         if (mAnimator == null) {
22441             mAnimator = new ViewPropertyAnimator(this);
22442         }
22443         return mAnimator;
22444     }
22445
22446     /**
22447      * Sets the name of the View to be used to identify Views in Transitions.
22448      * Names should be unique in the View hierarchy.
22449      *
22450      * @param transitionName The name of the View to uniquely identify it for Transitions.
22451      */
22452     public final void setTransitionName(String transitionName) {
22453         mTransitionName = transitionName;
22454     }
22455
22456     /**
22457      * Returns the name of the View to be used to identify Views in Transitions.
22458      * Names should be unique in the View hierarchy.
22459      *
22460      * <p>This returns null if the View has not been given a name.</p>
22461      *
22462      * @return The name used of the View to be used to identify Views in Transitions or null
22463      * if no name has been given.
22464      */
22465     @ViewDebug.ExportedProperty
22466     public String getTransitionName() {
22467         return mTransitionName;
22468     }
22469
22470     /**
22471      * @hide
22472      */
22473     public void requestKeyboardShortcuts(List<KeyboardShortcutGroup> data, int deviceId) {
22474         // Do nothing.
22475     }
22476
22477     /**
22478      * Interface definition for a callback to be invoked when a hardware key event is
22479      * dispatched to this view. The callback will be invoked before the key event is
22480      * given to the view. This is only useful for hardware keyboards; a software input
22481      * method has no obligation to trigger this listener.
22482      */
22483     public interface OnKeyListener {
22484         /**
22485          * Called when a hardware key is dispatched to a view. This allows listeners to
22486          * get a chance to respond before the target view.
22487          * <p>Key presses in software keyboards will generally NOT trigger this method,
22488          * although some may elect to do so in some situations. Do not assume a
22489          * software input method has to be key-based; even if it is, it may use key presses
22490          * in a different way than you expect, so there is no way to reliably catch soft
22491          * input key presses.
22492          *
22493          * @param v The view the key has been dispatched to.
22494          * @param keyCode The code for the physical key that was pressed
22495          * @param event The KeyEvent object containing full information about
22496          *        the event.
22497          * @return True if the listener has consumed the event, false otherwise.
22498          */
22499         boolean onKey(View v, int keyCode, KeyEvent event);
22500     }
22501
22502     /**
22503      * Interface definition for a callback to be invoked when a touch event is
22504      * dispatched to this view. The callback will be invoked before the touch
22505      * event is given to the view.
22506      */
22507     public interface OnTouchListener {
22508         /**
22509          * Called when a touch event is dispatched to a view. This allows listeners to
22510          * get a chance to respond before the target view.
22511          *
22512          * @param v The view the touch event has been dispatched to.
22513          * @param event The MotionEvent object containing full information about
22514          *        the event.
22515          * @return True if the listener has consumed the event, false otherwise.
22516          */
22517         boolean onTouch(View v, MotionEvent event);
22518     }
22519
22520     /**
22521      * Interface definition for a callback to be invoked when a hover event is
22522      * dispatched to this view. The callback will be invoked before the hover
22523      * event is given to the view.
22524      */
22525     public interface OnHoverListener {
22526         /**
22527          * Called when a hover event is dispatched to a view. This allows listeners to
22528          * get a chance to respond before the target view.
22529          *
22530          * @param v The view the hover event has been dispatched to.
22531          * @param event The MotionEvent object containing full information about
22532          *        the event.
22533          * @return True if the listener has consumed the event, false otherwise.
22534          */
22535         boolean onHover(View v, MotionEvent event);
22536     }
22537
22538     /**
22539      * Interface definition for a callback to be invoked when a generic motion event is
22540      * dispatched to this view. The callback will be invoked before the generic motion
22541      * event is given to the view.
22542      */
22543     public interface OnGenericMotionListener {
22544         /**
22545          * Called when a generic motion event is dispatched to a view. This allows listeners to
22546          * get a chance to respond before the target view.
22547          *
22548          * @param v The view the generic motion event has been dispatched to.
22549          * @param event The MotionEvent object containing full information about
22550          *        the event.
22551          * @return True if the listener has consumed the event, false otherwise.
22552          */
22553         boolean onGenericMotion(View v, MotionEvent event);
22554     }
22555
22556     /**
22557      * Interface definition for a callback to be invoked when a view has been clicked and held.
22558      */
22559     public interface OnLongClickListener {
22560         /**
22561          * Called when a view has been clicked and held.
22562          *
22563          * @param v The view that was clicked and held.
22564          *
22565          * @return true if the callback consumed the long click, false otherwise.
22566          */
22567         boolean onLongClick(View v);
22568     }
22569
22570     /**
22571      * Interface definition for a callback to be invoked when a drag is being dispatched
22572      * to this view.  The callback will be invoked before the hosting view's own
22573      * onDrag(event) method.  If the listener wants to fall back to the hosting view's
22574      * onDrag(event) behavior, it should return 'false' from this callback.
22575      *
22576      * <div class="special reference">
22577      * <h3>Developer Guides</h3>
22578      * <p>For a guide to implementing drag and drop features, read the
22579      * <a href="{@docRoot}guide/topics/ui/drag-drop.html">Drag and Drop</a> developer guide.</p>
22580      * </div>
22581      */
22582     public interface OnDragListener {
22583         /**
22584          * Called when a drag event is dispatched to a view. This allows listeners
22585          * to get a chance to override base View behavior.
22586          *
22587          * @param v The View that received the drag event.
22588          * @param event The {@link android.view.DragEvent} object for the drag event.
22589          * @return {@code true} if the drag event was handled successfully, or {@code false}
22590          * if the drag event was not handled. Note that {@code false} will trigger the View
22591          * to call its {@link #onDragEvent(DragEvent) onDragEvent()} handler.
22592          */
22593         boolean onDrag(View v, DragEvent event);
22594     }
22595
22596     /**
22597      * Interface definition for a callback to be invoked when the focus state of
22598      * a view changed.
22599      */
22600     public interface OnFocusChangeListener {
22601         /**
22602          * Called when the focus state of a view has changed.
22603          *
22604          * @param v The view whose state has changed.
22605          * @param hasFocus The new focus state of v.
22606          */
22607         void onFocusChange(View v, boolean hasFocus);
22608     }
22609
22610     /**
22611      * Interface definition for a callback to be invoked when a view is clicked.
22612      */
22613     public interface OnClickListener {
22614         /**
22615          * Called when a view has been clicked.
22616          *
22617          * @param v The view that was clicked.
22618          */
22619         void onClick(View v);
22620     }
22621
22622     /**
22623      * Interface definition for a callback to be invoked when a view is context clicked.
22624      */
22625     public interface OnContextClickListener {
22626         /**
22627          * Called when a view is context clicked.
22628          *
22629          * @param v The view that has been context clicked.
22630          * @return true if the callback consumed the context click, false otherwise.
22631          */
22632         boolean onContextClick(View v);
22633     }
22634
22635     /**
22636      * Interface definition for a callback to be invoked when the context menu
22637      * for this view is being built.
22638      */
22639     public interface OnCreateContextMenuListener {
22640         /**
22641          * Called when the context menu for this view is being built. It is not
22642          * safe to hold onto the menu after this method returns.
22643          *
22644          * @param menu The context menu that is being built
22645          * @param v The view for which the context menu is being built
22646          * @param menuInfo Extra information about the item for which the
22647          *            context menu should be shown. This information will vary
22648          *            depending on the class of v.
22649          */
22650         void onCreateContextMenu(ContextMenu menu, View v, ContextMenuInfo menuInfo);
22651     }
22652
22653     /**
22654      * Interface definition for a callback to be invoked when the status bar changes
22655      * visibility.  This reports <strong>global</strong> changes to the system UI
22656      * state, not what the application is requesting.
22657      *
22658      * @see View#setOnSystemUiVisibilityChangeListener(android.view.View.OnSystemUiVisibilityChangeListener)
22659      */
22660     public interface OnSystemUiVisibilityChangeListener {
22661         /**
22662          * Called when the status bar changes visibility because of a call to
22663          * {@link View#setSystemUiVisibility(int)}.
22664          *
22665          * @param visibility  Bitwise-or of flags {@link #SYSTEM_UI_FLAG_LOW_PROFILE},
22666          * {@link #SYSTEM_UI_FLAG_HIDE_NAVIGATION}, and {@link #SYSTEM_UI_FLAG_FULLSCREEN}.
22667          * This tells you the <strong>global</strong> state of these UI visibility
22668          * flags, not what your app is currently applying.
22669          */
22670         public void onSystemUiVisibilityChange(int visibility);
22671     }
22672
22673     /**
22674      * Interface definition for a callback to be invoked when this view is attached
22675      * or detached from its window.
22676      */
22677     public interface OnAttachStateChangeListener {
22678         /**
22679          * Called when the view is attached to a window.
22680          * @param v The view that was attached
22681          */
22682         public void onViewAttachedToWindow(View v);
22683         /**
22684          * Called when the view is detached from a window.
22685          * @param v The view that was detached
22686          */
22687         public void onViewDetachedFromWindow(View v);
22688     }
22689
22690     /**
22691      * Listener for applying window insets on a view in a custom way.
22692      *
22693      * <p>Apps may choose to implement this interface if they want to apply custom policy
22694      * to the way that window insets are treated for a view. If an OnApplyWindowInsetsListener
22695      * is set, its
22696      * {@link OnApplyWindowInsetsListener#onApplyWindowInsets(View, WindowInsets) onApplyWindowInsets}
22697      * method will be called instead of the View's own
22698      * {@link #onApplyWindowInsets(WindowInsets) onApplyWindowInsets} method. The listener
22699      * may optionally call the parameter View's <code>onApplyWindowInsets</code> method to apply
22700      * the View's normal behavior as part of its own.</p>
22701      */
22702     public interface OnApplyWindowInsetsListener {
22703         /**
22704          * When {@link View#setOnApplyWindowInsetsListener(View.OnApplyWindowInsetsListener) set}
22705          * on a View, this listener method will be called instead of the view's own
22706          * {@link View#onApplyWindowInsets(WindowInsets) onApplyWindowInsets} method.
22707          *
22708          * @param v The view applying window insets
22709          * @param insets The insets to apply
22710          * @return The insets supplied, minus any insets that were consumed
22711          */
22712         public WindowInsets onApplyWindowInsets(View v, WindowInsets insets);
22713     }
22714
22715     private final class UnsetPressedState implements Runnable {
22716         @Override
22717         public void run() {
22718             setPressed(false);
22719         }
22720     }
22721
22722     /**
22723      * Base class for derived classes that want to save and restore their own
22724      * state in {@link android.view.View#onSaveInstanceState()}.
22725      */
22726     public static class BaseSavedState extends AbsSavedState {
22727         String mStartActivityRequestWhoSaved;
22728
22729         /**
22730          * Constructor used when reading from a parcel. Reads the state of the superclass.
22731          *
22732          * @param source parcel to read from
22733          */
22734         public BaseSavedState(Parcel source) {
22735             this(source, null);
22736         }
22737
22738         /**
22739          * Constructor used when reading from a parcel using a given class loader.
22740          * Reads the state of the superclass.
22741          *
22742          * @param source parcel to read from
22743          * @param loader ClassLoader to use for reading
22744          */
22745         public BaseSavedState(Parcel source, ClassLoader loader) {
22746             super(source, loader);
22747             mStartActivityRequestWhoSaved = source.readString();
22748         }
22749
22750         /**
22751          * Constructor called by derived classes when creating their SavedState objects
22752          *
22753          * @param superState The state of the superclass of this view
22754          */
22755         public BaseSavedState(Parcelable superState) {
22756             super(superState);
22757         }
22758
22759         @Override
22760         public void writeToParcel(Parcel out, int flags) {
22761             super.writeToParcel(out, flags);
22762             out.writeString(mStartActivityRequestWhoSaved);
22763         }
22764
22765         public static final Parcelable.Creator<BaseSavedState> CREATOR
22766                 = new Parcelable.ClassLoaderCreator<BaseSavedState>() {
22767             @Override
22768             public BaseSavedState createFromParcel(Parcel in) {
22769                 return new BaseSavedState(in);
22770             }
22771
22772             @Override
22773             public BaseSavedState createFromParcel(Parcel in, ClassLoader loader) {
22774                 return new BaseSavedState(in, loader);
22775             }
22776
22777             @Override
22778             public BaseSavedState[] newArray(int size) {
22779                 return new BaseSavedState[size];
22780             }
22781         };
22782     }
22783
22784     /**
22785      * A set of information given to a view when it is attached to its parent
22786      * window.
22787      */
22788     final static class AttachInfo {
22789         interface Callbacks {
22790             void playSoundEffect(int effectId);
22791             boolean performHapticFeedback(int effectId, boolean always);
22792         }
22793
22794         /**
22795          * InvalidateInfo is used to post invalidate(int, int, int, int) messages
22796          * to a Handler. This class contains the target (View) to invalidate and
22797          * the coordinates of the dirty rectangle.
22798          *
22799          * For performance purposes, this class also implements a pool of up to
22800          * POOL_LIMIT objects that get reused. This reduces memory allocations
22801          * whenever possible.
22802          */
22803         static class InvalidateInfo {
22804             private static final int POOL_LIMIT = 10;
22805
22806             private static final SynchronizedPool<InvalidateInfo> sPool =
22807                     new SynchronizedPool<InvalidateInfo>(POOL_LIMIT);
22808
22809             View target;
22810
22811             int left;
22812             int top;
22813             int right;
22814             int bottom;
22815
22816             public static InvalidateInfo obtain() {
22817                 InvalidateInfo instance = sPool.acquire();
22818                 return (instance != null) ? instance : new InvalidateInfo();
22819             }
22820
22821             public void recycle() {
22822                 target = null;
22823                 sPool.release(this);
22824             }
22825         }
22826
22827         final IWindowSession mSession;
22828
22829         final IWindow mWindow;
22830
22831         final IBinder mWindowToken;
22832
22833         final Display mDisplay;
22834
22835         final Callbacks mRootCallbacks;
22836
22837         IWindowId mIWindowId;
22838         WindowId mWindowId;
22839
22840         /**
22841          * The top view of the hierarchy.
22842          */
22843         View mRootView;
22844
22845         IBinder mPanelParentWindowToken;
22846
22847         boolean mHardwareAccelerated;
22848         boolean mHardwareAccelerationRequested;
22849         ThreadedRenderer mHardwareRenderer;
22850         List<RenderNode> mPendingAnimatingRenderNodes;
22851
22852         /**
22853          * The state of the display to which the window is attached, as reported
22854          * by {@link Display#getState()}.  Note that the display state constants
22855          * declared by {@link Display} do not exactly line up with the screen state
22856          * constants declared by {@link View} (there are more display states than
22857          * screen states).
22858          */
22859         int mDisplayState = Display.STATE_UNKNOWN;
22860
22861         /**
22862          * Scale factor used by the compatibility mode
22863          */
22864         float mApplicationScale;
22865
22866         /**
22867          * Indicates whether the application is in compatibility mode
22868          */
22869         boolean mScalingRequired;
22870
22871         /**
22872          * Left position of this view's window
22873          */
22874         int mWindowLeft;
22875
22876         /**
22877          * Top position of this view's window
22878          */
22879         int mWindowTop;
22880
22881         /**
22882          * Indicates whether views need to use 32-bit drawing caches
22883          */
22884         boolean mUse32BitDrawingCache;
22885
22886         /**
22887          * For windows that are full-screen but using insets to layout inside
22888          * of the screen areas, these are the current insets to appear inside
22889          * the overscan area of the display.
22890          */
22891         final Rect mOverscanInsets = new Rect();
22892
22893         /**
22894          * For windows that are full-screen but using insets to layout inside
22895          * of the screen decorations, these are the current insets for the
22896          * content of the window.
22897          */
22898         final Rect mContentInsets = new Rect();
22899
22900         /**
22901          * For windows that are full-screen but using insets to layout inside
22902          * of the screen decorations, these are the current insets for the
22903          * actual visible parts of the window.
22904          */
22905         final Rect mVisibleInsets = new Rect();
22906
22907         /**
22908          * For windows that are full-screen but using insets to layout inside
22909          * of the screen decorations, these are the current insets for the
22910          * stable system windows.
22911          */
22912         final Rect mStableInsets = new Rect();
22913
22914         /**
22915          * For windows that include areas that are not covered by real surface these are the outsets
22916          * for real surface.
22917          */
22918         final Rect mOutsets = new Rect();
22919
22920         /**
22921          * In multi-window we force show the navigation bar. Because we don't want that the surface
22922          * size changes in this mode, we instead have a flag whether the navigation bar size should
22923          * always be consumed, so the app is treated like there is no virtual navigation bar at all.
22924          */
22925         boolean mAlwaysConsumeNavBar;
22926
22927         /**
22928          * The internal insets given by this window.  This value is
22929          * supplied by the client (through
22930          * {@link ViewTreeObserver.OnComputeInternalInsetsListener}) and will
22931          * be given to the window manager when changed to be used in laying
22932          * out windows behind it.
22933          */
22934         final ViewTreeObserver.InternalInsetsInfo mGivenInternalInsets
22935                 = new ViewTreeObserver.InternalInsetsInfo();
22936
22937         /**
22938          * Set to true when mGivenInternalInsets is non-empty.
22939          */
22940         boolean mHasNonEmptyGivenInternalInsets;
22941
22942         /**
22943          * All views in the window's hierarchy that serve as scroll containers,
22944          * used to determine if the window can be resized or must be panned
22945          * to adjust for a soft input area.
22946          */
22947         final ArrayList<View> mScrollContainers = new ArrayList<View>();
22948
22949         final KeyEvent.DispatcherState mKeyDispatchState
22950                 = new KeyEvent.DispatcherState();
22951
22952         /**
22953          * Indicates whether the view's window currently has the focus.
22954          */
22955         boolean mHasWindowFocus;
22956
22957         /**
22958          * The current visibility of the window.
22959          */
22960         int mWindowVisibility;
22961
22962         /**
22963          * Indicates the time at which drawing started to occur.
22964          */
22965         long mDrawingTime;
22966
22967         /**
22968          * Indicates whether or not ignoring the DIRTY_MASK flags.
22969          */
22970         boolean mIgnoreDirtyState;
22971
22972         /**
22973          * This flag tracks when the mIgnoreDirtyState flag is set during draw(),
22974          * to avoid clearing that flag prematurely.
22975          */
22976         boolean mSetIgnoreDirtyState = false;
22977
22978         /**
22979          * Indicates whether the view's window is currently in touch mode.
22980          */
22981         boolean mInTouchMode;
22982
22983         /**
22984          * Indicates whether the view has requested unbuffered input dispatching for the current
22985          * event stream.
22986          */
22987         boolean mUnbufferedDispatchRequested;
22988
22989         /**
22990          * Indicates that ViewAncestor should trigger a global layout change
22991          * the next time it performs a traversal
22992          */
22993         boolean mRecomputeGlobalAttributes;
22994
22995         /**
22996          * Always report new attributes at next traversal.
22997          */
22998         boolean mForceReportNewAttributes;
22999
23000         /**
23001          * Set during a traveral if any views want to keep the screen on.
23002          */
23003         boolean mKeepScreenOn;
23004
23005         /**
23006          * Set during a traveral if the light center needs to be updated.
23007          */
23008         boolean mNeedsUpdateLightCenter;
23009
23010         /**
23011          * Bitwise-or of all of the values that views have passed to setSystemUiVisibility().
23012          */
23013         int mSystemUiVisibility;
23014
23015         /**
23016          * Hack to force certain system UI visibility flags to be cleared.
23017          */
23018         int mDisabledSystemUiVisibility;
23019
23020         /**
23021          * Last global system UI visibility reported by the window manager.
23022          */
23023         int mGlobalSystemUiVisibility = -1;
23024
23025         /**
23026          * True if a view in this hierarchy has an OnSystemUiVisibilityChangeListener
23027          * attached.
23028          */
23029         boolean mHasSystemUiListeners;
23030
23031         /**
23032          * Set if the window has requested to extend into the overscan region
23033          * via WindowManager.LayoutParams.FLAG_LAYOUT_IN_OVERSCAN.
23034          */
23035         boolean mOverscanRequested;
23036
23037         /**
23038          * Set if the visibility of any views has changed.
23039          */
23040         boolean mViewVisibilityChanged;
23041
23042         /**
23043          * Set to true if a view has been scrolled.
23044          */
23045         boolean mViewScrollChanged;
23046
23047         /**
23048          * Set to true if high contrast mode enabled
23049          */
23050         boolean mHighContrastText;
23051
23052         /**
23053          * Set to true if a pointer event is currently being handled.
23054          */
23055         boolean mHandlingPointerEvent;
23056
23057         /**
23058          * Global to the view hierarchy used as a temporary for dealing with
23059          * x/y points in the transparent region computations.
23060          */
23061         final int[] mTransparentLocation = new int[2];
23062
23063         /**
23064          * Global to the view hierarchy used as a temporary for dealing with
23065          * x/y points in the ViewGroup.invalidateChild implementation.
23066          */
23067         final int[] mInvalidateChildLocation = new int[2];
23068
23069         /**
23070          * Global to the view hierarchy used as a temporary for dealing with
23071          * computing absolute on-screen location.
23072          */
23073         final int[] mTmpLocation = new int[2];
23074
23075         /**
23076          * Global to the view hierarchy used as a temporary for dealing with
23077          * x/y location when view is transformed.
23078          */
23079         final float[] mTmpTransformLocation = new float[2];
23080
23081         /**
23082          * The view tree observer used to dispatch global events like
23083          * layout, pre-draw, touch mode change, etc.
23084          */
23085         final ViewTreeObserver mTreeObserver = new ViewTreeObserver();
23086
23087         /**
23088          * A Canvas used by the view hierarchy to perform bitmap caching.
23089          */
23090         Canvas mCanvas;
23091
23092         /**
23093          * The view root impl.
23094          */
23095         final ViewRootImpl mViewRootImpl;
23096
23097         /**
23098          * A Handler supplied by a view's {@link android.view.ViewRootImpl}. This
23099          * handler can be used to pump events in the UI events queue.
23100          */
23101         final Handler mHandler;
23102
23103         /**
23104          * Temporary for use in computing invalidate rectangles while
23105          * calling up the hierarchy.
23106          */
23107         final Rect mTmpInvalRect = new Rect();
23108
23109         /**
23110          * Temporary for use in computing hit areas with transformed views
23111          */
23112         final RectF mTmpTransformRect = new RectF();
23113
23114         /**
23115          * Temporary for use in computing hit areas with transformed views
23116          */
23117         final RectF mTmpTransformRect1 = new RectF();
23118
23119         /**
23120          * Temporary list of rectanges.
23121          */
23122         final List<RectF> mTmpRectList = new ArrayList<>();
23123
23124         /**
23125          * Temporary for use in transforming invalidation rect
23126          */
23127         final Matrix mTmpMatrix = new Matrix();
23128
23129         /**
23130          * Temporary for use in transforming invalidation rect
23131          */
23132         final Transformation mTmpTransformation = new Transformation();
23133
23134         /**
23135          * Temporary for use in querying outlines from OutlineProviders
23136          */
23137         final Outline mTmpOutline = new Outline();
23138
23139         /**
23140          * Temporary list for use in collecting focusable descendents of a view.
23141          */
23142         final ArrayList<View> mTempArrayList = new ArrayList<View>(24);
23143
23144         /**
23145          * The id of the window for accessibility purposes.
23146          */
23147         int mAccessibilityWindowId = AccessibilityNodeInfo.UNDEFINED_ITEM_ID;
23148
23149         /**
23150          * Flags related to accessibility processing.
23151          *
23152          * @see AccessibilityNodeInfo#FLAG_INCLUDE_NOT_IMPORTANT_VIEWS
23153          * @see AccessibilityNodeInfo#FLAG_REPORT_VIEW_IDS
23154          */
23155         int mAccessibilityFetchFlags;
23156
23157         /**
23158          * The drawable for highlighting accessibility focus.
23159          */
23160         Drawable mAccessibilityFocusDrawable;
23161
23162         /**
23163          * Show where the margins, bounds and layout bounds are for each view.
23164          */
23165         boolean mDebugLayout = SystemProperties.getBoolean(DEBUG_LAYOUT_PROPERTY, false);
23166
23167         /**
23168          * Point used to compute visible regions.
23169          */
23170         final Point mPoint = new Point();
23171
23172         /**
23173          * Used to track which View originated a requestLayout() call, used when
23174          * requestLayout() is called during layout.
23175          */
23176         View mViewRequestingLayout;
23177
23178         /**
23179          * Used to track views that need (at least) a partial relayout at their current size
23180          * during the next traversal.
23181          */
23182         List<View> mPartialLayoutViews = new ArrayList<>();
23183
23184         /**
23185          * Swapped with mPartialLayoutViews during layout to avoid concurrent
23186          * modification. Lazily assigned during ViewRootImpl layout.
23187          */
23188         List<View> mEmptyPartialLayoutViews;
23189
23190         /**
23191          * Used to track the identity of the current drag operation.
23192          */
23193         IBinder mDragToken;
23194
23195         /**
23196          * The drag shadow surface for the current drag operation.
23197          */
23198         public Surface mDragSurface;
23199
23200         /**
23201          * Creates a new set of attachment information with the specified
23202          * events handler and thread.
23203          *
23204          * @param handler the events handler the view must use
23205          */
23206         AttachInfo(IWindowSession session, IWindow window, Display display,
23207                 ViewRootImpl viewRootImpl, Handler handler, Callbacks effectPlayer) {
23208             mSession = session;
23209             mWindow = window;
23210             mWindowToken = window.asBinder();
23211             mDisplay = display;
23212             mViewRootImpl = viewRootImpl;
23213             mHandler = handler;
23214             mRootCallbacks = effectPlayer;
23215         }
23216     }
23217
23218     /**
23219      * <p>ScrollabilityCache holds various fields used by a View when scrolling
23220      * is supported. This avoids keeping too many unused fields in most
23221      * instances of View.</p>
23222      */
23223     private static class ScrollabilityCache implements Runnable {
23224
23225         /**
23226          * Scrollbars are not visible
23227          */
23228         public static final int OFF = 0;
23229
23230         /**
23231          * Scrollbars are visible
23232          */
23233         public static final int ON = 1;
23234
23235         /**
23236          * Scrollbars are fading away
23237          */
23238         public static final int FADING = 2;
23239
23240         public boolean fadeScrollBars;
23241
23242         public int fadingEdgeLength;
23243         public int scrollBarDefaultDelayBeforeFade;
23244         public int scrollBarFadeDuration;
23245
23246         public int scrollBarSize;
23247         public ScrollBarDrawable scrollBar;
23248         public float[] interpolatorValues;
23249         public View host;
23250
23251         public final Paint paint;
23252         public final Matrix matrix;
23253         public Shader shader;
23254
23255         public final Interpolator scrollBarInterpolator = new Interpolator(1, 2);
23256
23257         private static final float[] OPAQUE = { 255 };
23258         private static final float[] TRANSPARENT = { 0.0f };
23259
23260         /**
23261          * When fading should start. This time moves into the future every time
23262          * a new scroll happens. Measured based on SystemClock.uptimeMillis()
23263          */
23264         public long fadeStartTime;
23265
23266
23267         /**
23268          * The current state of the scrollbars: ON, OFF, or FADING
23269          */
23270         public int state = OFF;
23271
23272         private int mLastColor;
23273
23274         public final Rect mScrollBarBounds = new Rect();
23275
23276         public static final int NOT_DRAGGING = 0;
23277         public static final int DRAGGING_VERTICAL_SCROLL_BAR = 1;
23278         public static final int DRAGGING_HORIZONTAL_SCROLL_BAR = 2;
23279         public int mScrollBarDraggingState = NOT_DRAGGING;
23280
23281         public float mScrollBarDraggingPos = 0;
23282
23283         public ScrollabilityCache(ViewConfiguration configuration, View host) {
23284             fadingEdgeLength = configuration.getScaledFadingEdgeLength();
23285             scrollBarSize = configuration.getScaledScrollBarSize();
23286             scrollBarDefaultDelayBeforeFade = ViewConfiguration.getScrollDefaultDelay();
23287             scrollBarFadeDuration = ViewConfiguration.getScrollBarFadeDuration();
23288
23289             paint = new Paint();
23290             matrix = new Matrix();
23291             // use use a height of 1, and then wack the matrix each time we
23292             // actually use it.
23293             shader = new LinearGradient(0, 0, 0, 1, 0xFF000000, 0, Shader.TileMode.CLAMP);
23294             paint.setShader(shader);
23295             paint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.DST_OUT));
23296
23297             this.host = host;
23298         }
23299
23300         public void setFadeColor(int color) {
23301             if (color != mLastColor) {
23302                 mLastColor = color;
23303
23304                 if (color != 0) {
23305                     shader = new LinearGradient(0, 0, 0, 1, color | 0xFF000000,
23306                             color & 0x00FFFFFF, Shader.TileMode.CLAMP);
23307                     paint.setShader(shader);
23308                     // Restore the default transfer mode (src_over)
23309                     paint.setXfermode(null);
23310                 } else {
23311                     shader = new LinearGradient(0, 0, 0, 1, 0xFF000000, 0, Shader.TileMode.CLAMP);
23312                     paint.setShader(shader);
23313                     paint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.DST_OUT));
23314                 }
23315             }
23316         }
23317
23318         public void run() {
23319             long now = AnimationUtils.currentAnimationTimeMillis();
23320             if (now >= fadeStartTime) {
23321
23322                 // the animation fades the scrollbars out by changing
23323                 // the opacity (alpha) from fully opaque to fully
23324                 // transparent
23325                 int nextFrame = (int) now;
23326                 int framesCount = 0;
23327
23328                 Interpolator interpolator = scrollBarInterpolator;
23329
23330                 // Start opaque
23331                 interpolator.setKeyFrame(framesCount++, nextFrame, OPAQUE);
23332
23333                 // End transparent
23334                 nextFrame += scrollBarFadeDuration;
23335                 interpolator.setKeyFrame(framesCount, nextFrame, TRANSPARENT);
23336
23337                 state = FADING;
23338
23339                 // Kick off the fade animation
23340                 host.invalidate(true);
23341             }
23342         }
23343     }
23344
23345     /**
23346      * Resuable callback for sending
23347      * {@link AccessibilityEvent#TYPE_VIEW_SCROLLED} accessibility event.
23348      */
23349     private class SendViewScrolledAccessibilityEvent implements Runnable {
23350         public volatile boolean mIsPending;
23351
23352         public void run() {
23353             sendAccessibilityEvent(AccessibilityEvent.TYPE_VIEW_SCROLLED);
23354             mIsPending = false;
23355         }
23356     }
23357
23358     /**
23359      * <p>
23360      * This class represents a delegate that can be registered in a {@link View}
23361      * to enhance accessibility support via composition rather via inheritance.
23362      * It is specifically targeted to widget developers that extend basic View
23363      * classes i.e. classes in package android.view, that would like their
23364      * applications to be backwards compatible.
23365      * </p>
23366      * <div class="special reference">
23367      * <h3>Developer Guides</h3>
23368      * <p>For more information about making applications accessible, read the
23369      * <a href="{@docRoot}guide/topics/ui/accessibility/index.html">Accessibility</a>
23370      * developer guide.</p>
23371      * </div>
23372      * <p>
23373      * A scenario in which a developer would like to use an accessibility delegate
23374      * is overriding a method introduced in a later API version then the minimal API
23375      * version supported by the application. For example, the method
23376      * {@link View#onInitializeAccessibilityNodeInfo(AccessibilityNodeInfo)} is not available
23377      * in API version 4 when the accessibility APIs were first introduced. If a
23378      * developer would like his application to run on API version 4 devices (assuming
23379      * all other APIs used by the application are version 4 or lower) and take advantage
23380      * of this method, instead of overriding the method which would break the application's
23381      * backwards compatibility, he can override the corresponding method in this
23382      * delegate and register the delegate in the target View if the API version of
23383      * the system is high enough i.e. the API version is same or higher to the API
23384      * version that introduced
23385      * {@link View#onInitializeAccessibilityNodeInfo(AccessibilityNodeInfo)}.
23386      * </p>
23387      * <p>
23388      * Here is an example implementation:
23389      * </p>
23390      * <code><pre><p>
23391      * if (Build.VERSION.SDK_INT >= 14) {
23392      *     // If the API version is equal of higher than the version in
23393      *     // which onInitializeAccessibilityNodeInfo was introduced we
23394      *     // register a delegate with a customized implementation.
23395      *     View view = findViewById(R.id.view_id);
23396      *     view.setAccessibilityDelegate(new AccessibilityDelegate() {
23397      *         public void onInitializeAccessibilityNodeInfo(View host,
23398      *                 AccessibilityNodeInfo info) {
23399      *             // Let the default implementation populate the info.
23400      *             super.onInitializeAccessibilityNodeInfo(host, info);
23401      *             // Set some other information.
23402      *             info.setEnabled(host.isEnabled());
23403      *         }
23404      *     });
23405      * }
23406      * </code></pre></p>
23407      * <p>
23408      * This delegate contains methods that correspond to the accessibility methods
23409      * in View. If a delegate has been specified the implementation in View hands
23410      * off handling to the corresponding method in this delegate. The default
23411      * implementation the delegate methods behaves exactly as the corresponding
23412      * method in View for the case of no accessibility delegate been set. Hence,
23413      * to customize the behavior of a View method, clients can override only the
23414      * corresponding delegate method without altering the behavior of the rest
23415      * accessibility related methods of the host view.
23416      * </p>
23417      * <p>
23418      * <strong>Note:</strong> On platform versions prior to
23419      * {@link android.os.Build.VERSION_CODES#M API 23}, delegate methods on
23420      * views in the {@code android.widget.*} package are called <i>before</i>
23421      * host methods. This prevents certain properties such as class name from
23422      * being modified by overriding
23423      * {@link AccessibilityDelegate#onInitializeAccessibilityNodeInfo(View, AccessibilityNodeInfo)},
23424      * as any changes will be overwritten by the host class.
23425      * <p>
23426      * Starting in {@link android.os.Build.VERSION_CODES#M API 23}, delegate
23427      * methods are called <i>after</i> host methods, which all properties to be
23428      * modified without being overwritten by the host class.
23429      */
23430     public static class AccessibilityDelegate {
23431
23432         /**
23433          * Sends an accessibility event of the given type. If accessibility is not
23434          * enabled this method has no effect.
23435          * <p>
23436          * The default implementation behaves as {@link View#sendAccessibilityEvent(int)
23437          *  View#sendAccessibilityEvent(int)} for the case of no accessibility delegate
23438          * been set.
23439          * </p>
23440          *
23441          * @param host The View hosting the delegate.
23442          * @param eventType The type of the event to send.
23443          *
23444          * @see View#sendAccessibilityEvent(int) View#sendAccessibilityEvent(int)
23445          */
23446         public void sendAccessibilityEvent(View host, int eventType) {
23447             host.sendAccessibilityEventInternal(eventType);
23448         }
23449
23450         /**
23451          * Performs the specified accessibility action on the view. For
23452          * possible accessibility actions look at {@link AccessibilityNodeInfo}.
23453          * <p>
23454          * The default implementation behaves as
23455          * {@link View#performAccessibilityAction(int, Bundle)
23456          *  View#performAccessibilityAction(int, Bundle)} for the case of
23457          *  no accessibility delegate been set.
23458          * </p>
23459          *
23460          * @param action The action to perform.
23461          * @return Whether the action was performed.
23462          *
23463          * @see View#performAccessibilityAction(int, Bundle)
23464          *      View#performAccessibilityAction(int, Bundle)
23465          */
23466         public boolean performAccessibilityAction(View host, int action, Bundle args) {
23467             return host.performAccessibilityActionInternal(action, args);
23468         }
23469
23470         /**
23471          * Sends an accessibility event. This method behaves exactly as
23472          * {@link #sendAccessibilityEvent(View, int)} but takes as an argument an
23473          * empty {@link AccessibilityEvent} and does not perform a check whether
23474          * accessibility is enabled.
23475          * <p>
23476          * The default implementation behaves as
23477          * {@link View#sendAccessibilityEventUnchecked(AccessibilityEvent)
23478          *  View#sendAccessibilityEventUnchecked(AccessibilityEvent)} for
23479          * the case of no accessibility delegate been set.
23480          * </p>
23481          *
23482          * @param host The View hosting the delegate.
23483          * @param event The event to send.
23484          *
23485          * @see View#sendAccessibilityEventUnchecked(AccessibilityEvent)
23486          *      View#sendAccessibilityEventUnchecked(AccessibilityEvent)
23487          */
23488         public void sendAccessibilityEventUnchecked(View host, AccessibilityEvent event) {
23489             host.sendAccessibilityEventUncheckedInternal(event);
23490         }
23491
23492         /**
23493          * Dispatches an {@link AccessibilityEvent} to the host {@link View} first and then
23494          * to its children for adding their text content to the event.
23495          * <p>
23496          * The default implementation behaves as
23497          * {@link View#dispatchPopulateAccessibilityEvent(AccessibilityEvent)
23498          *  View#dispatchPopulateAccessibilityEvent(AccessibilityEvent)} for
23499          * the case of no accessibility delegate been set.
23500          * </p>
23501          *
23502          * @param host The View hosting the delegate.
23503          * @param event The event.
23504          * @return True if the event population was completed.
23505          *
23506          * @see View#dispatchPopulateAccessibilityEvent(AccessibilityEvent)
23507          *      View#dispatchPopulateAccessibilityEvent(AccessibilityEvent)
23508          */
23509         public boolean dispatchPopulateAccessibilityEvent(View host, AccessibilityEvent event) {
23510             return host.dispatchPopulateAccessibilityEventInternal(event);
23511         }
23512
23513         /**
23514          * Gives a chance to the host View to populate the accessibility event with its
23515          * text content.
23516          * <p>
23517          * The default implementation behaves as
23518          * {@link View#onPopulateAccessibilityEvent(AccessibilityEvent)
23519          *  View#onPopulateAccessibilityEvent(AccessibilityEvent)} for
23520          * the case of no accessibility delegate been set.
23521          * </p>
23522          *
23523          * @param host The View hosting the delegate.
23524          * @param event The accessibility event which to populate.
23525          *
23526          * @see View#onPopulateAccessibilityEvent(AccessibilityEvent)
23527          *      View#onPopulateAccessibilityEvent(AccessibilityEvent)
23528          */
23529         public void onPopulateAccessibilityEvent(View host, AccessibilityEvent event) {
23530             host.onPopulateAccessibilityEventInternal(event);
23531         }
23532
23533         /**
23534          * Initializes an {@link AccessibilityEvent} with information about the
23535          * the host View which is the event source.
23536          * <p>
23537          * The default implementation behaves as
23538          * {@link View#onInitializeAccessibilityEvent(AccessibilityEvent)
23539          *  View#onInitializeAccessibilityEvent(AccessibilityEvent)} for
23540          * the case of no accessibility delegate been set.
23541          * </p>
23542          *
23543          * @param host The View hosting the delegate.
23544          * @param event The event to initialize.
23545          *
23546          * @see View#onInitializeAccessibilityEvent(AccessibilityEvent)
23547          *      View#onInitializeAccessibilityEvent(AccessibilityEvent)
23548          */
23549         public void onInitializeAccessibilityEvent(View host, AccessibilityEvent event) {
23550             host.onInitializeAccessibilityEventInternal(event);
23551         }
23552
23553         /**
23554          * Initializes an {@link AccessibilityNodeInfo} with information about the host view.
23555          * <p>
23556          * The default implementation behaves as
23557          * {@link View#onInitializeAccessibilityNodeInfo(AccessibilityNodeInfo)
23558          *  View#onInitializeAccessibilityNodeInfo(AccessibilityNodeInfo)} for
23559          * the case of no accessibility delegate been set.
23560          * </p>
23561          *
23562          * @param host The View hosting the delegate.
23563          * @param info The instance to initialize.
23564          *
23565          * @see View#onInitializeAccessibilityNodeInfo(AccessibilityNodeInfo)
23566          *      View#onInitializeAccessibilityNodeInfo(AccessibilityNodeInfo)
23567          */
23568         public void onInitializeAccessibilityNodeInfo(View host, AccessibilityNodeInfo info) {
23569             host.onInitializeAccessibilityNodeInfoInternal(info);
23570         }
23571
23572         /**
23573          * Called when a child of the host View has requested sending an
23574          * {@link AccessibilityEvent} and gives an opportunity to the parent (the host)
23575          * to augment the event.
23576          * <p>
23577          * The default implementation behaves as
23578          * {@link ViewGroup#onRequestSendAccessibilityEvent(View, AccessibilityEvent)
23579          *  ViewGroup#onRequestSendAccessibilityEvent(View, AccessibilityEvent)} for
23580          * the case of no accessibility delegate been set.
23581          * </p>
23582          *
23583          * @param host The View hosting the delegate.
23584          * @param child The child which requests sending the event.
23585          * @param event The event to be sent.
23586          * @return True if the event should be sent
23587          *
23588          * @see ViewGroup#onRequestSendAccessibilityEvent(View, AccessibilityEvent)
23589          *      ViewGroup#onRequestSendAccessibilityEvent(View, AccessibilityEvent)
23590          */
23591         public boolean onRequestSendAccessibilityEvent(ViewGroup host, View child,
23592                 AccessibilityEvent event) {
23593             return host.onRequestSendAccessibilityEventInternal(child, event);
23594         }
23595
23596         /**
23597          * Gets the provider for managing a virtual view hierarchy rooted at this View
23598          * and reported to {@link android.accessibilityservice.AccessibilityService}s
23599          * that explore the window content.
23600          * <p>
23601          * The default implementation behaves as
23602          * {@link View#getAccessibilityNodeProvider() View#getAccessibilityNodeProvider()} for
23603          * the case of no accessibility delegate been set.
23604          * </p>
23605          *
23606          * @return The provider.
23607          *
23608          * @see AccessibilityNodeProvider
23609          */
23610         public AccessibilityNodeProvider getAccessibilityNodeProvider(View host) {
23611             return null;
23612         }
23613
23614         /**
23615          * Returns an {@link AccessibilityNodeInfo} representing the host view from the
23616          * point of view of an {@link android.accessibilityservice.AccessibilityService}.
23617          * This method is responsible for obtaining an accessibility node info from a
23618          * pool of reusable instances and calling
23619          * {@link #onInitializeAccessibilityNodeInfo(AccessibilityNodeInfo)} on the host
23620          * view to initialize the former.
23621          * <p>
23622          * <strong>Note:</strong> The client is responsible for recycling the obtained
23623          * instance by calling {@link AccessibilityNodeInfo#recycle()} to minimize object
23624          * creation.
23625          * </p>
23626          * <p>
23627          * The default implementation behaves as
23628          * {@link View#createAccessibilityNodeInfo() View#createAccessibilityNodeInfo()} for
23629          * the case of no accessibility delegate been set.
23630          * </p>
23631          * @return A populated {@link AccessibilityNodeInfo}.
23632          *
23633          * @see AccessibilityNodeInfo
23634          *
23635          * @hide
23636          */
23637         public AccessibilityNodeInfo createAccessibilityNodeInfo(View host) {
23638             return host.createAccessibilityNodeInfoInternal();
23639         }
23640     }
23641
23642     private class MatchIdPredicate implements Predicate<View> {
23643         public int mId;
23644
23645         @Override
23646         public boolean apply(View view) {
23647             return (view.mID == mId);
23648         }
23649     }
23650
23651     private class MatchLabelForPredicate implements Predicate<View> {
23652         private int mLabeledId;
23653
23654         @Override
23655         public boolean apply(View view) {
23656             return (view.mLabelForId == mLabeledId);
23657         }
23658     }
23659
23660     private class SendViewStateChangedAccessibilityEvent implements Runnable {
23661         private int mChangeTypes = 0;
23662         private boolean mPosted;
23663         private boolean mPostedWithDelay;
23664         private long mLastEventTimeMillis;
23665
23666         @Override
23667         public void run() {
23668             mPosted = false;
23669             mPostedWithDelay = false;
23670             mLastEventTimeMillis = SystemClock.uptimeMillis();
23671             if (AccessibilityManager.getInstance(mContext).isEnabled()) {
23672                 final AccessibilityEvent event = AccessibilityEvent.obtain();
23673                 event.setEventType(AccessibilityEvent.TYPE_WINDOW_CONTENT_CHANGED);
23674                 event.setContentChangeTypes(mChangeTypes);
23675                 sendAccessibilityEventUnchecked(event);
23676             }
23677             mChangeTypes = 0;
23678         }
23679
23680         public void runOrPost(int changeType) {
23681             mChangeTypes |= changeType;
23682
23683             // If this is a live region or the child of a live region, collect
23684             // all events from this frame and send them on the next frame.
23685             if (inLiveRegion()) {
23686                 // If we're already posted with a delay, remove that.
23687                 if (mPostedWithDelay) {
23688                     removeCallbacks(this);
23689                     mPostedWithDelay = false;
23690                 }
23691                 // Only post if we're not already posted.
23692                 if (!mPosted) {
23693                     post(this);
23694                     mPosted = true;
23695                 }
23696                 return;
23697             }
23698
23699             if (mPosted) {
23700                 return;
23701             }
23702
23703             final long timeSinceLastMillis = SystemClock.uptimeMillis() - mLastEventTimeMillis;
23704             final long minEventIntevalMillis =
23705                     ViewConfiguration.getSendRecurringAccessibilityEventsInterval();
23706             if (timeSinceLastMillis >= minEventIntevalMillis) {
23707                 removeCallbacks(this);
23708                 run();
23709             } else {
23710                 postDelayed(this, minEventIntevalMillis - timeSinceLastMillis);
23711                 mPostedWithDelay = true;
23712             }
23713         }
23714     }
23715
23716     private boolean inLiveRegion() {
23717         if (getAccessibilityLiveRegion() != View.ACCESSIBILITY_LIVE_REGION_NONE) {
23718             return true;
23719         }
23720
23721         ViewParent parent = getParent();
23722         while (parent instanceof View) {
23723             if (((View) parent).getAccessibilityLiveRegion()
23724                     != View.ACCESSIBILITY_LIVE_REGION_NONE) {
23725                 return true;
23726             }
23727             parent = parent.getParent();
23728         }
23729
23730         return false;
23731     }
23732
23733     /**
23734      * Dump all private flags in readable format, useful for documentation and
23735      * sanity checking.
23736      */
23737     private static void dumpFlags() {
23738         final HashMap<String, String> found = Maps.newHashMap();
23739         try {
23740             for (Field field : View.class.getDeclaredFields()) {
23741                 final int modifiers = field.getModifiers();
23742                 if (Modifier.isStatic(modifiers) && Modifier.isFinal(modifiers)) {
23743                     if (field.getType().equals(int.class)) {
23744                         final int value = field.getInt(null);
23745                         dumpFlag(found, field.getName(), value);
23746                     } else if (field.getType().equals(int[].class)) {
23747                         final int[] values = (int[]) field.get(null);
23748                         for (int i = 0; i < values.length; i++) {
23749                             dumpFlag(found, field.getName() + "[" + i + "]", values[i]);
23750                         }
23751                     }
23752                 }
23753             }
23754         } catch (IllegalAccessException e) {
23755             throw new RuntimeException(e);
23756         }
23757
23758         final ArrayList<String> keys = Lists.newArrayList();
23759         keys.addAll(found.keySet());
23760         Collections.sort(keys);
23761         for (String key : keys) {
23762             Log.d(VIEW_LOG_TAG, found.get(key));
23763         }
23764     }
23765
23766     private static void dumpFlag(HashMap<String, String> found, String name, int value) {
23767         // Sort flags by prefix, then by bits, always keeping unique keys
23768         final String bits = String.format("%32s", Integer.toBinaryString(value)).replace('0', ' ');
23769         final int prefix = name.indexOf('_');
23770         final String key = (prefix > 0 ? name.substring(0, prefix) : name) + bits + name;
23771         final String output = bits + " " + name;
23772         found.put(key, output);
23773     }
23774
23775     /** {@hide} */
23776     public void encode(@NonNull ViewHierarchyEncoder stream) {
23777         stream.beginObject(this);
23778         encodeProperties(stream);
23779         stream.endObject();
23780     }
23781
23782     /** {@hide} */
23783     @CallSuper
23784     protected void encodeProperties(@NonNull ViewHierarchyEncoder stream) {
23785         Object resolveId = ViewDebug.resolveId(getContext(), mID);
23786         if (resolveId instanceof String) {
23787             stream.addProperty("id", (String) resolveId);
23788         } else {
23789             stream.addProperty("id", mID);
23790         }
23791
23792         stream.addProperty("misc:transformation.alpha",
23793                 mTransformationInfo != null ? mTransformationInfo.mAlpha : 0);
23794         stream.addProperty("misc:transitionName", getTransitionName());
23795
23796         // layout
23797         stream.addProperty("layout:left", mLeft);
23798         stream.addProperty("layout:right", mRight);
23799         stream.addProperty("layout:top", mTop);
23800         stream.addProperty("layout:bottom", mBottom);
23801         stream.addProperty("layout:width", getWidth());
23802         stream.addProperty("layout:height", getHeight());
23803         stream.addProperty("layout:layoutDirection", getLayoutDirection());
23804         stream.addProperty("layout:layoutRtl", isLayoutRtl());
23805         stream.addProperty("layout:hasTransientState", hasTransientState());
23806         stream.addProperty("layout:baseline", getBaseline());
23807
23808         // layout params
23809         ViewGroup.LayoutParams layoutParams = getLayoutParams();
23810         if (layoutParams != null) {
23811             stream.addPropertyKey("layoutParams");
23812             layoutParams.encode(stream);
23813         }
23814
23815         // scrolling
23816         stream.addProperty("scrolling:scrollX", mScrollX);
23817         stream.addProperty("scrolling:scrollY", mScrollY);
23818
23819         // padding
23820         stream.addProperty("padding:paddingLeft", mPaddingLeft);
23821         stream.addProperty("padding:paddingRight", mPaddingRight);
23822         stream.addProperty("padding:paddingTop", mPaddingTop);
23823         stream.addProperty("padding:paddingBottom", mPaddingBottom);
23824         stream.addProperty("padding:userPaddingRight", mUserPaddingRight);
23825         stream.addProperty("padding:userPaddingLeft", mUserPaddingLeft);
23826         stream.addProperty("padding:userPaddingBottom", mUserPaddingBottom);
23827         stream.addProperty("padding:userPaddingStart", mUserPaddingStart);
23828         stream.addProperty("padding:userPaddingEnd", mUserPaddingEnd);
23829
23830         // measurement
23831         stream.addProperty("measurement:minHeight", mMinHeight);
23832         stream.addProperty("measurement:minWidth", mMinWidth);
23833         stream.addProperty("measurement:measuredWidth", mMeasuredWidth);
23834         stream.addProperty("measurement:measuredHeight", mMeasuredHeight);
23835
23836         // drawing
23837         stream.addProperty("drawing:elevation", getElevation());
23838         stream.addProperty("drawing:translationX", getTranslationX());
23839         stream.addProperty("drawing:translationY", getTranslationY());
23840         stream.addProperty("drawing:translationZ", getTranslationZ());
23841         stream.addProperty("drawing:rotation", getRotation());
23842         stream.addProperty("drawing:rotationX", getRotationX());
23843         stream.addProperty("drawing:rotationY", getRotationY());
23844         stream.addProperty("drawing:scaleX", getScaleX());
23845         stream.addProperty("drawing:scaleY", getScaleY());
23846         stream.addProperty("drawing:pivotX", getPivotX());
23847         stream.addProperty("drawing:pivotY", getPivotY());
23848         stream.addProperty("drawing:opaque", isOpaque());
23849         stream.addProperty("drawing:alpha", getAlpha());
23850         stream.addProperty("drawing:transitionAlpha", getTransitionAlpha());
23851         stream.addProperty("drawing:shadow", hasShadow());
23852         stream.addProperty("drawing:solidColor", getSolidColor());
23853         stream.addProperty("drawing:layerType", mLayerType);
23854         stream.addProperty("drawing:willNotDraw", willNotDraw());
23855         stream.addProperty("drawing:hardwareAccelerated", isHardwareAccelerated());
23856         stream.addProperty("drawing:willNotCacheDrawing", willNotCacheDrawing());
23857         stream.addProperty("drawing:drawingCacheEnabled", isDrawingCacheEnabled());
23858         stream.addProperty("drawing:overlappingRendering", hasOverlappingRendering());
23859
23860         // focus
23861         stream.addProperty("focus:hasFocus", hasFocus());
23862         stream.addProperty("focus:isFocused", isFocused());
23863         stream.addProperty("focus:isFocusable", isFocusable());
23864         stream.addProperty("focus:isFocusableInTouchMode", isFocusableInTouchMode());
23865
23866         stream.addProperty("misc:clickable", isClickable());
23867         stream.addProperty("misc:pressed", isPressed());
23868         stream.addProperty("misc:selected", isSelected());
23869         stream.addProperty("misc:touchMode", isInTouchMode());
23870         stream.addProperty("misc:hovered", isHovered());
23871         stream.addProperty("misc:activated", isActivated());
23872
23873         stream.addProperty("misc:visibility", getVisibility());
23874         stream.addProperty("misc:fitsSystemWindows", getFitsSystemWindows());
23875         stream.addProperty("misc:filterTouchesWhenObscured", getFilterTouchesWhenObscured());
23876
23877         stream.addProperty("misc:enabled", isEnabled());
23878         stream.addProperty("misc:soundEffectsEnabled", isSoundEffectsEnabled());
23879         stream.addProperty("misc:hapticFeedbackEnabled", isHapticFeedbackEnabled());
23880
23881         // theme attributes
23882         Resources.Theme theme = getContext().getTheme();
23883         if (theme != null) {
23884             stream.addPropertyKey("theme");
23885             theme.encode(stream);
23886         }
23887
23888         // view attribute information
23889         int n = mAttributes != null ? mAttributes.length : 0;
23890         stream.addProperty("meta:__attrCount__", n/2);
23891         for (int i = 0; i < n; i += 2) {
23892             stream.addProperty("meta:__attr__" + mAttributes[i], mAttributes[i+1]);
23893         }
23894
23895         stream.addProperty("misc:scrollBarStyle", getScrollBarStyle());
23896
23897         // text
23898         stream.addProperty("text:textDirection", getTextDirection());
23899         stream.addProperty("text:textAlignment", getTextAlignment());
23900
23901         // accessibility
23902         CharSequence contentDescription = getContentDescription();
23903         stream.addProperty("accessibility:contentDescription",
23904                 contentDescription == null ? "" : contentDescription.toString());
23905         stream.addProperty("accessibility:labelFor", getLabelFor());
23906         stream.addProperty("accessibility:importantForAccessibility", getImportantForAccessibility());
23907     }
23908
23909     /**
23910      * Determine if this view is rendered on a round wearable device and is the main view
23911      * on the screen.
23912      */
23913     private boolean shouldDrawRoundScrollbar() {
23914         if (!mResources.getConfiguration().isScreenRound()) {
23915             return false;
23916         }
23917
23918         final View rootView = getRootView();
23919         final WindowInsets insets = getRootWindowInsets();
23920
23921         int height = getHeight();
23922         int width = getWidth();
23923         int displayHeight = rootView.getHeight();
23924         int displayWidth = rootView.getWidth();
23925
23926         if (height != displayHeight || width != displayWidth) {
23927             return false;
23928         }
23929
23930         getLocationOnScreen(mAttachInfo.mTmpLocation);
23931         return mAttachInfo.mTmpLocation[0] == insets.getStableInsetLeft()
23932                 && mAttachInfo.mTmpLocation[1] == insets.getStableInsetTop();
23933     }
23934 }