Support hotspots in View drawables

BUG: 15285217
Change-Id: Iad44454fe16ac27ed20b9c17ae2df69649339eed
diff --git a/core/java/android/view/View.java b/core/java/android/view/View.java
index f75ae55..3aaedd6 100644
--- a/core/java/android/view/View.java
+++ b/core/java/android/view/View.java
@@ -90,6 +90,7 @@
 import com.android.internal.R;
 import com.android.internal.util.Predicate;
 import com.android.internal.view.menu.MenuBuilder;
+
 import com.google.android.collect.Lists;
 import com.google.android.collect.Maps;
 
@@ -4794,14 +4795,10 @@
      * @param v previous or the next focus holder, or null if none
      */
     private void manageFocusHotspot(boolean focused, View v) {
-        if (mBackground == null) {
-            return;
-        }
-
         final Rect r = new Rect();
         if (!focused && v != null) {
             v.getBoundsOnScreen(r);
-            final int[] location = new int[2];
+            final int[] location = mAttachInfo.mTmpLocation;
             getLocationOnScreen(location);
             r.offset(-location[0], -location[1]);
         } else {
@@ -4810,7 +4807,20 @@
 
         final float x = r.exactCenterX();
         final float y = r.exactCenterY();
-        mBackground.setHotspot(x, y);
+        setDrawableHotspot(x, y);
+    }
+
+    /**
+     * Sets the hotspot position for this View's drawables.
+     *
+     * @param x hotspot x coordinate
+     * @param y hotspot y coordinate
+     * @hide
+     */
+    protected void setDrawableHotspot(float x, float y) {
+        if (mBackground != null) {
+            mBackground.setHotspot(x, y);
+        }
     }
 
     /**
@@ -6767,7 +6777,7 @@
      */
     private void setPressed(boolean pressed, float x, float y) {
         if (pressed) {
-            setHotspot(x, y);
+            setDrawableHotspot(x, y);
         }
 
         setPressed(pressed);
@@ -9106,8 +9116,7 @@
                         postDelayed(mPendingCheckForTap, ViewConfiguration.getTapTimeout());
                     } else {
                         // Not inside a scrolling container, so show the feedback right away
-                        setHotspot(x, y);
-                        setPressed(true);
+                        setPressed(true, x, y);
                         checkForLongClick(0);
                     }
                     break;
@@ -9119,7 +9128,7 @@
                     break;
 
                 case MotionEvent.ACTION_MOVE:
-                    setHotspot(x, y);
+                    setDrawableHotspot(x, y);
 
                     // Be lenient about moving outside of buttons
                     if (!pointInView(x, y, mTouchSlop)) {
@@ -9141,12 +9150,6 @@
         return false;
     }
 
-    private void setHotspot(float x, float y) {
-        if (mBackground != null) {
-            mBackground.setHotspot(x, y);
-        }
-    }
-
     /**
      * @hide
      */
@@ -19761,6 +19764,11 @@
          */
         final int[] mInvalidateChildLocation = new int[2];
 
+        /**
+         * Global to the view hierarchy used as a temporary for dealng with
+         * computing absolute on-screen location.
+         */
+        final int[] mTmpLocation = new int[2];
 
         /**
          * Global to the view hierarchy used as a temporary for dealing with
diff --git a/core/java/android/widget/AbsSeekBar.java b/core/java/android/widget/AbsSeekBar.java
index 43f623b..08931fe 100644
--- a/core/java/android/widget/AbsSeekBar.java
+++ b/core/java/android/widget/AbsSeekBar.java
@@ -255,6 +255,22 @@
         }
     }
 
+    /** @hide */
+    @Override
+    protected void setDrawableHotspot(float x, float y) {
+        super.setDrawableHotspot(x, y);
+
+        final Drawable progressDrawable = getProgressDrawable();
+        if (progressDrawable != null) {
+            progressDrawable.setHotspot(x, y);
+        }
+
+        final Drawable thumb = mThumb;
+        if (thumb != null) {
+            thumb.setHotspot(x, y);
+        }
+    }
+
     @Override
     public void invalidateDrawable(Drawable dr) {
         super.invalidateDrawable(dr);
diff --git a/core/java/android/widget/CheckedTextView.java b/core/java/android/widget/CheckedTextView.java
index 3ae9508..7113793 100644
--- a/core/java/android/widget/CheckedTextView.java
+++ b/core/java/android/widget/CheckedTextView.java
@@ -307,6 +307,16 @@
         }
     }
 
+    /** @hide */
+    @Override
+    protected void setDrawableHotspot(float x, float y) {
+        super.setDrawableHotspot(x, y);
+
+        if (mCheckMarkDrawable != null) {
+            mCheckMarkDrawable.setHotspot(x, y);
+        }
+    }
+
     @Override
     public void onInitializeAccessibilityEvent(AccessibilityEvent event) {
         super.onInitializeAccessibilityEvent(event);
diff --git a/core/java/android/widget/CompoundButton.java b/core/java/android/widget/CompoundButton.java
index 6aff4f4..c934ad7 100644
--- a/core/java/android/widget/CompoundButton.java
+++ b/core/java/android/widget/CompoundButton.java
@@ -320,6 +320,16 @@
         }
     }
 
+    /** @hide */
+    @Override
+    protected void setDrawableHotspot(float x, float y) {
+        super.setDrawableHotspot(x, y);
+
+        if (mButtonDrawable != null) {
+            mButtonDrawable.setHotspot(x, y);
+        }
+    }
+
     @Override
     protected boolean verifyDrawable(Drawable who) {
         return super.verifyDrawable(who) || who == mButtonDrawable;
diff --git a/core/java/android/widget/FrameLayout.java b/core/java/android/widget/FrameLayout.java
index b029328..01a6b8a 100644
--- a/core/java/android/widget/FrameLayout.java
+++ b/core/java/android/widget/FrameLayout.java
@@ -205,6 +205,16 @@
         }
     }
 
+    /** @hide */
+    @Override
+    protected void setDrawableHotspot(float x, float y) {
+        super.setDrawableHotspot(x, y);
+
+        if (mForeground != null) {
+            mForeground.setHotspot(x, y);
+        }
+    }
+
     /**
      * Returns a set of layout parameters with a width of
      * {@link android.view.ViewGroup.LayoutParams#MATCH_PARENT},
diff --git a/core/java/android/widget/ImageView.java b/core/java/android/widget/ImageView.java
index 572302a4..a40b85e 100644
--- a/core/java/android/widget/ImageView.java
+++ b/core/java/android/widget/ImageView.java
@@ -1010,7 +1010,17 @@
         }
     }
 
-    @Override 
+    /** @hide */
+    @Override
+    protected void setDrawableHotspot(float x, float y) {
+        super.setDrawableHotspot(x, y);
+
+        if (mDrawable != null) {
+            mDrawable.setHotspot(x, y);
+        }
+    }
+
+    @Override
     protected void onDraw(Canvas canvas) {
         super.onDraw(canvas);
 
diff --git a/core/java/android/widget/ProgressBar.java b/core/java/android/widget/ProgressBar.java
index b49938c..af32f1c 100644
--- a/core/java/android/widget/ProgressBar.java
+++ b/core/java/android/widget/ProgressBar.java
@@ -1144,6 +1144,20 @@
         }
     }
 
+    /** @hide */
+    @Override
+    protected void setDrawableHotspot(float x, float y) {
+        super.setDrawableHotspot(x, y);
+
+        if (mProgressDrawable != null) {
+            mProgressDrawable.setHotspot(x, y);
+        }
+
+        if (mIndeterminateDrawable != null) {
+            mIndeterminateDrawable.setHotspot(x, y);
+        }
+    }
+
     static class SavedState extends BaseSavedState {
         int progress;
         int secondaryProgress;
diff --git a/core/java/android/widget/QuickContactBadge.java b/core/java/android/widget/QuickContactBadge.java
index 0c31496..14d782d 100644
--- a/core/java/android/widget/QuickContactBadge.java
+++ b/core/java/android/widget/QuickContactBadge.java
@@ -112,6 +112,16 @@
         }
     }
 
+    /** @hide */
+    @Override
+    protected void setDrawableHotspot(float x, float y) {
+        super.setDrawableHotspot(x, y);
+
+        if (mOverlay != null) {
+            mOverlay.setHotspot(x, y);
+        }
+    }
+
     /** This call has no effect anymore, as there is only one QuickContact mode */
     @SuppressWarnings("unused")
     public void setMode(int size) {
diff --git a/core/java/android/widget/Switch.java b/core/java/android/widget/Switch.java
index c5c6e64..03193a2 100644
--- a/core/java/android/widget/Switch.java
+++ b/core/java/android/widget/Switch.java
@@ -962,6 +962,20 @@
         invalidate();
     }
 
+    /** @hide */
+    @Override
+    protected void setDrawableHotspot(float x, float y) {
+        super.setDrawableHotspot(x, y);
+
+        if (mThumbDrawable != null) {
+            mThumbDrawable.setHotspot(x, y);
+        }
+
+        if (mTrackDrawable != null) {
+            mTrackDrawable.setHotspot(x, y);
+        }
+    }
+
     @Override
     public void invalidateDrawable(Drawable drawable) {
         super.invalidateDrawable(drawable);
diff --git a/core/java/android/widget/TextView.java b/core/java/android/widget/TextView.java
index 84202eb..22f5e23 100644
--- a/core/java/android/widget/TextView.java
+++ b/core/java/android/widget/TextView.java
@@ -2551,7 +2551,7 @@
             r = c.getResources();
 
         setRawTextSize(TypedValue.applyDimension(
-            unit, size, r.getDisplayMetrics()));
+                unit, size, r.getDisplayMetrics()));
     }
 
     private void setRawTextSize(float size) {
@@ -3505,6 +3505,34 @@
         }
     }
 
+    /** @hide */
+    @Override
+    protected void setDrawableHotspot(float x, float y) {
+        super.setDrawableHotspot(x, y);
+
+        final Drawables dr = mDrawables;
+        if (dr != null) {
+            if (dr.mDrawableTop != null) {
+                dr.mDrawableTop.setHotspot(x, y);
+            }
+            if (dr.mDrawableBottom != null) {
+                dr.mDrawableBottom.setHotspot(x, y);
+            }
+            if (dr.mDrawableLeft != null) {
+                dr.mDrawableLeft.setHotspot(x, y);
+            }
+            if (dr.mDrawableRight != null) {
+                dr.mDrawableRight.setHotspot(x, y);
+            }
+            if (dr.mDrawableStart != null) {
+                dr.mDrawableStart.setHotspot(x, y);
+            }
+            if (dr.mDrawableEnd != null) {
+                dr.mDrawableEnd.setHotspot(x, y);
+            }
+        }
+    }
+
     @Override
     public Parcelable onSaveInstanceState() {
         Parcelable superState = super.onSaveInstanceState();