+ // Only populate the WebView provider if the SDK >= 21.
+ if (Build.VERSION.SDK_INT >= 21) {
+ // Create the WebView provider label.
+ String webViewProviderLabel = getString(R.string.webview_provider) + " ";
+
+ // Get the current WebView package info.
+ PackageInfo webViewPackageInfo = WebViewCompat.getCurrentWebViewPackage(context);
+
+ // Remove the warning below that the package info might be null.
+ assert webViewPackageInfo != null;
+
+ // Get the WebView provider name.
+ String webViewPackageName = webViewPackageInfo.packageName;
+
+ // Create the spannable string builder.
+ SpannableStringBuilder webViewProviderStringBuilder = new SpannableStringBuilder(webViewProviderLabel + webViewPackageName);
+
+ // Apply the coloration.
+ webViewProviderStringBuilder.setSpan(blueColorSpan, webViewProviderLabel.length(), webViewProviderStringBuilder.length(), Spanned.SPAN_INCLUSIVE_INCLUSIVE);
+
+ // Display the WebView provider.
+ webViewProviderTextView.setText(webViewProviderStringBuilder);
+ } else { // The API < 21.
+ // Hide the WebView provider text view.
+ webViewProviderTextView.setVisibility(View.GONE);
+ }
+
+ // Only populate the Orbot text view if it is installed.
+ if (!orbot.isEmpty()) {
+ String orbotLabel = getString(R.string.orbot) + " ";
+ SpannableStringBuilder orbotStringBuilder = new SpannableStringBuilder(orbotLabel + orbot);
+ orbotStringBuilder.setSpan(blueColorSpan, orbotLabel.length(), orbotStringBuilder.length(), Spanned.SPAN_INCLUSIVE_INCLUSIVE);
+ orbotTextView.setText(orbotStringBuilder);
+ } else { // Orbot is not installed.
+ orbotTextView.setVisibility(View.GONE);
+ }
+
+ // Only populate the I2P text view if it is installed.
+ if (!i2p.isEmpty()) {
+ String i2pLabel = getString(R.string.i2p) + " ";
+ SpannableStringBuilder i2pStringBuilder = new SpannableStringBuilder(i2pLabel + i2p);
+ i2pStringBuilder.setSpan(blueColorSpan, i2pLabel.length(), i2pStringBuilder.length(), Spanned.SPAN_INCLUSIVE_INCLUSIVE);
+ i2pTextView.setText(i2pStringBuilder);
+ } else { // I2P is not installed.
+ i2pTextView.setVisibility(View.GONE);
+ }
+
+ // Only populate the OpenKeychain text view if it is installed.
+ if (!openKeychain.isEmpty()) {
+ String openKeychainLabel = getString(R.string.openkeychain) + " ";
+ SpannableStringBuilder openKeychainStringBuilder = new SpannableStringBuilder(openKeychainLabel + openKeychain);
+ openKeychainStringBuilder.setSpan(blueColorSpan, openKeychainLabel.length(), openKeychainStringBuilder.length(), Spanned.SPAN_INCLUSIVE_INCLUSIVE);
+ openKeychainTextView.setText(openKeychainStringBuilder);
+ } else { //OpenKeychain is not installed.
+ openKeychainTextView.setVisibility(View.GONE);
+ }
+
+ // Display the package signature.
+ try {
+ // Get the first package signature. Suppress the lint warning about the need to be careful in implementing comparison of certificates for security purposes.
+ @SuppressLint("PackageManagerGetSignatures") Signature packageSignature = getContext().getPackageManager().getPackageInfo(getContext().getPackageName(),
+ PackageManager.GET_SIGNATURES).signatures[0];
+
+ // Convert the signature to a byte array input stream.
+ InputStream certificateByteArrayInputStream = new ByteArrayInputStream(packageSignature.toByteArray());
+
+ // Display the certificate information on the screen.
+ try {
+ // Instantiate a `CertificateFactory`.
+ CertificateFactory certificateFactory = CertificateFactory.getInstance("X509");
+
+ // Generate an `X509Certificate`.
+ X509Certificate x509Certificate = (X509Certificate) certificateFactory.generateCertificate(certificateByteArrayInputStream);
+
+ // Store the individual sections of the certificate that we are interested in.
+ Principal issuerDNPrincipal = x509Certificate.getIssuerDN();
+ Principal subjectDNPrincipal = x509Certificate.getSubjectDN();
+ Date startDate = x509Certificate.getNotBefore();
+ Date endDate = x509Certificate.getNotAfter();
+ int certificateVersion = x509Certificate.getVersion();
+ BigInteger serialNumberBigInteger = x509Certificate.getSerialNumber();
+ String signatureAlgorithmNameString = x509Certificate.getSigAlgName();
+
+ // Create a `SpannableStringBuilder` for each `TextView` that needs multiple colors of text.
+ SpannableStringBuilder issuerDNStringBuilder = new SpannableStringBuilder(issuerDNLabel + issuerDNPrincipal.toString());
+ SpannableStringBuilder subjectDNStringBuilder = new SpannableStringBuilder(subjectDNLabel + subjectDNPrincipal.toString());
+ SpannableStringBuilder startDateStringBuilder = new SpannableStringBuilder(startDateLabel + DateFormat.getDateTimeInstance(DateFormat.MEDIUM, DateFormat.LONG).format(startDate));
+ SpannableStringBuilder endDataStringBuilder = new SpannableStringBuilder(endDateLabel + DateFormat.getDateTimeInstance(DateFormat.MEDIUM, DateFormat.LONG).format(endDate));
+ SpannableStringBuilder certificateVersionStringBuilder = new SpannableStringBuilder(certificateVersionLabel + certificateVersion);
+ SpannableStringBuilder serialNumberStringBuilder = new SpannableStringBuilder(serialNumberLabel + serialNumberBigInteger);
+ SpannableStringBuilder signatureAlgorithmStringBuilder = new SpannableStringBuilder(signatureAlgorithmLabel + signatureAlgorithmNameString);
+
+ // Setup the spans to display the device information in blue. `SPAN_INCLUSIVE_INCLUSIVE` allows the span to grow in either direction.
+ issuerDNStringBuilder.setSpan(blueColorSpan, issuerDNLabel.length(), issuerDNStringBuilder.length(), Spanned.SPAN_INCLUSIVE_INCLUSIVE);
+ subjectDNStringBuilder.setSpan(blueColorSpan, subjectDNLabel.length(), subjectDNStringBuilder.length(), Spanned.SPAN_INCLUSIVE_INCLUSIVE);
+ startDateStringBuilder.setSpan(blueColorSpan, startDateLabel.length(), startDateStringBuilder.length(), Spanned.SPAN_INCLUSIVE_INCLUSIVE);
+ endDataStringBuilder.setSpan(blueColorSpan, endDateLabel.length(), endDataStringBuilder.length(), Spanned.SPAN_INCLUSIVE_INCLUSIVE);
+ certificateVersionStringBuilder.setSpan(blueColorSpan, certificateVersionLabel.length(), certificateVersionStringBuilder.length(), Spanned.SPAN_INCLUSIVE_INCLUSIVE);
+ serialNumberStringBuilder.setSpan(blueColorSpan, serialNumberLabel.length(), serialNumberStringBuilder.length(), Spanned.SPAN_INCLUSIVE_INCLUSIVE);
+ signatureAlgorithmStringBuilder.setSpan(blueColorSpan, signatureAlgorithmLabel.length(), signatureAlgorithmStringBuilder.length(), Spanned.SPAN_INCLUSIVE_INCLUSIVE);
+
+ // Display the strings in the text boxes.
+ certificateIssuerDNTextView.setText(issuerDNStringBuilder);
+ certificateSubjectDNTextView.setText(subjectDNStringBuilder);
+ certificateStartDateTextView.setText(startDateStringBuilder);
+ certificateEndDateTextView.setText(endDataStringBuilder);
+ certificateVersionTextView.setText(certificateVersionStringBuilder);
+ certificateSerialNumberTextView.setText(serialNumberStringBuilder);
+ certificateSignatureAlgorithmTextView.setText(signatureAlgorithmStringBuilder);
+ } catch (CertificateException e) {
+ // Do nothing if there is a certificate error.
+ }
+ } catch (PackageManager.NameNotFoundException e) {
+ // Do nothing if `PackageManager` says Privacy Browser isn't installed.