mirror of
https://github.com/sudosylabs/vnidrop.git
synced 2026-08-08 03:39:57 +02:00
Compare commits
1 Commits
feat/devic
...
feat/andro
| Author | SHA1 | Date | |
|---|---|---|---|
| 3118afdba0 |
@@ -1740,6 +1740,57 @@
|
|||||||
"ru": "Получайте уведомления об активности передач, пока VniDrop работает в фоне."
|
"ru": "Получайте уведомления об активности передач, пока VniDrop работает в фоне."
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"notifications_background_sharing_body": {
|
||||||
|
"context": "Android foreground-service notification: explains why VniDrop stays active.",
|
||||||
|
"targets": [
|
||||||
|
"kmp"
|
||||||
|
],
|
||||||
|
"translations": {
|
||||||
|
"en": "VniDrop is ready to share your files in the background.",
|
||||||
|
"fr": "VniDrop est prêt à partager vos fichiers en arrière-plan.",
|
||||||
|
"es": "VniDrop está listo para compartir sus archivos en segundo plano.",
|
||||||
|
"it": "VniDrop è pronto a condividere i tuoi file in background.",
|
||||||
|
"de": "VniDrop kann Ihre Dateien im Hintergrund freigeben.",
|
||||||
|
"pt": "O VniDrop está pronto para partilhar os seus ficheiros em segundo plano.",
|
||||||
|
"pl": "VniDrop jest gotowy do udostępniania plików w tle.",
|
||||||
|
"nl": "VniDrop is klaar om uw bestanden op de achtergrond te delen.",
|
||||||
|
"ru": "VniDrop готов отправлять ваши файлы в фоновом режиме."
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"notifications_background_sharing_channel": {
|
||||||
|
"context": "Android system notification channel for an active outgoing share.",
|
||||||
|
"targets": [
|
||||||
|
"kmp"
|
||||||
|
],
|
||||||
|
"translations": {
|
||||||
|
"en": "Active transfers",
|
||||||
|
"fr": "Transferts actifs",
|
||||||
|
"es": "Transferencias activas",
|
||||||
|
"it": "Trasferimenti attivi",
|
||||||
|
"de": "Aktive Übertragungen",
|
||||||
|
"pt": "Transferências ativas",
|
||||||
|
"pl": "Aktywne transfery",
|
||||||
|
"nl": "Actieve overdrachten",
|
||||||
|
"ru": "Активные передачи"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"notifications_background_sharing_title": {
|
||||||
|
"context": "Android foreground-service notification title while an outgoing share is available.",
|
||||||
|
"targets": [
|
||||||
|
"kmp"
|
||||||
|
],
|
||||||
|
"translations": {
|
||||||
|
"en": "Sharing in the background",
|
||||||
|
"fr": "Partage en arrière-plan",
|
||||||
|
"es": "Compartiendo en segundo plano",
|
||||||
|
"it": "Condivisione in background",
|
||||||
|
"de": "Freigabe im Hintergrund",
|
||||||
|
"pt": "Partilha em segundo plano",
|
||||||
|
"pl": "Udostępnianie w tle",
|
||||||
|
"nl": "Delen op de achtergrond",
|
||||||
|
"ru": "Отправка в фоне"
|
||||||
|
}
|
||||||
|
},
|
||||||
"notifications_enabled_message": {
|
"notifications_enabled_message": {
|
||||||
"context": "Settings > Notifications: confirmation when notifications are enabled.",
|
"context": "Settings > Notifications: confirmation when notifications are enabled.",
|
||||||
"translations": {
|
"translations": {
|
||||||
|
|||||||
@@ -2,7 +2,15 @@
|
|||||||
<manifest xmlns:android="http://schemas.android.com/apk/res/android">
|
<manifest xmlns:android="http://schemas.android.com/apk/res/android">
|
||||||
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
|
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
|
||||||
<uses-permission android:name="android.permission.POST_NOTIFICATIONS" />
|
<uses-permission android:name="android.permission.POST_NOTIFICATIONS" />
|
||||||
|
<uses-permission android:name="android.permission.FOREGROUND_SERVICE" />
|
||||||
|
<uses-permission android:name="android.permission.FOREGROUND_SERVICE_CONNECTED_DEVICE" />
|
||||||
<uses-permission
|
<uses-permission
|
||||||
android:name="android.permission.WRITE_EXTERNAL_STORAGE"
|
android:name="android.permission.WRITE_EXTERNAL_STORAGE"
|
||||||
android:maxSdkVersion="28" />
|
android:maxSdkVersion="28" />
|
||||||
|
<application>
|
||||||
|
<service
|
||||||
|
android:name="com.vnidrop.app.background.BackgroundSharingService"
|
||||||
|
android:exported="false"
|
||||||
|
android:foregroundServiceType="connectedDevice" />
|
||||||
|
</application>
|
||||||
</manifest>
|
</manifest>
|
||||||
|
|||||||
@@ -8,6 +8,7 @@ import android.os.Build
|
|||||||
import androidx.activity.ComponentActivity
|
import androidx.activity.ComponentActivity
|
||||||
import androidx.compose.runtime.Composable
|
import androidx.compose.runtime.Composable
|
||||||
import androidx.compose.runtime.remember
|
import androidx.compose.runtime.remember
|
||||||
|
import com.vnidrop.app.background.AndroidBackgroundSharingController
|
||||||
import com.vnidrop.app.core.rememberFileSystemService
|
import com.vnidrop.app.core.rememberFileSystemService
|
||||||
import com.vnidrop.app.notifications.rememberAndroidLocalNotificationService
|
import com.vnidrop.app.notifications.rememberAndroidLocalNotificationService
|
||||||
import com.vnidrop.app.feature.receive.ExternalInvitationController
|
import com.vnidrop.app.feature.receive.ExternalInvitationController
|
||||||
@@ -18,7 +19,8 @@ fun rememberAndroidAppDependencies(activity: ComponentActivity, externalInvitati
|
|||||||
val context = activity.applicationContext
|
val context = activity.applicationContext
|
||||||
val fileSystemService = rememberFileSystemService()
|
val fileSystemService = rememberFileSystemService()
|
||||||
val notificationService = rememberAndroidLocalNotificationService(activity)
|
val notificationService = rememberAndroidLocalNotificationService(activity)
|
||||||
return remember(context, fileSystemService, notificationService) {
|
val backgroundSharingController = remember(context) { AndroidBackgroundSharingController(context) }
|
||||||
|
return remember(context, fileSystemService, notificationService, backgroundSharingController) {
|
||||||
AppDependencies(
|
AppDependencies(
|
||||||
environment = PlatformEnvironment(
|
environment = PlatformEnvironment(
|
||||||
name = "Android ${Build.VERSION.SDK_INT}",
|
name = "Android ${Build.VERSION.SDK_INT}",
|
||||||
@@ -30,6 +32,7 @@ fun rememberAndroidAppDependencies(activity: ComponentActivity, externalInvitati
|
|||||||
deviceInfoProvider = AndroidDeviceInfoProvider(context),
|
deviceInfoProvider = AndroidDeviceInfoProvider(context),
|
||||||
fileSystemService = fileSystemService,
|
fileSystemService = fileSystemService,
|
||||||
localNotificationService = notificationService,
|
localNotificationService = notificationService,
|
||||||
|
backgroundSharingController = backgroundSharingController,
|
||||||
externalInvitations = externalInvitations,
|
externalInvitations = externalInvitations,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,18 @@
|
|||||||
|
package com.vnidrop.app.background
|
||||||
|
|
||||||
|
import android.content.Context
|
||||||
|
import android.content.Intent
|
||||||
|
import androidx.core.content.ContextCompat
|
||||||
|
|
||||||
|
class AndroidBackgroundSharingController(
|
||||||
|
private val context: Context,
|
||||||
|
) : BackgroundSharingController {
|
||||||
|
override fun setSharingActive(active: Boolean) {
|
||||||
|
val intent = Intent(context, BackgroundSharingService::class.java)
|
||||||
|
if (active) {
|
||||||
|
ContextCompat.startForegroundService(context, intent)
|
||||||
|
} else {
|
||||||
|
context.stopService(intent)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,69 @@
|
|||||||
|
package com.vnidrop.app.background
|
||||||
|
|
||||||
|
import android.app.Notification
|
||||||
|
import android.app.NotificationChannel
|
||||||
|
import android.app.NotificationManager
|
||||||
|
import android.app.PendingIntent
|
||||||
|
import android.app.Service
|
||||||
|
import android.content.Intent
|
||||||
|
import android.content.pm.ServiceInfo
|
||||||
|
import android.os.IBinder
|
||||||
|
import kotlinx.coroutines.runBlocking
|
||||||
|
import org.jetbrains.compose.resources.getString
|
||||||
|
import vnidrop.shared.generated.resources.Res
|
||||||
|
import vnidrop.shared.generated.resources.notifications_background_sharing_body
|
||||||
|
import vnidrop.shared.generated.resources.notifications_background_sharing_channel
|
||||||
|
import vnidrop.shared.generated.resources.notifications_background_sharing_title
|
||||||
|
|
||||||
|
class BackgroundSharingService : Service() {
|
||||||
|
override fun onStartCommand(intent: Intent?, flags: Int, startId: Int): Int {
|
||||||
|
ensureNotificationChannel()
|
||||||
|
startForeground(NotificationId, createNotification(), ServiceInfo.FOREGROUND_SERVICE_TYPE_CONNECTED_DEVICE)
|
||||||
|
return START_NOT_STICKY
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onBind(intent: Intent?): IBinder? = null
|
||||||
|
|
||||||
|
override fun onDestroy() {
|
||||||
|
stopForeground(STOP_FOREGROUND_REMOVE)
|
||||||
|
super.onDestroy()
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun ensureNotificationChannel() {
|
||||||
|
val manager = getSystemService(NotificationManager::class.java)
|
||||||
|
manager.createNotificationChannel(
|
||||||
|
NotificationChannel(
|
||||||
|
ChannelId,
|
||||||
|
localizedString(Res.string.notifications_background_sharing_channel),
|
||||||
|
NotificationManager.IMPORTANCE_LOW,
|
||||||
|
),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun createNotification(): Notification {
|
||||||
|
val launchIntent = packageManager.getLaunchIntentForPackage(packageName)
|
||||||
|
val contentIntent = launchIntent?.let {
|
||||||
|
PendingIntent.getActivity(
|
||||||
|
this,
|
||||||
|
0,
|
||||||
|
it,
|
||||||
|
PendingIntent.FLAG_UPDATE_CURRENT or PendingIntent.FLAG_IMMUTABLE,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
return Notification.Builder(this, ChannelId)
|
||||||
|
.setSmallIcon(android.R.drawable.stat_sys_upload)
|
||||||
|
.setContentTitle(localizedString(Res.string.notifications_background_sharing_title))
|
||||||
|
.setContentText(localizedString(Res.string.notifications_background_sharing_body))
|
||||||
|
.setOngoing(true)
|
||||||
|
.setContentIntent(contentIntent)
|
||||||
|
.build()
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun localizedString(resource: org.jetbrains.compose.resources.StringResource): String =
|
||||||
|
runBlocking { getString(resource) }
|
||||||
|
|
||||||
|
private companion object {
|
||||||
|
const val ChannelId = "vnidrop-background-sharing"
|
||||||
|
const val NotificationId = 3_427
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -116,6 +116,9 @@
|
|||||||
<string name="nav_settings">Einstellungen</string>
|
<string name="nav_settings">Einstellungen</string>
|
||||||
<string name="network_title">Netzwerk</string>
|
<string name="network_title">Netzwerk</string>
|
||||||
<string name="notifications_description">Werden Sie über Übertragungsaktivitäten benachrichtigt, während VniDrop im Hintergrund läuft.</string>
|
<string name="notifications_description">Werden Sie über Übertragungsaktivitäten benachrichtigt, während VniDrop im Hintergrund läuft.</string>
|
||||||
|
<string name="notifications_background_sharing_body">VniDrop kann Ihre Dateien im Hintergrund freigeben.</string>
|
||||||
|
<string name="notifications_background_sharing_channel">Aktive Übertragungen</string>
|
||||||
|
<string name="notifications_background_sharing_title">Freigabe im Hintergrund</string>
|
||||||
<string name="notifications_enabled_message">Mitteilungen aktiviert.</string>
|
<string name="notifications_enabled_message">Mitteilungen aktiviert.</string>
|
||||||
<string name="notifications_local_title">Mitteilungen erlauben</string>
|
<string name="notifications_local_title">Mitteilungen erlauben</string>
|
||||||
<string name="notifications_permission_denied">Mitteilungen sind für VniDrop deaktiviert. Sie können sie in den Einstellungen aktivieren.</string>
|
<string name="notifications_permission_denied">Mitteilungen sind für VniDrop deaktiviert. Sie können sie in den Einstellungen aktivieren.</string>
|
||||||
|
|||||||
@@ -116,6 +116,9 @@
|
|||||||
<string name="nav_settings">Ajustes</string>
|
<string name="nav_settings">Ajustes</string>
|
||||||
<string name="network_title">Red</string>
|
<string name="network_title">Red</string>
|
||||||
<string name="notifications_description">Reciba avisos sobre la actividad de las transferencias cuando VniDrop está en segundo plano.</string>
|
<string name="notifications_description">Reciba avisos sobre la actividad de las transferencias cuando VniDrop está en segundo plano.</string>
|
||||||
|
<string name="notifications_background_sharing_body">VniDrop está listo para compartir sus archivos en segundo plano.</string>
|
||||||
|
<string name="notifications_background_sharing_channel">Transferencias activas</string>
|
||||||
|
<string name="notifications_background_sharing_title">Compartiendo en segundo plano</string>
|
||||||
<string name="notifications_enabled_message">Notificaciones activadas.</string>
|
<string name="notifications_enabled_message">Notificaciones activadas.</string>
|
||||||
<string name="notifications_local_title">Permitir notificaciones</string>
|
<string name="notifications_local_title">Permitir notificaciones</string>
|
||||||
<string name="notifications_permission_denied">Las notificaciones están desactivadas para VniDrop. Puede activarlas en Ajustes.</string>
|
<string name="notifications_permission_denied">Las notificaciones están desactivadas para VniDrop. Puede activarlas en Ajustes.</string>
|
||||||
|
|||||||
@@ -116,6 +116,9 @@
|
|||||||
<string name="nav_settings">Réglages</string>
|
<string name="nav_settings">Réglages</string>
|
||||||
<string name="network_title">Réseau</string>
|
<string name="network_title">Réseau</string>
|
||||||
<string name="notifications_description">Soyez averti de l’activité des transferts lorsque VniDrop est en arrière-plan.</string>
|
<string name="notifications_description">Soyez averti de l’activité des transferts lorsque VniDrop est en arrière-plan.</string>
|
||||||
|
<string name="notifications_background_sharing_body">VniDrop est prêt à partager vos fichiers en arrière-plan.</string>
|
||||||
|
<string name="notifications_background_sharing_channel">Transferts actifs</string>
|
||||||
|
<string name="notifications_background_sharing_title">Partage en arrière-plan</string>
|
||||||
<string name="notifications_enabled_message">Notifications activées.</string>
|
<string name="notifications_enabled_message">Notifications activées.</string>
|
||||||
<string name="notifications_local_title">Autoriser les notifications</string>
|
<string name="notifications_local_title">Autoriser les notifications</string>
|
||||||
<string name="notifications_permission_denied">Les notifications sont désactivées pour VniDrop. Vous pouvez les activer dans les Réglages.</string>
|
<string name="notifications_permission_denied">Les notifications sont désactivées pour VniDrop. Vous pouvez les activer dans les Réglages.</string>
|
||||||
|
|||||||
@@ -116,6 +116,9 @@
|
|||||||
<string name="nav_settings">Impostazioni</string>
|
<string name="nav_settings">Impostazioni</string>
|
||||||
<string name="network_title">Rete</string>
|
<string name="network_title">Rete</string>
|
||||||
<string name="notifications_description">Ricevi avvisi sull’attività dei trasferimenti quando VniDrop è in background.</string>
|
<string name="notifications_description">Ricevi avvisi sull’attività dei trasferimenti quando VniDrop è in background.</string>
|
||||||
|
<string name="notifications_background_sharing_body">VniDrop è pronto a condividere i tuoi file in background.</string>
|
||||||
|
<string name="notifications_background_sharing_channel">Trasferimenti attivi</string>
|
||||||
|
<string name="notifications_background_sharing_title">Condivisione in background</string>
|
||||||
<string name="notifications_enabled_message">Notifiche attivate.</string>
|
<string name="notifications_enabled_message">Notifiche attivate.</string>
|
||||||
<string name="notifications_local_title">Consenti le notifiche</string>
|
<string name="notifications_local_title">Consenti le notifiche</string>
|
||||||
<string name="notifications_permission_denied">Le notifiche sono disattivate per VniDrop. Può attivarle in Impostazioni.</string>
|
<string name="notifications_permission_denied">Le notifiche sono disattivate per VniDrop. Può attivarle in Impostazioni.</string>
|
||||||
|
|||||||
@@ -116,6 +116,9 @@
|
|||||||
<string name="nav_settings">Instellingen</string>
|
<string name="nav_settings">Instellingen</string>
|
||||||
<string name="network_title">Netwerk</string>
|
<string name="network_title">Netwerk</string>
|
||||||
<string name="notifications_description">Ontvang meldingen over overdrachtsactiviteit terwijl VniDrop op de achtergrond draait.</string>
|
<string name="notifications_description">Ontvang meldingen over overdrachtsactiviteit terwijl VniDrop op de achtergrond draait.</string>
|
||||||
|
<string name="notifications_background_sharing_body">VniDrop is klaar om uw bestanden op de achtergrond te delen.</string>
|
||||||
|
<string name="notifications_background_sharing_channel">Actieve overdrachten</string>
|
||||||
|
<string name="notifications_background_sharing_title">Delen op de achtergrond</string>
|
||||||
<string name="notifications_enabled_message">Meldingen ingeschakeld.</string>
|
<string name="notifications_enabled_message">Meldingen ingeschakeld.</string>
|
||||||
<string name="notifications_local_title">Meldingen toestaan</string>
|
<string name="notifications_local_title">Meldingen toestaan</string>
|
||||||
<string name="notifications_permission_denied">Meldingen zijn uitgeschakeld voor VniDrop. U kunt ze inschakelen in Instellingen.</string>
|
<string name="notifications_permission_denied">Meldingen zijn uitgeschakeld voor VniDrop. U kunt ze inschakelen in Instellingen.</string>
|
||||||
|
|||||||
@@ -116,6 +116,9 @@
|
|||||||
<string name="nav_settings">Ustawienia</string>
|
<string name="nav_settings">Ustawienia</string>
|
||||||
<string name="network_title">Sieć</string>
|
<string name="network_title">Sieć</string>
|
||||||
<string name="notifications_description">Otrzymuj powiadomienia o aktywności transferów, gdy VniDrop działa w tle.</string>
|
<string name="notifications_description">Otrzymuj powiadomienia o aktywności transferów, gdy VniDrop działa w tle.</string>
|
||||||
|
<string name="notifications_background_sharing_body">VniDrop jest gotowy do udostępniania plików w tle.</string>
|
||||||
|
<string name="notifications_background_sharing_channel">Aktywne transfery</string>
|
||||||
|
<string name="notifications_background_sharing_title">Udostępnianie w tle</string>
|
||||||
<string name="notifications_enabled_message">Powiadomienia włączone.</string>
|
<string name="notifications_enabled_message">Powiadomienia włączone.</string>
|
||||||
<string name="notifications_local_title">Zezwól na powiadomienia</string>
|
<string name="notifications_local_title">Zezwól na powiadomienia</string>
|
||||||
<string name="notifications_permission_denied">Powiadomienia są wyłączone dla VniDrop. Możesz je włączyć w Ustawieniach.</string>
|
<string name="notifications_permission_denied">Powiadomienia są wyłączone dla VniDrop. Możesz je włączyć w Ustawieniach.</string>
|
||||||
|
|||||||
@@ -116,6 +116,9 @@
|
|||||||
<string name="nav_settings">Definições</string>
|
<string name="nav_settings">Definições</string>
|
||||||
<string name="network_title">Rede</string>
|
<string name="network_title">Rede</string>
|
||||||
<string name="notifications_description">Seja notificado sobre a atividade das transferências enquanto o VniDrop está em segundo plano.</string>
|
<string name="notifications_description">Seja notificado sobre a atividade das transferências enquanto o VniDrop está em segundo plano.</string>
|
||||||
|
<string name="notifications_background_sharing_body">O VniDrop está pronto para partilhar os seus ficheiros em segundo plano.</string>
|
||||||
|
<string name="notifications_background_sharing_channel">Transferências ativas</string>
|
||||||
|
<string name="notifications_background_sharing_title">Partilha em segundo plano</string>
|
||||||
<string name="notifications_enabled_message">Notificações ativadas.</string>
|
<string name="notifications_enabled_message">Notificações ativadas.</string>
|
||||||
<string name="notifications_local_title">Permitir notificações</string>
|
<string name="notifications_local_title">Permitir notificações</string>
|
||||||
<string name="notifications_permission_denied">As notificações estão desativadas para o VniDrop. Pode ativá-las nas Definições.</string>
|
<string name="notifications_permission_denied">As notificações estão desativadas para o VniDrop. Pode ativá-las nas Definições.</string>
|
||||||
|
|||||||
@@ -116,6 +116,9 @@
|
|||||||
<string name="nav_settings">Настройки</string>
|
<string name="nav_settings">Настройки</string>
|
||||||
<string name="network_title">Сеть</string>
|
<string name="network_title">Сеть</string>
|
||||||
<string name="notifications_description">Получайте уведомления об активности передач, пока VniDrop работает в фоне.</string>
|
<string name="notifications_description">Получайте уведомления об активности передач, пока VniDrop работает в фоне.</string>
|
||||||
|
<string name="notifications_background_sharing_body">VniDrop готов отправлять ваши файлы в фоновом режиме.</string>
|
||||||
|
<string name="notifications_background_sharing_channel">Активные передачи</string>
|
||||||
|
<string name="notifications_background_sharing_title">Отправка в фоне</string>
|
||||||
<string name="notifications_enabled_message">Уведомления включены.</string>
|
<string name="notifications_enabled_message">Уведомления включены.</string>
|
||||||
<string name="notifications_local_title">Разрешить уведомления</string>
|
<string name="notifications_local_title">Разрешить уведомления</string>
|
||||||
<string name="notifications_permission_denied">Уведомления отключены для VniDrop. Вы можете включить их в Настройках.</string>
|
<string name="notifications_permission_denied">Уведомления отключены для VniDrop. Вы можете включить их в Настройках.</string>
|
||||||
|
|||||||
@@ -116,6 +116,9 @@
|
|||||||
<string name="nav_settings">Settings</string>
|
<string name="nav_settings">Settings</string>
|
||||||
<string name="network_title">Network</string>
|
<string name="network_title">Network</string>
|
||||||
<string name="notifications_description">Get notified about transfer activity while VniDrop is in the background.</string>
|
<string name="notifications_description">Get notified about transfer activity while VniDrop is in the background.</string>
|
||||||
|
<string name="notifications_background_sharing_body">VniDrop is ready to share your files in the background.</string>
|
||||||
|
<string name="notifications_background_sharing_channel">Active transfers</string>
|
||||||
|
<string name="notifications_background_sharing_title">Sharing in the background</string>
|
||||||
<string name="notifications_enabled_message">Notifications enabled.</string>
|
<string name="notifications_enabled_message">Notifications enabled.</string>
|
||||||
<string name="notifications_local_title">Allow notifications</string>
|
<string name="notifications_local_title">Allow notifications</string>
|
||||||
<string name="notifications_permission_denied">Notifications are turned off for VniDrop. You can enable them in Settings.</string>
|
<string name="notifications_permission_denied">Notifications are turned off for VniDrop. You can enable them in Settings.</string>
|
||||||
|
|||||||
@@ -2,6 +2,7 @@ package com.vnidrop.app
|
|||||||
|
|
||||||
import com.vnidrop.app.core.CoreGateway
|
import com.vnidrop.app.core.CoreGateway
|
||||||
import com.vnidrop.app.core.CoreRepository
|
import com.vnidrop.app.core.CoreRepository
|
||||||
|
import com.vnidrop.app.background.BackgroundSharingCoordinator
|
||||||
import com.vnidrop.app.diagnostics.DiagnosticsCoordinator
|
import com.vnidrop.app.diagnostics.DiagnosticsCoordinator
|
||||||
import com.vnidrop.app.diagnostics.createDiagnosticsTransport
|
import com.vnidrop.app.diagnostics.createDiagnosticsTransport
|
||||||
import com.vnidrop.app.feature.approvals.ApprovalCoordinator
|
import com.vnidrop.app.feature.approvals.ApprovalCoordinator
|
||||||
@@ -66,6 +67,11 @@ class AppGraph(
|
|||||||
messages = messages,
|
messages = messages,
|
||||||
scope = applicationScope,
|
scope = applicationScope,
|
||||||
)
|
)
|
||||||
|
private val backgroundSharingCoordinator = BackgroundSharingCoordinator(
|
||||||
|
repository = coreRepository,
|
||||||
|
controller = dependencies.backgroundSharingController,
|
||||||
|
scope = applicationScope,
|
||||||
|
)
|
||||||
|
|
||||||
init {
|
init {
|
||||||
AppLogger.initialize(dependencies.environment.defaultCoreDataDir)
|
AppLogger.initialize(dependencies.environment.defaultCoreDataDir)
|
||||||
@@ -73,6 +79,7 @@ class AppGraph(
|
|||||||
}
|
}
|
||||||
|
|
||||||
fun close() {
|
fun close() {
|
||||||
|
backgroundSharingCoordinator.stop()
|
||||||
coreRepository.shutdown()
|
coreRepository.shutdown()
|
||||||
applicationScope.cancel()
|
applicationScope.cancel()
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,6 +3,7 @@ package com.vnidrop.app
|
|||||||
import com.vnidrop.app.core.FileSystemService
|
import com.vnidrop.app.core.FileSystemService
|
||||||
import com.vnidrop.app.notifications.LocalNotificationService
|
import com.vnidrop.app.notifications.LocalNotificationService
|
||||||
import com.vnidrop.app.feature.receive.ExternalInvitationController
|
import com.vnidrop.app.feature.receive.ExternalInvitationController
|
||||||
|
import com.vnidrop.app.background.BackgroundSharingController
|
||||||
|
|
||||||
enum class UiPlatform {
|
enum class UiPlatform {
|
||||||
Android,
|
Android,
|
||||||
@@ -39,5 +40,6 @@ data class AppDependencies(
|
|||||||
val deviceInfoProvider: DeviceInfoProvider,
|
val deviceInfoProvider: DeviceInfoProvider,
|
||||||
val fileSystemService: FileSystemService,
|
val fileSystemService: FileSystemService,
|
||||||
val localNotificationService: LocalNotificationService,
|
val localNotificationService: LocalNotificationService,
|
||||||
|
val backgroundSharingController: BackgroundSharingController,
|
||||||
val externalInvitations: ExternalInvitationController,
|
val externalInvitations: ExternalInvitationController,
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -0,0 +1,38 @@
|
|||||||
|
package com.vnidrop.app.background
|
||||||
|
|
||||||
|
import com.vnidrop.app.core.CoreGateway
|
||||||
|
import com.vnidrop.app.core.CoreState
|
||||||
|
import com.vnidrop.app.core.TransferDirection
|
||||||
|
import com.vnidrop.app.core.TransferStatus
|
||||||
|
import kotlinx.coroutines.CoroutineScope
|
||||||
|
import kotlinx.coroutines.flow.distinctUntilChanged
|
||||||
|
import kotlinx.coroutines.flow.map
|
||||||
|
import kotlinx.coroutines.launch
|
||||||
|
|
||||||
|
/** Keeps the platform process eligible to serve an outgoing share while its UI is backgrounded. */
|
||||||
|
fun interface BackgroundSharingController {
|
||||||
|
fun setSharingActive(active: Boolean)
|
||||||
|
}
|
||||||
|
|
||||||
|
class BackgroundSharingCoordinator(
|
||||||
|
repository: CoreGateway,
|
||||||
|
private val controller: BackgroundSharingController,
|
||||||
|
scope: CoroutineScope,
|
||||||
|
) {
|
||||||
|
init {
|
||||||
|
scope.launch {
|
||||||
|
repository.state
|
||||||
|
.map(::requiresBackgroundSharing)
|
||||||
|
.distinctUntilChanged()
|
||||||
|
.collect(controller::setSharingActive)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun stop() = controller.setSharingActive(false)
|
||||||
|
}
|
||||||
|
|
||||||
|
internal fun requiresBackgroundSharing(state: CoreState): Boolean =
|
||||||
|
state.isInitialized && state.transfers.any { transfer ->
|
||||||
|
transfer.direction == TransferDirection.Send &&
|
||||||
|
transfer.status in setOf(TransferStatus.Importing, TransferStatus.Sharing)
|
||||||
|
}
|
||||||
@@ -0,0 +1,63 @@
|
|||||||
|
package com.vnidrop.app.background
|
||||||
|
|
||||||
|
import com.vnidrop.app.core.CoreState
|
||||||
|
import com.vnidrop.app.core.ShareAccessPolicy
|
||||||
|
import com.vnidrop.app.core.Transfer
|
||||||
|
import com.vnidrop.app.core.TransferDirection
|
||||||
|
import com.vnidrop.app.core.TransferStatus
|
||||||
|
import com.vnidrop.app.support.FakeCoreGateway
|
||||||
|
import kotlinx.coroutines.ExperimentalCoroutinesApi
|
||||||
|
import kotlinx.coroutines.test.runCurrent
|
||||||
|
import kotlinx.coroutines.test.runTest
|
||||||
|
import kotlin.test.Test
|
||||||
|
import kotlin.test.assertEquals
|
||||||
|
|
||||||
|
@OptIn(ExperimentalCoroutinesApi::class)
|
||||||
|
class BackgroundSharingCoordinatorTest {
|
||||||
|
@Test
|
||||||
|
fun keepsThePlatformActiveOnlyWhileAnOutgoingShareIsAvailable() = runTest {
|
||||||
|
val core = FakeCoreGateway()
|
||||||
|
val activeStates = mutableListOf<Boolean>()
|
||||||
|
val coordinator = BackgroundSharingCoordinator(
|
||||||
|
repository = core,
|
||||||
|
controller = BackgroundSharingController(activeStates::add),
|
||||||
|
scope = backgroundScope,
|
||||||
|
)
|
||||||
|
|
||||||
|
runCurrent()
|
||||||
|
core.mutableState.value = CoreState(isInitialized = true, transfers = listOf(transfer(TransferDirection.Receive, TransferStatus.Receiving)))
|
||||||
|
runCurrent()
|
||||||
|
assertEquals(listOf(false), activeStates)
|
||||||
|
|
||||||
|
core.mutableState.value = CoreState(isInitialized = true, transfers = listOf(transfer(TransferDirection.Send, TransferStatus.Importing)))
|
||||||
|
runCurrent()
|
||||||
|
assertEquals(listOf(false, true), activeStates)
|
||||||
|
|
||||||
|
core.mutableState.value = CoreState(isInitialized = true, transfers = listOf(transfer(TransferDirection.Send, TransferStatus.Sharing)))
|
||||||
|
runCurrent()
|
||||||
|
assertEquals(listOf(false, true), activeStates)
|
||||||
|
|
||||||
|
core.mutableState.value = CoreState(isInitialized = true, transfers = listOf(transfer(TransferDirection.Send, TransferStatus.Stopped)))
|
||||||
|
runCurrent()
|
||||||
|
assertEquals(listOf(false, true, false), activeStates)
|
||||||
|
|
||||||
|
coordinator.stop()
|
||||||
|
assertEquals(listOf(false, true, false, false), activeStates)
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun transfer(direction: TransferDirection, status: TransferStatus) = Transfer(
|
||||||
|
localId = "local",
|
||||||
|
transferId = 1UL,
|
||||||
|
direction = direction,
|
||||||
|
status = status,
|
||||||
|
peerId = null,
|
||||||
|
transferName = "Photos",
|
||||||
|
contentHash = "hash",
|
||||||
|
fileCount = 1UL,
|
||||||
|
totalSize = 1UL,
|
||||||
|
ticket = "ticket",
|
||||||
|
accessPolicy = ShareAccessPolicy.RequireApproval,
|
||||||
|
createdAt = 1L,
|
||||||
|
updatedAt = 1L,
|
||||||
|
)
|
||||||
|
}
|
||||||
@@ -2,6 +2,7 @@ package com.vnidrop.app
|
|||||||
|
|
||||||
import androidx.compose.runtime.Composable
|
import androidx.compose.runtime.Composable
|
||||||
import androidx.compose.runtime.remember
|
import androidx.compose.runtime.remember
|
||||||
|
import com.vnidrop.app.background.BackgroundSharingController
|
||||||
import com.vnidrop.app.core.rememberFileSystemService
|
import com.vnidrop.app.core.rememberFileSystemService
|
||||||
import com.vnidrop.app.notifications.JvmLocalNotificationService
|
import com.vnidrop.app.notifications.JvmLocalNotificationService
|
||||||
import com.vnidrop.app.feature.receive.ExternalInvitationController
|
import com.vnidrop.app.feature.receive.ExternalInvitationController
|
||||||
@@ -22,6 +23,7 @@ fun rememberJvmAppDependencies(externalInvitations: ExternalInvitationController
|
|||||||
deviceInfoProvider = JvmDeviceInfoProvider,
|
deviceInfoProvider = JvmDeviceInfoProvider,
|
||||||
fileSystemService = fileSystemService,
|
fileSystemService = fileSystemService,
|
||||||
localNotificationService = JvmLocalNotificationService(),
|
localNotificationService = JvmLocalNotificationService(),
|
||||||
|
backgroundSharingController = BackgroundSharingController { },
|
||||||
externalInvitations = externalInvitations,
|
externalInvitations = externalInvitations,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user