+ // Get a URI for the URL with errors.
+ val uriWithErrors = Uri.parse(urlWithErrors)
+
+ // The alert dialog must be shown before the contents can be modified.
+ alertDialog.show()
+
+ // Get handles for the views.
+ val primaryErrorTextView = alertDialog.findViewById<TextView>(R.id.primary_error)!!
+ val urlTextView = alertDialog.findViewById<TextView>(R.id.url)!!
+ val ipAddressesTextView = alertDialog.findViewById<TextView>(R.id.ip_addresses)!!
+ val issuedToCNameTextView = alertDialog.findViewById<TextView>(R.id.issued_to_cname)!!
+ val issuedToONameTextView = alertDialog.findViewById<TextView>(R.id.issued_to_oname)!!
+ val issuedToUNameTextView = alertDialog.findViewById<TextView>(R.id.issued_to_uname)!!
+ val issuedByTextView = alertDialog.findViewById<TextView>(R.id.issued_by_textview)!!
+ val issuedByCNameTextView = alertDialog.findViewById<TextView>(R.id.issued_by_cname)!!
+ val issuedByONameTextView = alertDialog.findViewById<TextView>(R.id.issued_by_oname)!!
+ val issuedByUNameTextView = alertDialog.findViewById<TextView>(R.id.issued_by_uname)!!
+ val validDatesTextView = alertDialog.findViewById<TextView>(R.id.valid_dates_textview)!!
+ val startDateTextView = alertDialog.findViewById<TextView>(R.id.start_date)!!
+ val endDateTextView = alertDialog.findViewById<TextView>(R.id.end_date)!!
+
+ // Define the color spans.
+ val blueColorSpan = ForegroundColorSpan(requireContext().getColor(R.color.alt_blue_text))
+ val redColorSpan = ForegroundColorSpan(requireContext().getColor(R.color.red_text))
+
+ // Get the IP Addresses for the URI.
+ GetHostIpAddressesCoroutine.getAddresses(uriWithErrors.host!!, getString(R.string.ip_addresses), blueColorSpan, ipAddressesTextView)
+
+ // Setup the common strings.
+ val urlLabel = getString(R.string.url_label)
+ val cNameLabel = getString(R.string.common_name)
+ val oNameLabel = getString(R.string.organization)
+ val uNameLabel = getString(R.string.organizational_unit)
+ val startDateLabel = getString(R.string.start_date)
+ val endDateLabel = getString(R.string.end_date)
+
+ // Create a spannable string builder for each text view that needs multiple colors of text.
+ val urlStringBuilder = SpannableStringBuilder(urlLabel + urlWithErrors)
+ val issuedToCNameStringBuilder = SpannableStringBuilder(cNameLabel + issuedToCName)
+ val issuedToONameStringBuilder = SpannableStringBuilder(oNameLabel + issuedToOName)
+ val issuedToUNameStringBuilder = SpannableStringBuilder(uNameLabel + issuedToUName)
+ val issuedByCNameStringBuilder = SpannableStringBuilder(cNameLabel + issuedByCName)
+ val issuedByONameStringBuilder = SpannableStringBuilder(oNameLabel + issuedByOName)
+ val issuedByUNameStringBuilder = SpannableStringBuilder(uNameLabel + issuedByUName)
+ val startDateStringBuilder = SpannableStringBuilder(startDateLabel + startDate)
+ val endDateStringBuilder = SpannableStringBuilder(endDateLabel + endDate)
+
+ // Setup the spans to display the certificate information in blue. `SPAN_INCLUSIVE_INCLUSIVE` allows the span to grow in either direction.
+ urlStringBuilder.setSpan(blueColorSpan, urlLabel.length, urlStringBuilder.length, Spanned.SPAN_INCLUSIVE_INCLUSIVE)
+ issuedToCNameStringBuilder.setSpan(blueColorSpan, cNameLabel.length, issuedToCNameStringBuilder.length, Spanned.SPAN_INCLUSIVE_INCLUSIVE)
+ issuedToONameStringBuilder.setSpan(blueColorSpan, oNameLabel.length, issuedToONameStringBuilder.length, Spanned.SPAN_INCLUSIVE_INCLUSIVE)
+ issuedToUNameStringBuilder.setSpan(blueColorSpan, uNameLabel.length, issuedToUNameStringBuilder.length, Spanned.SPAN_INCLUSIVE_INCLUSIVE)
+ issuedByCNameStringBuilder.setSpan(blueColorSpan, cNameLabel.length, issuedByCNameStringBuilder.length, Spanned.SPAN_INCLUSIVE_INCLUSIVE)
+ issuedByONameStringBuilder.setSpan(blueColorSpan, oNameLabel.length, issuedByONameStringBuilder.length, Spanned.SPAN_INCLUSIVE_INCLUSIVE)
+ issuedByUNameStringBuilder.setSpan(blueColorSpan, uNameLabel.length, issuedByUNameStringBuilder.length, Spanned.SPAN_INCLUSIVE_INCLUSIVE)
+ startDateStringBuilder.setSpan(blueColorSpan, startDateLabel.length, startDateStringBuilder.length, Spanned.SPAN_INCLUSIVE_INCLUSIVE)
+ endDateStringBuilder.setSpan(blueColorSpan, endDateLabel.length, endDateStringBuilder.length, Spanned.SPAN_INCLUSIVE_INCLUSIVE)
+
+ // Define the primary error string.
+ var primaryErrorString = ""
+
+ // Highlight the primary error in red and store it in the primary error string.
+ when (primaryErrorInt) {
+ SslError.SSL_IDMISMATCH -> {
+ // Change the URL span colors to red.
+ urlStringBuilder.setSpan(redColorSpan, urlLabel.length, urlStringBuilder.length, Spanned.SPAN_INCLUSIVE_INCLUSIVE)
+ issuedToCNameStringBuilder.setSpan(redColorSpan, cNameLabel.length, issuedToCNameStringBuilder.length, Spanned.SPAN_INCLUSIVE_INCLUSIVE)
+
+ // Store the primary error string.
+ primaryErrorString = getString(R.string.cn_mismatch)
+ }
+
+ SslError.SSL_UNTRUSTED -> {
+ // Change the issued by text view text to red.
+ issuedByTextView.setTextColor(requireContext().getColor(R.color.red_text))
+
+ // Change the issued by span color to red.
+ issuedByCNameStringBuilder.setSpan(redColorSpan, cNameLabel.length, issuedByCNameStringBuilder.length, Spanned.SPAN_INCLUSIVE_INCLUSIVE)
+ issuedByONameStringBuilder.setSpan(redColorSpan, oNameLabel.length, issuedByONameStringBuilder.length, Spanned.SPAN_INCLUSIVE_INCLUSIVE)
+ issuedByUNameStringBuilder.setSpan(redColorSpan, uNameLabel.length, issuedByUNameStringBuilder.length, Spanned.SPAN_INCLUSIVE_INCLUSIVE)
+
+ // Store the primary error string.
+ primaryErrorString = getString(R.string.untrusted)
+ }
+
+ SslError.SSL_DATE_INVALID -> {
+ // Change the valid dates text view text to red.
+ validDatesTextView.setTextColor(requireContext().getColor(R.color.red_text))
+
+ // Change the date span colors to red.
+ startDateStringBuilder.setSpan(redColorSpan, startDateLabel.length, startDateStringBuilder.length, Spanned.SPAN_INCLUSIVE_INCLUSIVE)
+ endDateStringBuilder.setSpan(redColorSpan, endDateLabel.length, endDateStringBuilder.length, Spanned.SPAN_INCLUSIVE_INCLUSIVE)
+
+ // Store the primary error string.
+ primaryErrorString = getString(R.string.invalid_date)
+ }
+
+ SslError.SSL_NOTYETVALID -> {
+ // Change the start date span color to red.
+ startDateStringBuilder.setSpan(redColorSpan, startDateLabel.length, startDateStringBuilder.length, Spanned.SPAN_INCLUSIVE_INCLUSIVE)
+
+ // Store the primary error string.
+ primaryErrorString = getString(R.string.future_certificate)
+ }
+
+ SslError.SSL_EXPIRED -> {
+ // Change the end date span color to red.
+ endDateStringBuilder.setSpan(redColorSpan, endDateLabel.length, endDateStringBuilder.length, Spanned.SPAN_INCLUSIVE_INCLUSIVE)
+
+ // Store the primary error string.
+ primaryErrorString = getString(R.string.expired_certificate)
+ }
+
+ SslError.SSL_INVALID ->
+ // Store the primary error string.
+ primaryErrorString = getString(R.string.invalid_certificate)