2020-07-17 16:35:39 +02:00
package sushi.hardcore.droidfs
2023-02-28 22:50:59 +01:00
import android.content.Intent
2022-03-23 16:35:13 +01:00
import android.content.SharedPreferences
2022-03-05 12:51:02 +01:00
import android.os.Build
2020-07-17 16:35:39 +02:00
import android.os.Bundle
2022-03-24 20:08:23 +01:00
import android.text.InputType
2020-08-29 21:20:15 +02:00
import android.view.MenuItem
2022-03-23 16:35:13 +01:00
import android.widget.Toast
2023-09-06 19:27:41 +02:00
import androidx.preference.ListPreference
import androidx.preference.Preference
import androidx.preference.PreferenceFragmentCompat
import androidx.preference.PreferenceManager
import androidx.preference.SwitchPreference
import androidx.preference.SwitchPreferenceCompat
import sushi.hardcore.droidfs.content_providers.TemporaryFileProvider
import sushi.hardcore.droidfs.content_providers.VolumeProvider
2021-06-11 20:23:54 +02:00
import sushi.hardcore.droidfs.databinding.ActivitySettingsBinding
2023-09-06 19:27:41 +02:00
import sushi.hardcore.droidfs.util.Compat
2022-03-23 16:35:13 +01:00
import sushi.hardcore.droidfs.util.PathUtils
2022-03-05 12:51:02 +01:00
import sushi.hardcore.droidfs.widgets.CustomAlertDialogBuilder
2022-03-24 20:08:23 +01:00
import sushi.hardcore.droidfs.widgets.EditTextDialog
2020-07-17 16:35:39 +02:00
2021-06-07 16:34:50 +02:00
class SettingsActivity : BaseActivity ( ) {
2020-07-17 16:35:39 +02:00
override fun onCreate ( savedInstanceState : Bundle ? ) {
super . onCreate ( savedInstanceState )
2021-06-11 20:23:54 +02:00
val binding = ActivitySettingsBinding . inflate ( layoutInflater )
setContentView ( binding . root )
2020-07-17 16:35:39 +02:00
supportActionBar ?. setDisplayHomeAsUpEnabled ( true )
val screen = intent . extras ?. getString ( " screen " ) ?: " main "
2020-08-29 21:20:15 +02:00
val fragment = if ( screen == " UnsafeFeaturesSettingsFragment " ) {
2020-07-17 16:35:39 +02:00
UnsafeFeaturesSettingsFragment ( )
} else {
2022-03-26 19:26:53 +01:00
MainSettingsFragment ( )
2020-07-17 16:35:39 +02:00
}
supportFragmentManager
. beginTransaction ( )
. replace ( R . id . settings , fragment )
. commit ( )
}
2020-08-29 21:20:15 +02:00
override fun onOptionsItemSelected ( item : MenuItem ) : Boolean {
return when ( item . itemId ) {
android . R . id . home -> {
2022-09-23 12:09:22 +02:00
onBackPressedDispatcher . onBackPressed ( ) //return to the previous fragment rather than the activity
2020-08-29 21:20:15 +02:00
true
}
else -> super . onOptionsItemSelected ( item )
}
}
2022-03-26 19:26:53 +01:00
class MainSettingsFragment : PreferenceFragmentCompat ( ) {
private lateinit var sharedPrefs : SharedPreferences
2022-03-23 16:35:13 +01:00
private lateinit var maxSizePreference : Preference
private fun setThumbnailMaxSize ( input : String ) {
val value : Long
try {
value = input . toLong ( )
} catch ( e : NumberFormatException ) {
Toast . makeText ( requireContext ( ) , R . string . invalid _number , Toast . LENGTH _SHORT ) . show ( )
showMaxSizeDialog ( )
return
}
val size = value * 1000
if ( size < 0 ) {
Toast . makeText ( requireContext ( ) , R . string . invalid _number , Toast . LENGTH _SHORT ) . show ( )
showMaxSizeDialog ( )
} else {
with ( sharedPrefs . edit ( ) ) {
2023-02-06 10:52:51 +01:00
putLong ( Constants . THUMBNAIL _MAX _SIZE _KEY , value )
2022-03-23 16:35:13 +01:00
apply ( )
}
maxSizePreference . summary = PathUtils . formatSize ( size )
}
}
private fun showMaxSizeDialog ( ) {
2022-03-24 20:08:23 +01:00
with ( EditTextDialog ( ( requireActivity ( ) as BaseActivity ) , R . string . thumbnail _max _size ) {
setThumbnailMaxSize ( it )
} ) {
with ( binding . dialogEditText ) {
inputType = InputType . TYPE _CLASS _NUMBER
hint = getString ( R . string . size _hint )
2022-03-23 16:35:13 +01:00
}
2022-03-24 20:08:23 +01:00
show ( )
2022-03-23 16:35:13 +01:00
}
}
2023-02-28 22:50:59 +01:00
private fun refreshTheme ( ) {
with ( requireActivity ( ) ) {
startActivity ( Intent ( this , SettingsActivity :: class . java ) )
finish ( )
overridePendingTransition ( android . R . anim . fade _in , android . R . anim . fade _out )
}
}
2020-07-17 16:35:39 +02:00
override fun onCreatePreferences ( savedInstanceState : Bundle ? , rootKey : String ? ) {
setPreferencesFromResource ( R . xml . root _preferences , rootKey )
2022-03-26 19:26:53 +01:00
sharedPrefs = PreferenceManager . getDefaultSharedPreferences ( requireContext ( ) )
2023-02-28 22:50:59 +01:00
findPreference < ListPreference > ( " color " ) ?. setOnPreferenceChangeListener { _ , _ ->
refreshTheme ( )
true
}
findPreference < SwitchPreferenceCompat > ( " black_theme " ) ?. setOnPreferenceChangeListener { _ , _ ->
refreshTheme ( )
2021-11-09 11:12:09 +01:00
true
2020-08-07 22:40:13 +02:00
}
2023-02-06 10:52:51 +01:00
findPreference < Preference > ( Constants . THUMBNAIL _MAX _SIZE _KEY ) ?. let {
2022-03-23 16:35:13 +01:00
maxSizePreference = it
maxSizePreference . summary = getString (
R . string . thumbnail _max _size _summary ,
PathUtils . formatSize ( sharedPrefs . getLong (
2023-02-06 10:52:51 +01:00
Constants . THUMBNAIL _MAX _SIZE _KEY , Constants . DEFAULT _THUMBNAIL _MAX _SIZE
2022-03-23 16:35:13 +01:00
) * 1000 )
)
maxSizePreference . setOnPreferenceClickListener {
showMaxSizeDialog ( )
false
}
}
2020-07-17 16:35:39 +02:00
}
}
class UnsafeFeaturesSettingsFragment : PreferenceFragmentCompat ( ) {
override fun onCreatePreferences ( savedInstanceState : Bundle ? , rootKey : String ? ) {
setPreferencesFromResource ( R . xml . unsafe _features _preferences , rootKey )
2022-03-05 12:51:02 +01:00
findPreference < SwitchPreference > ( " usf_fingerprint " ) ?. setOnPreferenceChangeListener { _ , checked ->
if ( checked as Boolean ) {
var errorMsg : String ? = null
if ( Build . VERSION . SDK _INT >= Build . VERSION_CODES . M ) {
val reason = when ( FingerprintProtector . canAuthenticate ( requireContext ( ) ) ) {
0 -> null
1 -> R . string . keyguard _not _secure
2 -> R . string . no _hardware
3 -> R . string . hardware _unavailable
4 -> R . string . no _fingerprint
else -> R . string . unknown _error
}
reason ?. let {
errorMsg = getString ( R . string . fingerprint _error _msg , getString ( it ) )
}
} else {
errorMsg = getString ( R . string . error _marshmallow _required )
}
if ( errorMsg == null ) {
true
} else {
2023-02-28 22:50:59 +01:00
CustomAlertDialogBuilder ( requireContext ( ) , ( requireActivity ( ) as BaseActivity ) . theme )
2022-03-05 12:51:02 +01:00
. setTitle ( R . string . error )
. setMessage ( errorMsg )
. setPositiveButton ( R . string . ok , null )
. show ( )
false
}
} else {
true
}
}
2023-09-06 19:27:41 +02:00
val switchKeepOpen = findPreference < SwitchPreference > ( " usf_keep_open " ) !!
val switchExternalOpen = findPreference < SwitchPreference > ( " usf_open " ) !!
val switchExpose = findPreference < SwitchPreference > ( " usf_expose " ) !!
val switchSafWrite = findPreference < SwitchPreference > ( " usf_saf_write " ) !!
fun updateView ( usfOpen : Boolean ? = null , usfKeepOpen : Boolean ? = null , usfExpose : Boolean ? = null ) {
val usfKeepOpen = usfKeepOpen ?: switchKeepOpen . isChecked
switchExpose . isEnabled = usfKeepOpen
switchSafWrite . isEnabled = usfOpen ?: switchExternalOpen . isChecked || ( usfKeepOpen && usfExpose ?: switchExpose . isChecked )
}
updateView ( )
switchKeepOpen . setOnPreferenceChangeListener { _ , checked ->
updateView ( usfKeepOpen = checked as Boolean )
true
}
switchExternalOpen . setOnPreferenceChangeListener { _ , checked ->
updateView ( usfOpen = checked as Boolean )
true
}
switchExpose . setOnPreferenceChangeListener { _ , checked ->
if ( checked as Boolean ) {
if ( ! Compat . isMemFileSupported ( ) ) {
CustomAlertDialogBuilder ( requireContext ( ) , ( requireActivity ( ) as BaseActivity ) . theme )
. setTitle ( R . string . error )
. setMessage ( " Your current kernel does not support memfd_create(). This feature requires a minimum kernel version of ${Compat.MEMFD_CREATE_MINIMUM_KERNEL_VERSION} . " )
. setPositiveButton ( R . string . ok , null )
. show ( )
return @setOnPreferenceChangeListener false
}
}
VolumeProvider . usfExpose = checked
updateView ( usfExpose = checked )
VolumeProvider . notifyRootsChanged ( requireContext ( ) )
true
}
switchSafWrite . setOnPreferenceChangeListener { _ , checked ->
VolumeProvider . usfSafWrite = checked as Boolean
TemporaryFileProvider . usfSafWrite = checked
true
}
2020-07-17 16:35:39 +02:00
}
}
}