Commit 30a53c08 authored by Mygod's avatar Mygod

Fix direct boot with Crashlytics

parent f053a62f
...@@ -64,9 +64,9 @@ class App : Application() { ...@@ -64,9 +64,9 @@ class App : Application() {
} }
val handler by lazy { Handler(Looper.getMainLooper()) } val handler by lazy { Handler(Looper.getMainLooper()) }
val deviceContext: Context by lazy { if (Build.VERSION.SDK_INT < 24) this else DeviceContext(this) } val deviceStorage by lazy { if (Build.VERSION.SDK_INT < 24) this else DeviceStorageApp(this) }
val remoteConfig: FirebaseRemoteConfig by lazy { FirebaseRemoteConfig.getInstance() } val remoteConfig: FirebaseRemoteConfig by lazy { FirebaseRemoteConfig.getInstance() }
val analytics: FirebaseAnalytics by lazy { FirebaseAnalytics.getInstance(deviceContext) } val analytics: FirebaseAnalytics by lazy { FirebaseAnalytics.getInstance(deviceStorage) }
val info: PackageInfo by lazy { getPackageInfo(packageName) } val info: PackageInfo by lazy { getPackageInfo(packageName) }
val directBootSupported by lazy { val directBootSupported by lazy {
Build.VERSION.SDK_INT >= 24 && getSystemService<DevicePolicyManager>()?.storageEncryptionStatus == Build.VERSION.SDK_INT >= 24 && getSystemService<DevicePolicyManager>()?.storageEncryptionStatus ==
...@@ -96,13 +96,12 @@ class App : Application() { ...@@ -96,13 +96,12 @@ class App : Application() {
override fun onCreate() { override fun onCreate() {
super.onCreate() super.onCreate()
app = this app = this
Fabric.with(this, Crashlytics()) // multiple processes needs manual set-up
AppCompatDelegate.setCompatVectorFromResourcesEnabled(true) AppCompatDelegate.setCompatVectorFromResourcesEnabled(true)
PreferenceFragmentCompat.registerPreferenceFragment(IconListPreference::class.java, PreferenceFragmentCompat.registerPreferenceFragment(IconListPreference::class.java,
BottomSheetPreferenceDialogFragment::class.java) BottomSheetPreferenceDialogFragment::class.java)
if (Build.VERSION.SDK_INT >= 24) { // migrate old files if (Build.VERSION.SDK_INT >= 24) { // migrate old files
deviceContext.moveDatabaseFrom(this, Key.DB_PUBLIC) deviceStorage.moveDatabaseFrom(this, Key.DB_PUBLIC)
val old = Acl.getFile(Acl.CUSTOM_RULES, this) val old = Acl.getFile(Acl.CUSTOM_RULES, this)
if (old.canRead()) { if (old.canRead()) {
Acl.getFile(Acl.CUSTOM_RULES).writeText(old.readText()) Acl.getFile(Acl.CUSTOM_RULES).writeText(old.readText())
...@@ -110,7 +109,8 @@ class App : Application() { ...@@ -110,7 +109,8 @@ class App : Application() {
} }
} }
FirebaseApp.initializeApp(deviceContext) Fabric.with(deviceStorage, Crashlytics()) // multiple processes needs manual set-up
FirebaseApp.initializeApp(deviceStorage)
remoteConfig.setDefaults(R.xml.default_configs) remoteConfig.setDefaults(R.xml.default_configs)
remoteConfig.fetch().addOnCompleteListener { remoteConfig.fetch().addOnCompleteListener {
if (it.isSuccessful) remoteConfig.activateFetched() else { if (it.isSuccessful) remoteConfig.activateFetched() else {
...@@ -118,7 +118,7 @@ class App : Application() { ...@@ -118,7 +118,7 @@ class App : Application() {
Crashlytics.logException(it.exception) Crashlytics.logException(it.exception)
} }
} }
WorkManager.initialize(deviceContext, androidx.work.Configuration.Builder().build()) WorkManager.initialize(deviceStorage, androidx.work.Configuration.Builder().build())
// handle data restored/crash // handle data restored/crash
if (Build.VERSION.SDK_INT >= 24 && DataStore.directBootAware && if (Build.VERSION.SDK_INT >= 24 && DataStore.directBootAware &&
...@@ -129,7 +129,7 @@ class App : Application() { ...@@ -129,7 +129,7 @@ class App : Application() {
for (dir in arrayOf("acl", "overture")) for (dir in arrayOf("acl", "overture"))
try { try {
for (file in assetManager.list(dir)) assetManager.open("$dir/$file").use { input -> for (file in assetManager.list(dir)) assetManager.open("$dir/$file").use { input ->
File(deviceContext.filesDir, file).outputStream().use { output -> input.copyTo(output) } File(deviceStorage.filesDir, file).outputStream().use { output -> input.copyTo(output) }
} }
} catch (e: IOException) { } catch (e: IOException) {
printLog(e) printLog(e)
......
...@@ -46,7 +46,7 @@ class Acl { ...@@ -46,7 +46,7 @@ class Acl {
val networkAclParser = "^IMPORT_URL\\s*<(.+)>\\s*$".toRegex() val networkAclParser = "^IMPORT_URL\\s*<(.+)>\\s*$".toRegex()
fun getFile(id: String, context: Context = app.deviceContext) = File(context.filesDir, id + ".acl") fun getFile(id: String, context: Context = app.deviceStorage) = File(context.filesDir, id + ".acl")
var customRules: Acl var customRules: Acl
get() { get() {
......
...@@ -201,7 +201,7 @@ object BaseService { ...@@ -201,7 +201,7 @@ object BaseService {
} }
// sensitive Shadowsocks config is stored in // sensitive Shadowsocks config is stored in
val file = File(if (UserManagerCompat.isUserUnlocked(app)) app.filesDir else @TargetApi(24) { val file = File(if (UserManagerCompat.isUserUnlocked(app)) app.filesDir else @TargetApi(24) {
app.deviceContext.noBackupFilesDir // only API 24+ will be in locked state app.deviceStorage.noBackupFilesDir // only API 24+ will be in locked state
}, CONFIG_FILE) }, CONFIG_FILE)
shadowsocksConfigFile = file shadowsocksConfigFile = file
file.writeText(config.toString()) file.writeText(config.toString())
......
...@@ -67,7 +67,7 @@ class GuardedProcessPool { ...@@ -67,7 +67,7 @@ class GuardedProcessPool {
process = ProcessBuilder(cmd) process = ProcessBuilder(cmd)
.redirectErrorStream(true) .redirectErrorStream(true)
.directory(app.deviceContext.filesDir) .directory(app.deviceStorage.filesDir)
.start() .start()
streamLogger(process.inputStream, Log::i) streamLogger(process.inputStream, Log::i)
......
...@@ -82,7 +82,7 @@ object LocalDnsService { ...@@ -82,7 +82,7 @@ object LocalDnsService {
// no need to setup AlternativeDNS in Acl.ALL/BYPASS_LAN mode // no need to setup AlternativeDNS in Acl.ALL/BYPASS_LAN mode
.put("OnlyPrimaryDNS", true) .put("OnlyPrimaryDNS", true)
} }
File(app.deviceContext.filesDir, file).writeText(config.toString()) File(app.deviceStorage.filesDir, file).writeText(config.toString())
return file return file
} }
......
...@@ -29,7 +29,7 @@ import java.nio.ByteBuffer ...@@ -29,7 +29,7 @@ import java.nio.ByteBuffer
import java.nio.ByteOrder import java.nio.ByteOrder
class TrafficMonitorThread : LocalSocketListener("TrafficMonitorThread") { class TrafficMonitorThread : LocalSocketListener("TrafficMonitorThread") {
override val socketFile = File(app.deviceContext.filesDir, "stat_path") override val socketFile = File(app.deviceStorage.filesDir, "stat_path")
override fun accept(socket: LocalSocket) { override fun accept(socket: LocalSocket) {
try { try {
......
...@@ -51,7 +51,7 @@ class TransproxyService : Service(), LocalDnsService.Interface { ...@@ -51,7 +51,7 @@ class TransproxyService : Service(), LocalDnsService.Interface {
} }
private fun startRedsocksDaemon() { private fun startRedsocksDaemon() {
File(app.deviceContext.filesDir, "redsocks.conf").writeText("""base { File(app.deviceStorage.filesDir, "redsocks.conf").writeText("""base {
log_debug = off; log_debug = off;
log_info = off; log_info = off;
log = stderr; log = stderr;
......
...@@ -71,7 +71,7 @@ class VpnService : BaseVpnService(), LocalDnsService.Interface { ...@@ -71,7 +71,7 @@ class VpnService : BaseVpnService(), LocalDnsService.Interface {
} }
private inner class ProtectWorker : LocalSocketListener("ShadowsocksVpnThread") { private inner class ProtectWorker : LocalSocketListener("ShadowsocksVpnThread") {
override val socketFile: File = File(app.deviceContext.filesDir, "protect_path") override val socketFile: File = File(app.deviceStorage.filesDir, "protect_path")
override fun accept(socket: LocalSocket) { override fun accept(socket: LocalSocket) {
try { try {
...@@ -250,7 +250,7 @@ class VpnService : BaseVpnService(), LocalDnsService.Interface { ...@@ -250,7 +250,7 @@ class VpnService : BaseVpnService(), LocalDnsService.Interface {
var tries = 0 var tries = 0
while (tries < 10) { while (tries < 10) {
Thread.sleep(30L shl tries) Thread.sleep(30L shl tries)
if (JniHelper.sendFd(fd, File(app.deviceContext.filesDir, "sock_path").absolutePath) != -1) return true if (JniHelper.sendFd(fd, File(app.deviceStorage.filesDir, "sock_path").absolutePath) != -1) return true
tries += 1 tries += 1
} }
} }
......
...@@ -31,7 +31,7 @@ import com.github.shadowsocks.utils.Key ...@@ -31,7 +31,7 @@ import com.github.shadowsocks.utils.Key
abstract class PublicDatabase : RoomDatabase() { abstract class PublicDatabase : RoomDatabase() {
companion object { companion object {
private val instance by lazy { private val instance by lazy {
Room.databaseBuilder(app.deviceContext, PublicDatabase::class.java, Key.DB_PUBLIC) Room.databaseBuilder(app.deviceStorage, PublicDatabase::class.java, Key.DB_PUBLIC)
.allowMainThreadQueries() .allowMainThreadQueries()
.addMigrations( .addMigrations(
Migration3 Migration3
......
...@@ -162,7 +162,7 @@ object PluginManager { ...@@ -162,7 +162,7 @@ object PluginManager {
var initialized = false var initialized = false
fun entryNotFound(): Nothing = throw IndexOutOfBoundsException("Plugin entry binary not found") fun entryNotFound(): Nothing = throw IndexOutOfBoundsException("Plugin entry binary not found")
val list = ArrayList<String>() val list = ArrayList<String>()
val pluginDir = File(app.deviceContext.filesDir, "plugin") val pluginDir = File(app.deviceStorage.filesDir, "plugin")
(cr.query(uri, arrayOf(PluginContract.COLUMN_PATH, PluginContract.COLUMN_MODE), null, null, null) (cr.query(uri, arrayOf(PluginContract.COLUMN_PATH, PluginContract.COLUMN_MODE), null, null, null)
?: return null).use { cursor -> ?: return null).use { cursor ->
if (!cursor.moveToFirst()) entryNotFound() if (!cursor.moveToFirst()) entryNotFound()
......
...@@ -20,12 +20,18 @@ ...@@ -20,12 +20,18 @@
package com.github.shadowsocks.utils package com.github.shadowsocks.utils
import android.annotation.SuppressLint
import android.annotation.TargetApi import android.annotation.TargetApi
import android.app.Application
import android.content.Context import android.content.Context
import android.content.ContextWrapper
@SuppressLint("Registered")
@TargetApi(24) @TargetApi(24)
class DeviceContext(context: Context) : ContextWrapper(context.createDeviceProtectedStorageContext()) { class DeviceStorageApp(context: Context) : Application() {
init {
attachBaseContext(context.createDeviceProtectedStorageContext())
}
/** /**
* Thou shalt not get the REAL underlying application context which would no longer be operating under device * Thou shalt not get the REAL underlying application context which would no longer be operating under device
* protected storage. * protected storage.
......
...@@ -17,7 +17,7 @@ import java.io.ObjectOutputStream ...@@ -17,7 +17,7 @@ import java.io.ObjectOutputStream
@TargetApi(24) @TargetApi(24)
object DirectBoot : BroadcastReceiver() { object DirectBoot : BroadcastReceiver() {
private val file = File(app.deviceContext.noBackupFilesDir, "directBootProfile") private val file = File(app.deviceStorage.noBackupFilesDir, "directBootProfile")
private var registered = false private var registered = false
fun getDeviceProfile(): Profile? = try { fun getDeviceProfile(): Profile? = try {
...@@ -26,7 +26,7 @@ object DirectBoot : BroadcastReceiver() { ...@@ -26,7 +26,7 @@ object DirectBoot : BroadcastReceiver() {
fun clean() { fun clean() {
file.delete() file.delete()
File(app.deviceContext.noBackupFilesDir, BaseService.CONFIG_FILE).delete() File(app.deviceStorage.noBackupFilesDir, BaseService.CONFIG_FILE).delete()
} }
/** /**
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment