Wed, 31 Dec 2014 07:22:50 +0100
Correct previous dual key logic pending first delivery installment.
michael@0 | 1 | /* This Source Code Form is subject to the terms of the Mozilla Public |
michael@0 | 2 | * License, v. 2.0. If a copy of the MPL was not distributed with this |
michael@0 | 3 | * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ |
michael@0 | 4 | |
michael@0 | 5 | package org.mozilla.gecko.sync.setup.activities; |
michael@0 | 6 | |
michael@0 | 7 | import java.util.Locale; |
michael@0 | 8 | |
michael@0 | 9 | import org.mozilla.gecko.background.common.GlobalConstants; |
michael@0 | 10 | import org.mozilla.gecko.background.common.log.Logger; |
michael@0 | 11 | import org.mozilla.gecko.sync.SyncConstants; |
michael@0 | 12 | import org.mozilla.gecko.sync.setup.InvalidSyncKeyException; |
michael@0 | 13 | |
michael@0 | 14 | import android.content.Context; |
michael@0 | 15 | import android.content.Intent; |
michael@0 | 16 | import android.net.Uri; |
michael@0 | 17 | import android.text.Html; |
michael@0 | 18 | import android.text.SpannableString; |
michael@0 | 19 | import android.text.Spanned; |
michael@0 | 20 | import android.text.TextPaint; |
michael@0 | 21 | import android.text.method.LinkMovementMethod; |
michael@0 | 22 | import android.text.style.ClickableSpan; |
michael@0 | 23 | import android.text.style.URLSpan; |
michael@0 | 24 | import android.view.View; |
michael@0 | 25 | import android.widget.TextView; |
michael@0 | 26 | |
michael@0 | 27 | public class ActivityUtils { |
michael@0 | 28 | private static final String LOG_TAG = "ActivityUtils"; |
michael@0 | 29 | |
michael@0 | 30 | public static void prepareLogging() { |
michael@0 | 31 | Logger.setThreadLogTag(SyncConstants.GLOBAL_LOG_TAG); |
michael@0 | 32 | } |
michael@0 | 33 | |
michael@0 | 34 | /** |
michael@0 | 35 | * Sync key should be a 26-character string, and can include arbitrary |
michael@0 | 36 | * capitalization and hyphenation. |
michael@0 | 37 | * |
michael@0 | 38 | * @param key |
michael@0 | 39 | * Sync key entered by user in account setup. |
michael@0 | 40 | * @return Sync key in correct format (lower-case, no hyphens). |
michael@0 | 41 | * @throws InvalidSyncKeyException |
michael@0 | 42 | */ |
michael@0 | 43 | public static String validateSyncKey(String key) throws InvalidSyncKeyException { |
michael@0 | 44 | String charKey = key.trim().replace("-", "").toLowerCase(Locale.US); |
michael@0 | 45 | if (!charKey.matches("^[abcdefghijkmnpqrstuvwxyz23456789]{26}$")) { |
michael@0 | 46 | throw new InvalidSyncKeyException(); |
michael@0 | 47 | } |
michael@0 | 48 | return charKey; |
michael@0 | 49 | } |
michael@0 | 50 | |
michael@0 | 51 | /** |
michael@0 | 52 | * Open a URL in Fennec, if one is provided; or just open Fennec. |
michael@0 | 53 | * |
michael@0 | 54 | * @param context Android context. |
michael@0 | 55 | * @param url to visit, or null to just open Fennec. |
michael@0 | 56 | */ |
michael@0 | 57 | public static void openURLInFennec(final Context context, final String url) { |
michael@0 | 58 | Intent intent; |
michael@0 | 59 | if (url != null) { |
michael@0 | 60 | intent = new Intent(Intent.ACTION_VIEW); |
michael@0 | 61 | intent.setData(Uri.parse(url)); |
michael@0 | 62 | } else { |
michael@0 | 63 | intent = new Intent(Intent.ACTION_MAIN); |
michael@0 | 64 | } |
michael@0 | 65 | intent.setClassName(GlobalConstants.BROWSER_INTENT_PACKAGE, GlobalConstants.BROWSER_INTENT_CLASS); |
michael@0 | 66 | intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); |
michael@0 | 67 | context.startActivity(intent); |
michael@0 | 68 | } |
michael@0 | 69 | |
michael@0 | 70 | /** |
michael@0 | 71 | * Open a clicked span in Fennec with the provided URL. |
michael@0 | 72 | */ |
michael@0 | 73 | public static class FennecClickableSpan extends ClickableSpan { |
michael@0 | 74 | private final String url; |
michael@0 | 75 | private final boolean underlining; |
michael@0 | 76 | |
michael@0 | 77 | public FennecClickableSpan(final String url, boolean underlining) { |
michael@0 | 78 | this.url = url; |
michael@0 | 79 | this.underlining = underlining; |
michael@0 | 80 | } |
michael@0 | 81 | |
michael@0 | 82 | @Override |
michael@0 | 83 | public void updateDrawState(TextPaint ds) { |
michael@0 | 84 | super.updateDrawState(ds); |
michael@0 | 85 | if (!this.underlining) { |
michael@0 | 86 | ds.setUnderlineText(false); |
michael@0 | 87 | } |
michael@0 | 88 | } |
michael@0 | 89 | |
michael@0 | 90 | @Override |
michael@0 | 91 | public void onClick(View widget) { |
michael@0 | 92 | openURLInFennec(widget.getContext(), this.url); |
michael@0 | 93 | } |
michael@0 | 94 | } |
michael@0 | 95 | |
michael@0 | 96 | /** |
michael@0 | 97 | * Replace the contents of a plain text view with the provided text wrapped in a link. |
michael@0 | 98 | * TODO: escape the URL! |
michael@0 | 99 | */ |
michael@0 | 100 | public static void linkTextView(TextView view, int text, int link) { |
michael@0 | 101 | final Context context = view.getContext(); |
michael@0 | 102 | linkTextView(view, context.getString(text), context.getString(link)); |
michael@0 | 103 | } |
michael@0 | 104 | |
michael@0 | 105 | /** |
michael@0 | 106 | * Replace the contents of a plain text view with the provided text wrapped in a link. |
michael@0 | 107 | * TODO: escape the URL! |
michael@0 | 108 | */ |
michael@0 | 109 | public static void linkTextView(TextView view, String text, String url) { |
michael@0 | 110 | view.setText("<a href=\"" + url + "\">" + text + "</a>"); |
michael@0 | 111 | linkifyTextView(view, false); |
michael@0 | 112 | } |
michael@0 | 113 | |
michael@0 | 114 | public static void linkifyTextView(TextView textView, boolean underlining) { |
michael@0 | 115 | if (textView == null) { |
michael@0 | 116 | Logger.warn(LOG_TAG, "Could not process links for view."); |
michael@0 | 117 | return; |
michael@0 | 118 | } |
michael@0 | 119 | |
michael@0 | 120 | textView.setMovementMethod(LinkMovementMethod.getInstance()); |
michael@0 | 121 | |
michael@0 | 122 | // Create spans. |
michael@0 | 123 | final Spanned spanned = Html.fromHtml(textView.getText().toString()); |
michael@0 | 124 | |
michael@0 | 125 | // Replace the spans with Fennec-launching links. |
michael@0 | 126 | SpannableString replaced = new SpannableString(spanned); |
michael@0 | 127 | URLSpan[] spans = replaced.getSpans(0, replaced.length(), URLSpan.class); |
michael@0 | 128 | for (URLSpan span : spans) { |
michael@0 | 129 | final int start = replaced.getSpanStart(span); |
michael@0 | 130 | final int end = replaced.getSpanEnd(span); |
michael@0 | 131 | final int flags = replaced.getSpanFlags(span); |
michael@0 | 132 | |
michael@0 | 133 | replaced.removeSpan(span); |
michael@0 | 134 | replaced.setSpan(new FennecClickableSpan(span.getURL(), underlining), start, end, flags); |
michael@0 | 135 | } |
michael@0 | 136 | |
michael@0 | 137 | textView.setText(replaced); |
michael@0 | 138 | } |
michael@0 | 139 | } |