1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/mobile/android/base/sync/setup/activities/ActivityUtils.java Wed Dec 31 06:09:35 2014 +0100 1.3 @@ -0,0 +1,139 @@ 1.4 +/* This Source Code Form is subject to the terms of the Mozilla Public 1.5 + * License, v. 2.0. If a copy of the MPL was not distributed with this 1.6 + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 1.7 + 1.8 +package org.mozilla.gecko.sync.setup.activities; 1.9 + 1.10 +import java.util.Locale; 1.11 + 1.12 +import org.mozilla.gecko.background.common.GlobalConstants; 1.13 +import org.mozilla.gecko.background.common.log.Logger; 1.14 +import org.mozilla.gecko.sync.SyncConstants; 1.15 +import org.mozilla.gecko.sync.setup.InvalidSyncKeyException; 1.16 + 1.17 +import android.content.Context; 1.18 +import android.content.Intent; 1.19 +import android.net.Uri; 1.20 +import android.text.Html; 1.21 +import android.text.SpannableString; 1.22 +import android.text.Spanned; 1.23 +import android.text.TextPaint; 1.24 +import android.text.method.LinkMovementMethod; 1.25 +import android.text.style.ClickableSpan; 1.26 +import android.text.style.URLSpan; 1.27 +import android.view.View; 1.28 +import android.widget.TextView; 1.29 + 1.30 +public class ActivityUtils { 1.31 + private static final String LOG_TAG = "ActivityUtils"; 1.32 + 1.33 + public static void prepareLogging() { 1.34 + Logger.setThreadLogTag(SyncConstants.GLOBAL_LOG_TAG); 1.35 + } 1.36 + 1.37 + /** 1.38 + * Sync key should be a 26-character string, and can include arbitrary 1.39 + * capitalization and hyphenation. 1.40 + * 1.41 + * @param key 1.42 + * Sync key entered by user in account setup. 1.43 + * @return Sync key in correct format (lower-case, no hyphens). 1.44 + * @throws InvalidSyncKeyException 1.45 + */ 1.46 + public static String validateSyncKey(String key) throws InvalidSyncKeyException { 1.47 + String charKey = key.trim().replace("-", "").toLowerCase(Locale.US); 1.48 + if (!charKey.matches("^[abcdefghijkmnpqrstuvwxyz23456789]{26}$")) { 1.49 + throw new InvalidSyncKeyException(); 1.50 + } 1.51 + return charKey; 1.52 + } 1.53 + 1.54 + /** 1.55 + * Open a URL in Fennec, if one is provided; or just open Fennec. 1.56 + * 1.57 + * @param context Android context. 1.58 + * @param url to visit, or null to just open Fennec. 1.59 + */ 1.60 + public static void openURLInFennec(final Context context, final String url) { 1.61 + Intent intent; 1.62 + if (url != null) { 1.63 + intent = new Intent(Intent.ACTION_VIEW); 1.64 + intent.setData(Uri.parse(url)); 1.65 + } else { 1.66 + intent = new Intent(Intent.ACTION_MAIN); 1.67 + } 1.68 + intent.setClassName(GlobalConstants.BROWSER_INTENT_PACKAGE, GlobalConstants.BROWSER_INTENT_CLASS); 1.69 + intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); 1.70 + context.startActivity(intent); 1.71 + } 1.72 + 1.73 + /** 1.74 + * Open a clicked span in Fennec with the provided URL. 1.75 + */ 1.76 + public static class FennecClickableSpan extends ClickableSpan { 1.77 + private final String url; 1.78 + private final boolean underlining; 1.79 + 1.80 + public FennecClickableSpan(final String url, boolean underlining) { 1.81 + this.url = url; 1.82 + this.underlining = underlining; 1.83 + } 1.84 + 1.85 + @Override 1.86 + public void updateDrawState(TextPaint ds) { 1.87 + super.updateDrawState(ds); 1.88 + if (!this.underlining) { 1.89 + ds.setUnderlineText(false); 1.90 + } 1.91 + } 1.92 + 1.93 + @Override 1.94 + public void onClick(View widget) { 1.95 + openURLInFennec(widget.getContext(), this.url); 1.96 + } 1.97 + } 1.98 + 1.99 + /** 1.100 + * Replace the contents of a plain text view with the provided text wrapped in a link. 1.101 + * TODO: escape the URL! 1.102 + */ 1.103 + public static void linkTextView(TextView view, int text, int link) { 1.104 + final Context context = view.getContext(); 1.105 + linkTextView(view, context.getString(text), context.getString(link)); 1.106 + } 1.107 + 1.108 + /** 1.109 + * Replace the contents of a plain text view with the provided text wrapped in a link. 1.110 + * TODO: escape the URL! 1.111 + */ 1.112 + public static void linkTextView(TextView view, String text, String url) { 1.113 + view.setText("<a href=\"" + url + "\">" + text + "</a>"); 1.114 + linkifyTextView(view, false); 1.115 + } 1.116 + 1.117 + public static void linkifyTextView(TextView textView, boolean underlining) { 1.118 + if (textView == null) { 1.119 + Logger.warn(LOG_TAG, "Could not process links for view."); 1.120 + return; 1.121 + } 1.122 + 1.123 + textView.setMovementMethod(LinkMovementMethod.getInstance()); 1.124 + 1.125 + // Create spans. 1.126 + final Spanned spanned = Html.fromHtml(textView.getText().toString()); 1.127 + 1.128 + // Replace the spans with Fennec-launching links. 1.129 + SpannableString replaced = new SpannableString(spanned); 1.130 + URLSpan[] spans = replaced.getSpans(0, replaced.length(), URLSpan.class); 1.131 + for (URLSpan span : spans) { 1.132 + final int start = replaced.getSpanStart(span); 1.133 + final int end = replaced.getSpanEnd(span); 1.134 + final int flags = replaced.getSpanFlags(span); 1.135 + 1.136 + replaced.removeSpan(span); 1.137 + replaced.setSpan(new FennecClickableSpan(span.getURL(), underlining), start, end, flags); 1.138 + } 1.139 + 1.140 + textView.setText(replaced); 1.141 + } 1.142 +}