From 76884123b22dbdd7538add0d931c5f2d8e660ed2 Mon Sep 17 00:00:00 2001 From: cyBerta Date: Tue, 16 Jan 2018 13:59:33 +0100 Subject: #8788 implement VpnNotificationManager to handle notifications from VoidVPN and OpenVPN --- .../se/leap/bitmaskclient/eip/VoidVpnService.java | 139 +++++---------------- 1 file changed, 33 insertions(+), 106 deletions(-) (limited to 'app/src/main/java/se/leap/bitmaskclient/eip') diff --git a/app/src/main/java/se/leap/bitmaskclient/eip/VoidVpnService.java b/app/src/main/java/se/leap/bitmaskclient/eip/VoidVpnService.java index 792de2cb..6d49d83d 100644 --- a/app/src/main/java/se/leap/bitmaskclient/eip/VoidVpnService.java +++ b/app/src/main/java/se/leap/bitmaskclient/eip/VoidVpnService.java @@ -1,19 +1,27 @@ +/** + * Copyright (c) 2013 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 . + */ package se.leap.bitmaskclient.eip; -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.content.SharedPreferences; -import android.graphics.Color; import android.net.VpnService; import android.os.Build; import android.os.ParcelFileDescriptor; -import android.support.v4.app.NotificationCompat; -import android.support.v4.app.NotificationManagerCompat; import android.util.Log; import java.io.IOException; @@ -22,10 +30,9 @@ import java.util.Observer; import de.blinkt.openvpn.core.ConnectionStatus; import de.blinkt.openvpn.core.VpnStatus; -import se.leap.bitmaskclient.Dashboard; import se.leap.bitmaskclient.R; +import se.leap.bitmaskclient.VpnNotificationManager; -import static android.os.Build.VERSION_CODES.O; import static se.leap.bitmaskclient.Constants.EIP_ACTION_START_ALWAYS_ON_EIP; import static se.leap.bitmaskclient.Constants.EIP_ACTION_START_BLOCKING_VPN; import static se.leap.bitmaskclient.Constants.EIP_ACTION_STOP_BLOCKING_VPN; @@ -33,7 +40,7 @@ import static se.leap.bitmaskclient.Constants.EIP_IS_ALWAYS_ON; import static se.leap.bitmaskclient.Constants.SHARED_PREFERENCES; -public class VoidVpnService extends VpnService implements Observer { +public class VoidVpnService extends VpnService implements Observer, VpnNotificationManager.VpnServiceCallback { static final String TAG = VoidVpnService.class.getSimpleName(); static ParcelFileDescriptor fd; @@ -42,16 +49,15 @@ public class VoidVpnService extends VpnService implements Observer { private static final String STATE_ESTABLISH = "ESTABLISHVOIDVPN"; public static final String NOTIFICATION_CHANNEL_NEWSTATUS_ID = "bitmask_void_vpn_news"; private EipStatus eipStatus; - NotificationManager notificationManager; - NotificationManagerCompat compatNotificationManager; + private VpnNotificationManager notificationManager; @Override public void onCreate() { super.onCreate(); - notificationManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE); - compatNotificationManager = NotificationManagerCompat.from(this); eipStatus = EipStatus.getInstance(); eipStatus.addObserver(this); + notificationManager = new VpnNotificationManager(this, this); + notificationManager.createVoidVpnNotificationChannel(); } @Override @@ -91,24 +97,9 @@ public class VoidVpnService extends VpnService implements Observer { closeFd(); } - @TargetApi(O) - private void createNotificationChannel() { - - // Connection status change messages - CharSequence name = getString(R.string.channel_name_status); - NotificationChannel mChannel = new NotificationChannel(VoidVpnService.NOTIFICATION_CHANNEL_NEWSTATUS_ID, - name, NotificationManagerCompat.IMPORTANCE_DEFAULT); - - mChannel.setDescription(getString(R.string.channel_description_status)); - mChannel.enableLights(true); - - mChannel.setLightColor(Color.BLUE); - notificationManager.createNotificationChannel(mChannel); - } - - private void stop() { - stopNotifications(); + notificationManager.stopNotifications(NOTIFICATION_CHANNEL_NEWSTATUS_ID); + notificationManager.deleteNotificationChannel(NOTIFICATION_CHANNEL_NEWSTATUS_ID); if (thread != null) { thread.interrupt(); } @@ -174,87 +165,23 @@ public class VoidVpnService extends VpnService implements Observer { } if (eipStatus.isBlockingVpnEstablished()) { - showNotification(getString(eipStatus.getLocalizedResId()), - getString(eipStatus.getLocalizedResId()), eipStatus.getLevel()); + notificationManager.buildVoidVpnNotification( + getString(eipStatus.getLocalizedResId()), + getString(eipStatus.getLocalizedResId()), + eipStatus.getLevel()); } else { - stopNotifications(); + notificationManager.stopNotifications(NOTIFICATION_CHANNEL_NEWSTATUS_ID); } } - private void stopNotifications() { - stopForeground(true); - compatNotificationManager.cancel(NOTIFICATION_CHANNEL_NEWSTATUS_ID.hashCode()); - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O && - notificationManager.getNotificationChannel(NOTIFICATION_CHANNEL_NEWSTATUS_ID) != null) { - notificationManager.deleteNotificationChannel(NOTIFICATION_CHANNEL_NEWSTATUS_ID); - } - } - - /** - * @param msg - * @param tickerText - * @param status - */ - private void showNotification(final String msg, String tickerText, ConnectionStatus status) { - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { - createNotificationChannel(); - } - - int icon = getIconByConnectionStatus(status); - NotificationCompat.Builder nCompatBuilder = new NotificationCompat.Builder(this, NOTIFICATION_CHANNEL_NEWSTATUS_ID); - - nCompatBuilder.setContentTitle(getString(R.string.notifcation_title_bitmask, getString(R.string.void_vpn_title))); - nCompatBuilder.setCategory(NotificationCompat.CATEGORY_SERVICE); - nCompatBuilder.setLocalOnly(true); - nCompatBuilder.setContentText(msg); - nCompatBuilder.setOnlyAlertOnce(true); - nCompatBuilder.setSmallIcon(icon); - if (tickerText != null && !tickerText.equals("")) { - nCompatBuilder.setTicker(tickerText); - } - - nCompatBuilder.setContentIntent(getDashboardIntent()); - //TODO: implement extra Dashboard.ACTION_ASK_TO_CANCEL_BLOCKING_VPN - NotificationCompat.Action.Builder builder = new NotificationCompat.Action.Builder(R.drawable.ic_menu_close_clear_cancel, getString(R.string.vpn_button_turn_off_blocking), getStopVoidVpnIntent()); - nCompatBuilder.addAction(builder.build()); - - Notification notification = nCompatBuilder.build(); - int notificationId = NOTIFICATION_CHANNEL_NEWSTATUS_ID.hashCode(); - compatNotificationManager.notify(notificationId, notification); + @Override + public void onNotificationBuild(int notificationId, Notification notification) { startForeground(notificationId, notification); } - private PendingIntent getDashboardIntent() { - Intent startDashboard = new Intent(this, Dashboard.class); - startDashboard.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK | - Intent.FLAG_ACTIVITY_SINGLE_TOP); - return PendingIntent.getActivity(this, 0, startDashboard, PendingIntent.FLAG_CANCEL_CURRENT); - } - - private PendingIntent getStopVoidVpnIntent() { - Intent stopVoidVpnIntent = new Intent (this, VoidVpnService.class); - stopVoidVpnIntent.setAction(EIP_ACTION_STOP_BLOCKING_VPN); - return PendingIntent.getService(this, 0, stopVoidVpnIntent, PendingIntent.FLAG_CANCEL_CURRENT); + @Override + public void onNotificationStop() { + stopForeground(true); } - //TODO: replace with getIconByEipLevel(EipLevel level) - 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; - } - } } -- cgit v1.2.3