Update switch assets, fix SearchView asset 9-patch areas

BUG: 16606037
BUG: 16467249
Change-Id: I9a5888e37317d1f8a6481f9733f784bbd37268f3
diff --git a/core/java/android/widget/Switch.java b/core/java/android/widget/Switch.java
index 8ea1090..682f2ae 100644
--- a/core/java/android/widget/Switch.java
+++ b/core/java/android/widget/Switch.java
@@ -100,13 +100,35 @@
     private int mMinFlingVelocity;
 
     private float mThumbPosition;
-    private int mSwitchWidth;
-    private int mSwitchHeight;
-    private int mThumbWidth; // Does not include padding
 
+    /**
+     * Width required to draw the switch track and thumb. Includes padding and
+     * optical bounds for both the track and thumb.
+     */
+    private int mSwitchWidth;
+
+    /**
+     * Height required to draw the switch track and thumb. Includes padding and
+     * optical bounds for both the track and thumb.
+     */
+    private int mSwitchHeight;
+
+    /**
+     * Width of the thumb's content region. Does not include padding or
+     * optical bounds.
+     */
+    private int mThumbWidth;
+
+    /** Left bound for drawing the switch track and thumb. */
     private int mSwitchLeft;
+
+    /** Top bound for drawing the switch track and thumb. */
     private int mSwitchTop;
+
+    /** Right bound for drawing the switch track and thumb. */
     private int mSwitchRight;
+
+    /** Bottom bound for drawing the switch track and thumb. */
     private int mSwitchBottom;
 
     private TextPaint mTextPaint;
@@ -539,7 +561,7 @@
      * Sets whether the on/off text should be displayed.
      *
      * @param showText {@code true} to display on/off text
-     * @hide
+     * @attr ref android.R.styleable#Switch_showText
      */
     public void setShowText(boolean showText) {
         if (mShowText != showText) {
@@ -550,7 +572,7 @@
 
     /**
      * @return whether the on/off text should be displayed
-     * @hide
+     * @attr ref android.R.styleable#Switch_showText
      */
     public boolean getShowText() {
         return mShowText;
@@ -568,8 +590,30 @@
             }
         }
 
-        final int trackHeight;
         final Rect padding = mTempRect;
+        final int thumbWidth;
+        final int thumbHeight;
+        if (mThumbDrawable != null) {
+            // Cached thumb width does not include padding.
+            mThumbDrawable.getPadding(padding);
+            thumbWidth = mThumbDrawable.getIntrinsicWidth() - padding.left - padding.right;
+            thumbHeight = mThumbDrawable.getIntrinsicHeight();
+        } else {
+            thumbWidth = 0;
+            thumbHeight = 0;
+        }
+
+        final int maxTextWidth;
+        if (mShowText) {
+            maxTextWidth = Math.max(mOnLayout.getWidth(), mOffLayout.getWidth())
+                    + mThumbTextPadding * 2;
+        } else {
+            maxTextWidth = 0;
+        }
+
+        mThumbWidth = Math.max(maxTextWidth, thumbWidth);
+
+        final int trackHeight;
         if (mTrackDrawable != null) {
             mTrackDrawable.getPadding(padding);
             trackHeight = mTrackDrawable.getIntrinsicHeight();
@@ -578,22 +622,18 @@
             trackHeight = 0;
         }
 
-        final int thumbWidth;
-        final int thumbHeight;
+        // Adjust left and right padding to ensure there's enough room for the
+        // thumb's padding (when present).
+        int paddingLeft = padding.left;
+        int paddingRight = padding.right;
         if (mThumbDrawable != null) {
-            thumbWidth = mThumbDrawable.getIntrinsicWidth();
-            thumbHeight = mThumbDrawable.getIntrinsicHeight();
-        } else {
-            thumbWidth = 0;
-            thumbHeight = 0;
+            final Insets inset = mThumbDrawable.getOpticalInsets();
+            paddingLeft = Math.max(paddingLeft, inset.left);
+            paddingRight = Math.max(paddingRight, inset.right);
         }
 
-        final int maxTextWidth = mShowText ? Math.max(mOnLayout.getWidth(), mOffLayout.getWidth())
-                + mThumbTextPadding * 2 : 0;
-        mThumbWidth = Math.max(maxTextWidth, thumbWidth);
-
         final int switchWidth = Math.max(mSwitchMinWidth,
-                2 * mThumbWidth + padding.left + padding.right);
+                2 * mThumbWidth + paddingLeft + paddingRight);
         final int switchHeight = Math.max(trackHeight, thumbHeight);
         mSwitchWidth = switchWidth;
         mSwitchHeight = switchHeight;
@@ -806,19 +846,33 @@
     protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
         super.onLayout(changed, left, top, right, bottom);
 
-        int switchRight;
-        int switchLeft;
+        int opticalInsetLeft = 0;
+        int opticalInsetRight = 0;
+        if (mThumbDrawable != null) {
+            final Rect trackPadding = mTempRect;
+            if (mTrackDrawable != null) {
+                mTrackDrawable.getPadding(trackPadding);
+            } else {
+                trackPadding.setEmpty();
+            }
 
-        if (isLayoutRtl()) {
-            switchLeft = getPaddingLeft();
-            switchRight = switchLeft + mSwitchWidth;
-        } else {
-            switchRight = getWidth() - getPaddingRight();
-            switchLeft = switchRight - mSwitchWidth;
+            final Insets insets = mThumbDrawable.getOpticalInsets();
+            opticalInsetLeft = Math.max(0, insets.left - trackPadding.left);
+            opticalInsetRight = Math.max(0, insets.right - trackPadding.right);
         }
 
-        int switchTop = 0;
-        int switchBottom = 0;
+        final int switchRight;
+        final int switchLeft;
+        if (isLayoutRtl()) {
+            switchLeft = getPaddingLeft() + opticalInsetLeft;
+            switchRight = switchLeft + mSwitchWidth - opticalInsetLeft - opticalInsetRight;
+        } else {
+            switchRight = getWidth() - getPaddingRight() - opticalInsetRight;
+            switchLeft = switchRight - mSwitchWidth + opticalInsetLeft + opticalInsetRight;
+        }
+
+        final int switchTop;
+        final int switchBottom;
         switch (getGravity() & Gravity.VERTICAL_GRAVITY_MASK) {
             default:
             case Gravity.TOP:
@@ -847,27 +901,55 @@
     @Override
     public void draw(Canvas c) {
         final Rect padding = mTempRect;
-
-        // Layout the track.
         final int switchLeft = mSwitchLeft;
         final int switchTop = mSwitchTop;
         final int switchRight = mSwitchRight;
         final int switchBottom = mSwitchBottom;
-        if (mTrackDrawable != null) {
-            mTrackDrawable.setBounds(switchLeft, switchTop, switchRight, switchBottom);
-            mTrackDrawable.getPadding(padding);
+
+        int thumbInitialLeft = switchLeft + getThumbOffset();
+
+        final Insets thumbInsets;
+        if (mThumbDrawable != null) {
+            thumbInsets = mThumbDrawable.getOpticalInsets();
+        } else {
+            thumbInsets = Insets.NONE;
         }
 
-        final int switchInnerLeft = switchLeft + padding.left;
+        // Layout the track.
+        if (mTrackDrawable != null) {
+            mTrackDrawable.getPadding(padding);
 
-        // Relies on mTempRect, MUST be called first!
-        final int thumbPos = getThumbOffset();
+            // Adjust thumb position for track padding.
+            thumbInitialLeft += padding.left;
+
+            // If necessary, offset by the optical insets of the thumb asset.
+            int trackLeft = switchLeft;
+            int trackTop = switchTop;
+            int trackRight = switchRight;
+            int trackBottom = switchBottom;
+            if (thumbInsets != Insets.NONE) {
+                if (thumbInsets.left > padding.left) {
+                    trackLeft += thumbInsets.left - padding.left;
+                }
+                if (thumbInsets.top > padding.top) {
+                    trackTop += thumbInsets.top - padding.top;
+                }
+                if (thumbInsets.right > padding.right) {
+                    trackRight -= thumbInsets.right - padding.right;
+                }
+                if (thumbInsets.bottom > padding.bottom) {
+                    trackBottom -= thumbInsets.bottom - padding.bottom;
+                }
+            }
+            mTrackDrawable.setBounds(trackLeft, trackTop, trackRight, trackBottom);
+        }
 
         // Layout the thumb.
         if (mThumbDrawable != null) {
             mThumbDrawable.getPadding(padding);
-            final int thumbLeft = switchInnerLeft - padding.left + thumbPos;
-            final int thumbRight = switchInnerLeft + thumbPos + mThumbWidth + padding.right;
+
+            final int thumbLeft = thumbInitialLeft - padding.left;
+            final int thumbRight = thumbInitialLeft + mThumbWidth + padding.right;
             mThumbDrawable.setBounds(thumbLeft, switchTop, thumbRight, switchBottom);
 
             final Drawable background = getBackground();
@@ -894,9 +976,7 @@
 
         final int switchTop = mSwitchTop;
         final int switchBottom = mSwitchBottom;
-        final int switchInnerLeft = mSwitchLeft + padding.left;
         final int switchInnerTop = switchTop + padding.top;
-        final int switchInnerRight = mSwitchRight - padding.right;
         final int switchInnerBottom = switchBottom - padding.bottom;
 
         final Drawable thumbDrawable = mThumbDrawable;
@@ -919,7 +999,6 @@
         final int saveCount = canvas.save();
 
         if (thumbDrawable != null) {
-            canvas.clipRect(switchInnerLeft, switchTop, switchInnerRight, switchBottom);
             thumbDrawable.draw(canvas);
         }
 
@@ -974,7 +1053,7 @@
 
     /**
      * Translates thumb position to offset according to current RTL setting and
-     * thumb scroll range.
+     * thumb scroll range. Accounts for both track and thumb padding.
      *
      * @return thumb offset
      */
@@ -990,8 +1069,18 @@
 
     private int getThumbScrollRange() {
         if (mTrackDrawable != null) {
-            mTrackDrawable.getPadding(mTempRect);
-            return mSwitchWidth - mThumbWidth - mTempRect.left - mTempRect.right;
+            final Rect padding = mTempRect;
+            mTrackDrawable.getPadding(padding);
+
+            final Insets insets;
+            if (mThumbDrawable != null) {
+                insets = mThumbDrawable.getOpticalInsets();
+            } else {
+                insets = Insets.NONE;
+            }
+
+            return mSwitchWidth - mThumbWidth - padding.left - padding.right
+                    - insets.left - insets.right;
         } else {
             return 0;
         }