X-Git-Url: https://gitweb.stoutner.com/?p=PrivacyBrowserAndroid.git;a=blobdiff_plain;f=app%2Fsrc%2Fmain%2Fjava%2Fcom%2Fstoutner%2Fprivacybrowser%2Ffragments%2FAboutTabFragment.java;fp=app%2Fsrc%2Fmain%2Fjava%2Fcom%2Fstoutner%2Fprivacybrowser%2Ffragments%2FAboutTabFragment.java;h=0000000000000000000000000000000000000000;hp=9d8a2f1c43ebca2c7926b7f3a01dd62753217977;hb=1003c7842a01f338c8aaf9d4f07216111f294202;hpb=4196bafc4069857b554ac95addcae92fcabae901 diff --git a/app/src/main/java/com/stoutner/privacybrowser/fragments/AboutTabFragment.java b/app/src/main/java/com/stoutner/privacybrowser/fragments/AboutTabFragment.java deleted file mode 100644 index 9d8a2f1c..00000000 --- a/app/src/main/java/com/stoutner/privacybrowser/fragments/AboutTabFragment.java +++ /dev/null @@ -1,663 +0,0 @@ -/* - * Copyright © 2016-2020 Soren Stoutner . - * - * This file is part of Privacy Browser . - * - * Privacy Browser is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Privacy Browser is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with Privacy Browser. If not, see . - */ - -package com.stoutner.privacybrowser.fragments; - -import android.annotation.SuppressLint; -import android.app.Activity; -import android.app.ActivityManager; -import android.content.Context; -import android.content.pm.PackageInfo; -import android.content.pm.PackageManager; -import android.content.pm.Signature; -import android.content.res.Configuration; -import android.os.Build; -import android.os.Bundle; -import android.os.Handler; -import android.text.SpannableStringBuilder; -import android.text.Spanned; -import android.text.style.ForegroundColorSpan; -import android.view.LayoutInflater; -import android.view.View; -import android.view.ViewGroup; -import android.webkit.WebView; -import android.widget.TextView; - -import androidx.annotation.NonNull; -import androidx.fragment.app.Fragment; -import androidx.webkit.WebViewCompat; - -import com.stoutner.privacybrowser.BuildConfig; -import com.stoutner.privacybrowser.R; - -import java.io.ByteArrayInputStream; -import java.io.InputStream; -import java.math.BigInteger; -import java.security.Principal; -import java.security.cert.CertificateException; -import java.security.cert.CertificateFactory; -import java.security.cert.X509Certificate; -import java.text.DateFormat; -import java.text.NumberFormat; -import java.util.Date; - -public class AboutTabFragment extends Fragment { - // Declare the class constants. - final static String TAB_NUMBER = "tab_number"; - final static String BLOCKLIST_VERSIONS = "blocklist_versions"; - final long MEBIBYTE = 1048576; - - // Declare the class variables. - private boolean updateMemoryUsageBoolean = true; - private int tabNumber; - private String[] blocklistVersions; - private View tabLayout; - private String appConsumedMemoryLabel; - private String appAvailableMemoryLabel; - private String appTotalMemoryLabel; - private String appMaximumMemoryLabel; - private String systemConsumedMemoryLabel; - private String systemAvailableMemoryLabel; - private String systemTotalMemoryLabel; - private Runtime runtime; - private ActivityManager activityManager; - private ActivityManager.MemoryInfo memoryInfo; - private NumberFormat numberFormat; - private ForegroundColorSpan blueColorSpan; - - // Declare the class views. - private TextView appConsumedMemoryTextView; - private TextView appAvailableMemoryTextView; - private TextView appTotalMemoryTextView; - private TextView appMaximumMemoryTextView; - private TextView systemConsumedMemoryTextView; - private TextView systemAvailableMemoryTextView; - private TextView systemTotalMemoryTextView; - - public static AboutTabFragment createTab(int tabNumber, String[] blocklistVersions) { - // Create a bundle. - Bundle argumentsBundle = new Bundle(); - - // Store the tab number in the bundle. - argumentsBundle.putInt(TAB_NUMBER, tabNumber); - argumentsBundle.putStringArray(BLOCKLIST_VERSIONS, blocklistVersions); - - // Create a new instance of the tab fragment. - AboutTabFragment aboutTabFragment = new AboutTabFragment(); - - // Add the arguments bundle to the fragment. - aboutTabFragment.setArguments(argumentsBundle); - - // Return the new fragment. - return aboutTabFragment; - } - - @Override - public void onCreate(Bundle savedInstanceState) { - // Run the default commands. - super.onCreate(savedInstanceState); - - // Get a handle for the arguments. - Bundle arguments = getArguments(); - - // Remove the incorrect lint warning below that arguments might be null. - assert arguments != null; - - // Store the arguments in class variables. - tabNumber = getArguments().getInt(TAB_NUMBER); - blocklistVersions = getArguments().getStringArray(BLOCKLIST_VERSIONS); - } - - @Override - public View onCreateView(@NonNull LayoutInflater layoutInflater, ViewGroup container, Bundle savedInstanceState) { - // Get a handle for the context and assert that it isn't null. - Context context = getContext(); - assert context != null; - - // Get the current theme status. - int currentThemeStatus = getResources().getConfiguration().uiMode & Configuration.UI_MODE_NIGHT_MASK; - - // Load the tabs. Tab numbers start at 0. - if (tabNumber == 0) { // Load the about tab. - // Setting false at the end of inflater.inflate does not attach the inflated layout as a child of container. The fragment will take care of attaching the root automatically. - tabLayout = layoutInflater.inflate(R.layout.about_tab_version, container, false); - - // Get handles for the text views. - TextView versionTextView = tabLayout.findViewById(R.id.version); - TextView brandTextView = tabLayout.findViewById(R.id.brand); - TextView manufacturerTextView = tabLayout.findViewById(R.id.manufacturer); - TextView modelTextView = tabLayout.findViewById(R.id.model); - TextView deviceTextView = tabLayout.findViewById(R.id.device); - TextView bootloaderTextView = tabLayout.findViewById(R.id.bootloader); - TextView radioTextView = tabLayout.findViewById(R.id.radio); - TextView androidTextView = tabLayout.findViewById(R.id.android); - TextView securityPatchTextView = tabLayout.findViewById(R.id.security_patch); - TextView buildTextView = tabLayout.findViewById(R.id.build); - TextView webViewProviderTextView = tabLayout.findViewById(R.id.webview_provider); - TextView webViewVersionTextView = tabLayout.findViewById(R.id.webview_version); - TextView orbotTextView = tabLayout.findViewById(R.id.orbot); - TextView i2pTextView = tabLayout.findViewById(R.id.i2p); - TextView openKeychainTextView = tabLayout.findViewById(R.id.open_keychain); - appConsumedMemoryTextView = tabLayout.findViewById(R.id.app_consumed_memory); - appAvailableMemoryTextView = tabLayout.findViewById(R.id.app_available_memory); - appTotalMemoryTextView = tabLayout.findViewById(R.id.app_total_memory); - appMaximumMemoryTextView = tabLayout.findViewById(R.id.app_maximum_memory); - systemConsumedMemoryTextView = tabLayout.findViewById(R.id.system_consumed_memory); - systemAvailableMemoryTextView = tabLayout.findViewById(R.id.system_available_memory); - systemTotalMemoryTextView = tabLayout.findViewById(R.id.system_total_memory); - TextView easyListTextView = tabLayout.findViewById(R.id.easylist); - TextView easyPrivacyTextView = tabLayout.findViewById(R.id.easyprivacy); - TextView fanboyAnnoyanceTextView = tabLayout.findViewById(R.id.fanboy_annoyance); - TextView fanboySocialTextView = tabLayout.findViewById(R.id.fanboy_social); - TextView ultraListTextView = tabLayout.findViewById(R.id.ultralist); - TextView ultraPrivacyTextView = tabLayout.findViewById(R.id.ultraprivacy); - TextView certificateIssuerDNTextView = tabLayout.findViewById(R.id.certificate_issuer_dn); - TextView certificateSubjectDNTextView = tabLayout.findViewById(R.id.certificate_subject_dn); - TextView certificateStartDateTextView = tabLayout.findViewById(R.id.certificate_start_date); - TextView certificateEndDateTextView = tabLayout.findViewById(R.id.certificate_end_date); - TextView certificateVersionTextView = tabLayout.findViewById(R.id.certificate_version); - TextView certificateSerialNumberTextView = tabLayout.findViewById(R.id.certificate_serial_number); - TextView certificateSignatureAlgorithmTextView = tabLayout.findViewById(R.id.certificate_signature_algorithm); - - // Setup the labels. - String version = getString(R.string.version) + " " + BuildConfig.VERSION_NAME + " (" + getString(R.string.version_code) + " " + BuildConfig.VERSION_CODE + ")"; - String brandLabel = getString(R.string.brand) + " "; - String manufacturerLabel = getString(R.string.manufacturer) + " "; - String modelLabel = getString(R.string.model) + " "; - String deviceLabel = getString(R.string.device) + " "; - String bootloaderLabel = getString(R.string.bootloader) + " "; - String androidLabel = getString(R.string.android) + " "; - String buildLabel = getString(R.string.build) + " "; - String webViewVersionLabel = getString(R.string.webview_version) + " "; - appConsumedMemoryLabel = getString(R.string.app_consumed_memory) + " "; - appAvailableMemoryLabel = getString(R.string.app_available_memory) + " "; - appTotalMemoryLabel = getString(R.string.app_total_memory) + " "; - appMaximumMemoryLabel = getString(R.string.app_maximum_memory) + " "; - systemConsumedMemoryLabel = getString(R.string.system_consumed_memory) + " "; - systemAvailableMemoryLabel = getString(R.string.system_available_memory) + " "; - systemTotalMemoryLabel = getString(R.string.system_total_memory) + " "; - String easyListLabel = getString(R.string.easylist_label) + " "; - String easyPrivacyLabel = getString(R.string.easyprivacy_label) + " "; - String fanboyAnnoyanceLabel = getString(R.string.fanboy_annoyance_label) + " "; - String fanboySocialLabel = getString(R.string.fanboy_social_label) + " "; - String ultraListLabel = getString(R.string.ultralist_label) + " "; - String ultraPrivacyLabel = getString(R.string.ultraprivacy_label) + " "; - String issuerDNLabel = getString(R.string.issuer_dn) + " "; - String subjectDNLabel = getString(R.string.subject_dn) + " "; - String startDateLabel = getString(R.string.start_date) + " "; - String endDateLabel = getString(R.string.end_date) + " "; - String certificateVersionLabel = getString(R.string.certificate_version) + " "; - String serialNumberLabel = getString(R.string.serial_number) + " "; - String signatureAlgorithmLabel = getString(R.string.signature_algorithm) + " "; - - // The WebView layout is only used to get the default user agent from `bare_webview`. It is not used to render content on the screen. - // Once the minimum API >= 26 this can be accomplished with the WebView package info. - View webViewLayout = layoutInflater.inflate(R.layout.bare_webview, container, false); - WebView tabLayoutWebView = webViewLayout.findViewById(R.id.bare_webview); - String userAgentString = tabLayoutWebView.getSettings().getUserAgentString(); - - // Get the device's information and store it in strings. - String brand = Build.BRAND; - String manufacturer = Build.MANUFACTURER; - String model = Build.MODEL; - String device = Build.DEVICE; - String bootloader = Build.BOOTLOADER; - String radio = Build.getRadioVersion(); - String android = Build.VERSION.RELEASE + " (" + getString(R.string.api) + " " + Build.VERSION.SDK_INT + ")"; - String build = Build.DISPLAY; - // Select the substring that begins after `Chrome/` and goes until the next ` `. - String webView = userAgentString.substring(userAgentString.indexOf("Chrome/") + 7, userAgentString.indexOf(" ", userAgentString.indexOf("Chrome/"))); - - // Get the Orbot version name if Orbot is installed. - String orbot; - try { - // Store the version name. - orbot = context.getPackageManager().getPackageInfo("org.torproject.android", 0).versionName; - } catch (PackageManager.NameNotFoundException exception) { // Orbot is not installed. - orbot = ""; - } - - // Get the I2P version name if I2P is installed. - String i2p; - try { - // Store the version name. - i2p = context.getPackageManager().getPackageInfo("net.i2p.android.router", 0).versionName; - } catch (PackageManager.NameNotFoundException exception) { // I2P is not installed. - i2p = ""; - } - - // Get the OpenKeychain version name if it is installed. - String openKeychain; - try { - // Store the version name. - openKeychain = context.getPackageManager().getPackageInfo("org.sufficientlysecure.keychain", 0).versionName; - } catch (PackageManager.NameNotFoundException exception) { // OpenKeychain is not installed. - openKeychain = ""; - } - - // Create a spannable string builder for the hardware and software text views that needs multiple colors of text. - SpannableStringBuilder brandStringBuilder = new SpannableStringBuilder(brandLabel + brand); - SpannableStringBuilder manufacturerStringBuilder = new SpannableStringBuilder(manufacturerLabel + manufacturer); - SpannableStringBuilder modelStringBuilder = new SpannableStringBuilder(modelLabel + model); - SpannableStringBuilder deviceStringBuilder = new SpannableStringBuilder(deviceLabel + device); - SpannableStringBuilder bootloaderStringBuilder = new SpannableStringBuilder(bootloaderLabel + bootloader); - SpannableStringBuilder androidStringBuilder = new SpannableStringBuilder(androidLabel + android); - SpannableStringBuilder buildStringBuilder = new SpannableStringBuilder(buildLabel + build); - SpannableStringBuilder webViewVersionStringBuilder = new SpannableStringBuilder(webViewVersionLabel + webView); - SpannableStringBuilder easyListStringBuilder = new SpannableStringBuilder(easyListLabel + blocklistVersions[0]); - SpannableStringBuilder easyPrivacyStringBuilder = new SpannableStringBuilder(easyPrivacyLabel + blocklistVersions[1]); - SpannableStringBuilder fanboyAnnoyanceStringBuilder = new SpannableStringBuilder(fanboyAnnoyanceLabel + blocklistVersions[2]); - SpannableStringBuilder fanboySocialStringBuilder = new SpannableStringBuilder(fanboySocialLabel + blocklistVersions[3]); - SpannableStringBuilder ultraListStringBuilder = new SpannableStringBuilder(ultraListLabel + blocklistVersions[4]); - SpannableStringBuilder ultraPrivacyStringBuilder = new SpannableStringBuilder(ultraPrivacyLabel + blocklistVersions[5]); - - // Set the blue color span according to the theme. The deprecated `getResources()` must be used until the minimum API >= 23. - if (currentThemeStatus == Configuration.UI_MODE_NIGHT_NO) { - blueColorSpan = new ForegroundColorSpan(getResources().getColor(R.color.blue_700)); - } else { - blueColorSpan = new ForegroundColorSpan(getResources().getColor(R.color.violet_500)); - } - - // Setup the spans to display the device information in blue. `SPAN_INCLUSIVE_INCLUSIVE` allows the span to grow in either direction. - brandStringBuilder.setSpan(blueColorSpan, brandLabel.length(), brandStringBuilder.length(), Spanned.SPAN_INCLUSIVE_INCLUSIVE); - manufacturerStringBuilder.setSpan(blueColorSpan, manufacturerLabel.length(), manufacturerStringBuilder.length(), Spanned.SPAN_INCLUSIVE_INCLUSIVE); - modelStringBuilder.setSpan(blueColorSpan, modelLabel.length(), modelStringBuilder.length(), Spanned.SPAN_INCLUSIVE_INCLUSIVE); - deviceStringBuilder.setSpan(blueColorSpan, deviceLabel.length(), deviceStringBuilder.length(), Spanned.SPAN_INCLUSIVE_INCLUSIVE); - bootloaderStringBuilder.setSpan(blueColorSpan, bootloaderLabel.length(), bootloaderStringBuilder.length(), Spanned.SPAN_INCLUSIVE_INCLUSIVE); - androidStringBuilder.setSpan(blueColorSpan, androidLabel.length(), androidStringBuilder.length(), Spanned.SPAN_INCLUSIVE_INCLUSIVE); - buildStringBuilder.setSpan(blueColorSpan, buildLabel.length(), buildStringBuilder.length(), Spanned.SPAN_INCLUSIVE_INCLUSIVE); - webViewVersionStringBuilder.setSpan(blueColorSpan, webViewVersionLabel.length(), webViewVersionStringBuilder.length(), Spanned.SPAN_INCLUSIVE_INCLUSIVE); - easyListStringBuilder.setSpan(blueColorSpan, easyListLabel.length(), easyListStringBuilder.length(), Spanned.SPAN_INCLUSIVE_EXCLUSIVE); - easyPrivacyStringBuilder.setSpan(blueColorSpan, easyPrivacyLabel.length(), easyPrivacyStringBuilder.length(), Spanned.SPAN_INCLUSIVE_INCLUSIVE); - fanboyAnnoyanceStringBuilder.setSpan(blueColorSpan, fanboyAnnoyanceLabel.length(), fanboyAnnoyanceStringBuilder.length(), Spanned.SPAN_INCLUSIVE_INCLUSIVE); - fanboySocialStringBuilder.setSpan(blueColorSpan, fanboySocialLabel.length(), fanboySocialStringBuilder.length(), Spanned.SPAN_INCLUSIVE_INCLUSIVE); - ultraListStringBuilder.setSpan(blueColorSpan, ultraListLabel.length(), ultraListStringBuilder.length(), Spanned.SPAN_INCLUSIVE_INCLUSIVE); - ultraPrivacyStringBuilder.setSpan(blueColorSpan, ultraPrivacyLabel.length(), ultraPrivacyStringBuilder.length(), Spanned.SPAN_INCLUSIVE_INCLUSIVE); - - // Display the strings in the text boxes. - versionTextView.setText(version); - brandTextView.setText(brandStringBuilder); - manufacturerTextView.setText(manufacturerStringBuilder); - modelTextView.setText(modelStringBuilder); - deviceTextView.setText(deviceStringBuilder); - bootloaderTextView.setText(bootloaderStringBuilder); - androidTextView.setText(androidStringBuilder); - buildTextView.setText(buildStringBuilder); - webViewVersionTextView.setText(webViewVersionStringBuilder); - easyListTextView.setText(easyListStringBuilder); - easyPrivacyTextView.setText(easyPrivacyStringBuilder); - fanboyAnnoyanceTextView.setText(fanboyAnnoyanceStringBuilder); - fanboySocialTextView.setText(fanboySocialStringBuilder); - ultraListTextView.setText(ultraListStringBuilder); - ultraPrivacyTextView.setText(ultraPrivacyStringBuilder); - - // Only populate the radio text view if there is a radio in the device. - if (!radio.isEmpty()) { - String radioLabel = getString(R.string.radio) + " "; - SpannableStringBuilder radioStringBuilder = new SpannableStringBuilder(radioLabel + radio); - radioStringBuilder.setSpan(blueColorSpan, radioLabel.length(), radioStringBuilder.length(), Spanned.SPAN_INCLUSIVE_INCLUSIVE); - radioTextView.setText(radioStringBuilder); - } else { // This device does not have a radio. - radioTextView.setVisibility(View.GONE); - } - - // Build.VERSION.SECURITY_PATCH is only available for SDK_INT >= 23. - if (Build.VERSION.SDK_INT >= 23) { - String securityPatchLabel = getString(R.string.security_patch) + " "; - String securityPatch = Build.VERSION.SECURITY_PATCH; - SpannableStringBuilder securityPatchStringBuilder = new SpannableStringBuilder(securityPatchLabel + securityPatch); - securityPatchStringBuilder.setSpan(blueColorSpan, securityPatchLabel.length(), securityPatchStringBuilder.length(), Spanned.SPAN_INCLUSIVE_INCLUSIVE); - securityPatchTextView.setText(securityPatchStringBuilder); - } else { // The API < 23. - // Hide the security patch text view. - securityPatchTextView.setVisibility(View.GONE); - } - - // 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. - } - - // Get a handle for the runtime. - runtime = Runtime.getRuntime(); - - // Get a handle for the activity. - Activity activity = getActivity(); - - // Remove the incorrect lint warning below that the activity might be null. - assert activity != null; - - // Get a handle for the activity manager. - activityManager = (ActivityManager) activity.getSystemService(Context.ACTIVITY_SERVICE); - - // Remove the incorrect lint warning below that the activity manager might be null. - assert activityManager != null; - - // Instantiate a memory info variable. - memoryInfo = new ActivityManager.MemoryInfo(); - - // Define a number format. - numberFormat = NumberFormat.getInstance(); - - // Set the minimum and maximum number of fraction digits. - numberFormat.setMinimumFractionDigits(2); - numberFormat.setMaximumFractionDigits(2); - - // Update the memory usage. - updateMemoryUsage(getActivity()); - } catch (PackageManager.NameNotFoundException e) { - // Do nothing if `PackageManager` says Privacy Browser isn't installed. - } - } else { // load a WebView for all the other tabs. Tab numbers start at 0. - // Setting false at the end of inflater.inflate does not attach the inflated layout as a child of container. The fragment will take care of attaching the root automatically. - tabLayout = layoutInflater.inflate(R.layout.bare_webview, container, false); - - // Get a handle for `tabWebView`. - WebView tabWebView = (WebView) tabLayout; - - // Load the tabs according to the theme. - if (currentThemeStatus == Configuration.UI_MODE_NIGHT_YES) { // The dark theme is applied. - // Set the background color. The deprecated `.getColor()` must be used until the minimum API >= 23. - tabWebView.setBackgroundColor(getResources().getColor(R.color.gray_850)); - - switch (tabNumber) { - case 1: - tabWebView.loadUrl("file:///android_asset/" + getString(R.string.android_asset_path) + "/about_permissions_dark.html"); - break; - - case 2: - tabWebView.loadUrl("file:///android_asset/" + getString(R.string.android_asset_path) + "/about_privacy_policy_dark.html"); - break; - - case 3: - tabWebView.loadUrl("file:///android_asset/" + getString(R.string.android_asset_path) + "/about_changelog_dark.html"); - break; - - case 4: - tabWebView.loadUrl("file:///android_asset/" + getString(R.string.android_asset_path) + "/about_licenses_dark.html"); - break; - - case 5: - tabWebView.loadUrl("file:///android_asset/" + getString(R.string.android_asset_path) + "/about_contributors_dark.html"); - break; - - case 6: - tabWebView.loadUrl("file:///android_asset/" + getString(R.string.android_asset_path) + "/about_links_dark.html"); - break; - } - } else { // The light theme is applied. - switch (tabNumber) { - case 1: - tabWebView.loadUrl("file:///android_asset/" + getString(R.string.android_asset_path) + "/about_permissions_light.html"); - break; - - case 2: - tabWebView.loadUrl("file:///android_asset/" + getString(R.string.android_asset_path) + "/about_privacy_policy_light.html"); - break; - - case 3: - tabWebView.loadUrl("file:///android_asset/" + getString(R.string.android_asset_path) + "/about_changelog_light.html"); - break; - - case 4: - tabWebView.loadUrl("file:///android_asset/" + getString(R.string.android_asset_path) + "/about_licenses_light.html"); - break; - - case 5: - tabWebView.loadUrl("file:///android_asset/" + getString(R.string.android_asset_path) + "/about_contributors_light.html"); - break; - - case 6: - tabWebView.loadUrl("file:///android_asset/" + getString(R.string.android_asset_path) + "/about_links_light.html"); - break; - } - } - } - - // Scroll the tab if the saved instance state is not null. - if (savedInstanceState != null) { - tabLayout.post(() -> { - tabLayout.setScrollX(savedInstanceState.getInt("scroll_x")); - tabLayout.setScrollY(savedInstanceState.getInt("scroll_y")); - }); - } - - // Return the formatted `tabLayout`. - return tabLayout; - } - - @Override - public void onPause() { - // Run the default commands. - super.onPause(); - - // Pause the updating of the memory usage. - updateMemoryUsageBoolean = false; - } - - @Override - public void onResume() { - // Run the default commands. - super.onResume(); - - // Resume the updating of the memory usage. - updateMemoryUsageBoolean = true; - } - - @Override - public void onSaveInstanceState(@NonNull Bundle savedInstanceState) { - // Run the default commands. - super.onSaveInstanceState(savedInstanceState); - - // Save the scroll positions if the tab layout is not null, which can happen if a tab is not currently selected. - if (tabLayout != null) { - savedInstanceState.putInt("scroll_x", tabLayout.getScrollX()); - savedInstanceState.putInt("scroll_y", tabLayout.getScrollY()); - } - } - - public void updateMemoryUsage(Activity activity) { - try { - // Update the memory usage if enabled. - if (updateMemoryUsageBoolean) { - // Populate the memory info variable. - activityManager.getMemoryInfo(memoryInfo); - - // Get the app memory information. - long appAvailableMemoryLong = runtime.freeMemory(); - long appTotalMemoryLong = runtime.totalMemory(); - long appMaximumMemoryLong = runtime.maxMemory(); - - // Calculate the app consumed memory. - long appConsumedMemoryLong = appTotalMemoryLong - appAvailableMemoryLong; - - // Get the system memory information. - long systemTotalMemoryLong = memoryInfo.totalMem; - long systemAvailableMemoryLong = memoryInfo.availMem; - - // Calculate the system consumed memory. - long systemConsumedMemoryLong = systemTotalMemoryLong - systemAvailableMemoryLong; - - // Convert the memory information into mebibytes. - float appConsumedMemoryFloat = (float) appConsumedMemoryLong / MEBIBYTE; - float appAvailableMemoryFloat = (float) appAvailableMemoryLong / MEBIBYTE; - float appTotalMemoryFloat = (float) appTotalMemoryLong / MEBIBYTE; - float appMaximumMemoryFloat = (float) appMaximumMemoryLong / MEBIBYTE; - float systemConsumedMemoryFloat = (float) systemConsumedMemoryLong / MEBIBYTE; - float systemAvailableMemoryFloat = (float) systemAvailableMemoryLong / MEBIBYTE; - float systemTotalMemoryFloat = (float) systemTotalMemoryLong / MEBIBYTE; - - // Get the mebibyte string. - String mebibyte = getString(R.string.mebibyte); - - // Calculate the mebibyte length. - int mebibyteLength = mebibyte.length(); - - // Create spannable string builders. - SpannableStringBuilder appConsumedMemoryStringBuilder = new SpannableStringBuilder(appConsumedMemoryLabel + numberFormat.format(appConsumedMemoryFloat) + " " + mebibyte); - SpannableStringBuilder appAvailableMemoryStringBuilder = new SpannableStringBuilder(appAvailableMemoryLabel + numberFormat.format(appAvailableMemoryFloat) + " " + mebibyte); - SpannableStringBuilder appTotalMemoryStringBuilder = new SpannableStringBuilder(appTotalMemoryLabel + numberFormat.format(appTotalMemoryFloat) + " " + mebibyte); - SpannableStringBuilder appMaximumMemoryStringBuilder = new SpannableStringBuilder(appMaximumMemoryLabel + numberFormat.format(appMaximumMemoryFloat) + " " + mebibyte); - SpannableStringBuilder systemConsumedMemoryStringBuilder = new SpannableStringBuilder(systemConsumedMemoryLabel + numberFormat.format(systemConsumedMemoryFloat) + " " + mebibyte); - SpannableStringBuilder systemAvailableMemoryStringBuilder = new SpannableStringBuilder(systemAvailableMemoryLabel + numberFormat.format(systemAvailableMemoryFloat) + " " + mebibyte); - SpannableStringBuilder systemTotalMemoryStringBuilder = new SpannableStringBuilder(systemTotalMemoryLabel + numberFormat.format(systemTotalMemoryFloat) + " " + mebibyte); - - // Setup the spans to display the memory information in blue. `SPAN_INCLUSIVE_INCLUSIVE` allows the span to grow in either direction. - appConsumedMemoryStringBuilder.setSpan(blueColorSpan, appConsumedMemoryLabel.length(), appConsumedMemoryStringBuilder.length() - mebibyteLength, Spanned.SPAN_INCLUSIVE_INCLUSIVE); - appAvailableMemoryStringBuilder.setSpan(blueColorSpan, appAvailableMemoryLabel.length(), appAvailableMemoryStringBuilder.length() - mebibyteLength, Spanned.SPAN_INCLUSIVE_INCLUSIVE); - appTotalMemoryStringBuilder.setSpan(blueColorSpan, appTotalMemoryLabel.length(), appTotalMemoryStringBuilder.length() - mebibyteLength, Spanned.SPAN_INCLUSIVE_INCLUSIVE); - appMaximumMemoryStringBuilder.setSpan(blueColorSpan, appMaximumMemoryLabel.length(), appMaximumMemoryStringBuilder.length() - mebibyteLength, Spanned.SPAN_INCLUSIVE_INCLUSIVE); - systemConsumedMemoryStringBuilder.setSpan(blueColorSpan, systemConsumedMemoryLabel.length(), systemConsumedMemoryStringBuilder.length() - mebibyteLength, Spanned.SPAN_INCLUSIVE_INCLUSIVE); - systemAvailableMemoryStringBuilder.setSpan(blueColorSpan, systemAvailableMemoryLabel.length(), systemAvailableMemoryStringBuilder.length() - mebibyteLength, Spanned.SPAN_INCLUSIVE_INCLUSIVE); - systemTotalMemoryStringBuilder.setSpan(blueColorSpan, systemTotalMemoryLabel.length(), systemTotalMemoryStringBuilder.length() - mebibyteLength, Spanned.SPAN_INCLUSIVE_INCLUSIVE); - - // Display the string in the text boxes. - appConsumedMemoryTextView.setText(appConsumedMemoryStringBuilder); - appAvailableMemoryTextView.setText(appAvailableMemoryStringBuilder); - appTotalMemoryTextView.setText(appTotalMemoryStringBuilder); - appMaximumMemoryTextView.setText(appMaximumMemoryStringBuilder); - systemConsumedMemoryTextView.setText(systemConsumedMemoryStringBuilder); - systemAvailableMemoryTextView.setText(systemAvailableMemoryStringBuilder); - systemTotalMemoryTextView.setText(systemTotalMemoryStringBuilder); - } - - // Schedule another memory update if the activity has not been destroyed. - if (!activity.isDestroyed()) { - // Create a handler to update the memory usage. - Handler updateMemoryUsageHandler = new Handler(); - - // Create a runnable to update the memory usage. - Runnable updateMemoryUsageRunnable = () -> updateMemoryUsage(activity); - - // Update the memory usage after 1000 milliseconds - updateMemoryUsageHandler.postDelayed(updateMemoryUsageRunnable, 1000); - } - } catch (Exception exception) { - // Do nothing. - } - } -} \ No newline at end of file