diff options
author | Guillaume Jacquart <guillaume.jacquart@hoodbrains.com> | 2023-05-02 21:25:17 +0200 |
---|---|---|
committer | Guillaume Jacquart <guillaume.jacquart@hoodbrains.com> | 2023-05-02 22:00:35 +0200 |
commit | a8874167f663885f2d3371801cf03681576ac817 (patch) | |
tree | 5be07b8768142efeade536d4135f2250c1ac9071 /app/src/main/java/foundation/e/advancedprivacy/Notifications.kt | |
parent | a0ee04ea9dbc0802c828afdf660eb37dc6fa350f (diff) | |
download | advanced-privacy-a8874167f663885f2d3371801cf03681576ac817.tar.gz |
1200: rename everything to AdvancedPrivacy
Diffstat (limited to 'app/src/main/java/foundation/e/advancedprivacy/Notifications.kt')
-rw-r--r-- | app/src/main/java/foundation/e/advancedprivacy/Notifications.kt | 210 |
1 files changed, 210 insertions, 0 deletions
diff --git a/app/src/main/java/foundation/e/advancedprivacy/Notifications.kt b/app/src/main/java/foundation/e/advancedprivacy/Notifications.kt new file mode 100644 index 0000000..68c4bd3 --- /dev/null +++ b/app/src/main/java/foundation/e/advancedprivacy/Notifications.kt @@ -0,0 +1,210 @@ +/* + * Copyright (C) 2022 MURENA SAS + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <https://www.gnu.org/licenses/>. + */ + +package foundation.e.advancedprivacy + +import android.app.NotificationChannel +import android.app.NotificationManager +import android.app.PendingIntent +import android.content.Context +import android.content.Intent +import androidx.annotation.StringRes +import androidx.core.app.NotificationCompat +import androidx.core.app.NotificationManagerCompat +import foundation.e.advancedprivacy.domain.entities.InternetPrivacyMode +import foundation.e.advancedprivacy.domain.entities.MainFeatures +import foundation.e.advancedprivacy.domain.usecases.GetQuickPrivacyStateUseCase +import foundation.e.advancedprivacy.main.MainActivity +import foundation.e.privacymodules.permissions.PermissionsPrivacyModule +import kotlinx.coroutines.CoroutineScope +import kotlinx.coroutines.flow.distinctUntilChanged +import kotlinx.coroutines.flow.launchIn +import kotlinx.coroutines.flow.map +import kotlinx.coroutines.flow.onEach + +object Notifications { + const val CHANNEL_FIRST_BOOT = "first_boot_notification" + const val CHANNEL_FAKE_LOCATION_FLAG = "fake_location_flag" + const val CHANNEL_IPSCRAMBLING_FLAG = "ipscrambling_flag" + + const val NOTIFICATION_FIRST_BOOT = 1000 + const val NOTIFICATION_FAKE_LOCATION_FLAG = NOTIFICATION_FIRST_BOOT + 1 + const val NOTIFICATION_IPSCRAMBLING_FLAG = NOTIFICATION_FAKE_LOCATION_FLAG + 1 + + fun showFirstBootNotification(context: Context) { + createNotificationFirstBootChannel(context) + val notificationBuilder: NotificationCompat.Builder = notificationBuilder( + context, + NotificationContent( + channelId = CHANNEL_FIRST_BOOT, + icon = R.drawable.ic_notification_logo, + title = R.string.first_notification_title, + description = R.string.first_notification_summary, + destinationIntent = + context.packageManager.getLaunchIntentForPackage(context.packageName) + ) + ) + .setAutoCancel(true) + + NotificationManagerCompat.from(context).notify( + NOTIFICATION_FIRST_BOOT, notificationBuilder.build() + ) + } + + fun startListening( + appContext: Context, + getQuickPrivacyStateUseCase: GetQuickPrivacyStateUseCase, + permissionsPrivacyModule: PermissionsPrivacyModule, + appScope: CoroutineScope + ) { + createNotificationFlagChannel( + context = appContext, + permissionsPrivacyModule = permissionsPrivacyModule, + channelId = CHANNEL_FAKE_LOCATION_FLAG, + channelName = R.string.notifications_fake_location_channel_name, + channelDescription = R.string.notifications_fake_location_channel_description + ) + + createNotificationFlagChannel( + context = appContext, + permissionsPrivacyModule = permissionsPrivacyModule, + channelId = CHANNEL_IPSCRAMBLING_FLAG, + channelName = R.string.notifications_ipscrambling_channel_name, + channelDescription = R.string.notifications_ipscrambling_channel_description + ) + + getQuickPrivacyStateUseCase.isLocationHidden.onEach { + if (it) { + showFlagNotification(appContext, MainFeatures.FAKE_LOCATION) + } else { + hideFlagNotification(appContext, MainFeatures.FAKE_LOCATION) + } + }.launchIn(appScope) + + getQuickPrivacyStateUseCase.ipScramblingMode.map { + it != InternetPrivacyMode.REAL_IP + }.distinctUntilChanged().onEach { + if (it) { + showFlagNotification(appContext, MainFeatures.IP_SCRAMBLING) + } else { + hideFlagNotification(appContext, MainFeatures.IP_SCRAMBLING) + } + }.launchIn(appScope) + } + + private fun createNotificationFirstBootChannel(context: Context) { + val channel = NotificationChannel( + CHANNEL_FIRST_BOOT, + context.getString(R.string.notifications_first_boot_channel_name), + NotificationManager.IMPORTANCE_HIGH + ) + NotificationManagerCompat.from(context).createNotificationChannel(channel) + } + + private fun createNotificationFlagChannel( + context: Context, + permissionsPrivacyModule: PermissionsPrivacyModule, + channelId: String, + @StringRes channelName: Int, + @StringRes channelDescription: Int, + ) { + val channel = NotificationChannel( + channelId, context.getString(channelName), NotificationManager.IMPORTANCE_LOW + ) + channel.description = context.getString(channelDescription) + permissionsPrivacyModule.setBlockable(channel) + NotificationManagerCompat.from(context).createNotificationChannel(channel) + } + + private fun showFlagNotification(context: Context, feature: MainFeatures) { + when (feature) { + MainFeatures.FAKE_LOCATION -> showFlagNotification( + context = context, + id = NOTIFICATION_FAKE_LOCATION_FLAG, + content = NotificationContent( + channelId = CHANNEL_FAKE_LOCATION_FLAG, + icon = R.drawable.ic_fmd_bad, + title = R.string.notifications_fake_location_title, + description = R.string.notifications_fake_location_content, + destinationIntent = MainActivity.createFakeLocationIntent(context), + ) + ) + MainFeatures.IP_SCRAMBLING -> showFlagNotification( + context = context, + id = NOTIFICATION_IPSCRAMBLING_FLAG, + content = NotificationContent( + channelId = CHANNEL_IPSCRAMBLING_FLAG, + icon = R.drawable.ic_language, + title = R.string.notifications_ipscrambling_title, + description = R.string.notifications_ipscrambling_content, + destinationIntent = MainActivity.createIpScramblingIntent(context), + ) + ) + else -> {} + } + } + + private fun showFlagNotification( + context: Context, + id: Int, + content: NotificationContent, + ) { + val builder = notificationBuilder(context, content) + .setPriority(NotificationCompat.PRIORITY_LOW) + .setOngoing(true) + + NotificationManagerCompat.from(context).notify(id, builder.build()) + } + + private fun hideFlagNotification(context: Context, feature: MainFeatures) { + val id = when (feature) { + MainFeatures.FAKE_LOCATION -> NOTIFICATION_FAKE_LOCATION_FLAG + MainFeatures.IP_SCRAMBLING -> NOTIFICATION_IPSCRAMBLING_FLAG + else -> return + } + NotificationManagerCompat.from(context).cancel(id) + } + + private data class NotificationContent( + val channelId: String, + val icon: Int, + val title: Int, + val description: Int, + val destinationIntent: Intent? + ) + + private fun notificationBuilder( + context: Context, + content: NotificationContent + ): NotificationCompat.Builder { + val builder = NotificationCompat.Builder(context, content.channelId) + .setSmallIcon(content.icon) + .setPriority(NotificationCompat.PRIORITY_LOW) + .setContentTitle(context.getString(content.title)) + .setStyle(NotificationCompat.BigTextStyle().bigText(context.getString(content.description))) + + content.destinationIntent?.let { + it.flags = Intent.FLAG_ACTIVITY_NEW_TASK or Intent.FLAG_ACTIVITY_CLEAR_TASK + val pendingIntent: PendingIntent = PendingIntent.getActivity( + context, 0, it, PendingIntent.FLAG_IMMUTABLE + ) + builder.setContentIntent(pendingIntent) + } + + return builder + } +} |