Only restore services when permitted

This commit is contained in:
Mygod
2021-10-29 23:13:24 -04:00
parent e48810d944
commit 1b329558dc
7 changed files with 36 additions and 21 deletions

View File

@@ -48,6 +48,7 @@ class App : Application() {
// alternative to PreferenceManager.getDefaultSharedPreferencesName(this)
deviceStorage.moveSharedPreferencesFrom(this, PreferenceManager(this).sharedPreferencesName)
deviceStorage.moveDatabaseFrom(this, AppDatabase.DB_NAME)
BootReceiver.migrateIfNecessary()
} else deviceStorage = this
Services.init { this }
@@ -92,7 +93,6 @@ class App : Application() {
})
EBegFragment.init()
if (DhcpWorkaround.shouldEnable) DhcpWorkaround.enable(true)
BootReceiver.init()
}
override fun onConfigurationChanged(newConfig: Configuration) {

View File

@@ -5,13 +5,11 @@ import android.content.ComponentName
import android.content.Context
import android.content.Intent
import android.content.pm.PackageManager
import android.os.Build
import android.os.Parcelable
import android.widget.Toast
import androidx.annotation.RequiresApi
import be.mygod.librootkotlinx.toByteArray
import be.mygod.librootkotlinx.toParcelable
import be.mygod.vpnhotspot.App.Companion.app
import be.mygod.vpnhotspot.util.readableMessage
import kotlinx.parcelize.Parcelize
import timber.log.Timber
import java.io.DataInputStream
@@ -30,6 +28,7 @@ class BootReceiver : BroadcastReceiver() {
set(value) = app.packageManager.setComponentEnabledSetting(componentName,
if (value) PackageManager.COMPONENT_ENABLED_STATE_ENABLED
else PackageManager.COMPONENT_ENABLED_STATE_DISABLED, PackageManager.DONT_KILL_APP)
private val userEnabled get() = app.pref.getBoolean(KEY, false)
fun onUserSettingUpdated(shouldStart: Boolean) {
enabled = shouldStart && try {
config
@@ -39,7 +38,7 @@ class BootReceiver : BroadcastReceiver() {
}?.startables?.isEmpty() == false
}
private fun onConfigUpdated(isNotEmpty: Boolean) {
enabled = isNotEmpty && app.pref.getBoolean(KEY, false)
enabled = isNotEmpty && userEnabled
}
private const val FILENAME = "bootconfig"
@@ -75,16 +74,19 @@ class BootReceiver : BroadcastReceiver() {
inline fun <reified T> add(value: Startable) = add(T::class.java.name, value)
inline fun <reified T> delete() = delete(T::class.java.name)
fun init() {
if (Build.VERSION.SDK_INT >= 24) {
val oldFile = File(app.noBackupFilesDir, FILENAME)
if (oldFile.canRead()) try {
if (!configFile.exists()) oldFile.copyTo(configFile)
if (!oldFile.delete()) oldFile.deleteOnExit()
} catch (e: Exception) {
Timber.w(e)
}
@RequiresApi(24)
fun migrateIfNecessary() {
val oldFile = File(app.noBackupFilesDir, FILENAME)
if (oldFile.canRead()) try {
if (!configFile.exists()) oldFile.copyTo(configFile)
if (!oldFile.delete()) oldFile.deleteOnExit()
} catch (e: Exception) {
Timber.w(e)
}
}
private var started = false
private fun startIfNecessary() {
if (started) return
val config = try {
synchronized(BootReceiver) { config }
} catch (e: Exception) {
@@ -93,12 +95,11 @@ class BootReceiver : BroadcastReceiver() {
}
if (config == null || config.startables.isEmpty()) {
enabled = false
} else for (startable in config.startables.values) try {
startable.start(app)
} catch (e: IllegalStateException) { // ForegroundServiceStartNotAllowedException
Timber.w(e)
Toast.makeText(app, e.readableMessage, Toast.LENGTH_LONG).show()
}
} else for (startable in config.startables.values) startable.start(app)
started = true
}
fun startIfEnabled() {
if (started && userEnabled) startIfNecessary()
}
}
@@ -109,5 +110,11 @@ class BootReceiver : BroadcastReceiver() {
@Parcelize
private data class Config(var startables: MutableMap<String, Startable> = mutableMapOf()) : Parcelable
override fun onReceive(context: Context, intent: Intent) { }
override fun onReceive(context: Context, intent: Intent) {
when (intent.action) {
Intent.ACTION_BOOT_COMPLETED, Intent.ACTION_LOCKED_BOOT_COMPLETED, Intent.ACTION_MY_PACKAGE_REPLACED -> {
if (userEnabled) startIfNecessary() else enabled = false
}
}
}
}

View File

@@ -68,6 +68,7 @@ class LocalOnlyHotspotService : IpNeighbourMonitoringService(), CoroutineScope {
override fun onBind(intent: Intent?) = binder
override fun onStartCommand(intent: Intent?, flags: Int, startId: Int): Int {
BootReceiver.startIfEnabled()
if (binder.iface != null) return START_STICKY
binder.iface = ""
updateNotification() // show invisible foreground notification to avoid being killed

View File

@@ -62,6 +62,7 @@ class MainActivity : AppCompatActivity(), NavigationBarView.OnItemSelectedListen
SmartSnackbar.Register(binding.fragmentHolder)
WifiDoubleLock.ActivityListener(this)
lifecycleScope.launch {
BootReceiver.startIfEnabled()
repeatOnLifecycle(Lifecycle.State.STARTED) {
onAppUpdateAvailable(null)
try {

View File

@@ -354,6 +354,7 @@ class RepeaterService : Service(), CoroutineScope, WifiP2pManager.ChannelListene
* startService Step 1
*/
override fun onStartCommand(intent: Intent?, flags: Int, startId: Int): Int {
BootReceiver.startIfEnabled()
if (status != Status.IDLE) return START_NOT_STICKY
val channel = channel ?: return START_NOT_STICKY.also { stopSelf() }
status = Status.STARTING

View File

@@ -111,6 +111,7 @@ class TetheringService : IpNeighbourMonitoringService(), TetheringManager.Tether
override fun onBind(intent: Intent?) = binder
override fun onStartCommand(intent: Intent?, flags: Int, startId: Int): Int {
BootReceiver.startIfEnabled()
// call this first just in case we are shutting down immediately
if (Build.VERSION.SDK_INT >= 26) updateNotification()
launch {

View File

@@ -1,12 +1,14 @@
package be.mygod.vpnhotspot.util
import android.content.ComponentName
import android.content.Intent
import android.content.ServiceConnection
import android.os.Build
import android.os.IBinder
import android.service.quicksettings.Tile
import android.service.quicksettings.TileService
import androidx.annotation.RequiresApi
import be.mygod.vpnhotspot.BootReceiver
@RequiresApi(24)
abstract class KillableTileService : TileService(), ServiceConnection {
@@ -25,4 +27,6 @@ abstract class KillableTileService : TileService(), ServiceConnection {
onClick()
}
}
override fun onBind(intent: Intent?) = super.onBind(intent).also { BootReceiver.startIfEnabled() }
}