Updating more spans

Test: N/A
Bug: 72092996
Change-Id: Iecd3595a03cde2a1d58e4be00b7cf9b6783d4e2a
diff --git a/core/java/android/text/style/DrawableMarginSpan.java b/core/java/android/text/style/DrawableMarginSpan.java
index 3524179..cd199b3 100644
--- a/core/java/android/text/style/DrawableMarginSpan.java
+++ b/core/java/android/text/style/DrawableMarginSpan.java
@@ -16,60 +16,100 @@
 
 package android.text.style;
 
+import android.annotation.NonNull;
+import android.annotation.Px;
 import android.graphics.Canvas;
 import android.graphics.Paint;
 import android.graphics.drawable.Drawable;
 import android.text.Layout;
 import android.text.Spanned;
 
-public class DrawableMarginSpan
-implements LeadingMarginSpan, LineHeightSpan
-{
-    public DrawableMarginSpan(Drawable b) {
-        mDrawable = b;
+/**
+ * A span which adds a drawable and a padding to the paragraph it's attached to.
+ * <p>
+ * If the height of the drawable is bigger than the height of the line it's attached to then the
+ * line height is increased to fit the drawable. <code>DrawableMarginSpan</code> allows setting a
+ * padding between the drawable and the text. The default value is 0. The span must be set from the
+ * beginning of the text, otherwise either the span won't be rendered or it will be rendered
+ * incorrectly.
+ * <p>
+ * For example, a drawable and a padding of 20px can be added like this:
+ * <pre>{@code SpannableString string = new SpannableString("Text with a drawable.");
+ * string.setSpan(new DrawableMarginSpan(drawable, 20), 0, string.length(),
+ * Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);}</pre>
+ * <img src="{@docRoot}reference/android/images/text/style/drawablemarginspan.png" />
+ * <figcaption>Text with a drawable and a padding.</figcaption>
+ * <p>
+ *
+ * @see IconMarginSpan for working with a {@link android.graphics.Bitmap} instead of
+ * a {@link Drawable}.
+ */
+public class DrawableMarginSpan implements LeadingMarginSpan, LineHeightSpan {
+    private static final int STANDARD_PAD_WIDTH = 0;
+
+    @NonNull
+    private final Drawable mDrawable;
+    @Px
+    private final int mPad;
+
+    /**
+     * Creates a {@link DrawableMarginSpan} from a {@link Drawable}. The pad width will be 0.
+     *
+     * @param drawable the drawable to be added
+     */
+    public DrawableMarginSpan(@NonNull Drawable drawable) {
+        this(drawable, STANDARD_PAD_WIDTH);
     }
 
-    public DrawableMarginSpan(Drawable b, int pad) {
-        mDrawable = b;
+    /**
+     * Creates a {@link DrawableMarginSpan} from a {@link Drawable} and a padding, in pixels.
+     *
+     * @param drawable the drawable to be added
+     * @param pad      the distance between the drawable and the text
+     */
+    public DrawableMarginSpan(@NonNull Drawable drawable, int pad) {
+        mDrawable = drawable;
         mPad = pad;
     }
 
+    @Override
     public int getLeadingMargin(boolean first) {
         return mDrawable.getIntrinsicWidth() + mPad;
     }
 
-    public void drawLeadingMargin(Canvas c, Paint p, int x, int dir,
-                                  int top, int baseline, int bottom,
-                                  CharSequence text, int start, int end,
-                                  boolean first, Layout layout) {
+    @Override
+    public void drawLeadingMargin(@NonNull Canvas c, @NonNull Paint p, int x, int dir,
+            int top, int baseline, int bottom,
+            @NonNull CharSequence text, int start, int end,
+            boolean first, @NonNull Layout layout) {
         int st = ((Spanned) text).getSpanStart(this);
-        int ix = (int)x;
-        int itop = (int)layout.getLineTop(layout.getLineForOffset(st));
+        int ix = (int) x;
+        int itop = (int) layout.getLineTop(layout.getLineForOffset(st));
 
         int dw = mDrawable.getIntrinsicWidth();
         int dh = mDrawable.getIntrinsicHeight();
 
         // XXX What to do about Paint?
-        mDrawable.setBounds(ix, itop, ix+dw, itop+dh);
+        mDrawable.setBounds(ix, itop, ix + dw, itop + dh);
         mDrawable.draw(c);
     }
 
-    public void chooseHeight(CharSequence text, int start, int end,
-                             int istartv, int v,
-                             Paint.FontMetricsInt fm) {
+    @Override
+    public void chooseHeight(@NonNull CharSequence text, int start, int end,
+            int istartv, int v,
+            @NonNull Paint.FontMetricsInt fm) {
         if (end == ((Spanned) text).getSpanEnd(this)) {
             int ht = mDrawable.getIntrinsicHeight();
 
             int need = ht - (v + fm.descent - fm.ascent - istartv);
-            if (need > 0)
+            if (need > 0) {
                 fm.descent += need;
+            }
 
             need = ht - (v + fm.bottom - fm.top - istartv);
-            if (need > 0)
+            if (need > 0) {
                 fm.bottom += need;
+            }
         }
     }
-
-    private Drawable mDrawable;
-    private int mPad;
 }
diff --git a/core/java/android/text/style/DynamicDrawableSpan.java b/core/java/android/text/style/DynamicDrawableSpan.java
index 5b8a6dd..1b16f33 100644
--- a/core/java/android/text/style/DynamicDrawableSpan.java
+++ b/core/java/android/text/style/DynamicDrawableSpan.java
@@ -16,6 +16,9 @@
 
 package android.text.style;
 
+import android.annotation.IntRange;
+import android.annotation.NonNull;
+import android.annotation.Nullable;
 import android.graphics.Canvas;
 import android.graphics.Paint;
 import android.graphics.Rect;
@@ -24,32 +27,71 @@
 import java.lang.ref.WeakReference;
 
 /**
+ * Span that replaces the text it's attached to with a {@link Drawable} that can be aligned with
+ * the bottom or with the baseline of the surrounding text.
+ * <p>
+ * For an implementation that constructs the drawable from various sources (<code>Bitmap</code>,
+ * <code>Drawable</code>, resource id or <code>Uri</code>) use {@link ImageSpan}.
+ * <p>
+ * A simple implementation of <code>DynamicDrawableSpan</code> that uses drawables from resources
+ * looks like this:
+ * <pre>
+ * class MyDynamicDrawableSpan extends DynamicDrawableSpan {
  *
+ * private final Context mContext;
+ * private final int mResourceId;
+ *
+ * public MyDynamicDrawableSpan(Context context, @DrawableRes int resourceId) {
+ *     mContext = context;
+ *     mResourceId = resourceId;
+ * }
+ *
+ * {@literal @}Override
+ * public Drawable getDrawable() {
+ *      Drawable drawable = mContext.getDrawable(mResourceId);
+ *      drawable.setBounds(0, 0, drawable.getIntrinsicWidth(), drawable.getIntrinsicHeight());
+ *      return drawable;
+ * }
+ * }</pre>
+ * The class can be used like this:
+ * <pre>
+ * SpannableString string = new SpannableString("Text with a drawable span");
+ * string.setSpan(new MyDynamicDrawableSpan(context, R.mipmap.ic_launcher), 12, 20, Spanned
+ * .SPAN_EXCLUSIVE_EXCLUSIVE);</pre>
+ * <img src="{@docRoot}reference/android/images/text/style/dynamicdrawablespan.png" />
+ * <figcaption>Replacing text with a drawable.</figcaption>
  */
 public abstract class DynamicDrawableSpan extends ReplacementSpan {
-    private static final String TAG = "DynamicDrawableSpan";
-    
+
     /**
      * A constant indicating that the bottom of this span should be aligned
      * with the bottom of the surrounding text, i.e., at the same level as the
      * lowest descender in the text.
      */
     public static final int ALIGN_BOTTOM = 0;
-    
+
     /**
      * A constant indicating that the bottom of this span should be aligned
      * with the baseline of the surrounding text.
      */
     public static final int ALIGN_BASELINE = 1;
-    
+
     protected final int mVerticalAlignment;
-    
+
+    private WeakReference<Drawable> mDrawableRef;
+
+    /**
+     * Creates a {@link DynamicDrawableSpan}. The default vertical alignment is
+     * {@link #ALIGN_BOTTOM}
+     */
     public DynamicDrawableSpan() {
         mVerticalAlignment = ALIGN_BOTTOM;
     }
 
     /**
-     * @param verticalAlignment one of {@link #ALIGN_BOTTOM} or {@link #ALIGN_BASELINE}.
+     * Creates a {@link DynamicDrawableSpan} based on a vertical alignment.\
+     *
+     * @param verticalAlignment one of {@link #ALIGN_BOTTOM} or {@link #ALIGN_BASELINE}
      */
     protected DynamicDrawableSpan(int verticalAlignment) {
         mVerticalAlignment = verticalAlignment;
@@ -64,22 +106,22 @@
     }
 
     /**
-     * Your subclass must implement this method to provide the bitmap   
+     * Your subclass must implement this method to provide the bitmap
      * to be drawn.  The dimensions of the bitmap must be the same
      * from each call to the next.
      */
     public abstract Drawable getDrawable();
 
     @Override
-    public int getSize(Paint paint, CharSequence text,
-                         int start, int end,
-                         Paint.FontMetricsInt fm) {
+    public int getSize(@NonNull Paint paint, CharSequence text,
+            @IntRange(from = 0) int start, @IntRange(from = 0) int end,
+            @Nullable Paint.FontMetricsInt fm) {
         Drawable d = getCachedDrawable();
         Rect rect = d.getBounds();
 
         if (fm != null) {
-            fm.ascent = -rect.bottom; 
-            fm.descent = 0; 
+            fm.ascent = -rect.bottom;
+            fm.descent = 0;
 
             fm.top = fm.ascent;
             fm.bottom = 0;
@@ -89,12 +131,12 @@
     }
 
     @Override
-    public void draw(Canvas canvas, CharSequence text,
-                     int start, int end, float x, 
-                     int top, int y, int bottom, Paint paint) {
+    public void draw(@NonNull Canvas canvas, CharSequence text,
+            @IntRange(from = 0) int start, @IntRange(from = 0) int end, float x,
+            int top, int y, int bottom, @NonNull Paint paint) {
         Drawable b = getCachedDrawable();
         canvas.save();
-        
+
         int transY = bottom - b.getBounds().bottom;
         if (mVerticalAlignment == ALIGN_BASELINE) {
             transY -= paint.getFontMetricsInt().descent;
@@ -109,8 +151,9 @@
         WeakReference<Drawable> wr = mDrawableRef;
         Drawable d = null;
 
-        if (wr != null)
+        if (wr != null) {
             d = wr.get();
+        }
 
         if (d == null) {
             d = getDrawable();
@@ -119,7 +162,5 @@
 
         return d;
     }
-
-    private WeakReference<Drawable> mDrawableRef;
 }
 
diff --git a/core/java/android/text/style/IconMarginSpan.java b/core/java/android/text/style/IconMarginSpan.java
index 304c83f..ad78bd5 100644
--- a/core/java/android/text/style/IconMarginSpan.java
+++ b/core/java/android/text/style/IconMarginSpan.java
@@ -16,57 +16,98 @@
 
 package android.text.style;
 
+import android.annotation.IntRange;
+import android.annotation.NonNull;
+import android.annotation.Px;
 import android.graphics.Bitmap;
 import android.graphics.Canvas;
 import android.graphics.Paint;
 import android.text.Layout;
 import android.text.Spanned;
 
-public class IconMarginSpan
-implements LeadingMarginSpan, LineHeightSpan
-{
-    public IconMarginSpan(Bitmap b) {
-        mBitmap = b;
+/**
+ * Paragraph affecting span, that draws a bitmap at the beginning of a text. The span also allows
+ * setting a padding between the bitmap and the text. The default value of the padding is 0px. The
+ * span should be attached from the first character of the text.
+ * <p>
+ * For example, an <code>IconMarginSpan</code> with a bitmap and a padding of 30px can be set
+ * like this:
+ * <pre>
+ * SpannableString string = new SpannableString("Text with icon and padding");
+ * string.setSpan(new IconMarginSpan(bitmap, 30), 0, string.length(),
+ * Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
+ * </pre>
+ * <img src="{@docRoot}reference/android/images/text/style/iconmarginspan.png" />
+ * <figcaption>Text with <code>IconMarginSpan</code></figcaption>
+ * <p>
+ *
+ * @see DrawableMarginSpan for working with a {@link android.graphics.drawable.Drawable} instead of
+ * a {@link Bitmap}.
+ */
+public class IconMarginSpan implements LeadingMarginSpan, LineHeightSpan {
+
+    @NonNull
+    private final Bitmap mBitmap;
+    @Px
+    private final int mPad;
+
+    /**
+     * Creates an {@link IconMarginSpan} from a {@link Bitmap}.
+     *
+     * @param bitmap bitmap to be rendered at the beginning of the text
+     */
+    public IconMarginSpan(@NonNull Bitmap bitmap) {
+        this(bitmap, 0);
     }
 
-    public IconMarginSpan(Bitmap b, int pad) {
-        mBitmap = b;
+    /**
+     * Creates an {@link IconMarginSpan} from a {@link Bitmap}.
+     *
+     * @param bitmap bitmap to be rendered at the beginning of the text
+     * @param pad    padding width, in pixels, between the bitmap and the text
+     */
+    public IconMarginSpan(@NonNull Bitmap bitmap, @IntRange(from = 0) int pad) {
+        mBitmap = bitmap;
         mPad = pad;
     }
 
+    @Override
     public int getLeadingMargin(boolean first) {
         return mBitmap.getWidth() + mPad;
     }
 
+    @Override
     public void drawLeadingMargin(Canvas c, Paint p, int x, int dir,
-                                  int top, int baseline, int bottom,
-                                  CharSequence text, int start, int end,
-                                  boolean first, Layout layout) {
+            int top, int baseline, int bottom,
+            CharSequence text, int start, int end,
+            boolean first, Layout layout) {
         int st = ((Spanned) text).getSpanStart(this);
         int itop = layout.getLineTop(layout.getLineForOffset(st));
 
-        if (dir < 0)
+        if (dir < 0) {
             x -= mBitmap.getWidth();
+        }
 
         c.drawBitmap(mBitmap, x, itop, p);
     }
 
+    @Override
     public void chooseHeight(CharSequence text, int start, int end,
-                             int istartv, int v,
-                             Paint.FontMetricsInt fm) {
+            int istartv, int v,
+            Paint.FontMetricsInt fm) {
         if (end == ((Spanned) text).getSpanEnd(this)) {
             int ht = mBitmap.getHeight();
 
             int need = ht - (v + fm.descent - fm.ascent - istartv);
-            if (need > 0)
+            if (need > 0) {
                 fm.descent += need;
+            }
 
             need = ht - (v + fm.bottom - fm.top - istartv);
-            if (need > 0)
+            if (need > 0) {
                 fm.bottom += need;
+            }
         }
     }
 
-    private Bitmap mBitmap;
-    private int mPad;
 }
diff --git a/core/java/android/text/style/ImageSpan.java b/core/java/android/text/style/ImageSpan.java
index b0bff68..95f0b43 100644
--- a/core/java/android/text/style/ImageSpan.java
+++ b/core/java/android/text/style/ImageSpan.java
@@ -17,6 +17,8 @@
 package android.text.style;
 
 import android.annotation.DrawableRes;
+import android.annotation.NonNull;
+import android.annotation.Nullable;
 import android.content.Context;
 import android.graphics.Bitmap;
 import android.graphics.BitmapFactory;
@@ -27,18 +29,49 @@
 
 import java.io.InputStream;
 
+/**
+ * Span that replaces the text it's attached to with a {@link Drawable} that can be aligned with
+ * the bottom or with the baseline of the surrounding text. The drawable can be constructed from
+ * varied sources:
+ * <ul>
+ * <li>{@link Bitmap} - see {@link #ImageSpan(Context, Bitmap)} and
+ * {@link #ImageSpan(Context, Bitmap, int)}
+ * </li>
+ * <li>{@link Drawable} - see {@link #ImageSpan(Drawable, int)}</li>
+ * <li>resource id - see {@link #ImageSpan(Context, int, int)}</li>
+ * <li>{@link Uri} - see {@link #ImageSpan(Context, Uri, int)}</li>
+ * </ul>
+ * The default value for the vertical alignment is {@link DynamicDrawableSpan#ALIGN_BOTTOM}
+ * <p>
+ * For example, an <code>ImagedSpan</code> can be used like this:
+ * <pre>
+ * SpannableString string = SpannableString("Bottom: span.\nBaseline: span.");
+ * // using the default alignment: ALIGN_BOTTOM
+ * string.setSpan(ImageSpan(this, R.mipmap.ic_launcher), 7, 8, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
+ * string.setSpan(ImageSpan(this, R.mipmap.ic_launcher, DynamicDrawableSpan.ALIGN_BASELINE),
+ * 22, 23, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
+ * </pre>
+ * <img src="{@docRoot}reference/android/images/text/style/imagespan.png" />
+ * <figcaption>Text with <code>ImageSpan</code>s aligned bottom and baseline.</figcaption>
+ */
 public class ImageSpan extends DynamicDrawableSpan {
+
+    @Nullable
     private Drawable mDrawable;
+    @Nullable
     private Uri mContentUri;
+    @DrawableRes
     private int mResourceId;
+    @Nullable
     private Context mContext;
+    @Nullable
     private String mSource;
 
     /**
      * @deprecated Use {@link #ImageSpan(Context, Bitmap)} instead.
      */
     @Deprecated
-    public ImageSpan(Bitmap b) {
+    public ImageSpan(@NonNull Bitmap b) {
         this(null, b, ALIGN_BOTTOM);
     }
 
@@ -46,80 +79,143 @@
      * @deprecated Use {@link #ImageSpan(Context, Bitmap, int)} instead.
      */
     @Deprecated
-    public ImageSpan(Bitmap b, int verticalAlignment) {
+    public ImageSpan(@NonNull Bitmap b, int verticalAlignment) {
         this(null, b, verticalAlignment);
     }
 
-    public ImageSpan(Context context, Bitmap b) {
-        this(context, b, ALIGN_BOTTOM);
+    /**
+     * Constructs an {@link ImageSpan} from a {@link Context} and a {@link Bitmap} with the default
+     * alignment {@link DynamicDrawableSpan#ALIGN_BOTTOM}
+     *
+     * @param context context used to create a drawable from {@param bitmap} based on the display
+     *                metrics of the resources
+     * @param bitmap  bitmap to be rendered
+     */
+    public ImageSpan(@NonNull Context context, @NonNull Bitmap bitmap) {
+        this(context, bitmap, ALIGN_BOTTOM);
     }
 
     /**
+     * Constructs an {@link ImageSpan} from a {@link Context}, a {@link Bitmap} and a vertical
+     * alignment.
+     *
+     * @param context           context used to create a drawable from {@param bitmap} based on
+     *                          the display metrics of the resources
+     * @param bitmap            bitmap to be rendered
      * @param verticalAlignment one of {@link DynamicDrawableSpan#ALIGN_BOTTOM} or
-     * {@link DynamicDrawableSpan#ALIGN_BASELINE}.
+     *                          {@link DynamicDrawableSpan#ALIGN_BASELINE}
      */
-    public ImageSpan(Context context, Bitmap b, int verticalAlignment) {
+    public ImageSpan(@NonNull Context context, @NonNull Bitmap bitmap, int verticalAlignment) {
         super(verticalAlignment);
         mContext = context;
         mDrawable = context != null
-                ? new BitmapDrawable(context.getResources(), b)
-                : new BitmapDrawable(b);
+                ? new BitmapDrawable(context.getResources(), bitmap)
+                : new BitmapDrawable(bitmap);
         int width = mDrawable.getIntrinsicWidth();
         int height = mDrawable.getIntrinsicHeight();
-        mDrawable.setBounds(0, 0, width > 0 ? width : 0, height > 0 ? height : 0); 
-    }
-
-    public ImageSpan(Drawable d) {
-        this(d, ALIGN_BOTTOM);
+        mDrawable.setBounds(0, 0, width > 0 ? width : 0, height > 0 ? height : 0);
     }
 
     /**
-     * @param verticalAlignment one of {@link DynamicDrawableSpan#ALIGN_BOTTOM} or
-     * {@link DynamicDrawableSpan#ALIGN_BASELINE}.
+     * Constructs an {@link ImageSpan} from a drawable with the default
+     * alignment {@link DynamicDrawableSpan#ALIGN_BOTTOM}.
+     *
+     * @param drawable drawable to be rendered
      */
-    public ImageSpan(Drawable d, int verticalAlignment) {
-        super(verticalAlignment);
-        mDrawable = d;
-    }
-
-    public ImageSpan(Drawable d, String source) {
-        this(d, source, ALIGN_BOTTOM);
+    public ImageSpan(@NonNull Drawable drawable) {
+        this(drawable, ALIGN_BOTTOM);
     }
 
     /**
+     * Constructs an {@link ImageSpan} from a drawable and a vertical alignment.
+     *
+     * @param drawable          drawable to be rendered
      * @param verticalAlignment one of {@link DynamicDrawableSpan#ALIGN_BOTTOM} or
-     * {@link DynamicDrawableSpan#ALIGN_BASELINE}.
+     *                          {@link DynamicDrawableSpan#ALIGN_BASELINE}
      */
-    public ImageSpan(Drawable d, String source, int verticalAlignment) {
+    public ImageSpan(@NonNull Drawable drawable, int verticalAlignment) {
         super(verticalAlignment);
-        mDrawable = d;
+        mDrawable = drawable;
+    }
+
+    /**
+     * Constructs an {@link ImageSpan} from a drawable and a source with the default
+     * alignment {@link DynamicDrawableSpan#ALIGN_BOTTOM}
+     *
+     * @param drawable drawable to be rendered
+     * @param source   drawable's Uri source
+     */
+    public ImageSpan(@NonNull Drawable drawable, @NonNull String source) {
+        this(drawable, source, ALIGN_BOTTOM);
+    }
+
+    /**
+     * Constructs an {@link ImageSpan} from a drawable, a source and a vertical alignment.
+     *
+     * @param drawable          drawable to be rendered
+     * @param source            drawable's uri source
+     * @param verticalAlignment one of {@link DynamicDrawableSpan#ALIGN_BOTTOM} or
+     *                          {@link DynamicDrawableSpan#ALIGN_BASELINE}
+     */
+    public ImageSpan(@NonNull Drawable drawable, @NonNull String source, int verticalAlignment) {
+        super(verticalAlignment);
+        mDrawable = drawable;
         mSource = source;
     }
 
-    public ImageSpan(Context context, Uri uri) {
+    /**
+     * Constructs an {@link ImageSpan} from a {@link Context} and a {@link Uri} with the default
+     * alignment {@link DynamicDrawableSpan#ALIGN_BOTTOM}. The Uri source can be retrieved via
+     * {@link #getSource()}
+     *
+     * @param context context used to create a drawable from {@param bitmap} based on the display
+     *                metrics of the resources
+     * @param uri     {@link Uri} used to construct the drawable that will be rendered
+     */
+    public ImageSpan(@NonNull Context context, @NonNull Uri uri) {
         this(context, uri, ALIGN_BOTTOM);
     }
 
     /**
+     * Constructs an {@link ImageSpan} from a {@link Context}, a {@link Uri} and a vertical
+     * alignment. The Uri source can be retrieved via {@link #getSource()}
+     *
+     * @param context           context used to create a drawable from {@param bitmap} based on
+     *                          the display
+     *                          metrics of the resources
+     * @param uri               {@link Uri} used to construct the drawable that will be rendered.
      * @param verticalAlignment one of {@link DynamicDrawableSpan#ALIGN_BOTTOM} or
-     * {@link DynamicDrawableSpan#ALIGN_BASELINE}.
+     *                          {@link DynamicDrawableSpan#ALIGN_BASELINE}
      */
-    public ImageSpan(Context context, Uri uri, int verticalAlignment) {
+    public ImageSpan(@NonNull Context context, @NonNull Uri uri, int verticalAlignment) {
         super(verticalAlignment);
         mContext = context;
         mContentUri = uri;
         mSource = uri.toString();
     }
 
-    public ImageSpan(Context context, @DrawableRes int resourceId) {
+    /**
+     * Constructs an {@link ImageSpan} from a {@link Context} and a resource id with the default
+     * alignment {@link DynamicDrawableSpan#ALIGN_BOTTOM}
+     *
+     * @param context    context used to retrieve the drawable from resources
+     * @param resourceId drawable resource id based on which the drawable is retrieved
+     */
+    public ImageSpan(@NonNull Context context, @DrawableRes int resourceId) {
         this(context, resourceId, ALIGN_BOTTOM);
     }
 
     /**
+     * Constructs an {@link ImageSpan} from a {@link Context}, a resource id and a vertical
+     * alignment.
+     *
+     * @param context           context used to retrieve the drawable from resources
+     * @param resourceId        drawable resource id based on which the drawable is retrieved.
      * @param verticalAlignment one of {@link DynamicDrawableSpan#ALIGN_BOTTOM} or
-     * {@link DynamicDrawableSpan#ALIGN_BASELINE}.
+     *                          {@link DynamicDrawableSpan#ALIGN_BASELINE}
      */
-    public ImageSpan(Context context, @DrawableRes int resourceId, int verticalAlignment) {
+    public ImageSpan(@NonNull Context context, @DrawableRes int resourceId,
+            int verticalAlignment) {
         super(verticalAlignment);
         mContext = context;
         mResourceId = resourceId;
@@ -128,10 +224,10 @@
     @Override
     public Drawable getDrawable() {
         Drawable drawable = null;
-        
+
         if (mDrawable != null) {
             drawable = mDrawable;
-        } else  if (mContentUri != null) {
+        } else if (mContentUri != null) {
             Bitmap bitmap = null;
             try {
                 InputStream is = mContext.getContentResolver().openInputStream(
@@ -142,7 +238,7 @@
                         drawable.getIntrinsicHeight());
                 is.close();
             } catch (Exception e) {
-                Log.e("sms", "Failed to loaded content " + mContentUri, e);
+                Log.e("ImageSpan", "Failed to loaded content " + mContentUri, e);
             }
         } else {
             try {
@@ -150,8 +246,8 @@
                 drawable.setBounds(0, 0, drawable.getIntrinsicWidth(),
                         drawable.getIntrinsicHeight());
             } catch (Exception e) {
-                Log.e("sms", "Unable to find resource: " + mResourceId);
-            }                
+                Log.e("ImageSpan", "Unable to find resource: " + mResourceId);
+            }
         }
 
         return drawable;
@@ -159,9 +255,12 @@
 
     /**
      * Returns the source string that was saved during construction.
+     *
+     * @return the source string that was saved during construction
+     * @see #ImageSpan(Drawable, String) and this{@link #ImageSpan(Context, Uri)}
      */
+    @Nullable
     public String getSource() {
         return mSource;
     }
-
 }
diff --git a/core/java/android/text/style/LineHeightSpan.java b/core/java/android/text/style/LineHeightSpan.java
index 1ebee82..50ee5f3 100644
--- a/core/java/android/text/style/LineHeightSpan.java
+++ b/core/java/android/text/style/LineHeightSpan.java
@@ -19,16 +19,42 @@
 import android.graphics.Paint;
 import android.text.TextPaint;
 
-public interface LineHeightSpan
-extends ParagraphStyle, WrapTogetherSpan
-{
+/**
+ * The classes that affect the height of the line should implement this interface.
+ */
+public interface LineHeightSpan extends ParagraphStyle, WrapTogetherSpan {
+    /**
+     * Classes that implement this should define how the height is being calculated.
+     *
+     * @param text       the text
+     * @param start      the start of the line
+     * @param end        the end of the line
+     * @param spanstartv the start of the span
+     * @param lineHeight the line height
+     * @param fm         font metrics of the paint, in integers
+     */
     public void chooseHeight(CharSequence text, int start, int end,
-                             int spanstartv, int v,
-                             Paint.FontMetricsInt fm);
+            int spanstartv, int lineHeight,
+            Paint.FontMetricsInt fm);
 
+    /**
+     * The classes that affect the height of the line with respect to density, should implement this
+     * interface.
+     */
     public interface WithDensity extends LineHeightSpan {
+
+        /**
+         * Classes that implement this should define how the height is being calculated.
+         *
+         * @param text       the text
+         * @param start      the start of the line
+         * @param end        the end of the line
+         * @param spanstartv the start of the span
+         * @param lineHeight the line height
+         * @param paint      the paint
+         */
         public void chooseHeight(CharSequence text, int start, int end,
-                                 int spanstartv, int v,
-                                 Paint.FontMetricsInt fm, TextPaint paint);
+                int spanstartv, int lineHeight,
+                Paint.FontMetricsInt fm, TextPaint paint);
     }
 }
diff --git a/core/java/android/text/style/MaskFilterSpan.java b/core/java/android/text/style/MaskFilterSpan.java
index 2ff52a8f..d76ef94 100644
--- a/core/java/android/text/style/MaskFilterSpan.java
+++ b/core/java/android/text/style/MaskFilterSpan.java
@@ -18,15 +18,36 @@
 
 import android.graphics.MaskFilter;
 import android.text.TextPaint;
-
+/**
+ * Span that allows setting a {@link MaskFilter} to the text it's attached to.
+ * <p>
+ * For example, to blur a text, a {@link android.graphics.BlurMaskFilter} can be used:
+ * <pre>
+ * MaskFilter blurMask = new BlurMaskFilter(5f, BlurMaskFilter.Blur.NORMAL);
+ * SpannableString string = new SpannableString("Text with blur mask");
+ * string.setSpan(new MaskFilterSpan(blurMask), 10, 15, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
+ * </pre>
+ * <img src="{@docRoot}reference/android/images/text/style/maskfilterspan.png" />
+ * <figcaption>Text blurred with the <code>MaskFilterSpan</code>.</figcaption>
+ */
 public class MaskFilterSpan extends CharacterStyle implements UpdateAppearance {
 
     private MaskFilter mFilter;
 
+    /**
+     * Creates a {@link MaskFilterSpan} from a {@link MaskFilter}.
+     *
+     * @param filter the filter to be applied to the <code>TextPaint</code>
+     */
     public MaskFilterSpan(MaskFilter filter) {
         mFilter = filter;
     }
 
+    /**
+     * Return the mask filter for this span.
+     *
+     * @return the mask filter for this span
+     */
     public MaskFilter getMaskFilter() {
         return mFilter;
     }
diff --git a/core/java/android/text/style/StyleSpan.java b/core/java/android/text/style/StyleSpan.java
index f900db5..bdfa700 100644
--- a/core/java/android/text/style/StyleSpan.java
+++ b/core/java/android/text/style/StyleSpan.java
@@ -16,6 +16,7 @@
 
 package android.text.style;
 
+import android.annotation.NonNull;
 import android.graphics.Paint;
 import android.graphics.Typeface;
 import android.os.Parcel;
@@ -24,55 +25,76 @@
 import android.text.TextUtils;
 
 /**
- * 
- * Describes a style in a span.
+ * Span that allows setting the style of the text it's attached to.
+ * Possible styles are: {@link Typeface#NORMAL}, {@link Typeface#BOLD}, {@link Typeface#ITALIC} and
+ * {@link Typeface#BOLD_ITALIC}.
+ * <p>
  * Note that styles are cumulative -- if both bold and italic are set in
  * separate spans, or if the base style is bold and a span calls for italic,
  * you get bold italic.  You can't turn off a style from the base style.
- *
+ * <p>
+ * For example, the <code>StyleSpan</code> can be used like this:
+ * <pre>
+ * SpannableString string = new SpannableString("Bold and italic text");
+ * string.setSpan(new StyleSpan(Typeface.BOLD), 0, 4, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
+ * string.setSpan(new StyleSpan(Typeface.ITALIC), 9, 15, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
+ * </pre>
+ * <img src="{@docRoot}reference/android/images/text/style/stylespan.png" />
+ * <figcaption>Text styled bold and italic with the <code>StyleSpan</code>.</figcaption>
  */
 public class StyleSpan extends MetricAffectingSpan implements ParcelableSpan {
 
     private final int mStyle;
 
     /**
-     * 
+     * Creates a {@link StyleSpan} from a style.
+     *
      * @param style An integer constant describing the style for this span. Examples
-     * include bold, italic, and normal. Values are constants defined 
-     * in {@link android.graphics.Typeface}.
+     *              include bold, italic, and normal. Values are constants defined
+     *              in {@link Typeface}.
      */
     public StyleSpan(int style) {
         mStyle = style;
     }
 
-    public StyleSpan(Parcel src) {
+    /**
+     * Creates a {@link StyleSpan} from a parcel.
+     *
+     * @param src the parcel
+     */
+    public StyleSpan(@NonNull Parcel src) {
         mStyle = src.readInt();
     }
-    
+
+    @Override
     public int getSpanTypeId() {
         return getSpanTypeIdInternal();
     }
 
     /** @hide */
+    @Override
     public int getSpanTypeIdInternal() {
         return TextUtils.STYLE_SPAN;
     }
-    
+
+    @Override
     public int describeContents() {
         return 0;
     }
 
+    @Override
     public void writeToParcel(Parcel dest, int flags) {
         writeToParcelInternal(dest, flags);
     }
 
     /** @hide */
-    public void writeToParcelInternal(Parcel dest, int flags) {
+    @Override
+    public void writeToParcelInternal(@NonNull Parcel dest, int flags) {
         dest.writeInt(mStyle);
     }
 
     /**
-     * Returns the style constant defined in {@link android.graphics.Typeface}. 
+     * Returns the style constant defined in {@link Typeface}.
      */
     public int getStyle() {
         return mStyle;
diff --git a/core/java/android/text/style/TabStopSpan.java b/core/java/android/text/style/TabStopSpan.java
index 0566428..2cceb2c 100644
--- a/core/java/android/text/style/TabStopSpan.java
+++ b/core/java/android/text/style/TabStopSpan.java
@@ -16,39 +16,54 @@
 
 package android.text.style;
 
+import android.annotation.IntRange;
+import android.annotation.Px;
+
 /**
- * Represents a single tab stop on a line.
+ * Paragraph affecting span that changes the position of the tab with respect to
+ * the leading margin of the line. <code>TabStopSpan</code> will only affect the first tab
+ * encountered on the first line of the text.
  */
-public interface TabStopSpan
-extends ParagraphStyle
-{
-    /**
-     * Returns the offset of the tab stop from the leading margin of the
-     * line.
-     * @return the offset
-     */
-    public int getTabStop();
+public interface TabStopSpan extends ParagraphStyle {
 
     /**
-     * The default implementation of TabStopSpan.
+     * Returns the offset of the tab stop from the leading margin of the line, in pixels.
+     *
+     * @return the offset, in pixels
      */
-    public static class Standard
-    implements TabStopSpan
-    {
+    int getTabStop();
+
+    /**
+     * The default implementation of TabStopSpan that allows setting the offset of the tab stop
+     * from the leading margin of the first line of text.
+     * <p>
+     * Let's consider that we have the following text: <i>"\tParagraph text beginning with tab."</i>
+     * and we want to move the tab stop with 100px. This can be achieved like this:
+     * <pre>
+     * SpannableString string = new SpannableString("\tParagraph text beginning with tab.");
+     * string.setSpan(new TabStopSpan.Standard(100), 0, string.length(),
+     * Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);</pre>
+     * <img src="{@docRoot}reference/android/images/text/style/tabstopspan.png" />
+     * <figcaption>Text with a tab stop and a <code>TabStopSpan</code></figcaption>
+     */
+    class Standard implements TabStopSpan {
+
+        @Px
+        private int mTabOffset;
+
         /**
-         * Constructor.
+         * Constructs a {@link TabStopSpan.Standard} based on an offset.
          *
-         * @param where the offset of the tab stop from the leading margin of
-         *        the line
+         * @param offset the offset of the tab stop from the leading margin of
+         *               the line, in pixels
          */
-        public Standard(int where) {
-            mTab = where;
+        public Standard(@IntRange(from = 0) int offset) {
+            mTabOffset = offset;
         }
 
+        @Override
         public int getTabStop() {
-            return mTab;
+            return mTabOffset;
         }
-
-        private int mTab;
     }
 }
diff --git a/core/java/android/text/style/TypefaceSpan.java b/core/java/android/text/style/TypefaceSpan.java
index aa622d8..1622812 100644
--- a/core/java/android/text/style/TypefaceSpan.java
+++ b/core/java/android/text/style/TypefaceSpan.java
@@ -16,6 +16,7 @@
 
 package android.text.style;
 
+import android.annotation.NonNull;
 import android.graphics.Paint;
 import android.graphics.Typeface;
 import android.os.Parcel;
@@ -24,42 +25,59 @@
 import android.text.TextUtils;
 
 /**
- * Changes the typeface family of the text to which the span is attached.
+ * Changes the typeface family of the text to which the span is attached. Examples of typeface
+ * family include "monospace", "serif", and "sans-serif".
+ * <p>
+ * For example, change the typeface of a text to "monospace" like this:
+ * <pre>
+ * SpannableString string = new SpannableString("Text with typeface span");
+ * string.setSpan(new TypefaceSpan("monospace"), 10, 18, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
+ * </pre>
+ * <img src="{@docRoot}reference/android/images/text/style/typefacespan.png" />
+ * <figcaption>Text with "monospace" typeface family.</figcaption>
  */
 public class TypefaceSpan extends MetricAffectingSpan implements ParcelableSpan {
+
     private final String mFamily;
 
     /**
-     * @param family The font family for this typeface.  Examples include
-     * "monospace", "serif", and "sans-serif".
+     * Constructs a {@link TypefaceSpan} based on a font family.
+     *
+     * @param family The font family for this typeface. Examples include
+     *               "monospace", "serif", and "sans-serif".
      */
     public TypefaceSpan(String family) {
         mFamily = family;
     }
 
-    public TypefaceSpan(Parcel src) {
+    public TypefaceSpan(@NonNull Parcel src) {
         mFamily = src.readString();
     }
-    
+
+    @Override
     public int getSpanTypeId() {
         return getSpanTypeIdInternal();
     }
 
     /** @hide */
+    @Override
     public int getSpanTypeIdInternal() {
         return TextUtils.TYPEFACE_SPAN;
     }
-    
+
+    @Override
     public int describeContents() {
         return 0;
     }
 
-    public void writeToParcel(Parcel dest, int flags) {
+    @Override
+    public void writeToParcel(@NonNull Parcel dest, int flags) {
         writeToParcelInternal(dest, flags);
     }
 
     /** @hide */
-    public void writeToParcelInternal(Parcel dest, int flags) {
+    @Override
+    public void writeToParcelInternal(@NonNull Parcel dest, int flags) {
         dest.writeString(mFamily);
     }
 
@@ -71,16 +89,16 @@
     }
 
     @Override
-    public void updateDrawState(TextPaint ds) {
-        apply(ds, mFamily);
+    public void updateDrawState(@NonNull TextPaint textPaint) {
+        apply(textPaint, mFamily);
     }
 
     @Override
-    public void updateMeasureState(TextPaint paint) {
-        apply(paint, mFamily);
+    public void updateMeasureState(@NonNull TextPaint textPaint) {
+        apply(textPaint, mFamily);
     }
 
-    private static void apply(Paint paint, String family) {
+    private static void apply(@NonNull Paint paint, String family) {
         int oldStyle;
 
         Typeface old = paint.getTypeface();
diff --git a/core/java/android/text/style/URLSpan.java b/core/java/android/text/style/URLSpan.java
index 58239ef..eab1ef4 100644
--- a/core/java/android/text/style/URLSpan.java
+++ b/core/java/android/text/style/URLSpan.java
@@ -16,6 +16,7 @@
 
 package android.text.style;
 
+import android.annotation.NonNull;
 import android.content.ActivityNotFoundException;
 import android.content.Context;
 import android.content.Intent;
@@ -27,40 +28,71 @@
 import android.util.Log;
 import android.view.View;
 
+/**
+ * Implementation of the {@link ClickableSpan} that allows setting a url string. When
+ * selecting and clicking on the text to which the span is attached, the <code>URLSpan</code>
+ * will try to open the url, by launching an an Activity with an {@link Intent#ACTION_VIEW} intent.
+ * <p>
+ * For example, a <code>URLSpan</code> can be used like this:
+ * <pre>
+ * SpannableString string = new SpannableString("Text with a url span");
+ * string.setSpan(new URLSpan("http://www.developer.android.com"), 12, 15, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
+ * </pre>
+ * <img src="{@docRoot}reference/android/images/text/style/urlspan.png" />
+ * <figcaption>Text with <code>URLSpan</code>.</figcaption>
+ */
 public class URLSpan extends ClickableSpan implements ParcelableSpan {
 
     private final String mURL;
 
+    /**
+     * Constructs a {@link URLSpan} from a url string.
+     *
+     * @param url the url string
+     */
     public URLSpan(String url) {
         mURL = url;
     }
 
-    public URLSpan(Parcel src) {
+    /**
+     * Constructs a {@link URLSpan} from a parcel.
+     */
+    public URLSpan(@NonNull Parcel src) {
         mURL = src.readString();
     }
-    
+
+    @Override
     public int getSpanTypeId() {
         return getSpanTypeIdInternal();
     }
 
     /** @hide */
+    @Override
     public int getSpanTypeIdInternal() {
         return TextUtils.URL_SPAN;
     }
-    
+
+    @Override
     public int describeContents() {
         return 0;
     }
 
-    public void writeToParcel(Parcel dest, int flags) {
+    @Override
+    public void writeToParcel(@NonNull Parcel dest, int flags) {
         writeToParcelInternal(dest, flags);
     }
 
     /** @hide */
-    public void writeToParcelInternal(Parcel dest, int flags) {
+    @Override
+    public void writeToParcelInternal(@NonNull Parcel dest, int flags) {
         dest.writeString(mURL);
     }
 
+    /**
+     * Get the url string for this span.
+     *
+     * @return the url string.
+     */
     public String getURL() {
         return mURL;
     }
diff --git a/docs/html/reference/images/text/style/drawablemarginspan.png b/docs/html/reference/images/text/style/drawablemarginspan.png
new file mode 100644
index 0000000..edf926d
--- /dev/null
+++ b/docs/html/reference/images/text/style/drawablemarginspan.png
Binary files differ
diff --git a/docs/html/reference/images/text/style/dynamicdrawablespan.png b/docs/html/reference/images/text/style/dynamicdrawablespan.png
new file mode 100644
index 0000000..8776b03
--- /dev/null
+++ b/docs/html/reference/images/text/style/dynamicdrawablespan.png
Binary files differ
diff --git a/docs/html/reference/images/text/style/iconmarginspan.png b/docs/html/reference/images/text/style/iconmarginspan.png
new file mode 100644
index 0000000..8ec39be
--- /dev/null
+++ b/docs/html/reference/images/text/style/iconmarginspan.png
Binary files differ
diff --git a/docs/html/reference/images/text/style/imagespan.png b/docs/html/reference/images/text/style/imagespan.png
new file mode 100644
index 0000000..c03e6bb
--- /dev/null
+++ b/docs/html/reference/images/text/style/imagespan.png
Binary files differ
diff --git a/docs/html/reference/images/text/style/maskfilterspan.png b/docs/html/reference/images/text/style/maskfilterspan.png
new file mode 100644
index 0000000..6e55dbc
--- /dev/null
+++ b/docs/html/reference/images/text/style/maskfilterspan.png
Binary files differ
diff --git a/docs/html/reference/images/text/style/stylespan.png b/docs/html/reference/images/text/style/stylespan.png
new file mode 100644
index 0000000..9ffa05b
--- /dev/null
+++ b/docs/html/reference/images/text/style/stylespan.png
Binary files differ
diff --git a/docs/html/reference/images/text/style/tabstopspan.png b/docs/html/reference/images/text/style/tabstopspan.png
new file mode 100644
index 0000000..89a1121
--- /dev/null
+++ b/docs/html/reference/images/text/style/tabstopspan.png
Binary files differ
diff --git a/docs/html/reference/images/text/style/typefacespan.png b/docs/html/reference/images/text/style/typefacespan.png
new file mode 100644
index 0000000..67e2cf9
--- /dev/null
+++ b/docs/html/reference/images/text/style/typefacespan.png
Binary files differ
diff --git a/docs/html/reference/images/text/style/urlspan.png b/docs/html/reference/images/text/style/urlspan.png
new file mode 100644
index 0000000..1134520
--- /dev/null
+++ b/docs/html/reference/images/text/style/urlspan.png
Binary files differ