package io.nekohasekai.sfa import android.app.Application import android.app.NotificationManager import android.content.ClipboardManager import android.content.Context import android.content.Intent import android.content.IntentFilter import android.net.ConnectivityManager import android.net.wifi.WifiManager import android.os.PowerManager import androidx.core.content.getSystemService import go.Seq import io.nekohasekai.libbox.Libbox import io.nekohasekai.libbox.SetupOptions import io.nekohasekai.sfa.bg.AppChangeReceiver import io.nekohasekai.sfa.bg.UpdateProfileWork import io.nekohasekai.sfa.constant.Bugs import io.nekohasekai.sfa.utils.AppLifecycleObserver import io.nekohasekai.sfa.utils.HookModuleUpdateNotifier import io.nekohasekai.sfa.utils.HookStatusClient import io.nekohasekai.sfa.utils.PrivilegeSettingsClient import io.nekohasekai.sfa.vendor.Vendor import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.GlobalScope import kotlinx.coroutines.launch import java.io.File import java.util.Locale import io.nekohasekai.sfa.Application as BoxApplication class Application : Application() { override fun attachBaseContext(base: Context?) { super.attachBaseContext(base) application = this } override fun onCreate() { super.onCreate() AppLifecycleObserver.register(this) // Seq.setContext(this) Libbox.setLocale(Locale.getDefault().toLanguageTag().replace("-", "_")) HookStatusClient.register(this) PrivilegeSettingsClient.register(this) @Suppress("OPT_IN_USAGE") GlobalScope.launch(Dispatchers.IO) { initialize() UpdateProfileWork.reconfigureUpdater() HookModuleUpdateNotifier.sync(this@Application) } if (Vendor.isPerAppProxyAvailable()) { registerReceiver( AppChangeReceiver(), IntentFilter().apply { addAction(Intent.ACTION_PACKAGE_ADDED) addAction(Intent.ACTION_PACKAGE_REPLACED) addDataScheme("package") }, ) } } private fun initialize() { val baseDir = filesDir baseDir.mkdirs() val workingDir = getExternalFilesDir(null) ?: return workingDir.mkdirs() val tempDir = cacheDir tempDir.mkdirs() Libbox.setup( SetupOptions().also { it.basePath = baseDir.path it.workingPath = workingDir.path it.tempPath = tempDir.path it.fixAndroidStack = Bugs.fixAndroidStack it.logMaxLines = 3000 it.debug = BuildConfig.DEBUG }, ) Libbox.redirectStderr(File(workingDir, "stderr.log").path) } companion object { lateinit var application: BoxApplication val notification by lazy { application.getSystemService()!! } val connectivity by lazy { application.getSystemService()!! } val packageManager by lazy { application.packageManager } val powerManager by lazy { application.getSystemService()!! } val notificationManager by lazy { application.getSystemService()!! } val wifiManager by lazy { application.getSystemService()!! } val clipboard by lazy { application.getSystemService()!! } } }