+ // Save the cursor entries as variables.
+ String domainNameString = domainCursor.getString(domainCursor.getColumnIndex(DomainsDatabaseHelper.DOMAIN_NAME));
+ int javaScriptInt = domainCursor.getInt(domainCursor.getColumnIndex(DomainsDatabaseHelper.ENABLE_JAVASCRIPT));
+ int firstPartyCookiesInt = domainCursor.getInt(domainCursor.getColumnIndex(DomainsDatabaseHelper.ENABLE_FIRST_PARTY_COOKIES));
+ int thirdPartyCookiesInt = domainCursor.getInt(domainCursor.getColumnIndex(DomainsDatabaseHelper.ENABLE_THIRD_PARTY_COOKIES));
+ int domStorageInt = domainCursor.getInt(domainCursor.getColumnIndex(DomainsDatabaseHelper.ENABLE_DOM_STORAGE));
+ int formDataInt = domainCursor.getInt(domainCursor.getColumnIndex(DomainsDatabaseHelper.ENABLE_FORM_DATA)); // Form data can be remove once the minimum API >= 26.
+ int easyListInt = domainCursor.getInt(domainCursor.getColumnIndex(DomainsDatabaseHelper.ENABLE_EASYLIST));
+ int easyPrivacyInt = domainCursor.getInt(domainCursor.getColumnIndex(DomainsDatabaseHelper.ENABLE_EASYPRIVACY));
+ int fanboysAnnoyanceListInt = domainCursor.getInt(domainCursor.getColumnIndex(DomainsDatabaseHelper.ENABLE_FANBOYS_ANNOYANCE_LIST));
+ int fanboysSocialBlockingListInt = domainCursor.getInt(domainCursor.getColumnIndex(DomainsDatabaseHelper.ENABLE_FANBOYS_SOCIAL_BLOCKING_LIST));
+ int ultraListInt = domainCursor.getInt(domainCursor.getColumnIndex(DomainsDatabaseHelper.ULTRALIST));
+ int ultraPrivacyInt = domainCursor.getInt(domainCursor.getColumnIndex(DomainsDatabaseHelper.ENABLE_ULTRAPRIVACY));
+ int blockAllThirdPartyRequestsInt = domainCursor.getInt(domainCursor.getColumnIndex(DomainsDatabaseHelper.BLOCK_ALL_THIRD_PARTY_REQUESTS));
+ String currentUserAgentName = domainCursor.getString(domainCursor.getColumnIndex(DomainsDatabaseHelper.USER_AGENT));
+ int fontSizeInt = domainCursor.getInt(domainCursor.getColumnIndex(DomainsDatabaseHelper.FONT_SIZE));
+ int swipeToRefreshInt = domainCursor.getInt(domainCursor.getColumnIndex(DomainsDatabaseHelper.SWIPE_TO_REFRESH));
+ int nightModeInt = domainCursor.getInt(domainCursor.getColumnIndex(DomainsDatabaseHelper.NIGHT_MODE));
+ int wideViewportInt = domainCursor.getInt(domainCursor.getColumnIndex(DomainsDatabaseHelper.WIDE_VIEWPORT));
+ int displayImagesInt = domainCursor.getInt(domainCursor.getColumnIndex(DomainsDatabaseHelper.DISPLAY_IMAGES));
+ int pinnedSslCertificateInt = domainCursor.getInt(domainCursor.getColumnIndex(DomainsDatabaseHelper.PINNED_SSL_CERTIFICATE));
+ String savedSslIssuedToCNameString = domainCursor.getString(domainCursor.getColumnIndex(DomainsDatabaseHelper.SSL_ISSUED_TO_COMMON_NAME));
+ String savedSslIssuedToONameString = domainCursor.getString(domainCursor.getColumnIndex(DomainsDatabaseHelper.SSL_ISSUED_TO_ORGANIZATION));
+ String savedSslIssuedToUNameString = domainCursor.getString(domainCursor.getColumnIndex(DomainsDatabaseHelper.SSL_ISSUED_TO_ORGANIZATIONAL_UNIT));
+ String savedSslIssuedByCNameString = domainCursor.getString(domainCursor.getColumnIndex(DomainsDatabaseHelper.SSL_ISSUED_BY_COMMON_NAME));
+ String savedSslIssuedByONameString = domainCursor.getString(domainCursor.getColumnIndex(DomainsDatabaseHelper.SSL_ISSUED_BY_ORGANIZATION));
+ String savedSslIssuedByUNameString = domainCursor.getString(domainCursor.getColumnIndex(DomainsDatabaseHelper.SSL_ISSUED_BY_ORGANIZATIONAL_UNIT));
+ int pinnedIpAddressesInt = domainCursor.getInt(domainCursor.getColumnIndex(DomainsDatabaseHelper.PINNED_IP_ADDRESSES));
+ String savedIpAddresses = domainCursor.getString(domainCursor.getColumnIndex(DomainsDatabaseHelper.IP_ADDRESSES));
+
+ // Initialize the saved SSL certificate date variables.
+ Date savedSslStartDate = null;
+ Date savedSslEndDate = null;
+
+ // Only get the saved SSL certificate dates from the cursor if they are not set to `0`.
+ if (domainCursor.getLong(domainCursor.getColumnIndex(DomainsDatabaseHelper.SSL_START_DATE)) != 0) {
+ savedSslStartDate = new Date(domainCursor.getLong(domainCursor.getColumnIndex(DomainsDatabaseHelper.SSL_START_DATE)));
+ }
+
+ if (domainCursor.getLong(domainCursor.getColumnIndex(DomainsDatabaseHelper.SSL_END_DATE)) != 0) {
+ savedSslEndDate = new Date(domainCursor.getLong(domainCursor.getColumnIndex(DomainsDatabaseHelper.SSL_END_DATE)));
+ }
+
+ // Create array adapters for the spinners.
+ ArrayAdapter<CharSequence> translatedUserAgentArrayAdapter = ArrayAdapter.createFromResource(context, R.array.translated_domain_settings_user_agent_names, R.layout.spinner_item);
+ ArrayAdapter<CharSequence> fontSizeArrayAdapter = ArrayAdapter.createFromResource(context, R.array.font_size_array, R.layout.spinner_item);
+ ArrayAdapter<CharSequence> swipeToRefreshArrayAdapter = ArrayAdapter.createFromResource(context, R.array.swipe_to_refresh_array, R.layout.spinner_item);
+ ArrayAdapter<CharSequence> nightModeArrayAdapter = ArrayAdapter.createFromResource(context, R.array.night_mode_array, R.layout.spinner_item);
+ ArrayAdapter<CharSequence> wideViewportArrayAdapter = ArrayAdapter.createFromResource(context, R.array.wide_viewport_array, R.layout.spinner_item);
+ ArrayAdapter<CharSequence> displayImagesArrayAdapter = ArrayAdapter.createFromResource(context, R.array.display_webpage_images_array, R.layout.spinner_item);
+
+ // Set the drop down view resource on the spinners.
+ translatedUserAgentArrayAdapter.setDropDownViewResource(R.layout.domain_settings_spinner_dropdown_items);
+ fontSizeArrayAdapter.setDropDownViewResource(R.layout.domain_settings_spinner_dropdown_items);
+ swipeToRefreshArrayAdapter.setDropDownViewResource(R.layout.domain_settings_spinner_dropdown_items);
+ nightModeArrayAdapter.setDropDownViewResource(R.layout.domain_settings_spinner_dropdown_items);
+ wideViewportArrayAdapter.setDropDownViewResource(R.layout.domain_settings_spinner_dropdown_items);
+ displayImagesArrayAdapter.setDropDownViewResource(R.layout.domain_settings_spinner_dropdown_items);
+
+ // Set the array adapters for the spinners.
+ userAgentSpinner.setAdapter(translatedUserAgentArrayAdapter);
+ fontSizeSpinner.setAdapter(fontSizeArrayAdapter);
+ swipeToRefreshSpinner.setAdapter(swipeToRefreshArrayAdapter);
+ nightModeSpinner.setAdapter(nightModeArrayAdapter);
+ wideViewportSpinner.setAdapter(wideViewportArrayAdapter);
+ displayWebpageImagesSpinner.setAdapter(displayImagesArrayAdapter);
+
+ // Create a spannable string builder for each TextView that needs multiple colors of text.
+ SpannableStringBuilder savedSslIssuedToCNameStringBuilder = new SpannableStringBuilder(cNameLabel + savedSslIssuedToCNameString);
+ SpannableStringBuilder savedSslIssuedToONameStringBuilder = new SpannableStringBuilder(oNameLabel + savedSslIssuedToONameString);
+ SpannableStringBuilder savedSslIssuedToUNameStringBuilder = new SpannableStringBuilder(uNameLabel + savedSslIssuedToUNameString);
+ SpannableStringBuilder savedSslIssuedByCNameStringBuilder = new SpannableStringBuilder(cNameLabel + savedSslIssuedByCNameString);
+ SpannableStringBuilder savedSslIssuedByONameStringBuilder = new SpannableStringBuilder(oNameLabel + savedSslIssuedByONameString);
+ SpannableStringBuilder savedSslIssuedByUNameStringBuilder = new SpannableStringBuilder(uNameLabel + savedSslIssuedByUNameString);
+
+ // Initialize the spannable string builders for the saved SSL certificate dates.
+ SpannableStringBuilder savedSslStartDateStringBuilder;
+ SpannableStringBuilder savedSslEndDateStringBuilder;
+
+ // Leave the SSL certificate dates empty if they are `null`.
+ if (savedSslStartDate == null) {
+ savedSslStartDateStringBuilder = new SpannableStringBuilder(startDateLabel);
+ } else {
+ savedSslStartDateStringBuilder = new SpannableStringBuilder(startDateLabel + DateFormat.getDateTimeInstance(DateFormat.MEDIUM, DateFormat.LONG).format(savedSslStartDate));
+ }
+
+ if (savedSslEndDate == null) {
+ savedSslEndDateStringBuilder = new SpannableStringBuilder(endDateLabel);
+ } else {
+ savedSslEndDateStringBuilder = new SpannableStringBuilder(endDateLabel + DateFormat.getDateTimeInstance(DateFormat.MEDIUM, DateFormat.LONG).format(savedSslEndDate));
+ }
+
+ // Create a red foreground color span. The deprecated `resources.getColor` must be used until the minimum API >= 23.
+ final ForegroundColorSpan redColorSpan = new ForegroundColorSpan(resources.getColor(R.color.red_a700));
+
+ // Create a blue foreground color span.
+ final ForegroundColorSpan blueColorSpan;
+
+ // Set the blue color span according to the theme. The deprecated `resources` must be used until the minimum API >= 23.
+ if (currentThemeStatus == Configuration.UI_MODE_NIGHT_YES) {
+ blueColorSpan = new ForegroundColorSpan(resources.getColor(R.color.blue_400));
+ } else {
+ blueColorSpan = new ForegroundColorSpan(resources.getColor(R.color.blue_700));
+ }
+
+ // Set the domain name from the the database cursor.
+ domainNameEditText.setText(domainNameString);
+
+ // Update the certificates' `Common Name` color when the domain name text changes.
+ domainNameEditText.addTextChangedListener(new TextWatcher() {
+ @Override
+ public void beforeTextChanged(CharSequence s, int start, int count, int after) {
+ // Do nothing.
+ }
+
+ @Override
+ public void onTextChanged(CharSequence s, int start, int before, int count) {
+ // Do nothing.
+ }
+
+ @Override
+ public void afterTextChanged(Editable s) {
+ // Get the new domain name.
+ String newDomainName = domainNameEditText.getText().toString();
+
+ // Check the saved SSL certificate against the new domain name.
+ boolean savedSslMatchesNewDomainName = checkDomainNameAgainstCertificate(newDomainName, savedSslIssuedToCNameString);
+
+ // Create a `SpannableStringBuilder` for the saved certificate `Common Name`.
+ SpannableStringBuilder savedSslCNameStringBuilder = new SpannableStringBuilder(cNameLabel + savedSslIssuedToCNameString);
+
+ // Format the saved certificate `Common Name` color. `SPAN_INCLUSIVE_INCLUSIVE` allows the span to grow in either direction.
+ if (savedSslMatchesNewDomainName) {
+ savedSslCNameStringBuilder.setSpan(blueColorSpan, cNameLabel.length(), savedSslCNameStringBuilder.length(), Spanned.SPAN_INCLUSIVE_INCLUSIVE);
+ } else {
+ savedSslCNameStringBuilder.setSpan(redColorSpan, cNameLabel.length(), savedSslCNameStringBuilder.length(), Spanned.SPAN_INCLUSIVE_INCLUSIVE);
+ }
+
+ // Update the saved SSL issued to CName text view.
+ savedSslIssuedToCNameTextView.setText(savedSslCNameStringBuilder);
+
+ // Update the current website certificate if it exists.
+ if (DomainsActivity.sslIssuedToCName != null) {
+ // Check the current website certificate against the new domain name.
+ boolean currentSslMatchesNewDomainName = checkDomainNameAgainstCertificate(newDomainName, DomainsActivity.sslIssuedToCName);
+
+ // Create a `SpannableStringBuilder` for the current website certificate `Common Name`.
+ SpannableStringBuilder currentSslCNameStringBuilder = new SpannableStringBuilder(cNameLabel + DomainsActivity.sslIssuedToCName);
+
+ // Format the current certificate `Common Name` color. `SPAN_INCLUSIVE_INCLUSIVE` allows the span to grow in either direction.
+ if (currentSslMatchesNewDomainName) {
+ currentSslCNameStringBuilder.setSpan(blueColorSpan, cNameLabel.length(), currentSslCNameStringBuilder.length(), Spanned.SPAN_INCLUSIVE_INCLUSIVE);
+ } else {
+ currentSslCNameStringBuilder.setSpan(redColorSpan, cNameLabel.length(), currentSslCNameStringBuilder.length(), Spanned.SPAN_INCLUSIVE_INCLUSIVE);
+ }
+
+ // Update the current SSL issued to CName text view.
+ currentSslIssuedToCNameTextView.setText(currentSslCNameStringBuilder);
+ }
+ }
+ });
+
+ // Create a boolean to track if night mode is enabled.
+ boolean nightModeEnabled = (nightModeInt == DomainsDatabaseHelper.ENABLED) || ((nightModeInt == DomainsDatabaseHelper.SYSTEM_DEFAULT) && defaultNightMode);
+
+ // Disable the JavaScript switch if night mode is enabled.
+ if (nightModeEnabled) {
+ javaScriptSwitch.setEnabled(false);
+ } else {
+ javaScriptSwitch.setEnabled(true);
+ }
+
+ // Set the JavaScript icon.
+ if ((javaScriptInt == 1) || nightModeEnabled) {
+ javaScriptImageView.setImageDrawable(resources.getDrawable(R.drawable.javascript_enabled));
+ } else {
+ javaScriptImageView.setImageDrawable(resources.getDrawable(R.drawable.privacy_mode));
+ }
+
+ // Set the JavaScript switch status.
+ if (javaScriptInt == 1) { // JavaScript is enabled.
+ javaScriptSwitch.setChecked(true);
+ } else { // JavaScript is disabled.
+ javaScriptSwitch.setChecked(false);
+ }
+
+ // Set the first-party cookies status. Once the minimum API >= 21 a selector can be used as the tint mode instead of specifying different icons.
+ if (firstPartyCookiesInt == 1) { // First-party cookies are enabled.
+ firstPartyCookiesSwitch.setChecked(true);
+ firstPartyCookiesImageView.setImageDrawable(resources.getDrawable(R.drawable.cookies_enabled));
+ } else { // First-party cookies are disabled.
+ firstPartyCookiesSwitch.setChecked(false);
+
+ // Set the icon according to the theme.
+ if (currentThemeStatus == Configuration.UI_MODE_NIGHT_YES) {
+ firstPartyCookiesImageView.setImageDrawable(resources.getDrawable(R.drawable.cookies_disabled_night));
+ } else {
+ firstPartyCookiesImageView.setImageDrawable(resources.getDrawable(R.drawable.cookies_disabled_day));
+ }
+ }
+
+ // Only display third-party cookies if SDK_INT >= 21.
+ if (Build.VERSION.SDK_INT >= 21) { // Third-party cookies can be configured for API >= 21.
+ // Only enable third-party-cookies if first-party cookies are enabled.
+ if (firstPartyCookiesInt == 1) { // First-party cookies are enabled.
+ // Set the third-party cookies status. Once the minimum API >= 21 a selector can be used as the tint mode instead of specifying different icons.
+ if (thirdPartyCookiesInt == 1) { // Both first-party and third-party cookies are enabled.
+ thirdPartyCookiesSwitch.setChecked(true);
+ thirdPartyCookiesImageView.setImageDrawable(resources.getDrawable(R.drawable.cookies_warning));
+ } else { // First party cookies are enabled but third-party cookies are disabled.
+ thirdPartyCookiesSwitch.setChecked(false);
+
+ // Set the icon according to the theme.
+ if (currentThemeStatus == Configuration.UI_MODE_NIGHT_YES) {
+ thirdPartyCookiesImageView.setImageDrawable(resources.getDrawable(R.drawable.cookies_disabled_night));
+ } else {
+ thirdPartyCookiesImageView.setImageDrawable(resources.getDrawable(R.drawable.cookies_disabled_day));
+ }
+ }
+ } else { // First-party cookies are disabled.
+ // Set the status of third-party cookies.
+ if (thirdPartyCookiesInt == 1) {
+ thirdPartyCookiesSwitch.setChecked(true);
+ } else {
+ thirdPartyCookiesSwitch.setChecked(false);
+ }
+
+ // Disable the third-party cookies switch.
+ thirdPartyCookiesSwitch.setEnabled(false);
+
+ // Set the icon according to the theme.
+ if (currentThemeStatus == Configuration.UI_MODE_NIGHT_YES) {
+ thirdPartyCookiesImageView.setImageDrawable(resources.getDrawable(R.drawable.cookies_ghosted_night));
+ } else {
+ thirdPartyCookiesImageView.setImageDrawable(resources.getDrawable(R.drawable.cookies_ghosted_day));
+ }
+ }
+ } else { // Third-party cookies cannot be configured for API <= 21.
+ // Hide the LinearLayout for third-party cookies.
+ thirdPartyCookiesLinearLayout.setVisibility(View.GONE);
+ }
+
+ // Only enable DOM storage if JavaScript is enabled.
+ if ((javaScriptInt == 1) || nightModeEnabled) { // JavaScript is enabled.
+ // Enable the DOM storage `Switch`.
+ domStorageSwitch.setEnabled(true);
+
+ // Set the DOM storage status. Once the minimum API >= 21 a selector can be used as the tint mode instead of specifying different icons.
+ if (domStorageInt == 1) { // Both JavaScript and DOM storage are enabled.
+ domStorageSwitch.setChecked(true);
+ domStorageImageView.setImageDrawable(resources.getDrawable(R.drawable.dom_storage_enabled));
+ } else { // JavaScript is enabled but DOM storage is disabled.
+ // Set the DOM storage switch to off.
+ domStorageSwitch.setChecked(false);
+
+ // Set the icon according to the theme.
+ if (currentThemeStatus == Configuration.UI_MODE_NIGHT_YES) {
+ domStorageImageView.setImageDrawable(resources.getDrawable(R.drawable.dom_storage_disabled_night));
+ } else {
+ domStorageImageView.setImageDrawable(resources.getDrawable(R.drawable.dom_storage_disabled_day));
+ }
+ }
+ } else { // JavaScript is disabled.
+ // Disable the DOM storage `Switch`.
+ domStorageSwitch.setEnabled(false);
+
+ // Set the checked status of DOM storage.
+ if (domStorageInt == 1) { // DOM storage is enabled but JavaScript is disabled.
+ domStorageSwitch.setChecked(true);
+ } else { // Both JavaScript and DOM storage are disabled.
+ domStorageSwitch.setChecked(false);
+ }
+
+ // Set the icon according to the theme.
+ if (currentThemeStatus == Configuration.UI_MODE_NIGHT_YES) {
+ domStorageImageView.setImageDrawable(resources.getDrawable(R.drawable.dom_storage_ghosted_night));
+ } else {
+ domStorageImageView.setImageDrawable(resources.getDrawable(R.drawable.dom_storage_ghosted_day));
+ }
+ }
+
+ // Set the form data status. Once the minimum API >= 21 a selector can be used as the tint mode instead of specifying different icons. Form data can be removed once the minimum API >= 26.
+ if (Build.VERSION.SDK_INT >= 26) { // Form data no longer applies to newer versions of Android.
+ // Hide the form data switch.
+ formDataSwitch.setVisibility(View.GONE);
+ } else { // Form data should be displayed because this is an older version of Android.
+ if (formDataInt == 1) { // Form data is on.
+ formDataSwitch.setChecked(true);
+ formDataImageView.setImageDrawable(resources.getDrawable(R.drawable.form_data_enabled));
+ } else { // Form data is off.
+ // Turn the form data switch to off.
+ formDataSwitch.setChecked(false);
+
+ // Set the icon according to the theme.
+ if (currentThemeStatus == Configuration.UI_MODE_NIGHT_YES) {
+ formDataImageView.setImageDrawable(resources.getDrawable(R.drawable.form_data_disabled_night));
+ } else {
+ formDataImageView.setImageDrawable(resources.getDrawable(R.drawable.form_data_disabled_day));
+ }
+ }
+ }
+
+ // Set the EasyList status. Once the minimum API >= 21 a selector can be used as the tint mode instead of specifying different icons.
+ if (easyListInt == 1) { // EasyList is on.
+ // Turn the switch on.
+ easyListSwitch.setChecked(true);
+
+ // Set the icon according to the theme.
+ if (currentThemeStatus == Configuration.UI_MODE_NIGHT_YES) {
+ easyListImageView.setImageDrawable(resources.getDrawable(R.drawable.block_ads_enabled_night));
+ } else {
+ easyListImageView.setImageDrawable(resources.getDrawable(R.drawable.block_ads_enabled_day));
+ }
+ } else { // EasyList is off.
+ // Turn the switch off.
+ easyListSwitch.setChecked(false);
+
+ // Set the icon according to the theme.
+ if (currentThemeStatus == Configuration.UI_MODE_NIGHT_YES) {
+ easyListImageView.setImageDrawable(resources.getDrawable(R.drawable.block_ads_disabled_night));
+ } else {
+ easyListImageView.setImageDrawable(resources.getDrawable(R.drawable.block_ads_disabled_day));
+ }
+ }
+
+ // Set the EasyPrivacy status. Once the minimum API >= 21 a selector can be used as the tint mode instead of specifying different icons.
+ if (easyPrivacyInt == 1) { // EasyPrivacy is on.
+ // Turn the switch on.
+ easyPrivacySwitch.setChecked(true);
+
+ // Set the icon according to the theme.
+ if (currentThemeStatus == Configuration.UI_MODE_NIGHT_YES) {
+ easyPrivacyImageView.setImageDrawable(resources.getDrawable(R.drawable.block_tracking_enabled_night));
+ } else {
+ easyPrivacyImageView.setImageDrawable(resources.getDrawable(R.drawable.block_tracking_enabled_day));
+ }
+ } else { // EasyPrivacy is off.
+ // Turn the switch off.
+ easyPrivacySwitch.setChecked(false);
+
+ // Set the icon according to the theme.
+ if (currentThemeStatus == Configuration.UI_MODE_NIGHT_YES) {
+ easyPrivacyImageView.setImageDrawable(resources.getDrawable(R.drawable.block_tracking_disabled_night));
+ } else {
+ easyPrivacyImageView.setImageDrawable(resources.getDrawable(R.drawable.block_tracking_disabled_day));
+ }
+ }
+
+ // Set the Fanboy's Annoyance List status. Once the minimum API >= 21 a selector can be used as the tint mode instead of specifying different icons.
+ if (fanboysAnnoyanceListInt == 1) { // Fanboy's Annoyance List is on.
+ // Turn the switch on.
+ fanboysAnnoyanceListSwitch.setChecked(true);
+
+ // Set the icon according to the theme.
+ if (currentThemeStatus == Configuration.UI_MODE_NIGHT_YES) {
+ fanboysAnnoyanceListImageView.setImageDrawable(resources.getDrawable(R.drawable.social_media_enabled_night));
+ } else {
+ fanboysAnnoyanceListImageView.setImageDrawable(resources.getDrawable(R.drawable.social_media_enabled_day));
+ }
+ } else { // Fanboy's Annoyance List is off.
+ // Turn the switch off.
+ fanboysAnnoyanceListSwitch.setChecked(false);
+
+ // Set the icon according to the theme.
+ if (currentThemeStatus == Configuration.UI_MODE_NIGHT_YES) {
+ fanboysAnnoyanceListImageView.setImageDrawable(resources.getDrawable(R.drawable.social_media_disabled_night));
+ } else {
+ fanboysAnnoyanceListImageView.setImageDrawable(resources.getDrawable(R.drawable.social_media_disabled_day));
+ }
+ }
+
+ // Only enable Fanboy's Social Blocking List if Fanboy's Annoyance List is off.
+ if (fanboysAnnoyanceListInt == 0) { // Fanboy's Annoyance List is on.
+ // Enable Fanboy's Social Blocking List. Once the minimum API >= 21 a selector can be used as the tint mode instead of specifying different icons.
+ if (fanboysSocialBlockingListInt == 1) { // Fanboy's Social Blocking List is on.
+ // Enable the switch and turn it on.
+ fanboysSocialBlockingListSwitch.setEnabled(true);
+ fanboysSocialBlockingListSwitch.setChecked(true);
+
+ // Set the icon according to the theme.
+ if (currentThemeStatus == Configuration.UI_MODE_NIGHT_YES) {
+ fanboysSocialBlockingListImageView.setImageDrawable(resources.getDrawable(R.drawable.social_media_enabled_night));
+ } else {
+ fanboysSocialBlockingListImageView.setImageDrawable(resources.getDrawable(R.drawable.social_media_enabled_day));
+ }
+ } else { // Fanboy's Social Blocking List is off.
+ // Enable the switch but turn it off.
+ fanboysSocialBlockingListSwitch.setEnabled(true);
+ fanboysSocialBlockingListSwitch.setChecked(false);
+
+ // Set the icon according to the theme.
+ if (currentThemeStatus == Configuration.UI_MODE_NIGHT_YES) {
+ fanboysSocialBlockingListImageView.setImageDrawable(resources.getDrawable(R.drawable.social_media_disabled_night));
+ } else {
+ fanboysSocialBlockingListImageView.setImageDrawable(resources.getDrawable(R.drawable.social_media_disabled_day));
+ }
+ }
+ } else { // Fanboy's Annoyance List is on.
+ // Disable Fanboy's Social Blocking List. Once the minimum API >= 21 a selector can be used as the tint mode instead of specifying different icons.
+ if (fanboysSocialBlockingListInt == 1) { // Fanboy's Social Blocking List is on.
+ // Disable the switch but turn it on.
+ fanboysSocialBlockingListSwitch.setEnabled(false);
+ fanboysSocialBlockingListSwitch.setChecked(true);
+ } else { // Fanboy's Social Blocking List is off.
+ // Disable the switch and turn it off.
+ fanboysSocialBlockingListSwitch.setEnabled(false);
+ fanboysSocialBlockingListSwitch.setChecked(false);
+ }
+
+ // Set the icon according to the theme.
+ if (currentThemeStatus == Configuration.UI_MODE_NIGHT_YES) {
+ fanboysSocialBlockingListImageView.setImageDrawable(resources.getDrawable(R.drawable.social_media_ghosted_night));
+ } else {
+ fanboysSocialBlockingListImageView.setImageDrawable(resources.getDrawable(R.drawable.social_media_ghosted_day));
+ }
+ }
+
+ // Set the UltraList status. Once the minimum API >= 21 a selector can be used as the tint mode instead of specifying different icons.
+ if (ultraListInt == 1) { // UltraList is on.
+ // Turn the switch on.
+ ultraListSwitch.setChecked(true);
+
+ // Set the icon according to the theme.
+ if (currentThemeStatus == Configuration.UI_MODE_NIGHT_YES) {
+ ultraListImageView.setImageDrawable(resources.getDrawable(R.drawable.block_ads_enabled_night));
+ } else {
+ ultraListImageView.setImageDrawable(resources.getDrawable(R.drawable.block_ads_enabled_day));
+ }
+ } else { // UltraList is off.
+ // Turn the switch off.
+ ultraListSwitch.setChecked(false);
+
+ // Set the icon according to the theme.
+ if (currentThemeStatus == Configuration.UI_MODE_NIGHT_YES) {
+ ultraListImageView.setImageDrawable(resources.getDrawable(R.drawable.block_ads_disabled_night));
+ } else {
+ ultraListImageView.setImageDrawable(resources.getDrawable(R.drawable.block_ads_disabled_day));
+ }
+ }
+
+ // Set the UltraPrivacy status. Once the minimum API >= 21 a selector can be used as the tint mode instead of specifying different icons.
+ if (ultraPrivacyInt == 1) { // UltraPrivacy is on.
+ // Turn the switch on.
+ ultraPrivacySwitch.setChecked(true);
+
+ // Set the icon according to the theme.
+ if (currentThemeStatus == Configuration.UI_MODE_NIGHT_YES) {
+ ultraPrivacyImageView.setImageDrawable(resources.getDrawable(R.drawable.block_tracking_enabled_night));
+ } else {
+ ultraPrivacyImageView.setImageDrawable(resources.getDrawable(R.drawable.block_tracking_enabled_day));
+ }
+ } else { // EasyPrivacy is off.
+ // Turn the switch off.
+ ultraPrivacySwitch.setChecked(false);
+
+ // Set the icon according to the theme.
+ if (currentThemeStatus == Configuration.UI_MODE_NIGHT_YES) {
+ ultraPrivacyImageView.setImageDrawable(resources.getDrawable(R.drawable.block_tracking_disabled_night));
+ } else {
+ ultraPrivacyImageView.setImageDrawable(resources.getDrawable(R.drawable.block_tracking_disabled_day));
+ }
+ }
+
+ // Set the third-party resource blocking status. Once the minimum API >= 21 a selector can be used as the tint mode instead of specifying different icons.
+ if (blockAllThirdPartyRequestsInt == 1) { // Blocking all third-party requests is on.
+ // Turn the switch on.
+ blockAllThirdPartyRequestsSwitch.setChecked(true);
+
+ // Set the icon according to the theme.
+ if (currentThemeStatus == Configuration.UI_MODE_NIGHT_YES) {
+ blockAllThirdPartyRequestsImageView.setImageDrawable(resources.getDrawable(R.drawable.block_all_third_party_requests_enabled_night));
+ } else {
+ blockAllThirdPartyRequestsImageView.setImageDrawable(resources.getDrawable(R.drawable.block_all_third_party_requests_enabled_day));
+ }
+ } else { // Blocking all third-party requests is off.
+ // Turn the switch off.
+ blockAllThirdPartyRequestsSwitch.setChecked(false);
+
+ // Set the icon according to the theme.
+ if (currentThemeStatus == Configuration.UI_MODE_NIGHT_YES) {
+ blockAllThirdPartyRequestsImageView.setImageDrawable(resources.getDrawable(R.drawable.block_all_third_party_requests_disabled_night));
+ } else {
+ blockAllThirdPartyRequestsImageView.setImageDrawable(resources.getDrawable(R.drawable.block_all_third_party_requests_disabled_day));
+ }
+ }
+
+ // Inflated a WebView to get the default user agent.
+ // `@SuppressLint("InflateParams")` removes the warning about using `null` as the `ViewGroup`, which in this case makes sense because the bare WebView should not be displayed on the screen.
+ @SuppressLint("InflateParams") View bareWebViewLayout = inflater.inflate(R.layout.bare_webview, null, false);
+ WebView bareWebView = bareWebViewLayout.findViewById(R.id.bare_webview);
+ final String webViewDefaultUserAgentString = bareWebView.getSettings().getUserAgentString();
+
+ // Get a handle for the user agent array adapter. This array does not contain the `System default` entry.
+ ArrayAdapter<CharSequence> userAgentNamesArray = ArrayAdapter.createFromResource(context, R.array.user_agent_names, R.layout.spinner_item);
+
+ // Get the positions of the user agent and the default user agent.
+ int userAgentArrayPosition = userAgentNamesArray.getPosition(currentUserAgentName);
+ int defaultUserAgentArrayPosition = userAgentNamesArray.getPosition(defaultUserAgentName);
+
+ // Get a handle for the user agent data array. This array does not contain the `System default` entry.
+ String[] userAgentDataArray = resources.getStringArray(R.array.user_agent_data);
+
+ // Set the user agent text.
+ if (currentUserAgentName.equals(getString(R.string.system_default_user_agent))) { // Use the system default user agent.
+ // Set the user agent according to the system default.
+ switch (defaultUserAgentArrayPosition) {
+ case MainWebViewActivity.UNRECOGNIZED_USER_AGENT: // The default user agent name is not on the canonical list.
+ // This is probably because it was set in an older version of Privacy Browser before the switch to persistent user agent names.
+ userAgentTextView.setText(defaultUserAgentName);
+ break;
+
+ case MainWebViewActivity.SETTINGS_WEBVIEW_DEFAULT_USER_AGENT:
+ // Display the `WebView` default user agent.
+ userAgentTextView.setText(webViewDefaultUserAgentString);
+ break;
+
+ case MainWebViewActivity.SETTINGS_CUSTOM_USER_AGENT:
+ // Display the custom user agent.
+ userAgentTextView.setText(defaultCustomUserAgentString);
+ break;
+
+ default:
+ // Get the user agent string from the user agent data array.
+ userAgentTextView.setText(userAgentDataArray[defaultUserAgentArrayPosition]);
+ }
+ } else if (userAgentArrayPosition == MainWebViewActivity.UNRECOGNIZED_USER_AGENT) { // A custom user agent is stored in the current user agent name.
+ // Set the user agent spinner to `Custom user agent`.
+ userAgentSpinner.setSelection(MainWebViewActivity.DOMAINS_CUSTOM_USER_AGENT);
+
+ // Hide the user agent TextView.
+ userAgentTextView.setVisibility(View.GONE);
+
+ // Show the custom user agent EditText and set the current user agent name as the text.
+ customUserAgentEditText.setVisibility(View.VISIBLE);
+ customUserAgentEditText.setText(currentUserAgentName);
+ } else { // The user agent name contains one of the canonical user agents.
+ // Set the user agent spinner selection. The spinner has one more entry at the beginning than the user agent data array, so the position must be incremented.
+ userAgentSpinner.setSelection(userAgentArrayPosition + 1);
+
+ // Show the user agent TextView.
+ userAgentTextView.setVisibility(View.VISIBLE);
+
+ // Hide the custom user agent EditText.
+ customUserAgentEditText.setVisibility(View.GONE);
+
+ // Set the user agent text.
+ if (userAgentArrayPosition == MainWebViewActivity.DOMAINS_WEBVIEW_DEFAULT_USER_AGENT) { // The WebView default user agent is selected.
+ // Display the WebView default user agent.
+ userAgentTextView.setText(webViewDefaultUserAgentString);
+ } else { // A user agent besides the default is selected.
+ // Get the user agent string from the user agent data array. The spinner has one more entry at the beginning than the user agent data array, so the position must be incremented.
+ userAgentTextView.setText(userAgentDataArray[userAgentArrayPosition + 1]);
+ }
+ }
+
+ // Open the user agent spinner when the text view is clicked.
+ userAgentTextView.setOnClickListener((View v) -> {
+ // Open the user agent spinner.
+ userAgentSpinner.performClick();
+ });
+
+ // Display the font size settings.
+ if (fontSizeInt == 0) { // `0` is the code for system default font size.
+ // Set the font size to the system default
+ fontSizeSpinner.setSelection(0);
+
+ // Show the default font size text view.
+ defaultFontSizeTextView.setVisibility(View.VISIBLE);
+
+ // Hide the custom font size edit text.
+ customFontSizeEditText.setVisibility(View.GONE);
+
+ // Set the default font size as the text of the custom font size edit text. This way, if the user switches to custom it will already be populated.
+ customFontSizeEditText.setText(defaultFontSizeString);
+ } else { // A custom font size is selected.
+ // Set the spinner to the custom font size.
+ fontSizeSpinner.setSelection(1);
+
+ // Hide the default font size text view.
+ defaultFontSizeTextView.setVisibility(View.GONE);
+
+ // Show the custom font size edit text.
+ customFontSizeEditText.setVisibility(View.GONE);
+
+ // Set the custom font size.
+ customFontSizeEditText.setText(String.valueOf(fontSizeInt));
+ }
+
+ // Initialize the default font size percentage string.
+ String defaultFontSizePercentageString = defaultFontSizeString + "%";
+
+ // Set the default font size text in the text view.
+ defaultFontSizeTextView.setText(defaultFontSizePercentageString);
+
+ // Open the font size spinner when the text view is clicked.
+ defaultFontSizeTextView.setOnClickListener((View v) -> {
+ // Open the user agent spinner.
+ fontSizeSpinner.performClick();
+ });
+
+ // Display the swipe to refresh selection in the spinner.
+ swipeToRefreshSpinner.setSelection(swipeToRefreshInt);
+
+ // Set the swipe to refresh text.
+ if (defaultSwipeToRefresh) {
+ swipeToRefreshTextView.setText(swipeToRefreshArrayAdapter.getItem(DomainsDatabaseHelper.ENABLED));
+ } else {
+ swipeToRefreshTextView.setText(swipeToRefreshArrayAdapter.getItem(DomainsDatabaseHelper.DISABLED));
+ }
+
+ // Set the swipe to refresh icon and TextView settings. Once the minimum API >= 21 a selector can be used as the tint mode instead of specifying different icons.
+ switch (swipeToRefreshInt) {
+ case DomainsDatabaseHelper.SYSTEM_DEFAULT:
+ if (defaultSwipeToRefresh) { // Swipe to refresh is enabled by default.
+ // Set the icon according to the theme.
+ if (currentThemeStatus == Configuration.UI_MODE_NIGHT_YES) {
+ swipeToRefreshImageView.setImageDrawable(resources.getDrawable(R.drawable.refresh_enabled_night));
+ } else {
+ swipeToRefreshImageView.setImageDrawable(resources.getDrawable(R.drawable.refresh_enabled_day));
+ }
+ } else { // Swipe to refresh is disabled by default
+ // Set the icon according to the theme.
+ if (currentThemeStatus == Configuration.UI_MODE_NIGHT_YES) {
+ swipeToRefreshImageView.setImageDrawable(resources.getDrawable(R.drawable.refresh_disabled_night));
+ } else {
+ swipeToRefreshImageView.setImageDrawable(resources.getDrawable(R.drawable.refresh_disabled_day));
+ }
+ }
+
+ // Show the swipe to refresh TextView.
+ swipeToRefreshTextView.setVisibility(View.VISIBLE);
+ break;
+
+ case DomainsDatabaseHelper.ENABLED:
+ // Set the icon according to the theme.
+ if (currentThemeStatus == Configuration.UI_MODE_NIGHT_YES) {
+ swipeToRefreshImageView.setImageDrawable(resources.getDrawable(R.drawable.refresh_enabled_night));
+ } else {
+ swipeToRefreshImageView.setImageDrawable(resources.getDrawable(R.drawable.refresh_enabled_day));
+ }
+
+ // Hide the swipe to refresh TextView.`
+ swipeToRefreshTextView.setVisibility(View.GONE);
+ break;
+
+ case DomainsDatabaseHelper.DISABLED:
+ // Set the icon according to the theme.
+ if (currentThemeStatus == Configuration.UI_MODE_NIGHT_YES) {
+ swipeToRefreshImageView.setImageDrawable(resources.getDrawable(R.drawable.refresh_disabled_night));
+ } else {
+ swipeToRefreshImageView.setImageDrawable(resources.getDrawable(R.drawable.refresh_disabled_day));
+ }
+
+ // Hide the swipe to refresh TextView.
+ swipeToRefreshTextView.setVisibility(View.GONE);
+ }
+
+ // Open the swipe to refresh spinner when the TextView is clicked.
+ swipeToRefreshTextView.setOnClickListener((View v) -> {
+ // Open the swipe to refresh spinner.
+ swipeToRefreshSpinner.performClick();
+ });
+
+ // Display the night mode in the spinner.
+ nightModeSpinner.setSelection(nightModeInt);
+
+ // Set the default night mode text.
+ if (defaultNightMode) {
+ nightModeTextView.setText(nightModeArrayAdapter.getItem(DomainsDatabaseHelper.ENABLED));
+ } else {
+ nightModeTextView.setText(nightModeArrayAdapter.getItem(DomainsDatabaseHelper.DISABLED));
+ }
+
+ // Set the night mode icon and TextView settings. Once the minimum API >= 21 a selector can be used as the tint mode instead of specifying different icons.
+ switch (nightModeInt) {
+ case DomainsDatabaseHelper.SYSTEM_DEFAULT:
+ if (defaultNightMode) { // Night mode enabled by default.
+ // Set the icon according to the theme.
+ if (currentThemeStatus == Configuration.UI_MODE_NIGHT_YES) {
+ nightModeImageView.setImageDrawable(resources.getDrawable(R.drawable.night_mode_enabled_night));
+ } else {
+ nightModeImageView.setImageDrawable(resources.getDrawable(R.drawable.night_mode_enabled_day));
+ }
+ } else { // Night mode disabled by default.
+ // Set the icon according to the theme.
+ if (currentThemeStatus == Configuration.UI_MODE_NIGHT_YES) {
+ nightModeImageView.setImageDrawable(resources.getDrawable(R.drawable.night_mode_disabled_night));
+ } else {
+ nightModeImageView.setImageDrawable(resources.getDrawable(R.drawable.night_mode_disabled_day));
+ }
+ }
+
+ // Show night mode TextView.
+ nightModeTextView.setVisibility(View.VISIBLE);
+ break;
+
+ case DomainsDatabaseHelper.ENABLED:
+ // Set the icon according to the theme.
+ if (currentThemeStatus == Configuration.UI_MODE_NIGHT_YES) {
+ nightModeImageView.setImageDrawable(resources.getDrawable(R.drawable.night_mode_enabled_night));
+ } else {
+ nightModeImageView.setImageDrawable(resources.getDrawable(R.drawable.night_mode_enabled_day));
+ }
+
+ // Hide the night mode TextView.
+ nightModeTextView.setVisibility(View.GONE);
+ break;
+
+ case DomainsDatabaseHelper.DISABLED:
+ // Set the icon according to the theme.
+ if (currentThemeStatus == Configuration.UI_MODE_NIGHT_YES) {
+ nightModeImageView.setImageDrawable(resources.getDrawable(R.drawable.night_mode_disabled_night));
+ } else {
+ nightModeImageView.setImageDrawable(resources.getDrawable(R.drawable.night_mode_disabled_day));
+ }
+
+ // Hide the night mode TextView.
+ nightModeTextView.setVisibility(View.GONE);
+ break;
+ }
+
+ // Open the night mode spinner when the TextView is clicked.
+ nightModeTextView.setOnClickListener((View v) -> {
+ // Open the night mode spinner.
+ nightModeSpinner.performClick();
+ });
+
+ // Display the wide viewport in the spinner.
+ wideViewportSpinner.setSelection(wideViewportInt);
+
+ // Set the default wide viewport text.
+ if (defaultWideViewport) {
+ wideViewportTextView.setText(wideViewportArrayAdapter.getItem(DomainsDatabaseHelper.ENABLED));
+ } else {
+ wideViewportTextView.setText(wideViewportArrayAdapter.getItem(DomainsDatabaseHelper.DISABLED));
+ }
+
+ // Set the wide viewport icon and text view settings. Once the minimum API >= 21 a selector can be used as the tint mode instead of specifying different icons.
+ switch (wideViewportInt) {
+ case DomainsDatabaseHelper.SYSTEM_DEFAULT:
+ if (defaultWideViewport) { // Wide viewport enabled by default.
+ // Set the icon according to the theme.
+ if (currentThemeStatus == Configuration.UI_MODE_NIGHT_YES) {
+ wideViewportImageView.setImageDrawable(resources.getDrawable(R.drawable.wide_viewport_enabled_night));
+ } else {
+ wideViewportImageView.setImageDrawable(resources.getDrawable(R.drawable.wide_viewport_enabled_day));
+ }
+ } else { // Wide viewport disabled by default.
+ if (currentThemeStatus == Configuration.UI_MODE_NIGHT_YES) {
+ wideViewportImageView.setImageDrawable(resources.getDrawable(R.drawable.wide_viewport_disabled_night));
+ } else {
+ wideViewportImageView.setImageDrawable(resources.getDrawable(R.drawable.wide_viewport_disabled_day));
+ }
+ }
+
+ // Show the wide viewport text view.
+ wideViewportTextView.setVisibility(View.VISIBLE);
+ break;
+
+ case DomainsDatabaseHelper.ENABLED:
+ // Set the icon according to the theme.
+ if (currentThemeStatus == Configuration.UI_MODE_NIGHT_YES) {
+ wideViewportImageView.setImageDrawable(resources.getDrawable(R.drawable.wide_viewport_enabled_night));
+ } else {
+ wideViewportImageView.setImageDrawable(resources.getDrawable(R.drawable.wide_viewport_enabled_day));
+ }
+
+ // Hide the wide viewport text view.
+ wideViewportTextView.setVisibility(View.GONE);
+ break;
+
+ case DomainsDatabaseHelper.DISABLED:
+ // Set the icon according to the theme.
+ if (currentThemeStatus == Configuration.UI_MODE_NIGHT_YES) {
+ wideViewportImageView.setImageDrawable(resources.getDrawable(R.drawable.wide_viewport_disabled_night));
+ } else {
+ wideViewportImageView.setImageDrawable(resources.getDrawable(R.drawable.wide_viewport_disabled_day));
+ }
+
+ // Hide the wide viewport text view.
+ wideViewportTextView.setVisibility(View.GONE);
+ break;
+ }
+
+ // Open the wide viewport spinner when the text view is clicked.
+ wideViewportTextView.setOnClickListener((View view) -> {
+ // Open the wide viewport spinner.
+ wideViewportSpinner.performClick();
+ });
+
+ // Display the website images mode in the spinner.
+ displayWebpageImagesSpinner.setSelection(displayImagesInt);
+
+ // Set the default display images text.
+ if (defaultDisplayWebpageImages) {
+ displayImagesTextView.setText(displayImagesArrayAdapter.getItem(DomainsDatabaseHelper.ENABLED));
+ } else {
+ displayImagesTextView.setText(displayImagesArrayAdapter.getItem(DomainsDatabaseHelper.DISABLED));
+ }
+
+ // Set the display website images icon and text view settings. Once the minimum API >= 21 a selector can be used as the tint mode instead of specifying different icons.
+ switch (displayImagesInt) {
+ case DomainsDatabaseHelper.SYSTEM_DEFAULT:
+ if (defaultDisplayWebpageImages) { // Display webpage images enabled by default.
+ // Set the icon according to the theme.
+ if (currentThemeStatus == Configuration.UI_MODE_NIGHT_YES) {
+ displayWebpageImagesImageView.setImageDrawable(resources.getDrawable(R.drawable.images_enabled_night));
+ } else {
+ displayWebpageImagesImageView.setImageDrawable(resources.getDrawable(R.drawable.images_enabled_day));
+ }
+ } else { // Display webpage images disabled by default.
+ // Set the icon according to the theme.
+ if (currentThemeStatus == Configuration.UI_MODE_NIGHT_YES) {
+ displayWebpageImagesImageView.setImageDrawable(resources.getDrawable(R.drawable.images_disabled_night));
+ } else {
+ displayWebpageImagesImageView.setImageDrawable(resources.getDrawable(R.drawable.images_disabled_day));
+ }
+ }
+
+ // Show the display images text view.
+ displayImagesTextView.setVisibility(View.VISIBLE);
+ break;
+
+ case DomainsDatabaseHelper.ENABLED:
+ // Set the icon according to the theme.
+ if (currentThemeStatus == Configuration.UI_MODE_NIGHT_YES) {
+ displayWebpageImagesImageView.setImageDrawable(resources.getDrawable(R.drawable.images_enabled_night));
+ } else {
+ displayWebpageImagesImageView.setImageDrawable(resources.getDrawable(R.drawable.images_enabled_day));
+ }
+
+ // Hide the display images text view.
+ displayImagesTextView.setVisibility(View.GONE);
+ break;
+
+ case DomainsDatabaseHelper.DISABLED:
+ // Set the icon according to the theme.
+ if (currentThemeStatus == Configuration.UI_MODE_NIGHT_YES) {
+ displayWebpageImagesImageView.setImageDrawable(resources.getDrawable(R.drawable.images_disabled_night));
+ } else {
+ displayWebpageImagesImageView.setImageDrawable(resources.getDrawable(R.drawable.images_disabled_day));
+ }
+
+ // Hide the display images text view.
+ displayImagesTextView.setVisibility(View.GONE);
+ break;
+ }
+
+ // Open the display images spinner when the text view is clicked.
+ displayImagesTextView.setOnClickListener((View view) -> {
+ // Open the user agent spinner.
+ displayWebpageImagesSpinner.performClick();
+ });
+
+ // Set the pinned SSL certificate icon.
+ if (pinnedSslCertificateInt == 1) { // Pinned SSL certificate is enabled. Once the minimum API >= 21 a selector can be used as the tint mode instead of specifying different icons.
+ // Check the switch.
+ pinnedSslCertificateSwitch.setChecked(true);
+
+ // Set the icon according to the theme.
+ if (currentThemeStatus == Configuration.UI_MODE_NIGHT_YES) {
+ pinnedSslCertificateImageView.setImageDrawable(resources.getDrawable(R.drawable.ssl_certificate_enabled_night));
+ } else {
+ pinnedSslCertificateImageView.setImageDrawable(resources.getDrawable(R.drawable.ssl_certificate_enabled_day));
+ }
+ } else { // Pinned SSL certificate is disabled.
+ // Uncheck the switch.
+ pinnedSslCertificateSwitch.setChecked(false);
+
+ // Set the icon according to the theme.
+ if (currentThemeStatus == Configuration.UI_MODE_NIGHT_YES) {
+ pinnedSslCertificateImageView.setImageDrawable(resources.getDrawable(R.drawable.ssl_certificate_disabled_night));
+ } else {
+ pinnedSslCertificateImageView.setImageDrawable(resources.getDrawable(R.drawable.ssl_certificate_disabled_day));
+ }
+ }
+
+ // Store the current date.
+ Date currentDate = Calendar.getInstance().getTime();
+
+ // Setup the string builders to display the general certificate information in blue. `SPAN_INCLUSIVE_INCLUSIVE` allows the span to grow in either direction.
+ savedSslIssuedToONameStringBuilder.setSpan(blueColorSpan, oNameLabel.length(), savedSslIssuedToONameStringBuilder.length(), Spanned.SPAN_INCLUSIVE_INCLUSIVE);
+ savedSslIssuedToUNameStringBuilder.setSpan(blueColorSpan, uNameLabel.length(), savedSslIssuedToUNameStringBuilder.length(), Spanned.SPAN_INCLUSIVE_INCLUSIVE);
+ savedSslIssuedByCNameStringBuilder.setSpan(blueColorSpan, cNameLabel.length(), savedSslIssuedByCNameStringBuilder.length(), Spanned.SPAN_INCLUSIVE_INCLUSIVE);
+ savedSslIssuedByONameStringBuilder.setSpan(blueColorSpan, oNameLabel.length(), savedSslIssuedByONameStringBuilder.length(), Spanned.SPAN_INCLUSIVE_INCLUSIVE);
+ savedSslIssuedByUNameStringBuilder.setSpan(blueColorSpan, uNameLabel.length(), savedSslIssuedByUNameStringBuilder.length(), Spanned.SPAN_INCLUSIVE_INCLUSIVE);
+
+ // Check the certificate Common Name against the domain name.
+ boolean savedSslCommonNameMatchesDomainName = checkDomainNameAgainstCertificate(domainNameString, savedSslIssuedToCNameString);
+
+ // Format the issued to Common Name color. `SPAN_INCLUSIVE_INCLUSIVE` allows the span to grow in either direction.
+ if (savedSslCommonNameMatchesDomainName) {
+ savedSslIssuedToCNameStringBuilder.setSpan(blueColorSpan, cNameLabel.length(), savedSslIssuedToCNameStringBuilder.length(), Spanned.SPAN_INCLUSIVE_INCLUSIVE);
+ } else {
+ savedSslIssuedToCNameStringBuilder.setSpan(redColorSpan, cNameLabel.length(), savedSslIssuedToCNameStringBuilder.length(), Spanned.SPAN_INCLUSIVE_INCLUSIVE);
+ }
+
+ // Format the start date color. `SPAN_INCLUSIVE_INCLUSIVE` allows the span to grow in either direction.
+ if ((savedSslStartDate != null) && savedSslStartDate.after(currentDate)) { // The certificate start date is in the future.
+ savedSslStartDateStringBuilder.setSpan(redColorSpan, startDateLabel.length(), savedSslStartDateStringBuilder.length(), Spanned.SPAN_INCLUSIVE_INCLUSIVE);
+ } else { // The certificate start date is in the past.
+ savedSslStartDateStringBuilder.setSpan(blueColorSpan, startDateLabel.length(), savedSslStartDateStringBuilder.length(), Spanned.SPAN_INCLUSIVE_INCLUSIVE);
+ }
+
+ // Format the end date color. `SPAN_INCLUSIVE_INCLUSIVE` allows the span to grow in either direction.
+ if ((savedSslEndDate != null) && savedSslEndDate.before(currentDate)) { // The certificate end date is in the past.
+ savedSslEndDateStringBuilder.setSpan(redColorSpan, endDateLabel.length(), savedSslEndDateStringBuilder.length(), Spanned.SPAN_INCLUSIVE_INCLUSIVE);
+ } else { // The certificate end date is in the future.
+ savedSslEndDateStringBuilder.setSpan(blueColorSpan, endDateLabel.length(), savedSslEndDateStringBuilder.length(), Spanned.SPAN_INCLUSIVE_INCLUSIVE);
+ }
+
+ // Display the saved website SSL certificate strings.
+ savedSslIssuedToCNameTextView.setText(savedSslIssuedToCNameStringBuilder);
+ savedSslIssuedToONameTextView.setText(savedSslIssuedToONameStringBuilder);
+ savedSslIssuedToUNameTextView.setText(savedSslIssuedToUNameStringBuilder);
+ savedSslIssuedByCNameTextView.setText(savedSslIssuedByCNameStringBuilder);
+ savedSslIssuedByONameTextView.setText(savedSslIssuedByONameStringBuilder);
+ savedSslIssuedByUNameTextView.setText(savedSslIssuedByUNameStringBuilder);
+ savedSslStartDateTextView.setText(savedSslStartDateStringBuilder);
+ savedSslEndDateTextView.setText(savedSslEndDateStringBuilder);
+
+ // Populate the current website SSL certificate if there is one.
+ if (DomainsActivity.sslIssuedToCName != null) {
+ // Get dates from the raw long values.
+ Date currentSslStartDate = new Date(DomainsActivity.sslStartDateLong);
+ Date currentSslEndDate = new Date(DomainsActivity.sslEndDateLong);
+
+ // Create a spannable string builder for each text view that needs multiple colors of text.
+ SpannableStringBuilder currentSslIssuedToCNameStringBuilder = new SpannableStringBuilder(cNameLabel + DomainsActivity.sslIssuedToCName);
+ SpannableStringBuilder currentSslIssuedToONameStringBuilder = new SpannableStringBuilder(oNameLabel + DomainsActivity.sslIssuedToOName);
+ SpannableStringBuilder currentSslIssuedToUNameStringBuilder = new SpannableStringBuilder(uNameLabel + DomainsActivity.sslIssuedToUName);
+ SpannableStringBuilder currentSslIssuedByCNameStringBuilder = new SpannableStringBuilder(cNameLabel + DomainsActivity.sslIssuedByCName);
+ SpannableStringBuilder currentSslIssuedByONameStringBuilder = new SpannableStringBuilder(oNameLabel + DomainsActivity.sslIssuedByOName);
+ SpannableStringBuilder currentSslIssuedByUNameStringBuilder = new SpannableStringBuilder(uNameLabel + DomainsActivity.sslIssuedByUName);
+ SpannableStringBuilder currentSslStartDateStringBuilder = new SpannableStringBuilder(startDateLabel + DateFormat.getDateTimeInstance(DateFormat.MEDIUM, DateFormat.LONG)
+ .format(currentSslStartDate));
+ SpannableStringBuilder currentSslEndDateStringBuilder = new SpannableStringBuilder(endDateLabel + DateFormat.getDateTimeInstance(DateFormat.MEDIUM, DateFormat.LONG)
+ .format(currentSslEndDate));
+
+ // Setup the string builders to display the general certificate information in blue. `SPAN_INCLUSIVE_INCLUSIVE` allows the span to grow in either direction.
+ currentSslIssuedToONameStringBuilder.setSpan(blueColorSpan, oNameLabel.length(), currentSslIssuedToONameStringBuilder.length(), Spanned.SPAN_INCLUSIVE_INCLUSIVE);
+ currentSslIssuedToUNameStringBuilder.setSpan(blueColorSpan, uNameLabel.length(), currentSslIssuedToUNameStringBuilder.length(), Spanned.SPAN_INCLUSIVE_INCLUSIVE);
+ currentSslIssuedByCNameStringBuilder.setSpan(blueColorSpan, cNameLabel.length(), currentSslIssuedByCNameStringBuilder.length(), Spanned.SPAN_INCLUSIVE_INCLUSIVE);
+ currentSslIssuedByONameStringBuilder.setSpan(blueColorSpan, oNameLabel.length(), currentSslIssuedByONameStringBuilder.length(), Spanned.SPAN_INCLUSIVE_INCLUSIVE);
+ currentSslIssuedByUNameStringBuilder.setSpan(blueColorSpan, uNameLabel.length(), currentSslIssuedByUNameStringBuilder.length(), Spanned.SPAN_INCLUSIVE_INCLUSIVE);
+
+ // Check the certificate Common Name against the domain name.
+ boolean currentSslCommonNameMatchesDomainName = checkDomainNameAgainstCertificate(domainNameString, DomainsActivity.sslIssuedToCName);
+
+ // Format the issued to Common Name color. `SPAN_INCLUSIVE_INCLUSIVE` allows the span to grow in either direction.
+ if (currentSslCommonNameMatchesDomainName) {
+ currentSslIssuedToCNameStringBuilder.setSpan(blueColorSpan, cNameLabel.length(), currentSslIssuedToCNameStringBuilder.length(), Spanned.SPAN_INCLUSIVE_INCLUSIVE);
+ } else {
+ currentSslIssuedToCNameStringBuilder.setSpan(redColorSpan, cNameLabel.length(), currentSslIssuedToCNameStringBuilder.length(), Spanned.SPAN_INCLUSIVE_INCLUSIVE);
+ }
+
+ // Format the start date color. `SPAN_INCLUSIVE_INCLUSIVE` allows the span to grow in either direction.
+ if (currentSslStartDate.after(currentDate)) { // The certificate start date is in the future.
+ currentSslStartDateStringBuilder.setSpan(redColorSpan, startDateLabel.length(), currentSslStartDateStringBuilder.length(), Spanned.SPAN_INCLUSIVE_INCLUSIVE);
+ } else { // The certificate start date is in the past.
+ currentSslStartDateStringBuilder.setSpan(blueColorSpan, startDateLabel.length(), currentSslStartDateStringBuilder.length(), Spanned.SPAN_INCLUSIVE_INCLUSIVE);
+ }
+
+ // Format the end date color. `SPAN_INCLUSIVE_INCLUSIVE` allows the span to grow in either direction.
+ if (currentSslEndDate.before(currentDate)) { // The certificate end date is in the past.
+ currentSslEndDateStringBuilder.setSpan(redColorSpan, endDateLabel.length(), currentSslEndDateStringBuilder.length(), Spanned.SPAN_INCLUSIVE_INCLUSIVE);
+ } else { // The certificate end date is in the future.
+ currentSslEndDateStringBuilder.setSpan(blueColorSpan, endDateLabel.length(), currentSslEndDateStringBuilder.length(), Spanned.SPAN_INCLUSIVE_INCLUSIVE);
+ }
+
+ // Display the current website SSL certificate strings.
+ currentSslIssuedToCNameTextView.setText(currentSslIssuedToCNameStringBuilder);
+ currentSslIssuedToONameTextView.setText(currentSslIssuedToONameStringBuilder);
+ currentSslIssuedToUNameTextView.setText(currentSslIssuedToUNameStringBuilder);
+ currentSslIssuedByCNameTextView.setText(currentSslIssuedByCNameStringBuilder);
+ currentSslIssuedByONameTextView.setText(currentSslIssuedByONameStringBuilder);
+ currentSslIssuedByUNameTextView.setText(currentSslIssuedByUNameStringBuilder);
+ currentSslStartDateTextView.setText(currentSslStartDateStringBuilder);
+ currentSslEndDateTextView.setText(currentSslEndDateStringBuilder);
+ }
+
+ // Set the initial display status of the SSL certificates card views.
+ if (pinnedSslCertificateSwitch.isChecked()) { // An SSL certificate is pinned.
+ // Set the visibility of the saved SSL certificate.
+ if (savedSslIssuedToCNameString == null) {
+ savedSslCardView.setVisibility(View.GONE);
+ } else {
+ savedSslCardView.setVisibility(View.VISIBLE);
+ }
+
+ // Set the visibility of the current website SSL certificate.
+ if (DomainsActivity.sslIssuedToCName == null) { // There is no current SSL certificate.
+ // Hide the SSL certificate.
+ currentSslCardView.setVisibility(View.GONE);
+
+ // Show the instruction.
+ noCurrentWebsiteCertificateTextView.setVisibility(View.VISIBLE);
+ } else { // There is a current SSL certificate.
+ // Show the SSL certificate.
+ currentSslCardView.setVisibility(View.VISIBLE);
+
+ // Hide the instruction.
+ noCurrentWebsiteCertificateTextView.setVisibility(View.GONE);
+ }
+
+ // Set the status of the radio buttons and the card view backgrounds.
+ if (savedSslCardView.getVisibility() == View.VISIBLE) { // The saved SSL certificate is displayed.
+ // Check the saved SSL certificate radio button.
+ savedSslCertificateRadioButton.setChecked(true);
+
+ // Uncheck the current website SSL certificate radio button.
+ currentWebsiteCertificateRadioButton.setChecked(false);
+
+ // Darken the background of the current website SSL certificate linear layout according to the theme.
+ if (currentThemeStatus == Configuration.UI_MODE_NIGHT_YES) {
+ currentWebsiteCertificateLinearLayout.setBackgroundResource(R.color.black_translucent_33);
+ } else {
+ currentWebsiteCertificateLinearLayout.setBackgroundResource(R.color.black_translucent_11);
+ }
+ } else if (currentSslCardView.getVisibility() == View.VISIBLE) { // The saved SSL certificate is hidden but the current website SSL certificate is visible.
+ // Check the current website SSL certificate radio button.
+ currentWebsiteCertificateRadioButton.setChecked(true);
+
+ // Uncheck the saved SSL certificate radio button.
+ savedSslCertificateRadioButton.setChecked(false);
+ } else { // Neither SSL certificate is visible.
+ // Uncheck both radio buttons.
+ savedSslCertificateRadioButton.setChecked(false);
+ currentWebsiteCertificateRadioButton.setChecked(false);
+ }
+ } else { // An SSL certificate is not pinned.
+ // Hide the SSl certificates and instructions.
+ savedSslCardView.setVisibility(View.GONE);
+ currentSslCardView.setVisibility(View.GONE);
+ noCurrentWebsiteCertificateTextView.setVisibility(View.GONE);
+
+ // Uncheck the radio buttons.
+ savedSslCertificateRadioButton.setChecked(false);
+ currentWebsiteCertificateRadioButton.setChecked(false);
+ }
+
+ // Set the pinned IP addresses icon.
+ if (pinnedIpAddressesInt == 1) { // Pinned IP addresses is enabled. Once the minimum API >= 21 a selector can be sued as the tint mode instead of specifying different icons.
+ // Check the switch.
+ pinnedIpAddressesSwitch.setChecked(true);
+
+ // Set the icon according to the theme.
+ if (currentThemeStatus == Configuration.UI_MODE_NIGHT_YES) {
+ pinnedIpAddressesImageView.setImageDrawable(resources.getDrawable(R.drawable.ssl_certificate_enabled_night));
+ } else {
+ pinnedIpAddressesImageView.setImageDrawable(resources.getDrawable(R.drawable.ssl_certificate_enabled_day));
+ }
+ } else { // Pinned IP Addresses is disabled.
+ // Uncheck the switch.
+ pinnedIpAddressesSwitch.setChecked(false);