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>
|
<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] -->
|
<!-- 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>
|
<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] -->
|
<!-- Preference title for VPN settings. [CHAR LIMIT=40] -->
|
||||||
<string name="vpn_title">VPN</string>
|
<string name="vpn_title">VPN</string>
|
||||||
|
@@ -15,19 +15,26 @@
|
|||||||
*/
|
*/
|
||||||
package com.android.settings.vpn2;
|
package com.android.settings.vpn2;
|
||||||
|
|
||||||
|
import android.annotation.NonNull;
|
||||||
import android.app.AlertDialog;
|
import android.app.AlertDialog;
|
||||||
import android.app.AppOpsManager;
|
import android.app.AppOpsManager;
|
||||||
import android.app.Dialog;
|
import android.app.Dialog;
|
||||||
import android.app.DialogFragment;
|
import android.app.DialogFragment;
|
||||||
|
import android.app.Notification;
|
||||||
|
import android.app.NotificationManager;
|
||||||
|
import android.app.PendingIntent;
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import android.content.DialogInterface;
|
import android.content.DialogInterface;
|
||||||
|
import android.content.Intent;
|
||||||
import android.content.pm.PackageInfo;
|
import android.content.pm.PackageInfo;
|
||||||
import android.content.pm.PackageManager;
|
import android.content.pm.PackageManager;
|
||||||
import android.content.pm.PackageManager.NameNotFoundException;
|
import android.content.pm.PackageManager.NameNotFoundException;
|
||||||
|
import android.content.res.Resources;
|
||||||
import android.net.ConnectivityManager;
|
import android.net.ConnectivityManager;
|
||||||
import android.os.Bundle;
|
import android.os.Bundle;
|
||||||
import android.os.UserHandle;
|
import android.os.UserHandle;
|
||||||
import android.os.UserManager;
|
import android.os.UserManager;
|
||||||
|
import android.provider.Settings;
|
||||||
import android.support.v7.preference.Preference;
|
import android.support.v7.preference.Preference;
|
||||||
import android.util.Log;
|
import android.util.Log;
|
||||||
|
|
||||||
@@ -77,7 +84,7 @@ public class AppManagementFragment extends SettingsPreferenceFragment
|
|||||||
public void onForget() {
|
public void onForget() {
|
||||||
// Unset always-on-vpn when forgetting the VPN
|
// Unset always-on-vpn when forgetting the VPN
|
||||||
if (isVpnAlwaysOn()) {
|
if (isVpnAlwaysOn()) {
|
||||||
setAlwaysOnVpn(false);
|
setAlwaysOnVpnByUI(false);
|
||||||
}
|
}
|
||||||
// Also dismiss and go back to VPN list
|
// Also dismiss and go back to VPN list
|
||||||
finish();
|
finish();
|
||||||
@@ -159,18 +166,19 @@ public class AppManagementFragment extends SettingsPreferenceFragment
|
|||||||
mPreferenceAlwaysOn.setChecked(false);
|
mPreferenceAlwaysOn.setChecked(false);
|
||||||
ReplaceExistingVpnFragment.show(this);
|
ReplaceExistingVpnFragment.show(this);
|
||||||
} else {
|
} else {
|
||||||
setAlwaysOnVpn(isChecked);
|
setAlwaysOnVpnByUI(isChecked);
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void setAlwaysOnVpn(boolean isEnabled) {
|
private void setAlwaysOnVpnByUI(boolean isEnabled) {
|
||||||
// Only clear legacy lockdown vpn in system user.
|
// Only clear legacy lockdown vpn in system user.
|
||||||
if (mUserId == UserHandle.USER_SYSTEM) {
|
if (mUserId == UserHandle.USER_SYSTEM) {
|
||||||
VpnUtils.clearLockdownVpn(getContext());
|
VpnUtils.clearLockdownVpn(getContext());
|
||||||
}
|
}
|
||||||
mConnectivityManager.setAlwaysOnVpnPackageForUser(mUserId, isEnabled ? mPackageName : null);
|
mConnectivityManager.setAlwaysOnVpnPackageForUser(mUserId, isEnabled ? mPackageName : null);
|
||||||
updateUI();
|
updateUI();
|
||||||
|
showCantConnectNotificationIfNeeded(isEnabled);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void updateUI() {
|
private void updateUI() {
|
||||||
@@ -238,6 +246,45 @@ public class AppManagementFragment extends SettingsPreferenceFragment
|
|||||||
return getAlwaysOnVpnPackage() != null && !isVpnAlwaysOn();
|
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
|
public static class ReplaceExistingVpnFragment extends DialogFragment
|
||||||
implements DialogInterface.OnClickListener {
|
implements DialogInterface.OnClickListener {
|
||||||
|
|
||||||
@@ -260,7 +307,7 @@ public class AppManagementFragment extends SettingsPreferenceFragment
|
|||||||
@Override
|
@Override
|
||||||
public void onClick(DialogInterface dialog, int which) {
|
public void onClick(DialogInterface dialog, int which) {
|
||||||
if (getTargetFragment() instanceof AppManagementFragment) {
|
if (getTargetFragment() instanceof AppManagementFragment) {
|
||||||
((AppManagementFragment) getTargetFragment()).setAlwaysOnVpn(true);
|
((AppManagementFragment) getTargetFragment()).setAlwaysOnVpnByUI(true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user