diff options
Diffstat (limited to 'app/src/main/java/org/pacien')
4 files changed, 92 insertions, 9 deletions
diff --git a/app/src/main/java/org/pacien/tincapp/context/App.kt b/app/src/main/java/org/pacien/tincapp/context/App.kt index 2d9151e..88308ba 100644 --- a/app/src/main/java/org/pacien/tincapp/context/App.kt +++ b/app/src/main/java/org/pacien/tincapp/context/App.kt | |||
@@ -25,8 +25,6 @@ import android.net.Uri | |||
25 | import android.os.Build | 25 | import android.os.Build |
26 | import android.os.Handler | 26 | import android.os.Handler |
27 | import android.support.annotation.StringRes | 27 | import android.support.annotation.StringRes |
28 | import android.support.v7.app.AlertDialog | ||
29 | import android.view.WindowManager | ||
30 | import org.pacien.tincapp.BuildConfig | 28 | import org.pacien.tincapp.BuildConfig |
31 | import org.pacien.tincapp.R | 29 | import org.pacien.tincapp.R |
32 | import org.slf4j.LoggerFactory | 30 | import org.slf4j.LoggerFactory |
@@ -59,16 +57,13 @@ class App : Application() { | |||
59 | private var appContext: Context? = null | 57 | private var appContext: Context? = null |
60 | private var handler: Handler? = null | 58 | private var handler: Handler? = null |
61 | 59 | ||
60 | val notificationManager: AppNotificationManager by lazy { AppNotificationManager(appContext!!) } | ||
61 | |||
62 | fun getContext() = appContext!! | 62 | fun getContext() = appContext!! |
63 | fun getResources() = getContext().resources!! | 63 | fun getResources() = getContext().resources!! |
64 | 64 | ||
65 | fun alert(@StringRes title: Int, msg: String, manualLink: String? = null) = handler!!.post { | 65 | fun alert(@StringRes title: Int, msg: String, manualLink: String? = null) = |
66 | AlertDialog.Builder(getContext(), R.style.Theme_AppCompat_Dialog) | 66 | notificationManager.notifyError(appContext!!.getString(title), msg, manualLink) |
67 | .setTitle(title).setMessage(msg) | ||
68 | .apply { if (manualLink != null) setNeutralButton(R.string.action_open_manual) { _, _ -> openURL(manualLink) } } | ||
69 | .setPositiveButton(R.string.action_close) { _, _ -> Unit } | ||
70 | .create().apply { window.setType(WindowManager.LayoutParams.TYPE_SYSTEM_ERROR) }.show() | ||
71 | } | ||
72 | 67 | ||
73 | fun openURL(url: String) { | 68 | fun openURL(url: String) { |
74 | val intent = Intent(Intent.ACTION_VIEW, Uri.parse(url)) | 69 | val intent = Intent(Intent.ACTION_VIEW, Uri.parse(url)) |
diff --git a/app/src/main/java/org/pacien/tincapp/context/AppNotificationManager.kt b/app/src/main/java/org/pacien/tincapp/context/AppNotificationManager.kt new file mode 100644 index 0000000..0f9092a --- /dev/null +++ b/app/src/main/java/org/pacien/tincapp/context/AppNotificationManager.kt | |||
@@ -0,0 +1,84 @@ | |||
1 | /* | ||
2 | * tinc app, an Android binding and user interface for the tinc mesh VPN daemon | ||
3 | * Copyright (C) 2017-2018 Pacien TRAN-GIRARD | ||
4 | * | ||
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 | ||
7 | * the Free Software Foundation, either version 3 of the License, or | ||
8 | * (at your option) any later version. | ||
9 | * | ||
10 | * This program is distributed in the hope that it will be useful, | ||
11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
13 | * GNU General Public License for more details. | ||
14 | * | ||
15 | * You should have received a copy of the GNU General Public License | ||
16 | * along with this program. If not, see <https://www.gnu.org/licenses/>. | ||
17 | */ | ||
18 | |||
19 | package org.pacien.tincapp.context | ||
20 | |||
21 | import android.app.NotificationChannel | ||
22 | import android.app.NotificationManager | ||
23 | import android.app.PendingIntent | ||
24 | import android.content.Context | ||
25 | import android.content.Intent | ||
26 | import android.net.Uri | ||
27 | import android.os.Build | ||
28 | import android.support.annotation.RequiresApi | ||
29 | import android.support.v4.app.NotificationCompat | ||
30 | import android.support.v4.app.NotificationManagerCompat | ||
31 | import org.pacien.tincapp.R | ||
32 | |||
33 | /** | ||
34 | * @author pacien | ||
35 | */ | ||
36 | class AppNotificationManager(private val context: Context) { | ||
37 | companion object { | ||
38 | private const val CHANNEL_ID = "org.pacien.tincapp.notification.channels.error" | ||
39 | private const val ERROR_NOTIFICATION_ID = 0 | ||
40 | } | ||
41 | |||
42 | init { | ||
43 | if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) registerChannel() | ||
44 | } | ||
45 | |||
46 | fun notifyError(title: String, message: String, manualLink: String? = null) { | ||
47 | val notification = NotificationCompat.Builder(context, CHANNEL_ID) | ||
48 | .setSmallIcon(R.drawable.ic_warning_primary_24dp) | ||
49 | .setContentTitle(title) | ||
50 | .setContentText(message) | ||
51 | .setStyle(NotificationCompat.BigTextStyle().bigText(message)) | ||
52 | .setHighPriority() | ||
53 | .setAutoCancel(true) | ||
54 | .apply { if (manualLink != null) setManualLink(manualLink) } | ||
55 | .build() | ||
56 | |||
57 | NotificationManagerCompat.from(context) | ||
58 | .notify(ERROR_NOTIFICATION_ID, notification) | ||
59 | } | ||
60 | |||
61 | fun dismissAll() { | ||
62 | NotificationManagerCompat.from(context).cancelAll() | ||
63 | } | ||
64 | |||
65 | @RequiresApi(Build.VERSION_CODES.O) | ||
66 | private fun registerChannel() { | ||
67 | val name = context.getString(R.string.notification_channel_error_name) | ||
68 | val importance = NotificationManager.IMPORTANCE_HIGH | ||
69 | val channel = NotificationChannel(CHANNEL_ID, name, importance) | ||
70 | val notificationManager = context.getSystemService(NotificationManager::class.java) | ||
71 | notificationManager.createNotificationChannel(channel) | ||
72 | } | ||
73 | |||
74 | private fun NotificationCompat.Builder.setHighPriority() = apply { | ||
75 | priority = NotificationCompat.PRIORITY_MAX | ||
76 | if (Build.VERSION.SDK_INT < Build.VERSION_CODES.O) setDefaults(NotificationCompat.DEFAULT_SOUND) // force heads-up notification | ||
77 | } | ||
78 | |||
79 | private fun NotificationCompat.Builder.setManualLink(manualLink: String) = apply { | ||
80 | val intent = Intent(Intent.ACTION_VIEW, Uri.parse(manualLink)) | ||
81 | val pendingIntent = PendingIntent.getActivity(context, 0, intent, 0) | ||
82 | addAction(R.drawable.ic_help_primary_24dp, context.getString(R.string.action_open_manual), pendingIntent) | ||
83 | } | ||
84 | } | ||
diff --git a/app/src/main/java/org/pacien/tincapp/service/TincVpnService.kt b/app/src/main/java/org/pacien/tincapp/service/TincVpnService.kt index 30d7c8b..6ed9a34 100644 --- a/app/src/main/java/org/pacien/tincapp/service/TincVpnService.kt +++ b/app/src/main/java/org/pacien/tincapp/service/TincVpnService.kt | |||
@@ -197,6 +197,8 @@ class TincVpnService : VpnService() { | |||
197 | fun isConnected() = !(daemon?.isDone ?: true) | 197 | fun isConnected() = !(daemon?.isDone ?: true) |
198 | 198 | ||
199 | fun connect(netName: String, passphrase: String? = null) { | 199 | fun connect(netName: String, passphrase: String? = null) { |
200 | App.notificationManager.dismissAll() | ||
201 | |||
200 | App.getContext().startService( | 202 | App.getContext().startService( |
201 | Intent(App.getContext(), TincVpnService::class.java) | 203 | Intent(App.getContext(), TincVpnService::class.java) |
202 | .setAction(Actions.ACTION_CONNECT) | 204 | .setAction(Actions.ACTION_CONNECT) |
diff --git a/app/src/main/java/org/pacien/tincapp/utils/ProgressModal.kt b/app/src/main/java/org/pacien/tincapp/utils/ProgressModal.kt index 379e3af..6bf02d5 100644 --- a/app/src/main/java/org/pacien/tincapp/utils/ProgressModal.kt +++ b/app/src/main/java/org/pacien/tincapp/utils/ProgressModal.kt | |||
@@ -27,6 +27,8 @@ import android.widget.TextView | |||
27 | import org.pacien.tincapp.R | 27 | import org.pacien.tincapp.R |
28 | 28 | ||
29 | /** | 29 | /** |
30 | * An indefinite progress dialog replacing the deprecated `android.app.ProgressDialog`. | ||
31 | * | ||
30 | * @author pacien | 32 | * @author pacien |
31 | */ | 33 | */ |
32 | object ProgressModal { | 34 | object ProgressModal { |