Skip to content

Commit

Permalink
feat: boot receiver
Browse files Browse the repository at this point in the history
  • Loading branch information
arm64v8a committed May 2, 2023
1 parent 638a8db commit f557e20
Show file tree
Hide file tree
Showing 7 changed files with 69 additions and 1 deletion.
12 changes: 12 additions & 0 deletions app/src/main/AndroidManifest.xml
Original file line number Diff line number Diff line change
Expand Up @@ -305,6 +305,18 @@
android:authorities="${applicationId}.androidx-startup"
tools:node="remove" />

<receiver
android:name="io.nekohasekai.sagernet.BootReceiver"
android:enabled="false"
android:exported="true"
android:process=":bg">
<intent-filter>
<action android:name="android.intent.action.BOOT_COMPLETED" />
<action android:name="android.intent.action.LOCKED_BOOT_COMPLETED" />
<action android:name="android.intent.action.MY_PACKAGE_REPLACED" />
</intent-filter>
</receiver>

<service
android:name="androidx.room.MultiInstanceInvalidationService"
android:process=":bg" />
Expand Down
42 changes: 42 additions & 0 deletions app/src/main/java/io/nekohasekai/sagernet/BootReceiver.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
package io.nekohasekai.sagernet

import android.content.BroadcastReceiver
import android.content.ComponentName
import android.content.Context
import android.content.Intent
import android.content.pm.PackageManager
import android.os.Build
import io.nekohasekai.sagernet.bg.SubscriptionUpdater
import io.nekohasekai.sagernet.database.DataStore
import io.nekohasekai.sagernet.ktx.app
import io.nekohasekai.sagernet.ktx.runOnDefaultDispatcher

class BootReceiver : BroadcastReceiver() {
companion object {
private val componentName by lazy { ComponentName(app, BootReceiver::class.java) }
var enabled: Boolean
get() = app.packageManager.getComponentEnabledSetting(componentName) == PackageManager.COMPONENT_ENABLED_STATE_ENABLED
set(value) = app.packageManager.setComponentEnabledSetting(
componentName, if (value) PackageManager.COMPONENT_ENABLED_STATE_ENABLED
else PackageManager.COMPONENT_ENABLED_STATE_DISABLED, PackageManager.DONT_KILL_APP
)
}

override fun onReceive(context: Context, intent: Intent) {
runOnDefaultDispatcher {
SubscriptionUpdater.reconfigureUpdater()
}

if (!DataStore.persistAcrossReboot) { // sanity check
enabled = false
return
}

val doStart = when (intent.action) {
Intent.ACTION_LOCKED_BOOT_COMPLETED -> false // DataStore.directBootAware
else -> Build.VERSION.SDK_INT < 24 || SagerNet.user.isUserUnlocked
} && DataStore.selectedProxy > 0

if (doStart) SagerNet.startService()
}
}
2 changes: 2 additions & 0 deletions app/src/main/java/io/nekohasekai/sagernet/Constants.kt
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,8 @@ object Key {
const val DB_PUBLIC = "configuration.db"
const val DB_PROFILE = "sager_net.db"

const val PERSIST_ACROSS_REBOOT = "isAutoConnect"

const val APP_EXPERT = "isExpert"
const val APP_THEME = "appTheme"
const val NIGHT_THEME = "nightTheme"
Expand Down
2 changes: 2 additions & 0 deletions app/src/main/java/io/nekohasekai/sagernet/bg/BaseService.kt
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ import android.net.Network
import android.os.*
import android.widget.Toast
import io.nekohasekai.sagernet.Action
import io.nekohasekai.sagernet.BootReceiver
import io.nekohasekai.sagernet.R
import io.nekohasekai.sagernet.SagerNet
import io.nekohasekai.sagernet.aidl.AppStatsList
Expand Down Expand Up @@ -503,6 +504,7 @@ class BaseService {

val proxy = ProxyInstance(profile, this)
data.proxy = proxy
BootReceiver.enabled = DataStore.persistAcrossReboot
if (!data.closeReceiverRegistered) {
registerReceiver(data.receiver, IntentFilter().apply {
addAction(Action.RELOAD)
Expand Down
5 changes: 4 additions & 1 deletion app/src/main/java/io/nekohasekai/sagernet/bg/TileService.kt
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@ class TileService : BaseTileService(), SagerConnection.Callback {
}

override fun onClick() {
toggle()
if (isLocked) unlockAndRun(this::toggle) else toggle()
}

private fun updateTile(serviceState: BaseService.State, profileName: () -> String?) {
Expand All @@ -72,15 +72,18 @@ class TileService : BaseTileService(), SagerConnection.Callback {
icon = iconBusy
state = Tile.STATE_ACTIVE
}

BaseService.State.Connected -> {
icon = iconConnected
label = profileName()
state = Tile.STATE_ACTIVE
}

BaseService.State.Stopping -> {
icon = iconBusy
state = Tile.STATE_UNAVAILABLE
}

BaseService.State.Stopped -> {
icon = iconIdle
state = Tile.STATE_INACTIVE
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -182,6 +182,7 @@ object DataStore : OnPreferenceDataStoreChangeListener {
var bypass by configurationStore.boolean(Key.BYPASS_MODE) { true }
var individual by configurationStore.string(Key.INDIVIDUAL)
var showDirectSpeed by configurationStore.boolean(Key.SHOW_DIRECT_SPEED) { true }
val persistAcrossReboot by configurationStore.boolean(Key.PERSIST_ACROSS_REBOOT) { false }

var requireHttp by configurationStore.boolean(Key.REQUIRE_HTTP) { true }
var appendHttpProxy by configurationStore.boolean(Key.APPEND_HTTP_PROXY) { true }
Expand Down
6 changes: 6 additions & 0 deletions app/src/main/res/xml/global_preferences.xml
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,12 @@
app:icon="@drawable/ic_baseline_android_24"
app:key="nekoPlugins"
app:title="@string/neko_plugin" />
<SwitchPreference
app:defaultValue="false"
app:icon="@drawable/ic_communication_phonelink_ring"
app:key="isAutoConnect"
app:summary="@string/auto_connect_summary"
app:title="@string/auto_connect" />
<moe.matsuri.nya.ui.ColorPickerPreference
android:title="@string/theme"
app:icon="@drawable/ic_baseline_color_lens_24"
Expand Down

0 comments on commit f557e20

Please sign in to comment.