diff options
author | pacien | 2020-12-08 18:03:20 +0100 |
---|---|---|
committer | pacien | 2020-12-08 18:03:20 +0100 |
commit | 355251694d63640f028f3e2c17235d12a8573df6 (patch) | |
tree | 966ffd45ec29797afb440ead00586f4fcdf15589 | |
parent | 2760703484f9b12f8c21c395915f9780b1ae7e9e (diff) | |
download | tincapp-355251694d63640f028f3e2c17235d12a8573df6.tar.gz |
ConfigurationAccessService: prevent service from being stopped when app loses focus
This makes the ConfigurationAccessService (formerly ConfigurationFtpService) start in foreground
through the use of a persistent notification so that it isn't stopped by the system after the app
loses the focus on the user's screen, which happens when the user switches to an FTP client
application on the same device.
-rw-r--r-- | app/src/main/AndroidManifest.xml | 5 | ||||
-rw-r--r-- | app/src/main/java/org/pacien/tincapp/activities/configure/ConfigurationAccessServerFragment.kt (renamed from app/src/main/java/org/pacien/tincapp/activities/configure/ConfigurationFtpServerFragment.kt) | 24 | ||||
-rw-r--r-- | app/src/main/java/org/pacien/tincapp/context/AppNotificationManager.kt | 39 | ||||
-rw-r--r-- | app/src/main/java/org/pacien/tincapp/service/ConfigurationAccessService.kt (renamed from app/src/main/java/org/pacien/tincapp/service/ConfigurationFtpService.kt) | 26 | ||||
-rw-r--r-- | app/src/main/res/drawable/ic_baseline_folder_open_primary_24dp.xml | 29 | ||||
-rw-r--r-- | app/src/main/res/layout/configure_activity.xml | 4 | ||||
-rw-r--r-- | app/src/main/res/layout/configure_tools_configuration_access_fragment.xml (renamed from app/src/main/res/layout/configure_tools_configuration_ftp_server_fragment.xml) | 0 | ||||
-rw-r--r-- | app/src/main/res/values/strings.xml | 6 |
8 files changed, 105 insertions, 28 deletions
diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index 020d62d..c98555f 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml | |||
@@ -24,6 +24,9 @@ | |||
24 | 24 | ||
25 | <uses-permission android:name="android.permission.INTERNET" /> | 25 | <uses-permission android:name="android.permission.INTERNET" /> |
26 | 26 | ||
27 | <!-- needed for the configuration FTP server --> | ||
28 | <uses-permission android:name="android.permission.FOREGROUND_SERVICE" /> | ||
29 | |||
27 | <!-- workaround for broken file permissions on some Android ROMs --> | 30 | <!-- workaround for broken file permissions on some Android ROMs --> |
28 | <uses-permission-sdk-23 android:name="android.permission.WRITE_EXTERNAL_STORAGE" /> | 31 | <uses-permission-sdk-23 android:name="android.permission.WRITE_EXTERNAL_STORAGE" /> |
29 | 32 | ||
@@ -82,7 +85,7 @@ | |||
82 | </service> | 85 | </service> |
83 | 86 | ||
84 | <service | 87 | <service |
85 | android:name="org.pacien.tincapp.service.ConfigurationFtpService"> | 88 | android:name="org.pacien.tincapp.service.ConfigurationAccessService"> |
86 | </service> | 89 | </service> |
87 | 90 | ||
88 | </application> | 91 | </application> |
diff --git a/app/src/main/java/org/pacien/tincapp/activities/configure/ConfigurationFtpServerFragment.kt b/app/src/main/java/org/pacien/tincapp/activities/configure/ConfigurationAccessServerFragment.kt index b97a15e..9fee749 100644 --- a/app/src/main/java/org/pacien/tincapp/activities/configure/ConfigurationFtpServerFragment.kt +++ b/app/src/main/java/org/pacien/tincapp/activities/configure/ConfigurationAccessServerFragment.kt | |||
@@ -26,43 +26,43 @@ import android.view.ViewGroup | |||
26 | import androidx.databinding.Observable | 26 | import androidx.databinding.Observable |
27 | import androidx.databinding.ObservableBoolean | 27 | import androidx.databinding.ObservableBoolean |
28 | import org.pacien.tincapp.activities.BaseFragment | 28 | import org.pacien.tincapp.activities.BaseFragment |
29 | import org.pacien.tincapp.databinding.ConfigureToolsConfigurationFtpServerFragmentBinding | 29 | import org.pacien.tincapp.databinding.ConfigureToolsConfigurationAccessFragmentBinding |
30 | import org.pacien.tincapp.service.ConfigurationFtpService | 30 | import org.pacien.tincapp.service.ConfigurationAccessService |
31 | 31 | ||
32 | /** | 32 | /** |
33 | * @author pacien | 33 | * @author pacien |
34 | */ | 34 | */ |
35 | class ConfigurationFtpServerFragment : BaseFragment() { | 35 | class ConfigurationAccessServerFragment : BaseFragment() { |
36 | private val ftpServerStartListener = object : Observable.OnPropertyChangedCallback() { | 36 | private val ftpServerStartListener = object : Observable.OnPropertyChangedCallback() { |
37 | override fun onPropertyChanged(sender: Observable, propertyId: Int) { | 37 | override fun onPropertyChanged(sender: Observable, propertyId: Int) { |
38 | binding.ftpEnabled = (sender as ObservableBoolean).get() | 38 | binding.ftpEnabled = (sender as ObservableBoolean).get() |
39 | } | 39 | } |
40 | } | 40 | } |
41 | 41 | ||
42 | private lateinit var binding: ConfigureToolsConfigurationFtpServerFragmentBinding | 42 | private lateinit var binding: ConfigureToolsConfigurationAccessFragmentBinding |
43 | 43 | ||
44 | override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View { | 44 | override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View { |
45 | binding = ConfigureToolsConfigurationFtpServerFragmentBinding.inflate(inflater, container, false) | 45 | binding = ConfigureToolsConfigurationAccessFragmentBinding.inflate(inflater, container, false) |
46 | binding.ftpUsername = ConfigurationFtpService.FTP_USERNAME | 46 | binding.ftpUsername = ConfigurationAccessService.FTP_USERNAME |
47 | binding.ftpPassword = ConfigurationFtpService.FTP_PASSWORD | 47 | binding.ftpPassword = ConfigurationAccessService.FTP_PASSWORD |
48 | binding.ftpPort = ConfigurationFtpService.FTP_PORT | 48 | binding.ftpPort = ConfigurationAccessService.FTP_PORT |
49 | binding.toggleFtpState = { toggleServer() } | 49 | binding.toggleFtpState = { toggleServer() } |
50 | return binding.root | 50 | return binding.root |
51 | } | 51 | } |
52 | 52 | ||
53 | override fun onResume() { | 53 | override fun onResume() { |
54 | super.onResume() | 54 | super.onResume() |
55 | ConfigurationFtpService.runningState.addOnPropertyChangedCallback(ftpServerStartListener) | 55 | ConfigurationAccessService.runningState.addOnPropertyChangedCallback(ftpServerStartListener) |
56 | binding.ftpEnabled = ConfigurationFtpService.runningState.get() | 56 | binding.ftpEnabled = ConfigurationAccessService.runningState.get() |
57 | } | 57 | } |
58 | 58 | ||
59 | override fun onPause() { | 59 | override fun onPause() { |
60 | ConfigurationFtpService.runningState.removeOnPropertyChangedCallback(ftpServerStartListener) | 60 | ConfigurationAccessService.runningState.removeOnPropertyChangedCallback(ftpServerStartListener) |
61 | super.onPause() | 61 | super.onPause() |
62 | } | 62 | } |
63 | 63 | ||
64 | private fun toggleServer() { | 64 | private fun toggleServer() { |
65 | val targetServiceIntent = Intent(requireContext(), ConfigurationFtpService::class.java) | 65 | val targetServiceIntent = Intent(requireContext(), ConfigurationAccessService::class.java) |
66 | 66 | ||
67 | if (binding.ftpEnabled) | 67 | if (binding.ftpEnabled) |
68 | requireContext().stopService(targetServiceIntent) | 68 | requireContext().stopService(targetServiceIntent) |
diff --git a/app/src/main/java/org/pacien/tincapp/context/AppNotificationManager.kt b/app/src/main/java/org/pacien/tincapp/context/AppNotificationManager.kt index 38bf6e4..9d731a5 100644 --- a/app/src/main/java/org/pacien/tincapp/context/AppNotificationManager.kt +++ b/app/src/main/java/org/pacien/tincapp/context/AppNotificationManager.kt | |||
@@ -1,6 +1,6 @@ | |||
1 | /* | 1 | /* |
2 | * Tinc App, an Android binding and user interface for the tinc mesh VPN daemon | 2 | * Tinc App, an Android binding and user interface for the tinc mesh VPN daemon |
3 | * Copyright (C) 2017-2019 Pacien TRAN-GIRARD | 3 | * Copyright (C) 2017-2020 Pacien TRAN-GIRARD |
4 | * | 4 | * |
5 | * This program is free software: you can redistribute it and/or modify | 5 | * This program is free software: you can redistribute it and/or modify |
6 | * it under the terms of the GNU General Public License as published by | 6 | * it under the terms of the GNU General Public License as published by |
@@ -18,6 +18,7 @@ | |||
18 | 18 | ||
19 | package org.pacien.tincapp.context | 19 | package org.pacien.tincapp.context |
20 | 20 | ||
21 | import android.app.Notification | ||
21 | import android.app.NotificationChannel | 22 | import android.app.NotificationChannel |
22 | import android.app.NotificationManager | 23 | import android.app.NotificationManager |
23 | import android.app.PendingIntent | 24 | import android.app.PendingIntent |
@@ -35,16 +36,19 @@ import org.pacien.tincapp.R | |||
35 | */ | 36 | */ |
36 | class AppNotificationManager(private val context: Context) { | 37 | class AppNotificationManager(private val context: Context) { |
37 | companion object { | 38 | companion object { |
38 | private const val CHANNEL_ID = "org.pacien.tincapp.notification.channels.error" | 39 | private const val ERROR_CHANNEL_ID = "org.pacien.tincapp.notification.channels.error" |
39 | private const val ERROR_NOTIFICATION_ID = 0 | 40 | private const val CONFIG_ACCESS_CHANNEL_ID = "org.pacien.tincapp.notification.channels.configuration" |
41 | |||
42 | const val ERROR_NOTIFICATION_ID = 0 | ||
43 | const val CONFIG_ACCESS_NOTIFICATION_ID = 1 | ||
40 | } | 44 | } |
41 | 45 | ||
42 | init { | 46 | init { |
43 | if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) registerChannel() | 47 | if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) registerChannels() |
44 | } | 48 | } |
45 | 49 | ||
46 | fun notifyError(title: String, message: String, manualLink: String? = null) { | 50 | fun notifyError(title: String, message: String, manualLink: String? = null) { |
47 | val notification = NotificationCompat.Builder(context, CHANNEL_ID) | 51 | val notification = NotificationCompat.Builder(context, ERROR_CHANNEL_ID) |
48 | .setSmallIcon(R.drawable.ic_warning_primary_24dp) | 52 | .setSmallIcon(R.drawable.ic_warning_primary_24dp) |
49 | .setContentTitle(title) | 53 | .setContentTitle(title) |
50 | .setContentText(message) | 54 | .setContentText(message) |
@@ -62,13 +66,26 @@ class AppNotificationManager(private val context: Context) { | |||
62 | NotificationManagerCompat.from(context).cancelAll() | 66 | NotificationManagerCompat.from(context).cancelAll() |
63 | } | 67 | } |
64 | 68 | ||
69 | fun newConfigurationAccessNotificationBuilder() = | ||
70 | NotificationCompat.Builder(context, CONFIG_ACCESS_CHANNEL_ID) | ||
71 | |||
65 | @RequiresApi(Build.VERSION_CODES.O) | 72 | @RequiresApi(Build.VERSION_CODES.O) |
66 | private fun registerChannel() { | 73 | private fun registerChannels() { |
67 | val name = context.getString(R.string.notification_error_channel_name) | 74 | context.getSystemService(NotificationManager::class.java) |
68 | val importance = NotificationManager.IMPORTANCE_HIGH | 75 | .apply { |
69 | val channel = NotificationChannel(CHANNEL_ID, name, importance) | 76 | createNotificationChannel(NotificationChannel( |
70 | val notificationManager = context.getSystemService(NotificationManager::class.java) | 77 | ERROR_CHANNEL_ID, |
71 | notificationManager.createNotificationChannel(channel) | 78 | context.getString(R.string.notification_error_channel_name), |
79 | NotificationManager.IMPORTANCE_HIGH | ||
80 | )) | ||
81 | } | ||
82 | .apply { | ||
83 | createNotificationChannel(NotificationChannel( | ||
84 | CONFIG_ACCESS_CHANNEL_ID, | ||
85 | context.getString(R.string.notification_config_access_channel_name), | ||
86 | NotificationManager.IMPORTANCE_MIN | ||
87 | )) | ||
88 | } | ||
72 | } |