@ -3,77 +3,68 @@
package com.tailscale.ipn.mdm
package com.tailscale.ipn.mdm
import android.content.SharedPreferences
import android.os.Bundle
import android.os.Bundle
import com.tailscale.ipn.App
import com.tailscale.ipn.App
import com.tailscale.ipn.ui.util.set
import com.tailscale.ipn.ui.util.set
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.StateFlow
import kotlinx.coroutines.flow.StateFlow
data class SettingState < T > ( val value : T , val isSet : Boolean )
abstract class MDMSetting < T > ( defaultValue : T , val key : String , val localizedTitle : String ) {
abstract class MDMSetting < T > ( defaultValue : T , val key : String , val localizedTitle : String ) {
val flow : StateFlow < T > = MutableStateFlow < T > ( defaultValue )
val defaultValue = defaultValue
val flow = MutableStateFlow ( SettingState ( defaultValue , false ) )
fun setFrom ( bundle : Bundle ? , app: App ) {
fun setFrom ( bundle : Bundle ? , prefs: Lazy < SharedPreferences > ) {
val v = getFrom ( bundle , app )
val v : T ? = getFrom ( bundle , prefs )
flow . set ( v)
flow . set ( SettingState( v ?: defaultValue , v != null ) )
}
}
abstract fun getFrom ( bundle : Bundle ? , app : App ) : T
fun getFrom ( bundle : Bundle ? , prefs : Lazy < SharedPreferences > ) : T ? {
return when {
bundle != null -> bundle . takeIf { it . containsKey ( key ) } ?. let { getFromBundle ( it ) }
else -> prefs . value . takeIf { it . contains ( key ) } ?. let { getFromPrefs ( it ) }
}
}
protected abstract fun getFromBundle ( bundle : Bundle ) : T
protected abstract fun getFromPrefs ( prefs : SharedPreferences ) : T
}
}
class BooleanMDMSetting ( key : String , localizedTitle : String ) :
class BooleanMDMSetting ( key : String , localizedTitle : String ) :
MDMSetting < Boolean > ( false , key , localizedTitle ) {
MDMSetting < Boolean > ( false , key , localizedTitle ) {
override fun getFrom ( bundle : Bundle ? , app : App ) =
override fun getFrom Bundle ( bundle : Bundle ) = bundle . getBoolean ( key )
bundle ?. getBoolean ( key ) ?: app . getEncryptedPrefs ( ) . getBoolean ( key , false )
override fun getFromPrefs ( prefs : SharedPreferences ) = prefs . getBoolean ( key , false )
}
}
class StringMDMSetting ( key : String , localizedTitle : String ) :
class StringMDMSetting ( key : String , localizedTitle : String ) :
MDMSetting < String ? > ( null , key , localizedTitle ) {
MDMSetting < String ? > ( null , key , localizedTitle ) {
override fun getFrom ( bundle : Bundle ?, app : App ) =
override fun getFrom Bundle ( bundle : Bundle ) = bundle . getString ( key )
bundle ?. getString ( key ) ?: app . getEncryptedPrefs ( ) . getString ( key , null )
override fun getFromPrefs ( prefs : SharedPreferences ) = prefs . getString ( key , null )
}
}
class StringArrayListMDMSetting ( key : String , localizedTitle : String ) :
class StringArrayListMDMSetting ( key : String , localizedTitle : String ) :
MDMSetting < List < String > ? > ( null , key , localizedTitle ) {
MDMSetting < List < String > ? > ( null , key , localizedTitle ) {
override fun getFrom ( bundle : Bundle ?, app : App ) =
override fun getFrom Bundle ( bundle : Bundle ) = bundle . getStringArrayList ( key )
bundle ?. getStringArrayList ( key )
override fun getFromPrefs ( prefs : SharedPreferences ) =
?: a pp. getEncryptedP refs( ) . getStringSet ( key , HashSet < String > ( ) ) ?. toList ( )
prefs. getStringSet ( key , HashSet < String > ( ) ) ?. toList ( )
}
}
class AlwaysNeverUserDecidesMDMSetting ( key : String , localizedTitle : String ) :
class AlwaysNeverUserDecidesMDMSetting ( key : String , localizedTitle : String ) :
MDMSetting < AlwaysNeverUserDecides > ( AlwaysNeverUserDecides . UserDecides , key , localizedTitle ) {
MDMSetting < AlwaysNeverUserDecides > ( AlwaysNeverUserDecides . UserDecides , key , localizedTitle ) {
override fun getFrom ( bundle : Bundle ? , app : App ) : AlwaysNeverUserDecides {
override fun getFromBundle ( bundle : Bundle ) =
val storedString =
AlwaysNeverUserDecides . fromString ( bundle . getString ( key ) )
bundle ?. getString ( key )
override fun getFromPrefs ( prefs : SharedPreferences ) =
?: App . get ( ) . getEncryptedPrefs ( ) . getString ( key , null )
AlwaysNeverUserDecides . fromString ( prefs . getString ( key , null ) )
?: " user-decides "
return when ( storedString ) {
" always " -> {
AlwaysNeverUserDecides . Always
}
" never " -> {
AlwaysNeverUserDecides . Never
}
else -> {
AlwaysNeverUserDecides . UserDecides
}
}
}
}
}
class ShowHideMDMSetting ( key : String , localizedTitle : String ) :
class ShowHideMDMSetting ( key : String , localizedTitle : String ) :
MDMSetting < ShowHide > ( ShowHide . Show , key , localizedTitle ) {
MDMSetting < ShowHide > ( ShowHide . Show , key , localizedTitle ) {
override fun getFrom ( bundle : Bundle ? , app : App ) : ShowHide {
override fun getFromBundle ( bundle : Bundle ) =
val storedString =
ShowHide . fromString ( bundle . getString ( key ) )
bundle ?. getString ( key ) ?: App . get ( ) . getEncryptedPrefs ( ) . getString ( key , null ) ?: " show "
override fun getFromPrefs ( prefs : SharedPreferences ) =
return when ( storedString ) {
ShowHide . fromString ( prefs . getString ( key , null ) )
" hide " -> {
ShowHide . Hide
}
else -> {
ShowHide . Show
}
}
}
}
}
enum class AlwaysNeverUserDecides ( val value : String ) {
enum class AlwaysNeverUserDecides ( val value : String ) {
@ -89,6 +80,12 @@ enum class AlwaysNeverUserDecides(val value: String) {
override fun toString ( ) : String {
override fun toString ( ) : String {
return value
return value
}
}
companion object {
fun fromString ( value : String ? ) : AlwaysNeverUserDecides {
return values ( ) . find { it . value == value } ?: UserDecides
}
}
}
}
enum class ShowHide ( val value : String ) {
enum class ShowHide ( val value : String ) {
@ -98,4 +95,10 @@ enum class ShowHide(val value: String) {
override fun toString ( ) : String {
override fun toString ( ) : String {
return value
return value
}
}
companion object {
fun fromString ( value : String ? ) : ShowHide {
return ShowHide . values ( ) . find { it . value == value } ?: Show
}
}
}
}