| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127 |
- /******************************************************************************
- * *
- * Copyright (C) 2021 by nekohasekai <[email protected]> *
- * Copyright (C) 2021 by Max Lv <[email protected]> *
- * Copyright (C) 2021 by Mygod Studio <[email protected]> *
- * *
- * This program is free software: you can redistribute it and/or modify *
- * it under the terms of the GNU General Public License as published by *
- * the Free Software Foundation, either version 3 of the License, or *
- * (at your option) any later version. *
- * *
- * This program is distributed in the hope that it will be useful, *
- * but WITHOUT ANY WARRANTY; without even the implied warranty of *
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
- * GNU General Public License for more details. *
- * *
- * You should have received a copy of the GNU General Public License *
- * along with this program. If not, see <http://www.gnu.org/licenses/>. *
- * *
- ******************************************************************************/
- package io.nekohasekai.sagernet.database
- import android.os.Binder
- import android.os.Build
- import androidx.preference.PreferenceDataStore
- import io.nekohasekai.sagernet.Key
- import io.nekohasekai.sagernet.RouteMode
- import io.nekohasekai.sagernet.SagerNet
- import io.nekohasekai.sagernet.database.preference.OnPreferenceDataStoreChangeListener
- import io.nekohasekai.sagernet.database.preference.PublicDatabase
- import io.nekohasekai.sagernet.database.preference.RoomPreferenceDataStore
- import io.nekohasekai.sagernet.ktx.boolean
- import io.nekohasekai.sagernet.ktx.long
- import io.nekohasekai.sagernet.ktx.parsePort
- import io.nekohasekai.sagernet.ktx.string
- import io.nekohasekai.sagernet.utils.DirectBoot
- object DataStore : OnPreferenceDataStoreChangeListener {
- val configurationStore = RoomPreferenceDataStore(PublicDatabase.kvPairDao)
- val profileCacheStore = RoomPreferenceDataStore(SagerDatabase.profileCacheDao)
- fun init() {
- if (Build.VERSION.SDK_INT >= 24) {
- SagerNet.deviceStorage.moveDatabaseFrom(SagerNet.application, Key.DB_PUBLIC)
- }
- if (Build.VERSION.SDK_INT >= 24 && directBootAware && SagerNet.user.isUserUnlocked) {
- DirectBoot.flushTrafficStats()
- }
- }
- var selectedProxy by configurationStore.long(Key.PROFILE_ID)
- var selectedGroup by configurationStore.long(Key.PROFILE_GROUP) {
- SagerNet.currentProfile?.groupId ?: 0L
- }
- var serviceMode by configurationStore.string(Key.SERVICE_MODE) { Key.MODE_VPN }
- var routeMode by configurationStore.string(Key.ROUTE_MODE) { RouteMode.ALL }
- var allowAccess by configurationStore.boolean(Key.ALLOW_ACCESS)
- var enableLocalDNS by configurationStore.boolean(Key.ENABLE_LOCAL_DNS) { true }
- var remoteDNS by configurationStore.string(Key.REMOTE_DNS) { "1.1.1.1" }
- var domesticDns by configurationStore.string(Key.DOMESTIC_DNS) { "9.9.9.11" }
- // hopefully hashCode = mHandle doesn't change, currently this is true from KitKat to Nougat
- private val userIndex by lazy { Binder.getCallingUserHandle().hashCode() }
- var socksPort: Int
- get() = getLocalPort(Key.SOCKS_PORT, 2080)
- set(value) = saveLocalPort(Key.SOCKS_PORT, value)
- var localDNSPort: Int
- get() = getLocalPort(Key.LOCAL_DNS_PORT, 6450)
- set(value) {
- saveLocalPort(Key.LOCAL_DNS_PORT, value)
- }
- var httpPort: Int
- get() = getLocalPort(Key.HTTP_PORT, 9080)
- set(value) = saveLocalPort(Key.HTTP_PORT, value)
- fun initGlobal() {
- persistAcrossReboot
- if (configurationStore.getString(Key.SOCKS_PORT) == null) socksPort = socksPort
- if (configurationStore.getString(Key.LOCAL_DNS_PORT) == null) localDNSPort = localDNSPort
- if (configurationStore.getString(Key.HTTP_PORT) == null) httpPort = httpPort
- }
- private fun getLocalPort(key: String, default: Int): Int {
- return parsePort(configurationStore.getString(key), default + userIndex)
- }
- private fun saveLocalPort(key: String, value: Int) {
- configurationStore.putString(key, "$value")
- }
- var ipv6Route by configurationStore.boolean(Key.IPV6_ROUTE) { true }
- var preferIpv6 by configurationStore.boolean(Key.PREFER_IPV6)
- var meteredNetwork by configurationStore.boolean(Key.METERED_NETWORK)
- var proxyApps by configurationStore.boolean(Key.PROXY_APPS)
- var bypass by configurationStore.boolean(Key.BYPASS_MODE)
- var individual by configurationStore.string("individual")
- var forceShadowsocksRust by configurationStore.boolean(Key.FORCE_SHADOWSOCKS_RUST)
- var requireHttp by configurationStore.boolean(Key.REQUIRE_HTTP)
- val persistAcrossReboot by configurationStore.boolean(Key.PERSIST_ACROSS_REBOOT) { true }
- val canToggleLocked: Boolean get() = configurationStore.getBoolean(Key.DIRECT_BOOT_AWARE) == true
- val directBootAware: Boolean get() = SagerNet.directBootSupported && canToggleLocked
- // cache
- var dirty by profileCacheStore.boolean(Key.PROFILE_DIRTY)
- var editingId by profileCacheStore.long(Key.PROFILE_ID)
- var editingGroup by profileCacheStore.long(Key.PROFILE_GROUP)
- var profileName by profileCacheStore.string(Key.PROFILE_NAME)
- var serverAddress by profileCacheStore.string(Key.SERVER_ADDRESS)
- var serverPort by profileCacheStore.string(Key.SERVER_PORT)
- var serverUsername by profileCacheStore.string(Key.SERVER_USERNAME)
- var serverPassword by profileCacheStore.string(Key.SERVER_PASSWORD)
- var serverUdp by profileCacheStore.boolean(Key.SERVER_UDP)
- var serverMethod by profileCacheStore.string(Key.SERVER_METHOD)
- var serverPlugin by profileCacheStore.string(Key.SERVER_PLUGIN)
- override fun onPreferenceDataStoreChanged(store: PreferenceDataStore, key: String) {
- when (key) {
- Key.PROFILE_ID -> if (directBootAware) DirectBoot.update()
- }
- }
- }
|