summaryrefslogtreecommitdiff
path: root/app/src/main/java/se/leap/bitmaskclient/VpnNotificationManager.java
diff options
context:
space:
mode:
authorcyBerta <cyberta@riseup.net>2020-12-29 00:54:08 +0100
committercyBerta <cyberta@riseup.net>2020-12-29 00:54:08 +0100
commit6b032b751324a30120cfaabe88940f95171df11f (patch)
treeb6b26b84358726a02e27558562e7e9ea70a7aaa0 /app/src/main/java/se/leap/bitmaskclient/VpnNotificationManager.java
parent16da1eeb5180cbb4a0d916785a08ccbcd3c1d74e (diff)
new year cleanup: restructure messy project
Diffstat (limited to 'app/src/main/java/se/leap/bitmaskclient/VpnNotificationManager.java')
-rw-r--r--app/src/main/java/se/leap/bitmaskclient/VpnNotificationManager.java353
1 files changed, 0 insertions, 353 deletions
diff --git a/app/src/main/java/se/leap/bitmaskclient/VpnNotificationManager.java b/app/src/main/java/se/leap/bitmaskclient/VpnNotificationManager.java
deleted file mode 100644
index 290a9aa9..00000000
--- a/app/src/main/java/se/leap/bitmaskclient/VpnNotificationManager.java
+++ /dev/null
@@ -1,353 +0,0 @@
-/**
- * Copyright (c) 2018 LEAP Encryption Access Project and contributers
- *
- * 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 <http://www.gnu.org/licenses/>.
- */
-package se.leap.bitmaskclient;
-
-import android.annotation.TargetApi;
-import android.app.Notification;
-import android.app.NotificationChannel;
-import android.app.NotificationManager;
-import android.app.PendingIntent;
-import android.content.Context;
-import android.content.Intent;
-import android.graphics.Color;
-import android.graphics.Typeface;
-import android.os.Build;
-import android.os.Bundle;
-import androidx.annotation.NonNull;
-import androidx.core.app.NotificationCompat;
-import androidx.core.app.NotificationManagerCompat;
-import android.text.Spannable;
-import android.text.SpannableString;
-import android.text.TextUtils;
-import android.text.style.StyleSpan;
-import android.widget.RemoteViews;
-
-import de.blinkt.openvpn.LaunchVPN;
-import de.blinkt.openvpn.core.ConnectionStatus;
-import de.blinkt.openvpn.core.OpenVPNService;
-import se.leap.bitmaskclient.eip.VoidVpnService;
-
-import static android.os.Build.VERSION_CODES.O;
-import static androidx.core.app.NotificationCompat.PRIORITY_HIGH;
-import static androidx.core.app.NotificationCompat.PRIORITY_MAX;
-import static androidx.core.app.NotificationCompat.PRIORITY_MIN;
-import static android.text.TextUtils.isEmpty;
-import static de.blinkt.openvpn.core.ConnectionStatus.LEVEL_NONETWORK;
-import static de.blinkt.openvpn.core.ConnectionStatus.LEVEL_WAITING_FOR_USER_INPUT;
-import static se.leap.bitmaskclient.Constants.ASK_TO_CANCEL_VPN;
-import static se.leap.bitmaskclient.Constants.EIP_ACTION_STOP_BLOCKING_VPN;
-import static se.leap.bitmaskclient.MainActivity.ACTION_SHOW_VPN_FRAGMENT;
-
-/**
- * Created by cyberta on 14.01.18.
- */
-
-public class VpnNotificationManager {
-
- Context context;
- private VpnServiceCallback vpnServiceCallback;
- private NotificationManager notificationManager;
- private NotificationManagerCompat compatNotificationManager;
- private String[] notificationChannels = {
- OpenVPNService.NOTIFICATION_CHANNEL_NEWSTATUS_ID,
- OpenVPNService.NOTIFICATION_CHANNEL_BG_ID,
- VoidVpnService.NOTIFICATION_CHANNEL_NEWSTATUS_ID};
- private String lastNotificationChannel = "";
-
- public interface VpnServiceCallback {
- void onNotificationBuild(int notificationId, Notification notification);
- void onNotificationStop();
- }
-
- public VpnNotificationManager(@NonNull Context context, @NonNull VpnServiceCallback vpnServiceCallback) {
- this.context = context;
- notificationManager = (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE);
- compatNotificationManager = NotificationManagerCompat.from(context);
- this.vpnServiceCallback = vpnServiceCallback;
- }
-
- public void buildVoidVpnNotification(final String msg, String tickerText, ConnectionStatus status) {
- //TODO: implement extra Dashboard.ACTION_ASK_TO_CANCEL_BLOCKING_VPN
- NotificationCompat.Action.Builder actionBuilder = new NotificationCompat.Action.Builder(R.drawable.ic_menu_close_clear_cancel,
- context.getString(R.string.vpn_button_turn_off_blocking), getStopVoidVpnIntent());
-
- buildVpnNotification(
- context.getString(R.string.void_vpn_title),
- msg,
- null,
- tickerText,
- status,
- VoidVpnService.NOTIFICATION_CHANNEL_NEWSTATUS_ID,
- PRIORITY_MAX,
- 0,
- getMainActivityIntent(),
- actionBuilder.build());
- }
-
- public void stopNotifications(String notificationChannelNewstatusId) {
- vpnServiceCallback.onNotificationStop();
- compatNotificationManager.cancel(notificationChannelNewstatusId.hashCode());
- }
-
- public void deleteNotificationChannel(String notificationChannel) {
- if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O &&
- notificationManager.getNotificationChannel(notificationChannel) != null) {
- notificationManager.deleteNotificationChannel(notificationChannel);
- }
- }
-
- /**
- * @param msg
- * @param tickerText
- * @param status
- * @param when
- */
- public void buildOpenVpnNotification(String profileName, boolean isObfuscated, String msg, String tickerText, ConnectionStatus status, long when, String notificationChannelNewstatusId) {
- String cancelString;
- CharSequence bigmessage = null;
- String ghostIcon = new String(Character.toChars(0x1f309));
-
- switch (status) {
- // show cancel if no connection
- case LEVEL_START:
- case LEVEL_NONETWORK:
- case LEVEL_CONNECTING_SERVER_REPLIED:
- case LEVEL_CONNECTING_NO_SERVER_REPLY_YET:
- cancelString = context.getString(R.string.cancel);
- if (isObfuscated && Build.VERSION.SDK_INT > Build.VERSION_CODES.KITKAT) {
- Spannable spannable = new SpannableString(context.getString(R.string.obfuscated_connection_try));
- spannable.setSpan(new StyleSpan(Typeface.ITALIC), 0, spannable.length() -1, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
- bigmessage = TextUtils.concat(spannable, " " + ghostIcon + "\n" + msg);
- }
- break;
-
- // show disconnect if connection exists
- case LEVEL_CONNECTED:
- if (isObfuscated && Build.VERSION.SDK_INT > Build.VERSION_CODES.KITKAT) {
- Spannable spannable = new SpannableString(context.getString(R.string.obfuscated_connection));
- spannable.setSpan(new StyleSpan(Typeface.ITALIC), 0, spannable.length() -1, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
- bigmessage = TextUtils.concat(spannable, " " + ghostIcon + "\n" + msg);
- }
- default:
- cancelString = context.getString(R.string.cancel_connection);
- }
-
- if (isObfuscated) {
- msg = ghostIcon + " " + msg;
- }
-
- NotificationCompat.Action.Builder actionBuilder = new NotificationCompat.Action.
- Builder(R.drawable.ic_menu_close_clear_cancel, cancelString, getDisconnectIntent());
- String title;
- String appName = context.getString(R.string.app_name);
- if (isEmpty(profileName)) {
- title = appName;
- } else {
- title = context.getString(R.string.notifcation_title_bitmask, appName, profileName);
- }
-
- PendingIntent contentIntent;
- if (status == LEVEL_WAITING_FOR_USER_INPUT)
- contentIntent = getUserInputIntent(msg);
- else
- contentIntent = getMainActivityIntent();
-
- int priority;
- if (OpenVPNService.NOTIFICATION_CHANNEL_NEWSTATUS_ID.equals(notificationChannelNewstatusId)) {
- priority = PRIORITY_HIGH;
- } else {
- // background channel
- priority = PRIORITY_MIN;
- }
-
- buildVpnNotification(
- title,
- msg,
- bigmessage,
- tickerText,
- status,
- notificationChannelNewstatusId,
- priority,
- when,
- contentIntent,
- actionBuilder.build());
- }
-
-
- @TargetApi(O)
- public void createVoidVpnNotificationChannel() {
- if (Build.VERSION.SDK_INT < Build.VERSION_CODES.O) {
- return;
- }
-
- // Connection status change messages
- CharSequence name = context.getString(R.string.channel_name_status);
- NotificationChannel mChannel = new NotificationChannel(VoidVpnService.NOTIFICATION_CHANNEL_NEWSTATUS_ID,
- name, NotificationManager.IMPORTANCE_DEFAULT);
-
- mChannel.setDescription(context.getString(R.string.channel_description_status));
- mChannel.enableLights(true);
-
- mChannel.setLightColor(Color.BLUE);
- mChannel.setSound(null, null);
- notificationManager.createNotificationChannel(mChannel);
- }
-
- @TargetApi(O)
- public void createOpenVpnNotificationChannel() {
- if (Build.VERSION.SDK_INT < Build.VERSION_CODES.O) {
- return;
- }
-
- // Background message
- CharSequence name = context.getString(R.string.channel_name_background);
- NotificationChannel mChannel = new NotificationChannel(OpenVPNService.NOTIFICATION_CHANNEL_BG_ID,
- name, NotificationManager.IMPORTANCE_MIN);
-
- mChannel.setDescription(context.getString(R.string.channel_description_background));
- mChannel.enableLights(false);
-
- mChannel.setLightColor(Color.DKGRAY);
- notificationManager.createNotificationChannel(mChannel);
-
- // Connection status change messages
- name = context.getString(R.string.channel_name_status);
- mChannel = new NotificationChannel(OpenVPNService.NOTIFICATION_CHANNEL_NEWSTATUS_ID,
- name, NotificationManager.IMPORTANCE_DEFAULT);
-
-
- mChannel.setDescription(context.getString(R.string.channel_description_status));
- mChannel.enableLights(true);
-
- mChannel.setLightColor(Color.BLUE);
- mChannel.setSound(null, null);
- notificationManager.createNotificationChannel(mChannel);
- }
-
- /**
- * @return a custom remote view for notifications for API 16 - 19
- */
- private RemoteViews getKitkatCustomRemoteView(ConnectionStatus status, String title, String message) {
- int iconResource = getIconByConnectionStatus(status);
- RemoteViews remoteViews = new RemoteViews(context.getPackageName(), R.layout.v_custom_notification);
- remoteViews.setImageViewResource(R.id.image_icon, iconResource);
- remoteViews.setTextViewText(R.id.message, message);
- remoteViews.setTextViewText(R.id.title, title);
-
- return remoteViews;
- }
-
- private void buildVpnNotification(String title, String message, CharSequence bigMessage, String tickerText, ConnectionStatus status, String notificationChannelNewstatusId, int priority, long when, PendingIntent contentIntent, NotificationCompat.Action notificationAction) {
- NotificationCompat.Builder nCompatBuilder = new NotificationCompat.Builder(context, notificationChannelNewstatusId);
- int icon = getIconByConnectionStatus(status);
-
- // this is a workaround to avoid confusion between the Android's system vpn notification
- // showing a filled out key icon and the bitmask icon indicating a different state.
- if (Build.VERSION.SDK_INT <= Build.VERSION_CODES.KITKAT &&
- notificationChannelNewstatusId.equals(OpenVPNService.NOTIFICATION_CHANNEL_NEWSTATUS_ID)) {
- if (status != LEVEL_NONETWORK) {
- // removes the icon from the system status bar
- icon = android.R.color.transparent;
- // adds the icon to the notification in the notification drawer
- nCompatBuilder.setContent(getKitkatCustomRemoteView(status, title, message));
- }
- } else {
- nCompatBuilder.setStyle(new NotificationCompat.BigTextStyle().
- setBigContentTitle(title).
- bigText(bigMessage));
- }
- nCompatBuilder.addAction(notificationAction);
- nCompatBuilder.setContentTitle(title);
- nCompatBuilder.setCategory(NotificationCompat.CATEGORY_SERVICE);
- nCompatBuilder.setLocalOnly(true);
- nCompatBuilder.setContentText(message);
- nCompatBuilder.setOnlyAlertOnce(true);
- nCompatBuilder.setSmallIcon(icon);
- nCompatBuilder.setPriority(priority);
- nCompatBuilder.setOngoing(true);
- nCompatBuilder.setUsesChronometer(true);
- nCompatBuilder.setWhen(when);
- nCompatBuilder.setContentIntent(contentIntent);
- if (!isEmpty(tickerText)) {
- nCompatBuilder.setTicker(tickerText);
- }
-
- Notification notification = nCompatBuilder.build();
- int notificationId = notificationChannelNewstatusId.hashCode();
-
- if (!notificationChannelNewstatusId.equals(lastNotificationChannel)) {
- // Cancel old notification
- for (String channel : notificationChannels) {
- stopNotifications(channel);
- }
- }
-
- compatNotificationManager.notify(notificationId, notification);
- vpnServiceCallback.onNotificationBuild(notificationId, notification);
- lastNotificationChannel = notificationChannelNewstatusId;
- }
-
- private PendingIntent getMainActivityIntent() {
- Intent startActivity = new Intent(context, StartActivity.class);
- return PendingIntent.getActivity(context, 0, startActivity, PendingIntent.FLAG_CANCEL_CURRENT);
- }
-
- private PendingIntent getStopVoidVpnIntent() {
- Intent stopVoidVpnIntent = new Intent (context, VoidVpnService.class);
- stopVoidVpnIntent.setAction(EIP_ACTION_STOP_BLOCKING_VPN);
- return PendingIntent.getService(context, 0, stopVoidVpnIntent, PendingIntent.FLAG_CANCEL_CURRENT);
- }
-
- private PendingIntent getDisconnectIntent() {
- Intent disconnectVPN = new Intent(context, MainActivity.class);
- disconnectVPN.setAction(ACTION_SHOW_VPN_FRAGMENT);
- disconnectVPN.putExtra(ASK_TO_CANCEL_VPN, true);
- disconnectVPN.addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP);
- return PendingIntent.getActivity(context, 0, disconnectVPN, PendingIntent.FLAG_CANCEL_CURRENT);
- }
-
- private PendingIntent getUserInputIntent(String needed) {
- Intent intent = new Intent(context, LaunchVPN.class);
- intent.addFlags(Intent.FLAG_ACTIVITY_REORDER_TO_FRONT);
- intent.putExtra("need", needed);
- Bundle b = new Bundle();
- b.putString("need", needed);
- PendingIntent pIntent = PendingIntent.getActivity(context, 12, intent, 0);
- return pIntent;
- }
-
- private int getIconByConnectionStatus(ConnectionStatus level) {
- switch (level) {
- case LEVEL_CONNECTED:
- return R.drawable.ic_stat_vpn;
- case LEVEL_AUTH_FAILED:
- case LEVEL_NONETWORK:
- case LEVEL_NOTCONNECTED:
- return R.drawable.ic_stat_vpn_offline;
- case LEVEL_CONNECTING_NO_SERVER_REPLY_YET:
- case LEVEL_WAITING_FOR_USER_INPUT:
- case LEVEL_CONNECTING_SERVER_REPLIED:
- return R.drawable.ic_stat_vpn_outline;
- case LEVEL_BLOCKING:
- return R.drawable.ic_stat_vpn_blocking;
- case UNKNOWN_LEVEL:
- default:
- return R.drawable.ic_stat_vpn_offline;
- }
- }
-
-}