2 * Copyright 2017-2024 Soren Stoutner <soren@stoutner.com>.
4 * This file is part of Privacy Browser Android <https://www.stoutner.com/privacy-browser-android>.
6 * Privacy Browser Android is free software: you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation, either version 3 of the License, or
9 * (at your option) any later version.
11 * Privacy Browser Android is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
16 * You should have received a copy of the GNU General Public License
17 * along with Privacy Browser Android. If not, see <http://www.gnu.org/licenses/>.
20 package com.stoutner.privacybrowser.fragments
22 import android.annotation.SuppressLint
23 import android.content.Context
24 import android.content.res.Configuration
25 import android.os.Bundle
26 import android.text.Editable
27 import android.text.SpannableStringBuilder
28 import android.text.Spanned
29 import android.text.TextWatcher
30 import android.text.style.ForegroundColorSpan
31 import android.view.LayoutInflater
32 import android.view.View
33 import android.view.ViewGroup
34 import android.webkit.WebView
35 import android.widget.AdapterView
36 import android.widget.ArrayAdapter
37 import android.widget.CompoundButton
38 import android.widget.EditText
39 import android.widget.ImageView
40 import android.widget.LinearLayout
41 import android.widget.RadioButton
42 import android.widget.ScrollView
43 import android.widget.Spinner
44 import android.widget.TextView
46 import androidx.appcompat.widget.SwitchCompat
47 import androidx.cardview.widget.CardView
48 import androidx.core.content.ContextCompat.getColor
49 import androidx.core.content.res.ResourcesCompat
50 import androidx.fragment.app.Fragment
51 import androidx.preference.PreferenceManager
53 import com.stoutner.privacybrowser.R
54 import com.stoutner.privacybrowser.activities.DOMAINS_CUSTOM_USER_AGENT
55 import com.stoutner.privacybrowser.activities.DOMAINS_SYSTEM_DEFAULT_USER_AGENT
56 import com.stoutner.privacybrowser.activities.DOMAINS_WEBVIEW_DEFAULT_USER_AGENT
57 import com.stoutner.privacybrowser.activities.SETTINGS_CUSTOM_USER_AGENT
58 import com.stoutner.privacybrowser.activities.SETTINGS_WEBVIEW_DEFAULT_USER_AGENT
59 import com.stoutner.privacybrowser.activities.UNRECOGNIZED_USER_AGENT
60 import com.stoutner.privacybrowser.activities.DomainsActivity
61 import com.stoutner.privacybrowser.helpers.BLOCK_ALL_THIRD_PARTY_REQUESTS
62 import com.stoutner.privacybrowser.helpers.COOKIES
63 import com.stoutner.privacybrowser.helpers.DARK_THEME
64 import com.stoutner.privacybrowser.helpers.DISABLED
65 import com.stoutner.privacybrowser.helpers.DISPLAY_IMAGES
66 import com.stoutner.privacybrowser.helpers.DOMAIN_NAME
67 import com.stoutner.privacybrowser.helpers.ENABLED
68 import com.stoutner.privacybrowser.helpers.LIGHT_THEME
69 import com.stoutner.privacybrowser.helpers.SYSTEM_DEFAULT
70 import com.stoutner.privacybrowser.helpers.ENABLE_DOM_STORAGE
71 import com.stoutner.privacybrowser.helpers.ENABLE_EASYLIST
72 import com.stoutner.privacybrowser.helpers.ENABLE_EASYPRIVACY
73 import com.stoutner.privacybrowser.helpers.ENABLE_FANBOYS_ANNOYANCE_LIST
74 import com.stoutner.privacybrowser.helpers.ENABLE_FANBOYS_SOCIAL_BLOCKING_LIST
75 import com.stoutner.privacybrowser.helpers.ENABLE_JAVASCRIPT
76 import com.stoutner.privacybrowser.helpers.ENABLE_ULTRAPRIVACY
77 import com.stoutner.privacybrowser.helpers.FONT_SIZE
78 import com.stoutner.privacybrowser.helpers.IP_ADDRESSES
79 import com.stoutner.privacybrowser.helpers.PINNED_IP_ADDRESSES
80 import com.stoutner.privacybrowser.helpers.PINNED_SSL_CERTIFICATE
81 import com.stoutner.privacybrowser.helpers.SSL_END_DATE
82 import com.stoutner.privacybrowser.helpers.SSL_ISSUED_BY_COMMON_NAME
83 import com.stoutner.privacybrowser.helpers.SSL_ISSUED_BY_ORGANIZATION
84 import com.stoutner.privacybrowser.helpers.SSL_ISSUED_BY_ORGANIZATIONAL_UNIT
85 import com.stoutner.privacybrowser.helpers.SSL_ISSUED_TO_COMMON_NAME
86 import com.stoutner.privacybrowser.helpers.SSL_ISSUED_TO_ORGANIZATION
87 import com.stoutner.privacybrowser.helpers.SSL_ISSUED_TO_ORGANIZATIONAL_UNIT
88 import com.stoutner.privacybrowser.helpers.SSL_START_DATE
89 import com.stoutner.privacybrowser.helpers.SWIPE_TO_REFRESH
90 import com.stoutner.privacybrowser.helpers.ULTRALIST
91 import com.stoutner.privacybrowser.helpers.USER_AGENT
92 import com.stoutner.privacybrowser.helpers.WEBVIEW_THEME
93 import com.stoutner.privacybrowser.helpers.WIDE_VIEWPORT
94 import com.stoutner.privacybrowser.helpers.DomainsDatabaseHelper
96 import java.lang.IndexOutOfBoundsException
97 import java.text.DateFormat
98 import java.util.Calendar
101 class DomainSettingsFragment : Fragment() {
102 // Define the class variables.
103 private var scrollY = 0
105 // Declare the class variables.
106 private lateinit var context: Context
109 // Define the public constants.
110 const val DATABASE_ID = "database_id"
111 const val SCROLL_Y = "scroll_y"
113 // Define the public variables. `databaseId` is public so it can be accessed from `DomainsActivity`.
117 override fun onCreate(savedInstanceState: Bundle?) {
118 // Run the default commands.
119 super.onCreate(savedInstanceState)
121 // Store the arguments in class variables.
122 databaseId = requireArguments().getInt(DATABASE_ID)
123 scrollY = requireArguments().getInt(SCROLL_Y)
126 override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
127 // Inflate the layout. The fragment will take care of attaching the root automatically.
128 val domainSettingsView = inflater.inflate(R.layout.domain_settings_fragment, container, false)
130 // Get a handle for the context.
131 context = requireContext()
133 // Get the current theme status.
134 val currentThemeStatus = resources.configuration.uiMode and Configuration.UI_MODE_NIGHT_MASK
136 // Get a handle for the shared preference.
137 val sharedPreferences = PreferenceManager.getDefaultSharedPreferences(requireContext())
139 // Get the default values.
140 val javaScriptDefault = sharedPreferences.getBoolean(getString(R.string.javascript_key), false)
141 val cookiesDefault = sharedPreferences.getBoolean(getString(R.string.cookies_key), false)
142 val domStorageDefault = sharedPreferences.getBoolean(getString(R.string.dom_storage_key), false)
143 val userAgentDefault = sharedPreferences.getString(getString(R.string.user_agent_key), getString(R.string.user_agent_default_value))
144 val customUserAgentStringDefault = sharedPreferences.getString(getString(R.string.custom_user_agent_key), getString(R.string.custom_user_agent_default_value))
145 val easyListDefault = sharedPreferences.getBoolean(getString(R.string.easylist_key), true)
146 val easyPrivacyDefault = sharedPreferences.getBoolean(getString(R.string.easyprivacy_key), true)
147 val fanboysAnnoyanceListDefault = sharedPreferences.getBoolean(getString(R.string.fanboys_annoyance_list_key), true)
148 val fanboysSocialBlockingListDefault = sharedPreferences.getBoolean(getString(R.string.fanboys_social_blocking_list_key), true)
149 val ultraListDefault = sharedPreferences.getBoolean(getString(R.string.ultralist_key), true)
150 val ultraPrivacyDefault = sharedPreferences.getBoolean(getString(R.string.ultraprivacy_key), true)
151 val blockAllThirdPartyRequestsDefault = sharedPreferences.getBoolean(getString(R.string.block_all_third_party_requests_key), false)
152 val fontSizeStringDefault = sharedPreferences.getString(getString(R.string.font_size_key), getString(R.string.font_size_default_value))
153 val swipeToRefreshDefault = sharedPreferences.getBoolean(getString(R.string.swipe_to_refresh_key), true)
154 val webViewThemeDefault = sharedPreferences.getString(getString(R.string.webview_theme_key), getString(R.string.webview_theme_default_value))
155 val wideViewportDefault = sharedPreferences.getBoolean(getString(R.string.wide_viewport_key), true)
156 val displayWebpageImagesDefault = sharedPreferences.getBoolean(getString(R.string.display_webpage_images_key), true)
158 // Get handles for the views.
159 val domainSettingsScrollView = domainSettingsView.findViewById<ScrollView>(R.id.domain_settings_scrollview)
160 val domainNameEditText = domainSettingsView.findViewById<EditText>(R.id.domain_settings_name_edittext)
161 val javaScriptLinearLayout = domainSettingsView.findViewById<LinearLayout>(R.id.javascript_linearlayout)
162 val javaScriptImageView = domainSettingsView.findViewById<ImageView>(R.id.javascript_imageview)
163 val javaScriptSpinner = domainSettingsView.findViewById<Spinner>(R.id.javascript_spinner)
164 val javaScriptTextView = domainSettingsView.findViewById<TextView>(R.id.javascript_textview)
165 val cookiesLinearLayout = domainSettingsView.findViewById<LinearLayout>(R.id.cookies_linearlayout)
166 val cookiesImageView = domainSettingsView.findViewById<ImageView>(R.id.cookies_imageview)
167 val cookiesSpinner = domainSettingsView.findViewById<Spinner>(R.id.cookies_spinner)
168 val cookiesTextView = domainSettingsView.findViewById<TextView>(R.id.cookies_textview)
169 val domStorageLinearLayout = domainSettingsView.findViewById<LinearLayout>(R.id.dom_storage_linearlayout)
170 val domStorageImageView = domainSettingsView.findViewById<ImageView>(R.id.dom_storage_imageview)
171 val domStorageSpinner = domainSettingsView.findViewById<Spinner>(R.id.dom_storage_spinner)
172 val domStorageTextView = domainSettingsView.findViewById<TextView>(R.id.dom_storage_textview)
173 val userAgentLinearLayout = domainSettingsView.findViewById<LinearLayout>(R.id.user_agent_linearlayout)
174 val userAgentSpinner = domainSettingsView.findViewById<Spinner>(R.id.user_agent_spinner)
175 val userAgentTextView = domainSettingsView.findViewById<TextView>(R.id.user_agent_textview)
176 val customUserAgentEditText = domainSettingsView.findViewById<EditText>(R.id.custom_user_agent_edittext)
177 val easyListLinearLayout = domainSettingsView.findViewById<LinearLayout>(R.id.easylist_linearlayout)
178 val easyListImageView = domainSettingsView.findViewById<ImageView>(R.id.easylist_imageview)
179 val easyListSpinner = domainSettingsView.findViewById<Spinner>(R.id.easylist_spinner)
180 val easyListTextView = domainSettingsView.findViewById<TextView>(R.id.easylist_textview)
181 val easyPrivacyLinearLayout = domainSettingsView.findViewById<LinearLayout>(R.id.easyprivacy_linearlayout)
182 val easyPrivacyImageView = domainSettingsView.findViewById<ImageView>(R.id.easyprivacy_imageview)
183 val easyPrivacySpinner = domainSettingsView.findViewById<Spinner>(R.id.easyprivacy_spinner)
184 val easyPrivacyTextView = domainSettingsView.findViewById<TextView>(R.id.easyprivacy_textview)
185 val fanboysAnnoyanceListLinearLayout = domainSettingsView.findViewById<LinearLayout>(R.id.fanboys_annoyance_list_linearlayout)
186 val fanboysAnnoyanceListImageView = domainSettingsView.findViewById<ImageView>(R.id.fanboys_annoyance_list_imageview)
187 val fanboysAnnoyanceListSpinner = domainSettingsView.findViewById<Spinner>(R.id.fanboys_annoyance_list_spinner)
188 val fanboysAnnoyanceListTextView = domainSettingsView.findViewById<TextView>(R.id.fanboys_annoyance_list_textview)
189 val fanboysSocialBlockingListLinearLayout = domainSettingsView.findViewById<LinearLayout>(R.id.fanboys_social_blocking_list_linearlayout)
190 val fanboysSocialBlockingListImageView = domainSettingsView.findViewById<ImageView>(R.id.fanboys_social_blocking_list_imageview)
191 val fanboysSocialBlockingListSpinner = domainSettingsView.findViewById<Spinner>(R.id.fanboys_social_blocking_list_spinner)
192 val fanboysSocialBlockingListTextView = domainSettingsView.findViewById<TextView>(R.id.fanboys_social_blocking_list_textview)
193 val ultraListLinearLayout = domainSettingsView.findViewById<LinearLayout>(R.id.ultralist_linearlayout)
194 val ultraListImageView = domainSettingsView.findViewById<ImageView>(R.id.ultralist_imageview)
195 val ultraListSpinner = domainSettingsView.findViewById<Spinner>(R.id.ultralist_spinner)
196 val ultraListTextView = domainSettingsView.findViewById<TextView>(R.id.ultralist_textview)
197 val ultraPrivacyLinearLayout = domainSettingsView.findViewById<LinearLayout>(R.id.ultraprivacy_linearlayout)
198 val ultraPrivacyImageView = domainSettingsView.findViewById<ImageView>(R.id.ultraprivacy_imageview)
199 val ultraPrivacySpinner = domainSettingsView.findViewById<Spinner>(R.id.ultraprivacy_spinner)
200 val ultraPrivacyTextView = domainSettingsView.findViewById<TextView>(R.id.ultraprivacy_textview)
201 val blockAllThirdPartyRequestsLinearLayout = domainSettingsView.findViewById<LinearLayout>(R.id.block_all_third_party_requests_linearlayout)
202 val blockAllThirdPartyRequestsImageView = domainSettingsView.findViewById<ImageView>(R.id.block_all_third_party_requests_imageview)
203 val blockAllThirdPartyRequestsSpinner = domainSettingsView.findViewById<Spinner>(R.id.block_all_third_party_requests_spinner)
204 val blockAllThirdPartyRequestsTextView = domainSettingsView.findViewById<TextView>(R.id.block_all_third_party_requests_textview)
205 val fontSizeLinearLayout = domainSettingsView.findViewById<LinearLayout>(R.id.font_size_linearlayout)
206 val fontSizeSpinner = domainSettingsView.findViewById<Spinner>(R.id.font_size_spinner)
207 val defaultFontSizeTextView = domainSettingsView.findViewById<TextView>(R.id.default_font_size_textview)
208 val customFontSizeEditText = domainSettingsView.findViewById<EditText>(R.id.custom_font_size_edittext)
209 val swipeToRefreshLinearLayout = domainSettingsView.findViewById<LinearLayout>(R.id.swipe_to_refresh_linearlayout)
210 val swipeToRefreshImageView = domainSettingsView.findViewById<ImageView>(R.id.swipe_to_refresh_imageview)
211 val swipeToRefreshSpinner = domainSettingsView.findViewById<Spinner>(R.id.swipe_to_refresh_spinner)
212 val swipeToRefreshTextView = domainSettingsView.findViewById<TextView>(R.id.swipe_to_refresh_textview)
213 val webViewThemeLinearLayout = domainSettingsView.findViewById<LinearLayout>(R.id.webview_theme_linearlayout)
214 val webViewThemeImageView = domainSettingsView.findViewById<ImageView>(R.id.webview_theme_imageview)
215 val webViewThemeSpinner = domainSettingsView.findViewById<Spinner>(R.id.webview_theme_spinner)
216 val webViewThemeTextView = domainSettingsView.findViewById<TextView>(R.id.webview_theme_textview)
217 val wideViewportLinearLayout = domainSettingsView.findViewById<LinearLayout>(R.id.wide_viewport_linearlayout)
218 val wideViewportImageView = domainSettingsView.findViewById<ImageView>(R.id.wide_viewport_imageview)
219 val wideViewportSpinner = domainSettingsView.findViewById<Spinner>(R.id.wide_viewport_spinner)
220 val wideViewportTextView = domainSettingsView.findViewById<TextView>(R.id.wide_viewport_textview)
221 val displayImagesLinearLayout = domainSettingsView.findViewById<LinearLayout>(R.id.display_images_linearlayout)
222 val displayImagesImageView = domainSettingsView.findViewById<ImageView>(R.id.display_images_imageview)
223 val displayImagesSpinner = domainSettingsView.findViewById<Spinner>(R.id.display_images_spinner)
224 val displayImagesTextView = domainSettingsView.findViewById<TextView>(R.id.display_images_textview)
225 val pinnedSslCertificateImageView = domainSettingsView.findViewById<ImageView>(R.id.pinned_ssl_certificate_imageview)
226 val pinnedSslCertificateSwitch = domainSettingsView.findViewById<SwitchCompat>(R.id.pinned_ssl_certificate_switch)
227 val savedSslCardView = domainSettingsView.findViewById<CardView>(R.id.saved_ssl_certificate_cardview)
228 val savedSslCertificateLinearLayout = domainSettingsView.findViewById<LinearLayout>(R.id.saved_ssl_certificate_linearlayout)
229 val savedSslCertificateRadioButton = domainSettingsView.findViewById<RadioButton>(R.id.saved_ssl_certificate_radiobutton)
230 val savedSslIssuedToCNameTextView = domainSettingsView.findViewById<TextView>(R.id.saved_ssl_certificate_issued_to_cname)
231 val savedSslIssuedToONameTextView = domainSettingsView.findViewById<TextView>(R.id.saved_ssl_certificate_issued_to_oname)
232 val savedSslIssuedToUNameTextView = domainSettingsView.findViewById<TextView>(R.id.saved_ssl_certificate_issued_to_uname)
233 val savedSslIssuedByCNameTextView = domainSettingsView.findViewById<TextView>(R.id.saved_ssl_certificate_issued_by_cname)
234 val savedSslIssuedByONameTextView = domainSettingsView.findViewById<TextView>(R.id.saved_ssl_certificate_issued_by_oname)
235 val savedSslIssuedByUNameTextView = domainSettingsView.findViewById<TextView>(R.id.saved_ssl_certificate_issued_by_uname)
236 val savedSslStartDateTextView = domainSettingsView.findViewById<TextView>(R.id.saved_ssl_certificate_start_date)
237 val savedSslEndDateTextView = domainSettingsView.findViewById<TextView>(R.id.saved_ssl_certificate_end_date)
238 val currentSslCardView = domainSettingsView.findViewById<CardView>(R.id.current_website_certificate_cardview)
239 val currentWebsiteCertificateLinearLayout = domainSettingsView.findViewById<LinearLayout>(R.id.current_website_certificate_linearlayout)
240 val currentWebsiteCertificateRadioButton = domainSettingsView.findViewById<RadioButton>(R.id.current_website_certificate_radiobutton)
241 val currentSslIssuedToCNameTextView = domainSettingsView.findViewById<TextView>(R.id.current_website_certificate_issued_to_cname)
242 val currentSslIssuedToONameTextView = domainSettingsView.findViewById<TextView>(R.id.current_website_certificate_issued_to_oname)
243 val currentSslIssuedToUNameTextView = domainSettingsView.findViewById<TextView>(R.id.current_website_certificate_issued_to_uname)
244 val currentSslIssuedByCNameTextView = domainSettingsView.findViewById<TextView>(R.id.current_website_certificate_issued_by_cname)
245 val currentSslIssuedByONameTextView = domainSettingsView.findViewById<TextView>(R.id.current_website_certificate_issued_by_oname)
246 val currentSslIssuedByUNameTextView = domainSettingsView.findViewById<TextView>(R.id.current_website_certificate_issued_by_uname)
247 val currentSslStartDateTextView = domainSettingsView.findViewById<TextView>(R.id.current_website_certificate_start_date)
248 val currentSslEndDateTextView = domainSettingsView.findViewById<TextView>(R.id.current_website_certificate_end_date)
249 val noCurrentWebsiteCertificateTextView = domainSettingsView.findViewById<TextView>(R.id.no_current_website_certificate)
250 val pinnedIpAddressesImageView = domainSettingsView.findViewById<ImageView>(R.id.pinned_ip_addresses_imageview)
251 val pinnedIpAddressesSwitch = domainSettingsView.findViewById<SwitchCompat>(R.id.pinned_ip_addresses_switch)
252 val savedIpAddressesCardView = domainSettingsView.findViewById<CardView>(R.id.saved_ip_addresses_cardview)
253 val savedIpAddressesLinearLayout = domainSettingsView.findViewById<LinearLayout>(R.id.saved_ip_addresses_linearlayout)
254 val savedIpAddressesRadioButton = domainSettingsView.findViewById<RadioButton>(R.id.saved_ip_addresses_radiobutton)
255 val savedIpAddressesTextView = domainSettingsView.findViewById<TextView>(R.id.saved_ip_addresses_textview)
256 val currentIpAddressesCardView = domainSettingsView.findViewById<CardView>(R.id.current_ip_addresses_cardview)
257 val currentIpAddressesLinearLayout = domainSettingsView.findViewById<LinearLayout>(R.id.current_ip_addresses_linearlayout)
258 val currentIpAddressesRadioButton = domainSettingsView.findViewById<RadioButton>(R.id.current_ip_addresses_radiobutton)
259 val currentIpAddressesTextView = domainSettingsView.findViewById<TextView>(R.id.current_ip_addresses_textview)
261 // Initialize the database handler.
262 val domainsDatabaseHelper = DomainsDatabaseHelper(requireContext())
264 // Get the database cursor for this ID.
265 val domainCursor = domainsDatabaseHelper.getCursorForId(databaseId)
267 // Move to the first row.
268 domainCursor.moveToFirst()
270 // Save the cursor entries as variables.
271 val domainNameString = domainCursor.getString(domainCursor.getColumnIndexOrThrow(DOMAIN_NAME))
272 val javaScriptInt = domainCursor.getInt(domainCursor.getColumnIndexOrThrow(ENABLE_JAVASCRIPT))
273 val cookiesInt = domainCursor.getInt(domainCursor.getColumnIndexOrThrow(COOKIES))
274 val domStorageInt = domainCursor.getInt(domainCursor.getColumnIndexOrThrow(ENABLE_DOM_STORAGE))
275 val currentUserAgentName = domainCursor.getString(domainCursor.getColumnIndexOrThrow(USER_AGENT))
276 val easyListInt = domainCursor.getInt(domainCursor.getColumnIndexOrThrow(ENABLE_EASYLIST))
277 val easyPrivacyInt = domainCursor.getInt(domainCursor.getColumnIndexOrThrow(ENABLE_EASYPRIVACY))
278 val fanboysAnnoyanceListInt = domainCursor.getInt(domainCursor.getColumnIndexOrThrow(ENABLE_FANBOYS_ANNOYANCE_LIST))
279 val fanboysSocialBlockingListInt = domainCursor.getInt(domainCursor.getColumnIndexOrThrow(ENABLE_FANBOYS_SOCIAL_BLOCKING_LIST))
280 val ultraListInt = domainCursor.getInt(domainCursor.getColumnIndexOrThrow(ULTRALIST))
281 val ultraPrivacyInt = domainCursor.getInt(domainCursor.getColumnIndexOrThrow(ENABLE_ULTRAPRIVACY))
282 val blockAllThirdPartyRequestsInt = domainCursor.getInt(domainCursor.getColumnIndexOrThrow(BLOCK_ALL_THIRD_PARTY_REQUESTS))
283 val fontSizeInt = domainCursor.getInt(domainCursor.getColumnIndexOrThrow(FONT_SIZE))
284 val swipeToRefreshInt = domainCursor.getInt(domainCursor.getColumnIndexOrThrow(SWIPE_TO_REFRESH))
285 val webViewThemeInt = domainCursor.getInt(domainCursor.getColumnIndexOrThrow(WEBVIEW_THEME))
286 val wideViewportInt = domainCursor.getInt(domainCursor.getColumnIndexOrThrow(WIDE_VIEWPORT))
287 val displayImagesInt = domainCursor.getInt(domainCursor.getColumnIndexOrThrow(DISPLAY_IMAGES))
288 val pinnedSslCertificateInt = domainCursor.getInt(domainCursor.getColumnIndexOrThrow(PINNED_SSL_CERTIFICATE))
289 val savedSslIssuedToCNameString = domainCursor.getString(domainCursor.getColumnIndexOrThrow(SSL_ISSUED_TO_COMMON_NAME))
290 val savedSslIssuedToONameString = domainCursor.getString(domainCursor.getColumnIndexOrThrow(SSL_ISSUED_TO_ORGANIZATION))
291 val savedSslIssuedToUNameString = domainCursor.getString(domainCursor.getColumnIndexOrThrow(SSL_ISSUED_TO_ORGANIZATIONAL_UNIT))
292 val savedSslIssuedByCNameString = domainCursor.getString(domainCursor.getColumnIndexOrThrow(SSL_ISSUED_BY_COMMON_NAME))
293 val savedSslIssuedByONameString = domainCursor.getString(domainCursor.getColumnIndexOrThrow(SSL_ISSUED_BY_ORGANIZATION))
294 val savedSslIssuedByUNameString = domainCursor.getString(domainCursor.getColumnIndexOrThrow(SSL_ISSUED_BY_ORGANIZATIONAL_UNIT))
295 val savedSslStartDateLong = domainCursor.getLong(domainCursor.getColumnIndexOrThrow(SSL_START_DATE))
296 val savedSslEndDateLong = domainCursor.getLong(domainCursor.getColumnIndexOrThrow(SSL_END_DATE))
297 val pinnedIpAddressesInt = domainCursor.getInt(domainCursor.getColumnIndexOrThrow(PINNED_IP_ADDRESSES))
298 val savedIpAddresses = domainCursor.getString(domainCursor.getColumnIndexOrThrow(IP_ADDRESSES))
300 // Close the domain cursor.
303 // Create spinner array adapters.
304 val javaScriptArrayAdapter = ArrayAdapter.createFromResource(context, R.array.javascript_array, R.layout.spinner_item)
305 val cookiesArrayAdapter = ArrayAdapter.createFromResource(context, R.array.cookies_array, R.layout.spinner_item)
306 val domStorageArrayAdapter = ArrayAdapter.createFromResource(context, R.array.dom_storage_array, R.layout.spinner_item)
307 val translatedUserAgentArrayAdapter = ArrayAdapter.createFromResource(context, R.array.translated_domain_settings_user_agent_names, R.layout.spinner_item)
308 val easyListArrayAdapter = ArrayAdapter.createFromResource(context, R.array.easylist_array, R.layout.spinner_item)
309 val easyPrivacyArrayAdapter = ArrayAdapter.createFromResource(context, R.array.easyprivacy_array, R.layout.spinner_item)
310 val fanboysAnnoyanceListArrayAdapter = ArrayAdapter.createFromResource(context, R.array.fanboys_annoyance_list_array, R.layout.spinner_item)
311 val fanboysSocialBlockingListArrayAdapter = ArrayAdapter.createFromResource(context, R.array.fanboys_social_blocking_list_array, R.layout.spinner_item)
312 val ultraListArrayAdapter = ArrayAdapter.createFromResource(context, R.array.ultralist_array, R.layout.spinner_item)
313 val ultraPrivacyArrayAdapter = ArrayAdapter.createFromResource(context, R.array.ultraprivacy_array, R.layout.spinner_item)
314 val blockAllThirdPartyRequestsArrayAdapter = ArrayAdapter.createFromResource(context, R.array.block_all_third_party_requests_array, R.layout.spinner_item)
315 val fontSizeArrayAdapter = ArrayAdapter.createFromResource(context, R.array.font_size_array, R.layout.spinner_item)
316 val swipeToRefreshArrayAdapter = ArrayAdapter.createFromResource(context, R.array.swipe_to_refresh_array, R.layout.spinner_item)
317 val webViewThemeArrayAdapter = ArrayAdapter.createFromResource(context, R.array.webview_theme_array, R.layout.spinner_item)
318 val wideViewportArrayAdapter = ArrayAdapter.createFromResource(context, R.array.wide_viewport_array, R.layout.spinner_item)
319 val displayImagesArrayAdapter = ArrayAdapter.createFromResource(context, R.array.display_webpage_images_array, R.layout.spinner_item)
321 // Set the drop down view resource on the spinners.
322 javaScriptArrayAdapter.setDropDownViewResource(R.layout.domain_settings_spinner_dropdown_items)
323 cookiesArrayAdapter.setDropDownViewResource(R.layout.domain_settings_spinner_dropdown_items)
324 domStorageArrayAdapter.setDropDownViewResource(R.layout.domain_settings_spinner_dropdown_items)
325 translatedUserAgentArrayAdapter.setDropDownViewResource(R.layout.domain_settings_spinner_dropdown_items)
326 easyListArrayAdapter.setDropDownViewResource(R.layout.domain_settings_spinner_dropdown_items)
327 easyPrivacyArrayAdapter.setDropDownViewResource(R.layout.domain_settings_spinner_dropdown_items)
328 fanboysAnnoyanceListArrayAdapter.setDropDownViewResource(R.layout.domain_settings_spinner_dropdown_items)
329 fanboysSocialBlockingListArrayAdapter.setDropDownViewResource(R.layout.domain_settings_spinner_dropdown_items)
330 ultraListArrayAdapter.setDropDownViewResource(R.layout.domain_settings_spinner_dropdown_items)
331 ultraPrivacyArrayAdapter.setDropDownViewResource(R.layout.domain_settings_spinner_dropdown_items)
332 blockAllThirdPartyRequestsArrayAdapter.setDropDownViewResource(R.layout.domain_settings_spinner_dropdown_items)
333 fontSizeArrayAdapter.setDropDownViewResource(R.layout.domain_settings_spinner_dropdown_items)
334 swipeToRefreshArrayAdapter.setDropDownViewResource(R.layout.domain_settings_spinner_dropdown_items)
335 webViewThemeArrayAdapter.setDropDownViewResource(R.layout.domain_settings_spinner_dropdown_items)
336 wideViewportArrayAdapter.setDropDownViewResource(R.layout.domain_settings_spinner_dropdown_items)
337 displayImagesArrayAdapter.setDropDownViewResource(R.layout.domain_settings_spinner_dropdown_items)
339 // Set the array adapters for the spinners.
340 javaScriptSpinner.adapter = javaScriptArrayAdapter
341 cookiesSpinner.adapter = cookiesArrayAdapter
342 domStorageSpinner.adapter = domStorageArrayAdapter
343 userAgentSpinner.adapter = translatedUserAgentArrayAdapter
344 easyListSpinner.adapter = easyListArrayAdapter
345 easyPrivacySpinner.adapter = easyPrivacyArrayAdapter
346 fanboysAnnoyanceListSpinner.adapter = fanboysAnnoyanceListArrayAdapter
347 fanboysSocialBlockingListSpinner.adapter = fanboysSocialBlockingListArrayAdapter
348 ultraListSpinner.adapter = ultraListArrayAdapter
349 ultraPrivacySpinner.adapter = ultraPrivacyArrayAdapter
350 blockAllThirdPartyRequestsSpinner.adapter = blockAllThirdPartyRequestsArrayAdapter
351 fontSizeSpinner.adapter = fontSizeArrayAdapter
352 swipeToRefreshSpinner.adapter = swipeToRefreshArrayAdapter
353 webViewThemeSpinner.adapter = webViewThemeArrayAdapter
354 wideViewportSpinner.adapter = wideViewportArrayAdapter
355 displayImagesSpinner.adapter = displayImagesArrayAdapter
357 // Open the spinners when the text view is tapped.
358 javaScriptTextView.setOnClickListener { javaScriptSpinner.performClick() }
359 cookiesTextView.setOnClickListener { cookiesSpinner.performClick() }
360 domStorageTextView.setOnClickListener { domStorageSpinner.performClick() }
361 userAgentTextView.setOnClickListener { userAgentSpinner.performClick() }
362 easyListTextView.setOnClickListener { easyListSpinner.performClick() }
363 easyPrivacyTextView.setOnClickListener { easyPrivacySpinner.performClick() }
364 fanboysAnnoyanceListTextView.setOnClickListener { fanboysAnnoyanceListSpinner.performClick() }
365 fanboysSocialBlockingListTextView.setOnClickListener { fanboysSocialBlockingListSpinner.performClick() }
366 ultraListTextView.setOnClickListener { ultraListSpinner.performClick() }
367 ultraPrivacyTextView.setOnClickListener { ultraPrivacySpinner.performClick() }
368 blockAllThirdPartyRequestsTextView.setOnClickListener { blockAllThirdPartyRequestsSpinner.performClick() }
369 defaultFontSizeTextView.setOnClickListener { fontSizeSpinner.performClick() }
370 swipeToRefreshTextView.setOnClickListener { swipeToRefreshSpinner.performClick() }
371 webViewThemeTextView.setOnClickListener { webViewThemeSpinner.performClick() }
372 wideViewportTextView.setOnClickListener { wideViewportSpinner.performClick() }
373 displayImagesTextView.setOnClickListener { displayImagesSpinner.performClick() }
375 // Set the spinner selections. Items that aren't defined by an integer are handled individually below.
376 javaScriptSpinner.setSelection(javaScriptInt)
377 cookiesSpinner.setSelection(cookiesInt)
378 domStorageSpinner.setSelection(domStorageInt)
379 easyListSpinner.setSelection(easyListInt)
380 easyPrivacySpinner.setSelection(easyPrivacyInt)
381 fanboysAnnoyanceListSpinner.setSelection(fanboysAnnoyanceListInt)
382 fanboysSocialBlockingListSpinner.setSelection(fanboysSocialBlockingListInt)
383 ultraListSpinner.setSelection(ultraListInt)
384 ultraPrivacySpinner.setSelection(ultraPrivacyInt)
385 blockAllThirdPartyRequestsSpinner.setSelection(blockAllThirdPartyRequestsInt)
386 swipeToRefreshSpinner.setSelection(swipeToRefreshInt)
387 webViewThemeSpinner.setSelection(webViewThemeInt)
388 wideViewportSpinner.setSelection(wideViewportInt)
389 displayImagesSpinner.setSelection(displayImagesInt)
391 // Populate the text views. Items that aren't defined by an integer are handled individually below.
392 populateTextView(javaScriptDefault, javaScriptArrayAdapter, javaScriptTextView)
393 populateTextView(cookiesDefault, cookiesArrayAdapter, cookiesTextView)
394 populateTextView(domStorageDefault, domStorageArrayAdapter, domStorageTextView)
395 populateTextView(easyListDefault, easyListArrayAdapter, easyListTextView)
396 populateTextView(easyPrivacyDefault, easyPrivacyArrayAdapter, easyPrivacyTextView)
397 populateTextView(fanboysAnnoyanceListDefault, fanboysAnnoyanceListArrayAdapter, fanboysAnnoyanceListTextView)
398 populateTextView(fanboysSocialBlockingListDefault, fanboysSocialBlockingListArrayAdapter, fanboysSocialBlockingListTextView)
399 populateTextView(ultraListDefault, ultraListArrayAdapter, ultraListTextView)
400 populateTextView(ultraPrivacyDefault, ultraPrivacyArrayAdapter, ultraPrivacyTextView)
401 populateTextView(blockAllThirdPartyRequestsDefault, blockAllThirdPartyRequestsArrayAdapter, blockAllThirdPartyRequestsTextView)
402 populateTextView(swipeToRefreshDefault, swipeToRefreshArrayAdapter, swipeToRefreshTextView)
403 populateTextView(wideViewportDefault, wideViewportArrayAdapter, wideViewportTextView)
404 populateTextView(displayWebpageImagesDefault, displayImagesArrayAdapter, displayImagesTextView)
406 // Set the icon and text view settings. Non-standard items are handled individually below.
407 setIconAndTextViewSettings(cookiesInt, cookiesDefault, cookiesLinearLayout, cookiesImageView, cookiesTextView)
408 setIconAndTextViewSettings(domStorageInt, domStorageDefault, domStorageLinearLayout, domStorageImageView, domStorageTextView)
409 setIconAndTextViewSettings(easyListInt, easyListDefault, easyListLinearLayout, easyListImageView, easyListTextView)
410 setIconAndTextViewSettings(easyPrivacyInt, easyPrivacyDefault, easyPrivacyLinearLayout, easyPrivacyImageView, easyListTextView)
411 setIconAndTextViewSettings(fanboysAnnoyanceListInt, fanboysAnnoyanceListDefault, fanboysAnnoyanceListLinearLayout, fanboysAnnoyanceListImageView, fanboysAnnoyanceListTextView)
412 setIconAndTextViewSettings(fanboysSocialBlockingListInt, fanboysSocialBlockingListDefault, fanboysSocialBlockingListLinearLayout, fanboysSocialBlockingListImageView, fanboysSocialBlockingListTextView)
413 setIconAndTextViewSettings(ultraListInt, ultraListDefault, ultraListLinearLayout, ultraListImageView, ultraListTextView)
414 setIconAndTextViewSettings(ultraPrivacyInt, ultraPrivacyDefault, ultraPrivacyLinearLayout, ultraPrivacyImageView, ultraPrivacyTextView)
415 setIconAndTextViewSettings(blockAllThirdPartyRequestsInt, blockAllThirdPartyRequestsDefault, blockAllThirdPartyRequestsLinearLayout, blockAllThirdPartyRequestsImageView,
416 blockAllThirdPartyRequestsTextView)
417 setIconAndTextViewSettings(swipeToRefreshInt, swipeToRefreshDefault, swipeToRefreshLinearLayout, swipeToRefreshImageView, swipeToRefreshTextView)
418 setIconAndTextViewSettings(wideViewportInt, wideViewportDefault, wideViewportLinearLayout, wideViewportImageView, wideViewportTextView)
419 setIconAndTextViewSettings(displayImagesInt, displayWebpageImagesDefault, displayImagesLinearLayout, displayImagesImageView, displayImagesTextView)
422 // Set the domain name from the the database cursor.
423 domainNameEditText.setText(domainNameString)
425 // Setup the pinned labels.
426 val cNameLabel = getString(R.string.common_name)
427 val oNameLabel = getString(R.string.organization)
428 val uNameLabel = getString(R.string.organizational_unit)
429 val startDateLabel = getString(R.string.start_date)
430 val endDateLabel = getString(R.string.end_date)
432 // Create the color spans.
433 val blueColorSpan = ForegroundColorSpan(context.getColor(R.color.alt_blue_text))
434 val redColorSpan = ForegroundColorSpan(context.getColor(R.color.red_text))
436 // Update the certificates' Common Name color when the domain name text changes.
437 domainNameEditText.addTextChangedListener(object : TextWatcher {
438 override fun beforeTextChanged(s: CharSequence, start: Int, count: Int, after: Int) {
442 override fun onTextChanged(s: CharSequence, start: Int, before: Int, count: Int) {
446 override fun afterTextChanged(s: Editable) {
447 // Get the new domain name.
448 val newDomainName = domainNameEditText.text.toString()
450 // Check the saved SSL certificate against the new domain name.
451 val savedSslMatchesNewDomainName = checkDomainNameAgainstCertificate(newDomainName, savedSslIssuedToCNameString)
453 // Create a spannable string builder for the saved certificate's Common Name.
454 val savedSslCNameStringBuilder = SpannableStringBuilder(cNameLabel + savedSslIssuedToCNameString)
456 // Format the saved certificate's Common Name color. `SPAN_INCLUSIVE_INCLUSIVE` allows the span to grow in either direction.
457 if (savedSslMatchesNewDomainName) {
458 savedSslCNameStringBuilder.setSpan(blueColorSpan, cNameLabel.length, savedSslCNameStringBuilder.length, Spanned.SPAN_INCLUSIVE_INCLUSIVE)
460 savedSslCNameStringBuilder.setSpan(redColorSpan, cNameLabel.length, savedSslCNameStringBuilder.length, Spanned.SPAN_INCLUSIVE_INCLUSIVE)
463 // Update the saved SSL issued to CName text view.
464 savedSslIssuedToCNameTextView.text = savedSslCNameStringBuilder
466 // Update the current website certificate if it exists.
467 if (DomainsActivity.sslIssuedToCName != null) {
468 // Check the current website certificate against the new domain name.
469 val currentSslMatchesNewDomainName = checkDomainNameAgainstCertificate(newDomainName, DomainsActivity.sslIssuedToCName)
471 // Create a spannable string builder for the current website certificate's Common Name.
472 val currentSslCNameStringBuilder = SpannableStringBuilder(cNameLabel + DomainsActivity.sslIssuedToCName)
474 // Format the current certificate Common Name color. `SPAN_INCLUSIVE_INCLUSIVE` allows the span to grow in either direction.
475 if (currentSslMatchesNewDomainName) {
476 currentSslCNameStringBuilder.setSpan(blueColorSpan, cNameLabel.length, currentSslCNameStringBuilder.length, Spanned.SPAN_INCLUSIVE_INCLUSIVE)
478 currentSslCNameStringBuilder.setSpan(redColorSpan, cNameLabel.length, currentSslCNameStringBuilder.length, Spanned.SPAN_INCLUSIVE_INCLUSIVE)
481 // Update the current SSL issued to CName text view.
482 currentSslIssuedToCNameTextView.text = currentSslCNameStringBuilder
488 // Set the javaScript icon and text view settings.
489 when (javaScriptInt) {
492 if (javaScriptDefault)
493 javaScriptImageView.setImageDrawable(ResourcesCompat.getDrawable(resources, R.drawable.javascript_enabled, null))
495 javaScriptImageView.setImageDrawable(ResourcesCompat.getDrawable(resources, R.drawable.privacy_mode, null))
497 // Show the text view.
498 javaScriptTextView.visibility = View.VISIBLE
500 // Set the background color to be transparent.
501 javaScriptLinearLayout.setBackgroundColor(getColor(context, R.color.transparent))
506 javaScriptImageView.setImageDrawable(ResourcesCompat.getDrawable(resources, R.drawable.javascript_enabled, null))
508 // Hide the text view.
509 javaScriptTextView.visibility = View.GONE
511 // Set the background color to be blue.
512 javaScriptLinearLayout.setBackgroundColor(getColor(context, R.color.blue_background))
517 javaScriptImageView.setImageDrawable(ResourcesCompat.getDrawable(resources, R.drawable.privacy_mode, null))
519 // Hide the text view.
520 javaScriptTextView.visibility = View.GONE
522 // Set the background color to be blue.
523 javaScriptLinearLayout.setBackgroundColor(getColor(context, R.color.blue_background))
528 // Calculate if JavaScript is enabled, either because it is the system default and that default is enabled, or because it is explicitly set to be enabled for this domain.
529 val javaScriptEnabled = (((javaScriptInt == 0) && javaScriptDefault) || (javaScriptInt == 1))
531 // Set the DOM storage spinner and text view status based on the JavaScript status.
532 domStorageSpinner.isEnabled = javaScriptEnabled
533 domStorageTextView.isEnabled = javaScriptEnabled
535 // Set the DOM storage icon ghosted status based on the JavaScript status.
536 domStorageImageView.isEnabled = javaScriptEnabled
539 // Inflated a WebView to get the default user agent.
540 // `@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.
541 @SuppressLint("InflateParams") val bareWebViewLayout = inflater.inflate(R.layout.bare_webview, null, false)
543 // Get a handle for the bare WebView.
544 val bareWebView = bareWebViewLayout.findViewById<WebView>(R.id.bare_webview)
546 // Get the default user agent.
547 val webViewDefaultUserAgentString = bareWebView.settings.userAgentString
549 // Get a handle for the user agent array adapter. This array does not contain the `System default` entry.
550 val userAgentNamesArray = ArrayAdapter.createFromResource(context, R.array.user_agent_names, R.layout.spinner_item)
552 // Get the positions of the user agent and the default user agent.
553 val userAgentArrayPosition = userAgentNamesArray.getPosition(currentUserAgentName)
554 val defaultUserAgentArrayPosition = userAgentNamesArray.getPosition(userAgentDefault)
556 // Get a handle for the user agent data array. This array does not contain the `System default` entry.
557 val userAgentDataArray = resources.getStringArray(R.array.user_agent_data)
559 // Set the user agent text.
560 if (currentUserAgentName == getString(R.string.system_default_user_agent)) { // Use the system default user agent.
561 // Set the user agent according to the system default.
562 when (defaultUserAgentArrayPosition) {
563 // This is probably because it was set in an older version of Privacy Browser before the switch to persistent user agent names.
564 UNRECOGNIZED_USER_AGENT -> userAgentTextView.text = userAgentDefault
566 // Display the WebView default user agent.
567 SETTINGS_WEBVIEW_DEFAULT_USER_AGENT -> userAgentTextView.text = webViewDefaultUserAgentString
569 // Display the custom user agent.
570 SETTINGS_CUSTOM_USER_AGENT -> userAgentTextView.text = customUserAgentStringDefault
572 // Get the user agent string from the user agent data array.
573 else -> userAgentTextView.text = userAgentDataArray[defaultUserAgentArrayPosition]
576 // Set the background color to be transparent.
577 userAgentLinearLayout.setBackgroundColor(getColor(context, R.color.transparent))
578 } else if (userAgentArrayPosition == UNRECOGNIZED_USER_AGENT || currentUserAgentName == getString(R.string.custom_user_agent)) {
579 // A custom user agent is stored in the current user agent name. The second check is necessary in case the user did not change the default custom text.
580 // Set the user agent spinner to `Custom user agent`.
581 userAgentSpinner.setSelection(DOMAINS_CUSTOM_USER_AGENT)
583 // Hide the user agent text view.
584 userAgentTextView.visibility = View.GONE
586 // Show the custom user agent edit text and set the current user agent name as the text.
587 customUserAgentEditText.visibility = View.VISIBLE
588 customUserAgentEditText.setText(currentUserAgentName)
590 // Set the background color to be blue.
591 userAgentLinearLayout.setBackgroundColor(getColor(context, R.color.blue_background))
592 } else { // The user agent name contains one of the canonical user agents.
593 // 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.
594 userAgentSpinner.setSelection(userAgentArrayPosition + 1)
596 // Show the user agent text view.
597 userAgentTextView.visibility = View.VISIBLE
599 // Hide the custom user agent edit text.
600 customUserAgentEditText.visibility = View.GONE
602 // Set the user agent text.
603 if (userAgentArrayPosition == DOMAINS_WEBVIEW_DEFAULT_USER_AGENT) { // The WebView default user agent is selected.
604 // Display the WebView default user agent.
605 userAgentTextView.text = webViewDefaultUserAgentString
606 } else { // A user agent besides the default is selected.
607 // 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.
608 userAgentTextView.text = userAgentDataArray[userAgentArrayPosition + 1]
611 // Set the background color to be blue.
612 userAgentLinearLayout.setBackgroundColor(getColor(context, R.color.blue_background))
616 // Calculate if Fanboy's Annoyance List is enabled, either because it is the system default and that default is enabled, or because it is explicitly set to be enabled for this domain.
617 val fanboysAnnoyanceListEnabled = (((fanboysAnnoyanceListInt == 0) && fanboysAnnoyanceListDefault) || (fanboysAnnoyanceListInt == 1))
619 // Set Fanboy's Social Blocking List spinner and text view status based on the Annoyance List status.
620 fanboysSocialBlockingListSpinner.isEnabled = !fanboysAnnoyanceListEnabled
621 fanboysSocialBlockingListTextView.isEnabled = !fanboysAnnoyanceListEnabled
623 // Set the Social Blocking List icon ghosted status based on the Annoyance List status.
624 fanboysSocialBlockingListImageView.isEnabled = !fanboysAnnoyanceListEnabled
627 // Display the font size settings.
628 if (fontSizeInt == SYSTEM_DEFAULT) { // `0` is the code for system default font size.
629 // Set the font size to the system default.
630 fontSizeSpinner.setSelection(SYSTEM_DEFAULT)
632 // Show the default font size text view.
633 defaultFontSizeTextView.visibility = View.VISIBLE
635 // Hide the custom font size edit text.
636 customFontSizeEditText.visibility = View.GONE
638 // 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.
639 customFontSizeEditText.setText(fontSizeStringDefault)
641 // Set the background color to be transparent.
642 fontSizeLinearLayout.setBackgroundColor(getColor(context, R.color.transparent))
643 } else { // A custom font size is selected.
644 // Set the spinner to the custom font size.
645 fontSizeSpinner.setSelection(1)
647 // Hide the default font size text view.
648 defaultFontSizeTextView.visibility = View.GONE
650 // Show the custom font size edit text.
651 customFontSizeEditText.visibility = View.GONE
653 // Set the custom font size.
654 customFontSizeEditText.setText(fontSizeInt.toString())
656 // Set the background color to be blue.
657 fontSizeLinearLayout.setBackgroundColor(getColor(context, R.color.blue_background))
660 // Initialize the default font size percentage string.
661 val defaultFontSizePercentageString = "$fontSizeStringDefault%"
663 // Set the default font size text in the text view.
664 defaultFontSizeTextView.text = defaultFontSizePercentageString
667 // Get the WebView theme string arrays.
668 val webViewThemeStringArray = resources.getStringArray(R.array.webview_theme_array)
669 val webViewThemeEntryValuesStringArray = resources.getStringArray(R.array.webview_theme_entry_values)
671 // Get the WebView theme entry number that matches the current WebView theme string.
672 val appWebViewThemeEntryNumber = when (webViewThemeDefault) {
673 webViewThemeEntryValuesStringArray[1] -> { LIGHT_THEME } // The light theme is selected.
674 webViewThemeEntryValuesStringArray[2] -> { DARK_THEME } // The dark theme is selected.
675 else -> { SYSTEM_DEFAULT } // The system default theme is selected.
678 // Set the WebView theme text. This is only displayed if system default is selection, but it should be set here in case the user changes the selection.
679 if (appWebViewThemeEntryNumber == SYSTEM_DEFAULT) { // The app WebView theme is system default.
680 // Set the text according to the current UI theme.
681 if (currentThemeStatus == Configuration.UI_MODE_NIGHT_NO)
682 webViewThemeTextView.text = webViewThemeStringArray[LIGHT_THEME]
684 webViewThemeTextView.text = webViewThemeStringArray[DARK_THEME]
685 } else { // The app WebView theme is not system default.
686 // Set the text according to the app WebView theme.
687 webViewThemeTextView.text = webViewThemeStringArray[appWebViewThemeEntryNumber]
690 // Set the WebView theme icon and text visibility.
691 when (webViewThemeInt) {
693 // Set the icon color.
694 when (appWebViewThemeEntryNumber) {
695 SYSTEM_DEFAULT -> webViewThemeImageView.isSelected = (currentThemeStatus == Configuration.UI_MODE_NIGHT_NO)
696 LIGHT_THEME -> webViewThemeImageView.isSelected = true
697 DARK_THEME -> webViewThemeImageView.isSelected = false
700 // Show the WebView theme text view.
701 webViewThemeTextView.visibility = View.VISIBLE
703 // Set the background color to be transparent.
704 webViewThemeLinearLayout.setBackgroundColor(getColor(context, R.color.transparent))
708 // Set the icon color.
709 webViewThemeImageView.isSelected = true
711 // Hide the WebView theme text view.
712 webViewThemeTextView.visibility = View.GONE
714 // Set the background color to be blue.
715 webViewThemeLinearLayout.setBackgroundColor(getColor(context, R.color.blue_background))
719 // Set the icon color.
720 webViewThemeImageView.isSelected = false
722 // Hide the WebView theme text view.
723 webViewThemeTextView.visibility = View.GONE
725 // Set the background color to be blue.
726 webViewThemeLinearLayout.setBackgroundColor(getColor(context, R.color.blue_background))
731 // Set the switch positions.
732 pinnedSslCertificateSwitch.isChecked = (pinnedSslCertificateInt == 1)
733 pinnedIpAddressesSwitch.isChecked = (pinnedIpAddressesInt == 1)
735 // Set the switch icon colors.
736 pinnedSslCertificateImageView.isSelected = (pinnedSslCertificateInt == 1)
737 pinnedIpAddressesImageView.isSelected = (pinnedIpAddressesInt == 1)
739 // Store the current date.
740 val currentDate = Calendar.getInstance().time
742 // Create a spannable string builder for each text view that needs multiple colors of text.
743 val savedSslIssuedToCNameStringBuilder = SpannableStringBuilder(cNameLabel + savedSslIssuedToCNameString)
744 val savedSslIssuedToONameStringBuilder = SpannableStringBuilder(oNameLabel + savedSslIssuedToONameString)
745 val savedSslIssuedToUNameStringBuilder = SpannableStringBuilder(uNameLabel + savedSslIssuedToUNameString)
746 val savedSslIssuedByCNameStringBuilder = SpannableStringBuilder(cNameLabel + savedSslIssuedByCNameString)
747 val savedSslIssuedByONameStringBuilder = SpannableStringBuilder(oNameLabel + savedSslIssuedByONameString)
748 val savedSslIssuedByUNameStringBuilder = SpannableStringBuilder(uNameLabel + savedSslIssuedByUNameString)
750 // Initialize the saved SSL certificate date variables.
751 var savedSslStartDate: Date? = null
752 var savedSslEndDate: Date? = null
754 // Only get the saved SSL certificate dates from the cursor if they are not set to `0`.
755 if (savedSslStartDateLong != 0L)
756 savedSslStartDate = Date(savedSslStartDateLong)
757 if (savedSslEndDateLong != 0L)
758 savedSslEndDate = Date(savedSslEndDateLong)
760 // Create the date spannable string builders.
761 val savedSslStartDateStringBuilder: SpannableStringBuilder = if (savedSslStartDate == null)
762 SpannableStringBuilder(startDateLabel)
764 SpannableStringBuilder(startDateLabel + DateFormat.getDateTimeInstance(DateFormat.MEDIUM, DateFormat.LONG).format(savedSslStartDate))
766 val savedSslEndDateStringBuilder: SpannableStringBuilder = if (savedSslEndDate == null)
767 SpannableStringBuilder(endDateLabel)
769 SpannableStringBuilder(endDateLabel + DateFormat.getDateTimeInstance(DateFormat.MEDIUM, DateFormat.LONG).format(savedSslEndDate))
771 // Setup the string builders to display the general certificate information in blue. `SPAN_INCLUSIVE_INCLUSIVE` allows the span to grow in either direction.
772 savedSslIssuedToONameStringBuilder.setSpan(blueColorSpan, oNameLabel.length, savedSslIssuedToONameStringBuilder.length, Spanned.SPAN_INCLUSIVE_INCLUSIVE)
773 savedSslIssuedToUNameStringBuilder.setSpan(blueColorSpan, uNameLabel.length, savedSslIssuedToUNameStringBuilder.length, Spanned.SPAN_INCLUSIVE_INCLUSIVE)
774 savedSslIssuedByCNameStringBuilder.setSpan(blueColorSpan, cNameLabel.length, savedSslIssuedByCNameStringBuilder.length, Spanned.SPAN_INCLUSIVE_INCLUSIVE)
775 savedSslIssuedByONameStringBuilder.setSpan(blueColorSpan, oNameLabel.length, savedSslIssuedByONameStringBuilder.length, Spanned.SPAN_INCLUSIVE_INCLUSIVE)
776 savedSslIssuedByUNameStringBuilder.setSpan(blueColorSpan, uNameLabel.length, savedSslIssuedByUNameStringBuilder.length, Spanned.SPAN_INCLUSIVE_INCLUSIVE)
778 // Check the certificate Common Name against the domain name.
779 val savedSslCommonNameMatchesDomainName = checkDomainNameAgainstCertificate(domainNameString, savedSslIssuedToCNameString)
781 // Format the issued to Common Name color. `SPAN_INCLUSIVE_INCLUSIVE` allows the span to grow in either direction.
782 if (savedSslCommonNameMatchesDomainName)
783 savedSslIssuedToCNameStringBuilder.setSpan(blueColorSpan, cNameLabel.length, savedSslIssuedToCNameStringBuilder.length, Spanned.SPAN_INCLUSIVE_INCLUSIVE)
785 savedSslIssuedToCNameStringBuilder.setSpan(redColorSpan, cNameLabel.length, savedSslIssuedToCNameStringBuilder.length, Spanned.SPAN_INCLUSIVE_INCLUSIVE)
787 // Format the start date color. `SPAN_INCLUSIVE_INCLUSIVE` allows the span to grow in either direction.
788 if (savedSslStartDate != null && savedSslStartDate.after(currentDate)) // The certificate start date is in the future.
789 savedSslStartDateStringBuilder.setSpan(redColorSpan, startDateLabel.length, savedSslStartDateStringBuilder.length, Spanned.SPAN_INCLUSIVE_INCLUSIVE)
790 else // The certificate start date is in the past.
791 savedSslStartDateStringBuilder.setSpan(blueColorSpan, startDateLabel.length, savedSslStartDateStringBuilder.length, Spanned.SPAN_INCLUSIVE_INCLUSIVE)
793 // Format the end date color. `SPAN_INCLUSIVE_INCLUSIVE` allows the span to grow in either direction.
794 if (savedSslEndDate != null && savedSslEndDate.before(currentDate)) // The certificate end date is in the past.
795 savedSslEndDateStringBuilder.setSpan(redColorSpan, endDateLabel.length, savedSslEndDateStringBuilder.length, Spanned.SPAN_INCLUSIVE_INCLUSIVE)
796 else // The certificate end date is in the future.
797 savedSslEndDateStringBuilder.setSpan(blueColorSpan, endDateLabel.length, savedSslEndDateStringBuilder.length, Spanned.SPAN_INCLUSIVE_INCLUSIVE)
799 // Display the saved website SSL certificate strings.
800 savedSslIssuedToCNameTextView.text = savedSslIssuedToCNameStringBuilder
801 savedSslIssuedToONameTextView.text = savedSslIssuedToONameStringBuilder
802 savedSslIssuedToUNameTextView.text = savedSslIssuedToUNameStringBuilder
803 savedSslIssuedByCNameTextView.text = savedSslIssuedByCNameStringBuilder
804 savedSslIssuedByONameTextView.text = savedSslIssuedByONameStringBuilder
805 savedSslIssuedByUNameTextView.text = savedSslIssuedByUNameStringBuilder
806 savedSslStartDateTextView.text = savedSslStartDateStringBuilder
807 savedSslEndDateTextView.text = savedSslEndDateStringBuilder
809 // Populate the current website SSL certificate if there is one.
810 if (DomainsActivity.sslIssuedToCName != null) {
811 // Get dates from the raw long values.
812 val currentSslStartDate = Date(DomainsActivity.sslStartDateLong)
813 val currentSslEndDate = Date(DomainsActivity.sslEndDateLong)
815 // Create a spannable string builder for each text view that needs multiple colors of text.
816 val currentSslIssuedToCNameStringBuilder = SpannableStringBuilder(cNameLabel + DomainsActivity.sslIssuedToCName)
817 val currentSslIssuedToONameStringBuilder = SpannableStringBuilder(oNameLabel + DomainsActivity.sslIssuedToOName)
818 val currentSslIssuedToUNameStringBuilder = SpannableStringBuilder(uNameLabel + DomainsActivity.sslIssuedToUName)
819 val currentSslIssuedByCNameStringBuilder = SpannableStringBuilder(cNameLabel + DomainsActivity.sslIssuedByCName)
820 val currentSslIssuedByONameStringBuilder = SpannableStringBuilder(oNameLabel + DomainsActivity.sslIssuedByOName)
821 val currentSslIssuedByUNameStringBuilder = SpannableStringBuilder(uNameLabel + DomainsActivity.sslIssuedByUName)
822 val currentSslStartDateStringBuilder = SpannableStringBuilder(startDateLabel + DateFormat.getDateTimeInstance(DateFormat.MEDIUM, DateFormat.LONG).format(currentSslStartDate))
823 val currentSslEndDateStringBuilder = SpannableStringBuilder(endDateLabel + DateFormat.getDateTimeInstance(DateFormat.MEDIUM, DateFormat.LONG).format(currentSslEndDate))
825 // Setup the string builders to display the general certificate information in blue. `SPAN_INCLUSIVE_INCLUSIVE` allows the span to grow in either direction.
826 currentSslIssuedToONameStringBuilder.setSpan(blueColorSpan, oNameLabel.length, currentSslIssuedToONameStringBuilder.length, Spanned.SPAN_INCLUSIVE_INCLUSIVE)
827 currentSslIssuedToUNameStringBuilder.setSpan(blueColorSpan, uNameLabel.length, currentSslIssuedToUNameStringBuilder.length, Spanned.SPAN_INCLUSIVE_INCLUSIVE)
828 currentSslIssuedByCNameStringBuilder.setSpan(blueColorSpan, cNameLabel.length, currentSslIssuedByCNameStringBuilder.length, Spanned.SPAN_INCLUSIVE_INCLUSIVE)
829 currentSslIssuedByONameStringBuilder.setSpan(blueColorSpan, oNameLabel.length, currentSslIssuedByONameStringBuilder.length, Spanned.SPAN_INCLUSIVE_INCLUSIVE)
830 currentSslIssuedByUNameStringBuilder.setSpan(blueColorSpan, uNameLabel.length, currentSslIssuedByUNameStringBuilder.length, Spanned.SPAN_INCLUSIVE_INCLUSIVE)
832 // Check the certificate Common Name against the domain name.
833 val currentSslCommonNameMatchesDomainName = checkDomainNameAgainstCertificate(domainNameString, DomainsActivity.sslIssuedToCName)
835 // Format the issued to Common Name color. `SPAN_INCLUSIVE_INCLUSIVE` allows the span to grow in either direction.
836 if (currentSslCommonNameMatchesDomainName)
837 currentSslIssuedToCNameStringBuilder.setSpan(blueColorSpan, cNameLabel.length, currentSslIssuedToCNameStringBuilder.length, Spanned.SPAN_INCLUSIVE_INCLUSIVE)
839 currentSslIssuedToCNameStringBuilder.setSpan(redColorSpan, cNameLabel.length, currentSslIssuedToCNameStringBuilder.length, Spanned.SPAN_INCLUSIVE_INCLUSIVE)
841 // Format the start date color. `SPAN_INCLUSIVE_INCLUSIVE` allows the span to grow in either direction.
842 if (currentSslStartDate.after(currentDate)) // The certificate start date is in the future.
843 currentSslStartDateStringBuilder.setSpan(redColorSpan, startDateLabel.length, currentSslStartDateStringBuilder.length, Spanned.SPAN_INCLUSIVE_INCLUSIVE)
844 else // The certificate start date is in the past.
845 currentSslStartDateStringBuilder.setSpan(blueColorSpan, startDateLabel.length, currentSslStartDateStringBuilder.length, Spanned.SPAN_INCLUSIVE_INCLUSIVE)
847 // Format the end date color. `SPAN_INCLUSIVE_INCLUSIVE` allows the span to grow in either direction.
848 if (currentSslEndDate.before(currentDate)) // The certificate end date is in the past.
849 currentSslEndDateStringBuilder.setSpan(redColorSpan, endDateLabel.length, currentSslEndDateStringBuilder.length, Spanned.SPAN_INCLUSIVE_INCLUSIVE)
850 else // The certificate end date is in the future.
851 currentSslEndDateStringBuilder.setSpan(blueColorSpan, endDateLabel.length, currentSslEndDateStringBuilder.length, Spanned.SPAN_INCLUSIVE_INCLUSIVE)
853 // Display the current website SSL certificate strings.
854 currentSslIssuedToCNameTextView.text = currentSslIssuedToCNameStringBuilder
855 currentSslIssuedToONameTextView.text = currentSslIssuedToONameStringBuilder
856 currentSslIssuedToUNameTextView.text = currentSslIssuedToUNameStringBuilder
857 currentSslIssuedByCNameTextView.text = currentSslIssuedByCNameStringBuilder
858 currentSslIssuedByONameTextView.text = currentSslIssuedByONameStringBuilder
859 currentSslIssuedByUNameTextView.text = currentSslIssuedByUNameStringBuilder
860 currentSslStartDateTextView.text = currentSslStartDateStringBuilder
861 currentSslEndDateTextView.text = currentSslEndDateStringBuilder
864 // Set the initial display status of the SSL certificates card views.
865 if (pinnedSslCertificateSwitch.isChecked) { // An SSL certificate is pinned.
866 // Set the visibility of the saved SSL certificate.
867 if (savedSslIssuedToCNameString == null)
868 savedSslCardView.visibility = View.GONE
870 savedSslCardView.visibility = View.VISIBLE
872 // Set the visibility of the current website SSL certificate.
873 if (DomainsActivity.sslIssuedToCName == null) { // There is no current SSL certificate.
874 // Hide the SSL certificate.
875 currentSslCardView.visibility = View.GONE
877 // Show the instruction.
878 noCurrentWebsiteCertificateTextView.visibility = View.VISIBLE
879 } else { // There is a current SSL certificate.
880 // Show the SSL certificate.
881 currentSslCardView.visibility = View.VISIBLE
883 // Hide the instruction.
884 noCurrentWebsiteCertificateTextView.visibility = View.GONE
887 // Set the status of the radio buttons and the card view backgrounds.
888 if (savedSslCardView.visibility == View.VISIBLE) { // The saved SSL certificate is displayed.
889 // Check the saved SSL certificate radio button.
890 savedSslCertificateRadioButton.isChecked = true
892 // Uncheck the current website SSL certificate radio button.
893 currentWebsiteCertificateRadioButton.isChecked = false
895 // Darken the background of the current website SSL certificate linear layout.
896 currentWebsiteCertificateLinearLayout.setBackgroundResource(R.color.translucent_background)
897 } else if (currentSslCardView.visibility == View.VISIBLE) { // The saved SSL certificate is hidden but the current website SSL certificate is visible.
898 // Check the current website SSL certificate radio button.
899 currentWebsiteCertificateRadioButton.isChecked = true
901 // Uncheck the saved SSL certificate radio button.
902 savedSslCertificateRadioButton.isChecked = false
903 } else { // Neither SSL certificate is visible.
904 // Uncheck both radio buttons.
905 savedSslCertificateRadioButton.isChecked = false
906 currentWebsiteCertificateRadioButton.isChecked = false
908 } else { // An SSL certificate is not pinned.
909 // Hide the SSl certificates and instructions.
910 savedSslCardView.visibility = View.GONE
911 currentSslCardView.visibility = View.GONE
912 noCurrentWebsiteCertificateTextView.visibility = View.GONE
914 // Uncheck the radio buttons.
915 savedSslCertificateRadioButton.isChecked = false
916 currentWebsiteCertificateRadioButton.isChecked = false
919 // Populate the saved and current IP addresses.
920 savedIpAddressesTextView.text = savedIpAddresses
921 currentIpAddressesTextView.text = DomainsActivity.currentIpAddresses
923 // Set the initial display status of the IP addresses card views.
924 if (pinnedIpAddressesSwitch.isChecked) { // IP addresses are pinned.
925 // Set the visibility of the saved IP addresses.
926 if (savedIpAddresses == null) // There are no saved IP addresses.
927 savedIpAddressesCardView.visibility = View.GONE
928 else // There are saved IP addresses.
929 savedIpAddressesCardView.visibility = View.VISIBLE
931 // Set the visibility of the current IP addresses.
932 currentIpAddressesCardView.visibility = View.VISIBLE
934 // Set the status of the radio buttons and the card view backgrounds.
935 if (savedIpAddressesCardView.visibility == View.VISIBLE) { // The saved IP addresses are displayed.
936 // Check the saved IP addresses radio button.
937 savedIpAddressesRadioButton.isChecked = true
939 // Uncheck the current IP addresses radio button.
940 currentIpAddressesRadioButton.isChecked = false
942 // Darken the background of the current IP addresses linear layout.
943 currentIpAddressesLinearLayout.setBackgroundResource(R.color.translucent_background)
944 } else { // The saved IP addresses are hidden.
945 // Check the current IP addresses radio button.
946 currentIpAddressesRadioButton.isChecked = true
948 // Uncheck the saved IP addresses radio button.
949 savedIpAddressesRadioButton.isChecked = false
951 } else { // IP addresses are not pinned.
952 // Hide the IP addresses card views.
953 savedIpAddressesCardView.visibility = View.GONE
954 currentIpAddressesCardView.visibility = View.GONE
956 // Uncheck the radio buttons.
957 savedIpAddressesRadioButton.isChecked = false
958 currentIpAddressesRadioButton.isChecked = false
962 // Set the JavaScript spinner listener.
963 javaScriptSpinner.onItemSelectedListener = object : AdapterView.OnItemSelectedListener {
964 override fun onItemSelected(parent: AdapterView<*>?, view: View?, position: Int, id: Long) {
968 if (javaScriptDefault)
969 javaScriptImageView.setImageDrawable(ResourcesCompat.getDrawable(resources, R.drawable.javascript_enabled, null))
971 javaScriptImageView.setImageDrawable(ResourcesCompat.getDrawable(resources, R.drawable.privacy_mode, null))
973 // Show the text view.
974 javaScriptTextView.visibility = View.VISIBLE
976 // Set the background color to be transparent.
977 javaScriptLinearLayout.setBackgroundColor(getColor(context, R.color.transparent))
982 javaScriptImageView.setImageDrawable(ResourcesCompat.getDrawable(resources, R.drawable.javascript_enabled, null))
984 // Hide the text view.
985 javaScriptTextView.visibility = View.GONE
987 // Set the background color to be blue.
988 javaScriptLinearLayout.setBackgroundColor(getColor(context, R.color.blue_background))
993 javaScriptImageView.setImageDrawable(ResourcesCompat.getDrawable(resources, R.drawable.privacy_mode, null))
995 // Hide the text view.
996 javaScriptTextView.visibility = View.GONE
998 // Set the background color to be blue.
999 javaScriptLinearLayout.setBackgroundColor(getColor(context, R.color.blue_background))
1003 // Calculate if JavaScript is enabled, either because it is the system default and that default is enabled, or because it is explicitly set to be enabled for this domain.
1004 val updatedJavaScriptEnabled = (((position == 0) && javaScriptDefault) || (position == 1))
1006 // Set the DOM storage spinner and text view status based on the JavaScript status.
1007 domStorageSpinner.isEnabled = updatedJavaScriptEnabled
1008 domStorageTextView.isEnabled = updatedJavaScriptEnabled
1010 // Set the DOM storage icon ghosted status based on the JavaScript status.
1011 domStorageImageView.isEnabled = updatedJavaScriptEnabled
1014 override fun onNothingSelected(parent: AdapterView<*>?) {
1019 // Set the cookies switch listener.
1020 cookiesSpinner.onItemSelectedListener = object : AdapterView.OnItemSelectedListener {
1021 override fun onItemSelected(parent: AdapterView<*>?, view: View?, position: Int, id: Long) {
1022 // Update the icon and the text view settings.
1023 setIconAndTextViewSettings(position, cookiesDefault, cookiesLinearLayout, cookiesImageView, cookiesTextView)
1026 override fun onNothingSelected(parent: AdapterView<*>?) {
1031 // Set the DOM Storage spinner listener.
1032 domStorageSpinner.onItemSelectedListener = object : AdapterView.OnItemSelectedListener {
1033 override fun onItemSelected(parent: AdapterView<*>?, view: View?, position: Int, id: Long) {
1034 // Update the icon and the text view settings.
1035 setIconAndTextViewSettings(position, domStorageDefault, domStorageLinearLayout, domStorageImageView, domStorageTextView)
1038 override fun onNothingSelected(parent: AdapterView<*>?) {
1043 // Set the user agent spinner listener.
1044 userAgentSpinner.onItemSelectedListener = object : AdapterView.OnItemSelectedListener {
1045 override fun onItemSelected(parent: AdapterView<*>?, view: View?, position: Int, id: Long) {
1046 // Set the new user agent.
1048 DOMAINS_SYSTEM_DEFAULT_USER_AGENT -> {
1049 // Show the user agent text view.
1050 userAgentTextView.visibility = View.VISIBLE
1052 // Hide the custom user agent edit text.
1053 customUserAgentEditText.visibility = View.GONE
1055 // Set the user text.
1056 when (defaultUserAgentArrayPosition) {
1057 // This is probably because it was set in an older version of Privacy Browser before the switch to persistent user agent names.
1058 UNRECOGNIZED_USER_AGENT -> userAgentTextView.text = userAgentDefault
1060 // Display the `WebView` default user agent.
1061 SETTINGS_WEBVIEW_DEFAULT_USER_AGENT -> userAgentTextView.text = webViewDefaultUserAgentString
1063 // Display the custom user agent.
1064 SETTINGS_CUSTOM_USER_AGENT -> userAgentTextView.text = customUserAgentStringDefault
1066 // Get the user agent string from the user agent data array.
1067 else -> userAgentTextView.text = userAgentDataArray[defaultUserAgentArrayPosition]
1070 // Set the background color to be transparent.
1071 userAgentLinearLayout.setBackgroundColor(getColor(context, R.color.transparent))
1074 DOMAINS_WEBVIEW_DEFAULT_USER_AGENT -> {
1075 // Show the user agent text view.
1076 userAgentTextView.visibility = View.VISIBLE
1078 // Set the user agent text.
1079 userAgentTextView.text = webViewDefaultUserAgentString
1081 // Hide the custom user agent edit text.
1082 customUserAgentEditText.visibility = View.GONE
1084 // Set the background color to be blue.
1085 userAgentLinearLayout.setBackgroundColor(getColor(context, R.color.blue_background))
1088 DOMAINS_CUSTOM_USER_AGENT -> {
1089 // Hide the user agent text view.
1090 userAgentTextView.visibility = View.GONE
1092 // Show the custom user agent edit text.
1093 customUserAgentEditText.visibility = View.VISIBLE
1095 // Set the current user agent name as the text.
1096 customUserAgentEditText.setText(currentUserAgentName)
1098 // Set the background color to be blue.
1099 userAgentLinearLayout.setBackgroundColor(getColor(context, R.color.blue_background))
1103 // Show the user agent text view.
1104 userAgentTextView.visibility = View.VISIBLE
1106 // Set the text from the user agent data array, which has one less entry than the spinner, so the position must be decremented.
1107 userAgentTextView.text = userAgentDataArray[position - 1]
1109 // Hide the custom user agent edit text.
1110 customUserAgentEditText.visibility = View.GONE
1112 // Set the background color to be blue.
1113 userAgentLinearLayout.setBackgroundColor(getColor(context, R.color.blue_background))
1118 override fun onNothingSelected(parent: AdapterView<*>?) {
1123 // Set the EasyList spinner listener.
1124 easyListSpinner.onItemSelectedListener = object : AdapterView.OnItemSelectedListener {
1125 override fun onItemSelected(parent: AdapterView<*>?, view: View?, position: Int, id: Long) {
1126 // Update the icon and the text view settings.
1127 setIconAndTextViewSettings(position, easyListDefault, easyListLinearLayout, easyListImageView, easyListTextView)
1130 override fun onNothingSelected(parent: AdapterView<*>?) {
1135 // Set the EasyPrivacy spinner listener.
1136 easyPrivacySpinner.onItemSelectedListener = object : AdapterView.OnItemSelectedListener {
1137 override fun onItemSelected(parent: AdapterView<*>?, view: View?, position: Int, id: Long) {
1138 // Update the icon and the text view settings.
1139 setIconAndTextViewSettings(position, easyPrivacyDefault, easyPrivacyLinearLayout, easyPrivacyImageView, easyPrivacyTextView)
1142 override fun onNothingSelected(parent: AdapterView<*>?) {
1147 // Set the Fanboy's Annoyance List spinner listener.
1148 fanboysAnnoyanceListSpinner.onItemSelectedListener = object : AdapterView.OnItemSelectedListener {
1149 override fun onItemSelected(parent: AdapterView<*>?, view: View?, position: Int, id: Long) {
1150 // Update the icon and the text view settings.
1151 setIconAndTextViewSettings(position, fanboysAnnoyanceListDefault, fanboysAnnoyanceListLinearLayout, fanboysAnnoyanceListImageView, fanboysAnnoyanceListTextView)
1153 // Calculate if Fanboy's Annoyance List is enabled, either because it is the system default and that default is enabled, or because it is explicitly set to be enabled for this domain.
1154 val updatedFanboysAnnoyanceListEnabled = (((position == 0) && fanboysAnnoyanceListDefault) || (position == 1))
1156 // Set Fanboy's Social Blocking List spinner and test view status based on the Annoyance List status.
1157 fanboysSocialBlockingListSpinner.isEnabled = !updatedFanboysAnnoyanceListEnabled
1158 fanboysSocialBlockingListTextView.isEnabled = !updatedFanboysAnnoyanceListEnabled
1160 // Set the Social Blocking List icon ghosted status based on the Annoyance List status.
1161 fanboysSocialBlockingListImageView.isEnabled = !updatedFanboysAnnoyanceListEnabled
1164 override fun onNothingSelected(parent: AdapterView<*>?) {
1169 // Set the Fanboy's Social Blocking List spinner listener.
1170 fanboysSocialBlockingListSpinner.onItemSelectedListener = object : AdapterView.OnItemSelectedListener {
1171 override fun onItemSelected(parent: AdapterView<*>?, view: View?, position: Int, id: Long) {
1172 // Update the icon and the text view settings.
1173 setIconAndTextViewSettings(position, fanboysSocialBlockingListDefault, fanboysSocialBlockingListLinearLayout, fanboysSocialBlockingListImageView, fanboysSocialBlockingListTextView)
1176 override fun onNothingSelected(parent: AdapterView<*>?) {
1181 // Set the UltraList spinner listener.
1182 ultraListSpinner.onItemSelectedListener = object : AdapterView.OnItemSelectedListener {
1183 override fun onItemSelected(parent: AdapterView<*>?, view: View?, position: Int, id: Long) {
1184 // Update the icon and the text view settings.
1185 setIconAndTextViewSettings(position, ultraListDefault, ultraListLinearLayout, ultraListImageView, ultraListTextView)
1188 override fun onNothingSelected(parent: AdapterView<*>?) {
1193 // Set the UltraPrivacy spinner listener.
1194 ultraPrivacySpinner.onItemSelectedListener = object : AdapterView.OnItemSelectedListener {
1195 override fun onItemSelected(parent: AdapterView<*>?, view: View?, position: Int, id: Long) {
1196 // Update the icon and the text view settings.
1197 setIconAndTextViewSettings(position, ultraPrivacyDefault, ultraPrivacyLinearLayout, ultraPrivacyImageView, ultraPrivacyTextView)
1200 override fun onNothingSelected(parent: AdapterView<*>?) {
1205 // Set the block all third-party requests spinner listener.
1206 blockAllThirdPartyRequestsSpinner.onItemSelectedListener = object : AdapterView.OnItemSelectedListener {
1207 override fun onItemSelected(parent: AdapterView<*>?, view: View?, position: Int, id: Long) {
1208 // Update the icon and the text view settings.
1209 setIconAndTextViewSettings(position, blockAllThirdPartyRequestsDefault, blockAllThirdPartyRequestsLinearLayout, blockAllThirdPartyRequestsImageView, blockAllThirdPartyRequestsTextView)
1212 override fun onNothingSelected(parent: AdapterView<*>?) {
1217 // Set the font size spinner listener.
1218 fontSizeSpinner.onItemSelectedListener = object : AdapterView.OnItemSelectedListener {
1219 override fun onItemSelected(parent: AdapterView<*>?, view: View?, position: Int, id: Long) {
1220 // Update the font size display options.
1221 if (position == SYSTEM_DEFAULT) { // The system default font size has been selected.
1222 // Show the default font size text view.
1223 defaultFontSizeTextView.visibility = View.VISIBLE
1225 // Hide the custom font size edit text.
1226 customFontSizeEditText.visibility = View.GONE
1228 // Set the background color to be transparent.
1229 fontSizeLinearLayout.setBackgroundColor(getColor(context, R.color.transparent))
1230 } else { // A custom font size has been selected.
1231 // Hide the default font size text view.
1232 defaultFontSizeTextView.visibility = View.GONE
1234 // Show the custom font size edit text.
1235 customFontSizeEditText.visibility = View.VISIBLE
1237 // Set the background color to be blue.
1238 fontSizeLinearLayout.setBackgroundColor(getColor(context, R.color.blue_background))
1242 override fun onNothingSelected(parent: AdapterView<*>?) {
1247 // Set the swipe-to-refresh spinner listener.
1248 swipeToRefreshSpinner.onItemSelectedListener = object : AdapterView.OnItemSelectedListener {
1249 override fun onItemSelected(parent: AdapterView<*>?, view: View?, position: Int, id: Long) {
1250 // Update the icon and the text view settings.
1251 setIconAndTextViewSettings(position, swipeToRefreshDefault, swipeToRefreshLinearLayout, swipeToRefreshImageView, swipeToRefreshTextView)
1254 override fun onNothingSelected(parent: AdapterView<*>?) {
1259 // Set the WebView theme spinner listener.
1260 webViewThemeSpinner.onItemSelectedListener = object : AdapterView.OnItemSelectedListener {
1261 override fun onItemSelected(parent: AdapterView<*>?, view: View?, position: Int, id: Long) {
1262 // Update the icon and the WebView theme text view settings.
1265 // Set the icon color.
1266 when (appWebViewThemeEntryNumber) {
1267 SYSTEM_DEFAULT -> webViewThemeImageView.isSelected = (currentThemeStatus == Configuration.UI_MODE_NIGHT_NO)
1268 LIGHT_THEME -> webViewThemeImageView.isSelected = true
1269 DARK_THEME -> webViewThemeImageView.isSelected = false
1272 // Show the WebView theme text view.
1273 webViewThemeTextView.visibility = View.VISIBLE
1275 // Set the background color to be transparent.
1276 webViewThemeLinearLayout.setBackgroundColor(getColor(context, R.color.transparent))
1280 // Set the icon color.
1281 webViewThemeImageView.isSelected = true
1283 // Hide the WebView theme text view.
1284 webViewThemeTextView.visibility = View.GONE
1286 // Set the background color to be blue.
1287 webViewThemeLinearLayout.setBackgroundColor(getColor(context, R.color.blue_background))
1291 // Set the icon color.
1292 webViewThemeImageView.isSelected = false
1294 // Hide the WebView theme text view.
1295 webViewThemeTextView.visibility = View.GONE
1297 // Set the background color to be blue.
1298 webViewThemeLinearLayout.setBackgroundColor(getColor(context, R.color.blue_background))
1303 override fun onNothingSelected(parent: AdapterView<*>?) {
1308 // Set the wide viewport spinner listener.
1309 wideViewportSpinner.onItemSelectedListener = object : AdapterView.OnItemSelectedListener {
1310 override fun onItemSelected(parent: AdapterView<*>?, view: View?, position: Int, id: Long) {
1311 // Update the icon and the text view settings.
1312 setIconAndTextViewSettings(position, wideViewportDefault, wideViewportLinearLayout, wideViewportImageView, wideViewportTextView)
1315 override fun onNothingSelected(parent: AdapterView<*>?) {
1320 // Set the display webpage images spinner listener.
1321 displayImagesSpinner.onItemSelectedListener = object : AdapterView.OnItemSelectedListener {
1322 override fun onItemSelected(parent: AdapterView<*>?, view: View?, position: Int, id: Long) {
1323 // Update the icon and the text view settings.
1324 setIconAndTextViewSettings(position, displayWebpageImagesDefault, displayImagesLinearLayout, displayImagesImageView, displayImagesTextView)
1327 override fun onNothingSelected(parent: AdapterView<*>?) {
1332 // Set the pinned SSL certificate switch listener.
1333 pinnedSslCertificateSwitch.setOnCheckedChangeListener { _: CompoundButton?, isChecked: Boolean ->
1334 // Update the icon color.
1335 pinnedSslCertificateImageView.isSelected = isChecked
1337 // Update the views.
1338 if (isChecked) { // SSL certificate pinning is enabled.
1339 // Update the visibility of the saved SSL certificate.
1340 if (savedSslIssuedToCNameString == null)
1341 savedSslCardView.visibility = View.GONE
1343 savedSslCardView.visibility = View.VISIBLE
1345 // Update the visibility of the current website SSL certificate.
1346 if (DomainsActivity.sslIssuedToCName == null) {
1347 // Hide the SSL certificate.
1348 currentSslCardView.visibility = View.GONE
1350 // Show the instruction.
1351 noCurrentWebsiteCertificateTextView.visibility = View.VISIBLE
1353 // Show the SSL certificate.
1354 currentSslCardView.visibility = View.VISIBLE
1356 // Hide the instruction.
1357 noCurrentWebsiteCertificateTextView.visibility = View.GONE
1360 // Set the status of the radio buttons.
1361 if (savedSslCardView.visibility == View.VISIBLE) { // The saved SSL certificate is displayed.
1362 // Check the saved SSL certificate radio button.
1363 savedSslCertificateRadioButton.isChecked = true
1365 // Uncheck the current website SSL certificate radio button.
1366 currentWebsiteCertificateRadioButton.isChecked = false
1368 // Set the background of the saved SSL certificate linear layout to be transparent.
1369 savedSslCertificateLinearLayout.setBackgroundResource(R.color.transparent)
1371 // Darken the background of the current website SSL certificate linear layout according to the theme.
1372 currentWebsiteCertificateLinearLayout.setBackgroundResource(R.color.translucent_background)
1374 // Scroll to the current website SSL certificate card.
1375 savedSslCardView.parent.requestChildFocus(savedSslCardView, savedSslCardView)
1376 } else if (currentSslCardView.visibility == View.VISIBLE) { // The saved SSL certificate is hidden but the current website SSL certificate is visible.
1377 // Check the current website SSL certificate radio button.
1378 currentWebsiteCertificateRadioButton.isChecked = true
1380 // Uncheck the saved SSL certificate radio button.
1381 savedSslCertificateRadioButton.isChecked = false
1383 // Set the background of the current website SSL certificate linear layout to be transparent.
1384 currentWebsiteCertificateLinearLayout.setBackgroundResource(R.color.transparent)
1386 // Darken the background of the saved SSL certificate linear layout according to the theme.
1387 savedSslCertificateLinearLayout.setBackgroundResource(R.color.translucent_background)
1389 // Scroll to the current website SSL certificate card.
1390 currentSslCardView.parent.requestChildFocus(currentSslCardView, currentSslCardView)
1391 } else { // Neither SSL certificate is visible.
1392 // Uncheck both radio buttons.
1393 savedSslCertificateRadioButton.isChecked = false
1394 currentWebsiteCertificateRadioButton.isChecked = false
1396 // Scroll to the current website SSL certificate card.
1397 noCurrentWebsiteCertificateTextView.parent.requestChildFocus(noCurrentWebsiteCertificateTextView, noCurrentWebsiteCertificateTextView)
1399 } else { // SSL certificate pinning is disabled.
1400 // Hide the SSl certificates and instructions.
1401 savedSslCardView.visibility = View.GONE
1402 currentSslCardView.visibility = View.GONE
1403 noCurrentWebsiteCertificateTextView.visibility = View.GONE
1405 // Uncheck the radio buttons.
1406 savedSslCertificateRadioButton.isChecked = false
1407 currentWebsiteCertificateRadioButton.isChecked = false
1411 // Set the saved SSL card view listener.
1412 savedSslCardView.setOnClickListener {
1413 // Check the saved SSL certificate radio button.
1414 savedSslCertificateRadioButton.isChecked = true
1416 // Uncheck the current website SSL certificate radio button.
1417 currentWebsiteCertificateRadioButton.isChecked = false
1419 // Set the background of the saved SSL certificate linear layout to be transparent.
1420 savedSslCertificateLinearLayout.setBackgroundResource(R.color.transparent)
1422 // Darken the background of the current website SSL certificate linear layout.
1423 currentWebsiteCertificateLinearLayout.setBackgroundResource(R.color.translucent_background)
1426 // Set the saved SSL certificate radio button listener.
1427 savedSslCertificateRadioButton.setOnClickListener {
1428 // Check the saved SSL certificate radio button.
1429 savedSslCertificateRadioButton.isChecked = true
1431 // Uncheck the current website SSL certificate radio button.
1432 currentWebsiteCertificateRadioButton.isChecked = false
1434 // Set the background of the saved SSL certificate linear layout to be transparent.
1435 savedSslCertificateLinearLayout.setBackgroundResource(R.color.transparent)
1437 // Darken the background of the current website SSL certificate linear layout.
1438 currentWebsiteCertificateLinearLayout.setBackgroundResource(R.color.translucent_background)
1441 // Set the current SSL card view listener.
1442 currentSslCardView.setOnClickListener {
1443 // Check the current website SSL certificate radio button.
1444 currentWebsiteCertificateRadioButton.isChecked = true
1446 // Uncheck the saved SSL certificate radio button.
1447 savedSslCertificateRadioButton.isChecked = false
1449 // Set the background of the current website SSL certificate linear layout to be transparent.
1450 currentWebsiteCertificateLinearLayout.setBackgroundResource(R.color.transparent)
1452 // Darken the background of the saved SSL certificate linear layout.
1453 savedSslCertificateLinearLayout.setBackgroundResource(R.color.translucent_background)
1456 // Set the current website certificate radio button listener.
1457 currentWebsiteCertificateRadioButton.setOnClickListener {
1458 // Check the current website SSL certificate radio button.
1459 currentWebsiteCertificateRadioButton.isChecked = true
1461 // Uncheck the saved SSL certificate radio button.
1462 savedSslCertificateRadioButton.isChecked = false
1464 // Set the background of the current website SSL certificate linear layout to be transparent.
1465 currentWebsiteCertificateLinearLayout.setBackgroundResource(R.color.transparent)
1467 // Darken the background of the saved SSL certificate linear layout.
1468 savedSslCertificateLinearLayout.setBackgroundResource(R.color.translucent_background)
1471 // Set the pinned IP addresses switch listener.
1472 pinnedIpAddressesSwitch.setOnCheckedChangeListener { _: CompoundButton?, isChecked: Boolean ->
1473 // Update the icon color.
1474 pinnedIpAddressesImageView.isSelected = isChecked
1476 // Update the views.
1477 if (isChecked) { // IP addresses pinning is enabled.
1478 // Update the visibility of the saved IP addresses card view.
1479 if (savedIpAddresses == null)
1480 savedIpAddressesCardView.visibility = View.GONE
1482 savedIpAddressesCardView.visibility = View.VISIBLE
1484 // Show the current IP addresses card view.
1485 currentIpAddressesCardView.visibility = View.VISIBLE
1487 // Set the status of the radio buttons.
1488 if (savedIpAddressesCardView.visibility == View.VISIBLE) { // The saved IP addresses are visible.
1489 // Check the saved IP addresses radio button.
1490 savedIpAddressesRadioButton.isChecked = true
1492 // Uncheck the current IP addresses radio button.
1493 currentIpAddressesRadioButton.isChecked = false
1495 // Set the background of the saved IP addresses linear layout to be transparent.
1496 savedSslCertificateLinearLayout.setBackgroundResource(R.color.transparent)
1498 // Darken the background of the current IP addresses linear layout.
1499 currentIpAddressesLinearLayout.setBackgroundResource(R.color.translucent_background)
1500 } else { // The saved IP addresses are not visible.
1501 // Check the current IP addresses radio button.
1502 currentIpAddressesRadioButton.isChecked = true
1504 // Uncheck the saved IP addresses radio button.
1505 savedIpAddressesRadioButton.isChecked = false
1507 // Set the background of the current IP addresses linear layout to be transparent.
1508 currentIpAddressesLinearLayout.setBackgroundResource(R.color.transparent)
1510 // Darken the background of the saved IP addresses linear layout.
1511 savedIpAddressesLinearLayout.setBackgroundResource(R.color.translucent_background)
1514 // Scroll to the bottom of the card views.
1515 currentIpAddressesCardView.parent.requestChildFocus(currentIpAddressesCardView, currentIpAddressesCardView)
1516 } else { // IP addresses pinning is disabled.
1517 // Hide the IP addresses card views.
1518 savedIpAddressesCardView.visibility = View.GONE
1519 currentIpAddressesCardView.visibility = View.GONE
1521 // Uncheck the radio buttons.
1522 savedIpAddressesRadioButton.isChecked = false
1523 currentIpAddressesRadioButton.isChecked = false
1527 // Set the saved IP addresses card view listener.
1528 savedIpAddressesCardView.setOnClickListener {
1529 // Check the saved IP addresses radio button.
1530 savedIpAddressesRadioButton.isChecked = true
1532 // Uncheck the current website IP addresses radio button.
1533 currentIpAddressesRadioButton.isChecked = false
1535 // Set the background of the saved IP addresses linear layout to be transparent.
1536 savedIpAddressesLinearLayout.setBackgroundResource(R.color.transparent)
1538 // Darken the background of the current IP addresses linear layout.
1539 currentIpAddressesLinearLayout.setBackgroundResource(R.color.translucent_background)
1542 // Set the saved IP addresses radio button listener.
1543 savedIpAddressesRadioButton.setOnClickListener {
1544 // Check the saved IP addresses radio button.
1545 savedIpAddressesRadioButton.isChecked = true
1547 // Uncheck the current website IP addresses radio button.
1548 currentIpAddressesRadioButton.isChecked = false
1550 // Set the background of the saved IP addresses linear layout to be transparent.
1551 savedIpAddressesLinearLayout.setBackgroundResource(R.color.transparent)
1553 // Darken the background of the current IP addresses linear layout.
1554 currentIpAddressesLinearLayout.setBackgroundResource(R.color.translucent_background)
1557 // Set the current IP addresses card view listener.
1558 currentIpAddressesCardView.setOnClickListener {
1559 // Check the current IP addresses radio button.
1560 currentIpAddressesRadioButton.isChecked = true
1562 // Uncheck the saved IP addresses radio button.
1563 savedIpAddressesRadioButton.isChecked = false
1565 // Set the background of the current IP addresses linear layout to be transparent.
1566 currentIpAddressesLinearLayout.setBackgroundResource(R.color.transparent)
1568 // Darken the background of the saved IP addresses linear layout.
1569 savedIpAddressesLinearLayout.setBackgroundResource(R.color.translucent_background)
1572 // Set the current IP addresses radio button listener.
1573 currentIpAddressesRadioButton.setOnClickListener {
1574 // Check the current IP addresses radio button.
1575 currentIpAddressesRadioButton.isChecked = true
1577 // Uncheck the saved IP addresses radio button.
1578 savedIpAddressesRadioButton.isChecked = false
1580 // Set the background of the current IP addresses linear layout to be transparent.
1581 currentIpAddressesLinearLayout.setBackgroundResource(R.color.transparent)
1583 // Darken the background of the saved IP addresses linear layout.
1584 savedIpAddressesLinearLayout.setBackgroundResource(R.color.translucent_background)
1587 // Set the scroll Y.
1588 domainSettingsScrollView.post { domainSettingsScrollView.scrollY = scrollY }
1590 // Return the domain settings view.
1591 return domainSettingsView
1594 private fun checkDomainNameAgainstCertificate(domainName: String?, certificateCommonName: String?): Boolean {
1595 // Initialize the domain names match tracker.
1596 var domainNamesMatch = false
1598 // Check various wildcard permutations if the domain name and the certificate Common Name are not empty.
1599 if ((domainName != null) && (certificateCommonName != null)) {
1600 // Check if the domains match.
1601 if (domainName == certificateCommonName)
1602 domainNamesMatch = true
1604 // If the domain name starts with a wildcard, check the base domain against all the subdomains of the certificate Common Name.
1605 if (!domainNamesMatch && domainName.startsWith("*.") && domainName.length > 2) {
1606 // Remove the initial `*.`.
1607 val baseDomainName = domainName.substring(2)
1609 // Create a copy of the certificate Common Name to test subdomains.
1610 var certificateCommonNameSubdomain: String = certificateCommonName
1612 // Check all the subdomains in the certificate Common Name subdomain against the base domain name.
1613 while (!domainNamesMatch && certificateCommonNameSubdomain.contains(".")) { // Stop checking if the domain names match or if there are no more dots.
1614 // Test the certificate Common Name subdomain against the base domain name.
1615 if (certificateCommonNameSubdomain == baseDomainName)
1616 domainNamesMatch = true
1618 // Strip out the lowest subdomain of the certificate Common Name subdomain.
1619 certificateCommonNameSubdomain = try {
1620 certificateCommonNameSubdomain.substring(certificateCommonNameSubdomain.indexOf(".") + 1)
1621 } catch (e: IndexOutOfBoundsException) { // The certificate Common Name subdomain ends with a dot.
1627 // If the certificate Common Name starts with a wildcard, check the base common name against all the subdomains of the domain name.
1628 if (!domainNamesMatch && certificateCommonName.startsWith("*.") && certificateCommonName.length > 2) {
1629 // Remove the initial `*.`.
1630 val baseCertificateCommonName = certificateCommonName.substring(2)
1632 // Setup a copy of domain name to test subdomains.
1633 var domainNameSubdomain: String = domainName
1635 // Check all the subdomains in the domain name subdomain against the base certificate Common Name.
1636 while (!domainNamesMatch && domainNameSubdomain.contains(".") && domainNameSubdomain.length > 2) {
1637 // Test the domain name subdomain against the base certificate Common Name.
1638 if (domainNameSubdomain == baseCertificateCommonName)
1639 domainNamesMatch = true
1641 // Strip out the lowest subdomain of the domain name subdomain.
1642 domainNameSubdomain = try {
1643 domainNameSubdomain.substring(domainNameSubdomain.indexOf(".") + 1)
1644 } catch (e: IndexOutOfBoundsException) { // `domainNameSubdomain` ends with a dot.
1650 // If both names start with a wildcard, check if the root of one contains the root of the other.
1651 if (!domainNamesMatch && domainName.startsWith("*.") && domainName.length > 2 && certificateCommonName.startsWith("*.") && certificateCommonName.length > 2) {
1652 // Remove the wildcards.
1653 val rootDomainName = domainName.substring(2)
1654 val rootCertificateCommonName = certificateCommonName.substring(2)
1656 // Check if one name ends with the contents of the other. If so, there will be overlap in the their wildcard subdomains.
1657 if (rootDomainName.endsWith(rootCertificateCommonName) || rootCertificateCommonName.endsWith(rootDomainName))
1658 domainNamesMatch = true
1662 return domainNamesMatch
1665 private fun populateTextView(defaultValue: Boolean, arrayAdapter: ArrayAdapter<CharSequence>, textView: TextView) {
1667 textView.text = if (defaultValue)
1668 arrayAdapter.getItem(ENABLED)
1670 arrayAdapter.getItem(DISABLED)
1673 private fun setIconAndTextViewSettings(databaseInt: Int, defaultValue: Boolean, linearLayout: LinearLayout, imageView: ImageView, textView: TextView) {
1674 // Set the icon and text view settings.
1675 when (databaseInt) {
1677 // Set the icon color.
1678 imageView.isSelected = defaultValue
1680 // Show the text view.
1681 textView.visibility = View.VISIBLE
1683 // Set the background color to be transparent.
1684 linearLayout.setBackgroundColor(getColor(context, R.color.transparent))
1688 // Set the icon color.
1689 imageView.isSelected = true
1691 // Hide the text view.
1692 textView.visibility = View.GONE
1694 // Set the background color to be blue.
1695 linearLayout.setBackgroundColor(getColor(context, R.color.blue_background))
1699 // Set the icon color.
1700 imageView.isSelected = false
1702 // Hide the text view.
1703 textView.visibility = View.GONE
1705 // Set the background color to be blue.
1706 linearLayout.setBackgroundColor(getColor(context, R.color.blue_background))