ariane/app/src/main/java/oppen/ariane/ui/settings/SettingsFragment.kt

161 lines
6.0 KiB
Kotlin

package oppen.ariane.ui.settings
import android.os.Bundle
import android.text.InputType
import android.text.Spannable
import android.text.SpannableString
import android.text.style.ForegroundColorSpan
import android.view.inputmethod.EditorInfo
import android.widget.EditText
import androidx.core.content.ContextCompat
import androidx.preference.*
import oppen.ariane.Ariane
import java.security.SecureRandom
import java.util.*
import javax.net.ssl.SSLContext
import javax.net.ssl.SSLSocket
import javax.net.ssl.SSLSocketFactory
class SettingsFragment: PreferenceFragmentCompat(), Preference.OnPreferenceChangeListener {
lateinit var protocols: Array<String>
override fun onCreatePreferences(savedInstanceState: Bundle?, rootKey: String?) {
val context = preferenceManager.context
val screen = preferenceManager.createPreferenceScreen(context)
/**
* Ariane App Settings
*/
val appCategory = PreferenceCategory(context)
appCategory.key = "app_category"
appCategory.title = "Configure Ariane"
screen.addPreference(appCategory)
//Home
val homePreference = EditTextPreference(context)
homePreference.title = "Home Capsule"
homePreference.key = "home_capsule"
val homecapsule = preferenceManager.sharedPreferences.getString(
"home_capsule",
Ariane.DEFAULT_HOME_CAPSULE
)
homePreference.summary = homecapsule
homePreference.positiveButtonText = getThemedSpan("Update")
homePreference.negativeButtonText = getThemedSpan("Cancel")
homePreference.title = getThemedSpan("Home Capsule")
homePreference.setOnPreferenceChangeListener { _, newValue ->
homePreference.summary = newValue.toString()
true
}
homePreference.setOnBindEditTextListener{ editText ->
editText.imeOptions = EditorInfo.IME_ACTION_DONE
editText.setSelection(editText.text.toString().length)//Set caret position to end
}
appCategory.addPreference(homePreference)
/**
* TLS Settings
*/
val tlsCategory = PreferenceCategory(context)
tlsCategory.key = "tls_category"
tlsCategory.title = "TLS Config"
screen.addPreference(tlsCategory)
val tlsDefaultPreference = SwitchPreferenceCompat(context)
tlsDefaultPreference.key = "tls_Default"
tlsDefaultPreference.title = "TLS Default"
tlsDefaultPreference.onPreferenceChangeListener = this
tlsCategory.addPreference(tlsDefaultPreference)
val tlsAllSupportedPreference = SwitchPreferenceCompat(context)
tlsAllSupportedPreference.key = "tls_All_Supported"
tlsAllSupportedPreference.title = "TLS Enable all supported"
tlsAllSupportedPreference.onPreferenceChangeListener = this
tlsCategory.addPreference(tlsAllSupportedPreference)
val sslContext = SSLContext.getInstance("TLS")
sslContext.init(null, null, SecureRandom())
val factory: SSLSocketFactory = sslContext.socketFactory
val socket = factory.createSocket() as SSLSocket
protocols = socket.supportedProtocols
protocols.forEach { protocol ->
val tlsPreference = SwitchPreferenceCompat(context)
tlsPreference.key = "tls_${protocol.toLowerCase(Locale.getDefault())}"
tlsPreference.title = protocol
tlsPreference.onPreferenceChangeListener = this
tlsCategory.addPreference(tlsPreference)
}
preferenceScreen = screen
}
override fun onPreferenceChange(preference: Preference?, newValue: Any?): Boolean {
if(preference is SwitchPreferenceCompat && newValue is Boolean && newValue == true) {
preference.key?.let { key ->
when {
key.startsWith("tls_") -> {
if(key != "tls_Default"){
val default = preferenceScreen.findPreference<SwitchPreferenceCompat>("tls_Default")
default?.isChecked = false
}
if(key != "tls_All_Supported"){
val default = preferenceScreen.findPreference<SwitchPreferenceCompat>("tls_All_Supported")
default?.isChecked = false
}
protocols.forEach { protocol ->
val tlsSwitchKey = "tls_${protocol.toLowerCase(Locale.getDefault())}"
if (tlsSwitchKey != key) {
val otherTLSSwitch = preferenceScreen.findPreference<SwitchPreferenceCompat>(
tlsSwitchKey
)
otherTLSSwitch?.isChecked = false
}
}
}
}
}
when (preference.key) {
"tls_Default" -> setTLSProtocol("TLS")
"tls_All_Supported" -> setTLSProtocol("TLS_ALL")
else -> {
val prefTitle = preference.title.toString()
setTLSProtocol(prefTitle)
}
}
return true
}
return false
}
private fun setTLSProtocol(protocol: String){
preferenceManager.sharedPreferences.edit().putString(
"tls_protocol",
protocol
).apply()
}
/**
* Unfortunately it doesn't look like EditTextPreference supports Day/Night theme
* or else is otherwise broken. Use Spannable to set a suitable text colour for the dialog buttons
*/
private fun getThemedSpan(text: String): Spannable{
val textSpan = SpannableString(text)
textSpan.setSpan(
ForegroundColorSpan(
ContextCompat.getColor(
requireContext(),
oppen.ariane.R.color.themed_text
)
), 0, text.length, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE
)
return textSpan
}
}