From 754eb4c15f9111dd62cae1e2875417f986d8d067 Mon Sep 17 00:00:00 2001 From: Farnam Taheri Date: Mon, 11 May 2026 23:36:06 +0330 Subject: [PATCH] fix(android): keep boot TODO dormant and preserve selection --- android/app/src/main/AndroidManifest.xml | 8 ++++-- .../masterdns/vpn/data/local/ProfileDao.kt | 3 ++ .../vpn/data/repository/ProfileRepository.kt | 10 ++++++- .../com/masterdns/vpn/service/BootReceiver.kt | 28 +++++++++---------- 4 files changed, 32 insertions(+), 17 deletions(-) diff --git a/android/app/src/main/AndroidManifest.xml b/android/app/src/main/AndroidManifest.xml index 7149fbd..eaf411e 100644 --- a/android/app/src/main/AndroidManifest.xml +++ b/android/app/src/main/AndroidManifest.xml @@ -7,7 +7,8 @@ - + + @@ -76,12 +77,15 @@ + diff --git a/android/app/src/main/java/com/masterdns/vpn/data/local/ProfileDao.kt b/android/app/src/main/java/com/masterdns/vpn/data/local/ProfileDao.kt index 6ba5f43..e1ebdb9 100644 --- a/android/app/src/main/java/com/masterdns/vpn/data/local/ProfileDao.kt +++ b/android/app/src/main/java/com/masterdns/vpn/data/local/ProfileDao.kt @@ -20,6 +20,9 @@ interface ProfileDao { @Query("SELECT * FROM profiles WHERE isSelected = 1 LIMIT 1") fun getSelectedProfileFlow(): Flow + @Query("SELECT * FROM profiles ORDER BY createdAt DESC LIMIT 1") + suspend fun getNewestProfile(): ProfileEntity? + @Insert(onConflict = OnConflictStrategy.REPLACE) suspend fun insertProfile(profile: ProfileEntity): Long diff --git a/android/app/src/main/java/com/masterdns/vpn/data/repository/ProfileRepository.kt b/android/app/src/main/java/com/masterdns/vpn/data/repository/ProfileRepository.kt index 258445f..967140d 100644 --- a/android/app/src/main/java/com/masterdns/vpn/data/repository/ProfileRepository.kt +++ b/android/app/src/main/java/com/masterdns/vpn/data/repository/ProfileRepository.kt @@ -23,7 +23,15 @@ class ProfileRepository @Inject constructor( suspend fun updateProfile(profile: ProfileEntity) = profileDao.updateProfile(profile) - suspend fun deleteProfile(profile: ProfileEntity) = profileDao.deleteProfile(profile) + suspend fun deleteProfile(profile: ProfileEntity) { + val wasSelected = profile.isSelected + profileDao.deleteProfile(profile) + if (wasSelected) { + profileDao.getNewestProfile()?.let { remaining -> + profileDao.setSelectedProfile(remaining.id) + } + } + } suspend fun setSelectedProfile(id: Long) = profileDao.setSelectedProfile(id) } diff --git a/android/app/src/main/java/com/masterdns/vpn/service/BootReceiver.kt b/android/app/src/main/java/com/masterdns/vpn/service/BootReceiver.kt index 0a6211b..0b94f80 100644 --- a/android/app/src/main/java/com/masterdns/vpn/service/BootReceiver.kt +++ b/android/app/src/main/java/com/masterdns/vpn/service/BootReceiver.kt @@ -1,16 +1,16 @@ package com.masterdns.vpn.service -import android.content.BroadcastReceiver -import android.content.Context -import android.content.Intent -import android.util.Log - -class BootReceiver : BroadcastReceiver() { - override fun onReceive(context: Context, intent: Intent) { - if (intent.action == Intent.ACTION_BOOT_COMPLETED) { - Log.i("MasterDnsVPN", "Boot completed, auto-connect can be triggered here") - // TODO: Check settings if auto-connect on boot is enabled - // If so, load selected profile and start VPN service - } - } -} +/* + * TODO(auto-connect): keep this receiver dormant until the app has an explicit + * auto-connect-on-boot setting and a permission-safe startup flow. + * + * Intended shape: + * + * class BootReceiver : BroadcastReceiver() { + * override fun onReceive(context: Context, intent: Intent) { + * if (intent.action != Intent.ACTION_BOOT_COMPLETED) return + * // Check user setting, VPN permission, and selected profile. + * // Start MasterDnsVpnService only when all prerequisites are satisfied. + * } + * } + */