Show notification when failing to turn on always-on vpn
- Notification icon is Settings icon - VpnName is obtained as the same way as AppPreference - Post notification as the current user with PendingIntent to VpnSettings to parent user - Auto-cancel when user taps on the notification - This implementation posts notification only when the failure happens sychronously (Assume ConnectivityService only unset always-on package immediately after calling setAlwaysOnVpnPackageForUser) Bug:27374485 Change-Id: I0aee38498c8cc300dd8eb9687adcae5f9dc4f8af
This commit is contained in:
@@ -5179,6 +5179,10 @@
|
||||
<string name="vpn_replace_always_on_vpn_title">Replace existing VPN?</string>
|
||||
<!-- Dialog message body to set another VPN app to be always-on [CHAR LIMIT=NONE] -->
|
||||
<string name="vpn_replace_always_on_vpn_message">You already have a VPN connected to this profile. If you connected to one, your existing VPN will be replaced.</string>
|
||||
<!-- Notification title when the user can't connect an always-on vpn [CHAR LIMIT=NONE] -->
|
||||
<string name="vpn_cant_connect_notification_title"><xliff:g id="vpn_name" example="OpenVPN">%1$s</xliff:g> can\'t connect</string>
|
||||
<!-- Notification subtitle when the user can't connect an always-on vpn [CHAR LIMIT=NONE] -->
|
||||
<string name="vpn_tap_for_vpn_settings">Tap for VPN settings</string>
|
||||
|
||||
<!-- Preference title for VPN settings. [CHAR LIMIT=40] -->
|
||||
<string name="vpn_title">VPN</string>
|
||||
|
@@ -15,19 +15,26 @@
|
||||
*/
|
||||
package com.android.settings.vpn2;
|
||||
|
||||
import android.annotation.NonNull;
|
||||
import android.app.AlertDialog;
|
||||
import android.app.AppOpsManager;
|
||||
import android.app.Dialog;
|
||||
import android.app.DialogFragment;
|
||||
import android.app.Notification;
|
||||
import android.app.NotificationManager;
|
||||
import android.app.PendingIntent;
|
||||
import android.content.Context;
|
||||
import android.content.DialogInterface;
|
||||
import android.content.Intent;
|
||||
import android.content.pm.PackageInfo;
|
||||
import android.content.pm.PackageManager;
|
||||
import android.content.pm.PackageManager.NameNotFoundException;
|
||||
import android.content.res.Resources;
|
||||
import android.net.ConnectivityManager;
|
||||
import android.os.Bundle;
|
||||
import android.os.UserHandle;
|
||||
import android.os.UserManager;
|
||||
import android.provider.Settings;
|
||||
import android.support.v7.preference.Preference;
|
||||
import android.util.Log;
|
||||
|
||||
@@ -77,7 +84,7 @@ public class AppManagementFragment extends SettingsPreferenceFragment
|
||||
public void onForget() {
|
||||
// Unset always-on-vpn when forgetting the VPN
|
||||
if (isVpnAlwaysOn()) {
|
||||
setAlwaysOnVpn(false);
|
||||
setAlwaysOnVpnByUI(false);
|
||||
}
|
||||
// Also dismiss and go back to VPN list
|
||||
finish();
|
||||
@@ -159,18 +166,19 @@ public class AppManagementFragment extends SettingsPreferenceFragment
|
||||
mPreferenceAlwaysOn.setChecked(false);
|
||||
ReplaceExistingVpnFragment.show(this);
|
||||
} else {
|
||||
setAlwaysOnVpn(isChecked);
|
||||
setAlwaysOnVpnByUI(isChecked);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
private void setAlwaysOnVpn(boolean isEnabled) {
|
||||
private void setAlwaysOnVpnByUI(boolean isEnabled) {
|
||||
// Only clear legacy lockdown vpn in system user.
|
||||
if (mUserId == UserHandle.USER_SYSTEM) {
|
||||
VpnUtils.clearLockdownVpn(getContext());
|
||||
}
|
||||
mConnectivityManager.setAlwaysOnVpnPackageForUser(mUserId, isEnabled ? mPackageName : null);
|
||||
updateUI();
|
||||
showCantConnectNotificationIfNeeded(isEnabled);
|
||||
}
|
||||
|
||||
private void updateUI() {
|
||||
@@ -238,6 +246,45 @@ public class AppManagementFragment extends SettingsPreferenceFragment
|
||||
return getAlwaysOnVpnPackage() != null && !isVpnAlwaysOn();
|
||||
}
|
||||
|
||||
private void showCantConnectNotificationIfNeeded(boolean isEnabledExpected) {
|
||||
// Display notification only when user tries to turn on but system fails to turn it on.
|
||||
if (isEnabledExpected && !isVpnAlwaysOn()) {
|
||||
String appDisplayName = mPackageName;
|
||||
try {
|
||||
appDisplayName = VpnConfig.getVpnLabel(getContext(), mPackageName).toString();
|
||||
} catch (NameNotFoundException e) {
|
||||
// Use default package name as app name. Quietly fail.
|
||||
}
|
||||
postCantConnectNotification(getContext(), appDisplayName,
|
||||
mPackageUid /* notificationId */);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param notificationId should be unique to the vpn app, e.g. uid, to keep one notification per
|
||||
* vpn app per user
|
||||
*/
|
||||
private static void postCantConnectNotification(Context context, @NonNull String vpnName,
|
||||
int notificationId) {
|
||||
final Resources res = context.getResources();
|
||||
// Only action is specified to match cross-profile intent filter set by ManagedProfileSetup
|
||||
final Intent intent = new Intent(Settings.ACTION_VPN_SETTINGS);
|
||||
final PendingIntent pendingIntent = PendingIntent.getActivity(context, 0, intent,
|
||||
Intent.FLAG_ACTIVITY_NEW_TASK);
|
||||
|
||||
final Notification notification = new Notification.Builder(context)
|
||||
.setContentTitle(res.getString(R.string.vpn_cant_connect_notification_title,
|
||||
vpnName))
|
||||
.setContentText(res.getString(R.string.vpn_tap_for_vpn_settings))
|
||||
.setSmallIcon(R.drawable.ic_settings_wireless)
|
||||
.setContentIntent(pendingIntent)
|
||||
.setAutoCancel(true)
|
||||
.build();
|
||||
|
||||
NotificationManager nm = context.getSystemService(NotificationManager.class);
|
||||
nm.notify(notificationId, notification);
|
||||
}
|
||||
|
||||
public static class ReplaceExistingVpnFragment extends DialogFragment
|
||||
implements DialogInterface.OnClickListener {
|
||||
|
||||
@@ -260,7 +307,7 @@ public class AppManagementFragment extends SettingsPreferenceFragment
|
||||
@Override
|
||||
public void onClick(DialogInterface dialog, int which) {
|
||||
if (getTargetFragment() instanceof AppManagementFragment) {
|
||||
((AppManagementFragment) getTargetFragment()).setAlwaysOnVpn(true);
|
||||
((AppManagementFragment) getTargetFragment()).setAlwaysOnVpnByUI(true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Reference in New Issue
Block a user