1 /* 2 * Copyright 2017, 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 package com.android.managedprovisioning.common; 17 18 import static android.text.Spanned.SPAN_EXCLUSIVE_EXCLUSIVE; 19 20 import static com.android.internal.util.Preconditions.checkNotNull; 21 import static com.android.internal.util.Preconditions.checkStringNotEmpty; 22 23 import android.content.Intent; 24 import android.text.Html; 25 import android.text.SpannableStringBuilder; 26 import android.text.Spanned; 27 import android.text.style.ClickableSpan; 28 import android.text.style.URLSpan; 29 30 import com.android.managedprovisioning.preprovisioning.WebActivity; 31 32 /** 33 * Parses HTML text using {@link Html} and sets URL links to be handled by {@link WebActivity} 34 */ 35 public class HtmlToSpannedParser { 36 private static final int HTML_MODE = Html.FROM_HTML_MODE_COMPACT; 37 38 private final ClickableSpanFactory mClickableSpanFactory; 39 private final UrlIntentFactory mUrlIntentFactory; 40 41 /** 42 * Default constructor 43 * 44 * @param clickableSpanFactory Factory of {@link ClickableSpan} objects for urls 45 * @param urlIntentFactory Factory of {@link Intent} objects for handling urls 46 */ HtmlToSpannedParser(ClickableSpanFactory clickableSpanFactory, UrlIntentFactory urlIntentFactory)47 public HtmlToSpannedParser(ClickableSpanFactory clickableSpanFactory, 48 UrlIntentFactory urlIntentFactory) { 49 mClickableSpanFactory = checkNotNull(clickableSpanFactory); 50 mUrlIntentFactory = checkNotNull(urlIntentFactory); 51 } 52 53 /** 54 * See {@link Html#fromHtml(String, int)} for caveats regarding limited HTML support 55 */ parseHtml(String htmlContent)56 public Spanned parseHtml(String htmlContent) { 57 Spanned spanned = Html.fromHtml(checkStringNotEmpty(htmlContent), HTML_MODE); 58 if (spanned == null) { 59 return null; 60 } 61 62 // Make html <a> tags open WebActivity 63 SpannableStringBuilder result = new SpannableStringBuilder(spanned); 64 65 URLSpan[] urlSpans = result.getSpans(0, result.length(), URLSpan.class); 66 for (URLSpan urlSpan : urlSpans) { 67 Intent intent = mUrlIntentFactory.create(urlSpan.getURL()); 68 if (intent != null) { 69 int spanStart = result.getSpanStart(urlSpan); 70 int spanEnd = result.getSpanEnd(urlSpan); 71 result.setSpan(mClickableSpanFactory.create(intent), spanStart, spanEnd, 72 SPAN_EXCLUSIVE_EXCLUSIVE); 73 result.removeSpan(urlSpan); 74 } 75 } 76 77 return result; 78 } 79 80 /** 81 * Allows to specify an intent to handle URLs 82 */ 83 public interface UrlIntentFactory { 84 /** 85 * Creates an {@link Intent} based on a passed in {@link String} url 86 */ create(String url)87 Intent create(String url); 88 } 89 }