diff options
| author | 2015-04-16 17:01:49 +0100 | |
|---|---|---|
| committer | 2015-04-21 15:28:20 +0100 | |
| commit | 9cb1d5f6418da8cecdee58114c6e97b80c1b153f (patch) | |
| tree | 5a9d1cc1bc31a0a960d161098c1b3400d7d5f0b6 | |
| parent | ca02bc7cebabcf347bde98a45cce41c7d1ab26ee (diff) | |
SecurityController: track VPN for all users
Fixes inconsistencies when switching users.
Bug: 17763561
Bug: 17506956
Bug: 18419023
Change-Id: I65988e6c45afd00a402d1e266922d5648fd12743
4 files changed, 91 insertions, 159 deletions
diff --git a/packages/SystemUI/res/values/strings.xml b/packages/SystemUI/res/values/strings.xml index 67a0bc61c4a8..f12fd0c8406a 100644 --- a/packages/SystemUI/res/values/strings.xml +++ b/packages/SystemUI/res/values/strings.xml @@ -909,37 +909,25 @@ <string name="disconnect_vpn">Disconnect VPN</string> <!-- Monitoring dialog device owner body text [CHAR LIMIT=400] --> - <string name="monitoring_description_device_owned">This device is managed by:\n<xliff:g id="organization">%1$s</xliff:g>\n\nYour administrator can monitor your device and network activity, including emails, apps and secure websites.\n\nFor more information, contact your administrator.</string> - - <!-- Monitoring dialog non-legacy VPN text [CHAR LIMIT=400] --> - <string name="monitoring_description_vpn">You gave \"<xliff:g id="application">%1$s</xliff:g>\" permission to set up a VPN connection.\n\nThis app can monitor your device and network activity, including emails, apps and secure websites.</string> - - <!-- Monitoring dialog legacy VPN text [CHAR LIMIT=400] --> - <string name="monitoring_description_legacy_vpn">You\'re connected to a VPN (\"<xliff:g id="application">%1$s</xliff:g>\").\n\nYour VPN service provider can monitor your device and network activity including emails, apps, and secure websites.</string> - - <!-- Monitoring dialog non-legacy VPN with device owner text [CHAR LIMIT=400] --> - <string name="monitoring_description_vpn_device_owned">This device is managed by:\n<xliff:g id="organization">%1$s</xliff:g>\n\nYour administrator is capable of monitoring your network activity including emails, apps, and secure websites. For more information, contact your administrator.\n\nAlso, you gave \"<xliff:g id="application">%2$s</xliff:g>\" permission to set up a VPN connection. This app can monitor network activity too.</string> - - <!-- Monitoring dialog legacy VPN with device owner text [CHAR LIMIT=400] --> - <string name="monitoring_description_legacy_vpn_device_owned">This device is managed by:\n<xliff:g id="organization">%1$s</xliff:g>\n\nYour administrator is capable of monitoring your network activity including emails, apps, and secure websites. For more information, contact your administrator.\n\nAlso, you\'re connected to a VPN (\"<xliff:g id="application">%2$s</xliff:g>\"). Your VPN service provider can monitor network activity too.</string> + <string name="monitoring_description_device_owned">Your device is managed by <xliff:g id="organization">%1$s</xliff:g>.\n\nYour administrator can monitor and manage settings, corporate access, apps, data associated with your device, and your device\'s location information. For more information, contact your administrator.</string> <!-- Monitoring dialog profile owner body text [CHAR LIMIT=400] --> - <string name="monitoring_description_profile_owned">This profile is managed by:\n<xliff:g id="organization">%1$s</xliff:g>\n\nYour administrator can monitor your device and network activity, including emails, apps and secure websites.\n\nFor more information, contact your administrator.</string> + <string name="monitoring_description_profile_owned">Your work profile is managed by <xliff:g id="organization">%1$s</xliff:g>.\n\nYour administrator is capable of monitoring your network activity including emails, apps and secure websites.\n\nFor more information, contact your administrator.</string> <!-- Monitoring dialog device and profile owner body text [CHAR LIMIT=400] --> - <string name="monitoring_description_device_and_profile_owned">This device is managed by:\n<xliff:g id="organization">%1$s</xliff:g>\nYour profile is managed by:\n<xliff:g id="organization">%2$s</xliff:g>\n\nYour administrator can monitor your device and network activity, including emails, apps and secure websites.\n\nFor more information, contact your administrator.</string> + <string name="monitoring_description_device_and_profile_owned">Your device is managed by:\n<xliff:g id="organization">%1$s</xliff:g>.\nYour work profile is managed by:\n<xliff:g id="organization">%2$s</xliff:g>.\n\nYour administrator can monitor your device and network activity, including emails, apps and secure websites.\n\nFor more information, contact your administrator.</string> - <!-- Monitoring dialog non-legacy VPN with profile owner text [CHAR LIMIT=400] --> - <string name="monitoring_description_vpn_profile_owned">This profile is managed by:\n<xliff:g id="organization">%1$s</xliff:g>\n\nYour administrator is capable of monitoring your network activity including emails, apps, and secure websites. For more information, contact your administrator.\n\nAlso, you gave \"<xliff:g id="application">%2$s</xliff:g>\" permission to set up a VPN connection. This app can monitor network activity too.</string> + <!-- Monitoring dialog VPN text [CHAR LIMIT=400] --> + <string name="monitoring_description_vpn">You gave an app permission to set up a VPN connection.\n\nThis app can monitor your device and network activity, including emails, apps and secure websites.</string> - <!-- Monitoring dialog legacy VPN with profile owner text [CHAR LIMIT=400] --> - <string name="monitoring_description_legacy_vpn_profile_owned">This profile is managed by:\n<xliff:g id="organization">%1$s</xliff:g>\n\nYour administrator is capable of monitoring your network activity including emails, apps, and secure websites. For more information, contact your administrator.\n\nAlso, you\'re connected to a VPN (\"<xliff:g id="application">%2$s</xliff:g>\"). Your VPN service provider can monitor network activity too.</string> + <!-- Monitoring dialog VPN with device owner text [CHAR LIMIT=400] --> + <string name="monitoring_description_vpn_device_owned">Your device is managed by <xliff:g id="organization">%1$s</xliff:g>.\n\nYour administrator can monitor and manage settings, corporate access, apps, data associated with your device, and your device\'s location information.\n\nYou\'re connected to a VPN, which can monitor your network activity, including emails, apps, and websites.\n\nFor more information, contact your administrator.</string> - <!-- Monitoring dialog non-legacy VPN with device and profile owner text [CHAR LIMIT=400] --> - <string name="monitoring_description_vpn_device_and_profile_owned">This device is managed by:\n<xliff:g id="organization">%1$s</xliff:g>\nYour profile is managed by:\n<xliff:g id="organization">%2$s</xliff:g>\n\nYour administrator is capable of monitoring your network activity including emails, apps, and secure websites. For more information, contact your administrator.\n\nAlso, you gave \"<xliff:g id="application">%3$s</xliff:g>\" permission to set up a VPN connection. This app can monitor network activity too.</string> + <!-- Monitoring dialog VPN with profile owner text [CHAR LIMIT=400] --> + <string name="monitoring_description_vpn_profile_owned">Your work profile is managed by <xliff:g id="organization">%1$s</xliff:g>.\n\nYour administrator is capable of monitoring your network activity including emails, apps, and secure websites.\n\nFor more information, contact your administrator.\n\nYou\'re also connected to a VPN, which can monitor your network activity.</string> - <!-- Monitoring dialog legacy VPN with device and profile owner text [CHAR LIMIT=400] --> - <string name="monitoring_description_legacy_vpn_device_and_profile_owned">This device is managed by:\n<xliff:g id="organization">%1$s</xliff:g>\nYour profile is managed by:\n<xliff:g id="organization">%2$s</xliff:g>\n\nYour administrator is capable of monitoring your network activity including emails, apps, and secure websites. For more information, contact your administrator.\n\nAlso, you\'re connected to a VPN (\"<xliff:g id="application">%3$s</xliff:g>\"). Your VPN service provider can monitor network activity too.</string> + <!-- Monitoring dialog VPN with device and profile owner text [CHAR LIMIT=400] --> + <string name="monitoring_description_vpn_device_and_profile_owned">Your device is managed by <xliff:g id="organization">%1$s</xliff:g>.\nYour work profile is managed by:\n<xliff:g id="organization">%2$s</xliff:g>.\n\nYour administrator is capable of monitoring your network activity including emails, apps, and secure websites.\n\nFor more information, contact your administrator.\n\nYou\'re also connected to a VPN, which can monitor your personal network activity</string> <!-- Indication on the keyguard that appears when the user disables trust agents until the next time they unlock manually. [CHAR LIMIT=NONE] --> <string name="keyguard_indication_trust_disabled">Device will stay locked until you manually unlock</string> diff --git a/packages/SystemUI/src/com/android/systemui/qs/QSFooter.java b/packages/SystemUI/src/com/android/systemui/qs/QSFooter.java index 0ab644ab2b8a..d8e3984a2bbb 100644 --- a/packages/SystemUI/src/com/android/systemui/qs/QSFooter.java +++ b/packages/SystemUI/src/com/android/systemui/qs/QSFooter.java @@ -18,9 +18,11 @@ package com.android.systemui.qs; import android.app.AlertDialog; import android.content.Context; import android.content.DialogInterface; +import android.content.Intent; import android.os.Handler; import android.os.Looper; import android.os.Message; +import android.os.UserHandle; import android.util.Log; import android.view.LayoutInflater; import android.view.View; @@ -38,6 +40,8 @@ public class QSFooter implements OnClickListener, DialogInterface.OnClickListene protected static final String TAG = "QSFooter"; protected static final boolean DEBUG = Log.isLoggable(TAG, Log.DEBUG); + private static final String ACTION_VPN_SETTINGS = "android.net.vpn.SETTINGS"; + private final View mRootView; private final TextView mFooterText; private final ImageView mFooterIcon; @@ -128,50 +132,42 @@ public class QSFooter implements OnClickListener, DialogInterface.OnClickListene @Override public void onClick(DialogInterface dialog, int which) { if (which == DialogInterface.BUTTON_NEGATIVE) { - mSecurityController.disconnectFromVpn(); + final Intent settingsIntent = new Intent(ACTION_VPN_SETTINGS); + mContext.startActivityAsUser(settingsIntent, UserHandle.CURRENT); } } private void createDialog() { + boolean hasDeviceOwner = mSecurityController.hasDeviceOwner(); + boolean hasProfile = mSecurityController.hasProfileOwner(); + boolean hasVpn = mSecurityController.isVpnEnabled(); + mDialog = new SystemUIDialog(mContext); - mDialog.setTitle(getTitle()); - mDialog.setMessage(getMessage()); + mDialog.setTitle(getTitle(hasDeviceOwner, hasProfile)); + mDialog.setMessage(getMessage(hasDeviceOwner, hasProfile, hasVpn)); mDialog.setButton(DialogInterface.BUTTON_POSITIVE, getPositiveButton(), this); - if (mSecurityController.isVpnEnabled()) { + if (hasVpn) { mDialog.setButton(DialogInterface.BUTTON_NEGATIVE, getNegativeButton(), this); } mDialog.show(); } private String getNegativeButton() { - if (mSecurityController.isLegacyVpn()) { - return mContext.getString(R.string.disconnect_vpn); - } else { - return mContext.getString(R.string.disable_vpn); - } + return mContext.getString(R.string.status_bar_settings_settings_button); } private String getPositiveButton() { return mContext.getString(R.string.quick_settings_done); } - private String getMessage() { - if (mSecurityController.hasDeviceOwner()) { - if (mSecurityController.hasProfileOwner()) { - if (mSecurityController.isVpnEnabled()) { - if (mSecurityController.isLegacyVpn()) { - return mContext.getString( - R.string.monitoring_description_legacy_vpn_device_and_profile_owned, - mSecurityController.getDeviceOwnerName(), - mSecurityController.getProfileOwnerName(), - mSecurityController.getLegacyVpnName()); - } else { - return mContext.getString( - R.string.monitoring_description_vpn_device_and_profile_owned, - mSecurityController.getDeviceOwnerName(), - mSecurityController.getProfileOwnerName(), - mSecurityController.getVpnApp()); - } + private String getMessage(boolean hasDeviceOwner, boolean hasProfile, boolean hasVpn) { + if (hasDeviceOwner) { + if (hasProfile) { + if (hasVpn) { + return mContext.getString( + R.string.monitoring_description_vpn_device_and_profile_owned, + mSecurityController.getDeviceOwnerName(), + mSecurityController.getProfileOwnerName()); } else { return mContext.getString( R.string.monitoring_description_device_and_profile_owned, @@ -179,57 +175,33 @@ public class QSFooter implements OnClickListener, DialogInterface.OnClickListene mSecurityController.getProfileOwnerName()); } } else { - if (mSecurityController.isVpnEnabled()) { - if (mSecurityController.isLegacyVpn()) { - return mContext.getString( - R.string.monitoring_description_legacy_vpn_device_owned, - mSecurityController.getDeviceOwnerName(), - mSecurityController.getLegacyVpnName()); - } else { - return mContext.getString(R.string.monitoring_description_vpn_device_owned, - mSecurityController.getDeviceOwnerName(), - mSecurityController.getVpnApp()); - } + if (hasVpn) { + return mContext.getString(R.string.monitoring_description_vpn_device_owned, + mSecurityController.getDeviceOwnerName()); } else { return mContext.getString(R.string.monitoring_description_device_owned, mSecurityController.getDeviceOwnerName()); } } - } else if (mSecurityController.hasProfileOwner()) { - if (mSecurityController.isVpnEnabled()) { - if (mSecurityController.isLegacyVpn()) { - return mContext.getString( - R.string.monitoring_description_legacy_vpn_profile_owned, - mSecurityController.getProfileOwnerName(), - mSecurityController.getLegacyVpnName()); - } else { - return mContext.getString( - R.string.monitoring_description_vpn_profile_owned, - mSecurityController.getProfileOwnerName(), - mSecurityController.getVpnApp()); - } + } else if (hasProfile) { + if (hasVpn) { + return mContext.getString( + R.string.monitoring_description_vpn_profile_owned, + mSecurityController.getProfileOwnerName()); } else { return mContext.getString( R.string.monitoring_description_profile_owned, mSecurityController.getProfileOwnerName()); } } else { - if (mSecurityController.isLegacyVpn()) { - return mContext.getString(R.string.monitoring_description_legacy_vpn, - mSecurityController.getLegacyVpnName()); - - } else { - return mContext.getString(R.string.monitoring_description_vpn, - mSecurityController.getVpnApp()); - } + return mContext.getString(R.string.monitoring_description_vpn); } } - private int getTitle() { - if (mSecurityController.hasDeviceOwner()) { + private int getTitle(boolean hasDeviceOwner, boolean hasProfile) { + if (hasDeviceOwner) { return R.string.monitoring_title_device_owned; - } - if (mSecurityController.hasProfileOwner()) { + } else if (hasProfile) { return R.string.monitoring_title_profile_owned; } return R.string.monitoring_title; diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/SecurityController.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/SecurityController.java index 6148febb3885..e1e022d8ac77 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/SecurityController.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/SecurityController.java @@ -22,10 +22,6 @@ public interface SecurityController { String getDeviceOwnerName(); String getProfileOwnerName(); boolean isVpnEnabled(); - String getVpnApp(); - boolean isLegacyVpn(); - String getLegacyVpnName(); - void disconnectFromVpn(); void onUserSwitched(int newUserId); void addCallback(SecurityControllerCallback callback); diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/SecurityControllerImpl.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/SecurityControllerImpl.java index f0dd943e93f3..4f47cc6943d1 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/SecurityControllerImpl.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/SecurityControllerImpl.java @@ -19,6 +19,7 @@ import android.app.ActivityManager; import android.app.admin.DevicePolicyManager; import android.content.Context; import android.content.pm.PackageManager.NameNotFoundException; +import android.content.pm.UserInfo; import android.net.ConnectivityManager; import android.net.ConnectivityManager.NetworkCallback; import android.net.IConnectivityManager; @@ -27,10 +28,14 @@ import android.net.NetworkCapabilities; import android.net.NetworkRequest; import android.os.RemoteException; import android.os.ServiceManager; +import android.os.UserHandle; +import android.os.UserManager; import android.text.TextUtils; import android.util.Log; +import android.util.SparseArray; import com.android.internal.net.VpnConfig; +import com.android.internal.net.VpnInfo; import java.io.FileDescriptor; import java.io.PrintWriter; @@ -50,15 +55,13 @@ public class SecurityControllerImpl implements SecurityController { private final Context mContext; private final ConnectivityManager mConnectivityManager; - private final IConnectivityManager mConnectivityService = IConnectivityManager.Stub.asInterface( - ServiceManager.getService(Context.CONNECTIVITY_SERVICE)); + private final IConnectivityManager mConnectivityManagerService; private final DevicePolicyManager mDevicePolicyManager; + private final UserManager mUserManager; private final ArrayList<SecurityControllerCallback> mCallbacks = new ArrayList<SecurityControllerCallback>(); - private VpnConfig mVpnConfig; - private String mVpnName; - private int mCurrentVpnNetworkId = NO_NETWORK; + private SparseArray<Boolean> mCurrentVpnUsers = new SparseArray<>(); private int mCurrentUserId; public SecurityControllerImpl(Context context) { @@ -67,6 +70,10 @@ public class SecurityControllerImpl implements SecurityController { context.getSystemService(Context.DEVICE_POLICY_SERVICE); mConnectivityManager = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE); + mConnectivityManagerService = IConnectivityManager.Stub.asInterface( + ServiceManager.getService(Context.CONNECTIVITY_SERVICE)); + mUserManager = (UserManager) + context.getSystemService(Context.USER_SERVICE); // TODO: re-register network callback on user change. mConnectivityManager.registerNetworkCallback(REQUEST, mNetworkCallback); @@ -75,9 +82,7 @@ public class SecurityControllerImpl implements SecurityController { public void dump(FileDescriptor fd, PrintWriter pw, String[] args) { pw.println("SecurityController state:"); - pw.print(" mCurrentVpnNetworkId="); pw.println(mCurrentVpnNetworkId); - pw.print(" mVpnConfig="); pw.println(mVpnConfig); - pw.print(" mVpnName="); pw.println(mVpnName); + pw.print(" mCurrentVpnUsers=" + mCurrentVpnUsers); } @Override @@ -86,56 +91,33 @@ public class SecurityControllerImpl implements SecurityController { } @Override - public boolean hasProfileOwner() { - return !TextUtils.isEmpty(mDevicePolicyManager.getProfileOwnerNameAsUser(mCurrentUserId)); - } - - @Override public String getDeviceOwnerName() { return mDevicePolicyManager.getDeviceOwnerName(); } @Override - public String getProfileOwnerName() { - return mDevicePolicyManager.getProfileOwnerNameAsUser(mCurrentUserId); - } - - - @Override - public boolean isVpnEnabled() { - return mCurrentVpnNetworkId != NO_NETWORK; - } - - @Override - public boolean isLegacyVpn() { - return mVpnConfig.legacy; - } - - @Override - public String getVpnApp() { - return mVpnName; + public boolean hasProfileOwner() { + boolean result = false; + for (UserInfo profile : mUserManager.getProfiles(mCurrentUserId)) { + result |= (mDevicePolicyManager.getProfileOwnerAsUser(profile.id) != null); + } + return result; } @Override - public String getLegacyVpnName() { - return mVpnConfig.session; + public String getProfileOwnerName() { + for (UserInfo profile : mUserManager.getProfiles(mCurrentUserId)) { + String name = mDevicePolicyManager.getProfileOwnerNameAsUser(profile.id); + if (name != null) { + return name; + } + } + return null; } @Override - public void disconnectFromVpn() { - try { - if (isLegacyVpn()) { - mConnectivityService.prepareVpn(VpnConfig.LEGACY_VPN, VpnConfig.LEGACY_VPN); - } else { - // Prevent this app from initiating VPN connections in the future without user - // intervention. - mConnectivityService.setVpnPackageAuthorization(false); - - mConnectivityService.prepareVpn(mVpnConfig.user, VpnConfig.LEGACY_VPN); - } - } catch (Exception e) { - Log.e(TAG, "Unable to disconnect from VPN", e); - } + public boolean isVpnEnabled() { + return mCurrentVpnUsers.get(mCurrentUserId) != null; } @Override @@ -158,14 +140,6 @@ public class SecurityControllerImpl implements SecurityController { fireCallbacks(); } - private void setCurrentNetid(int netId) { - if (netId != mCurrentVpnNetworkId) { - mCurrentVpnNetworkId = netId; - updateState(); - fireCallbacks(); - } - } - private void fireCallbacks() { for (SecurityControllerCallback callback : mCallbacks) { callback.onStateChanged(); @@ -173,27 +147,30 @@ public class SecurityControllerImpl implements SecurityController { } private void updateState() { + // Find all users with an active VPN + SparseArray<Boolean> vpnUsers = new SparseArray<>(); try { - mVpnConfig = mConnectivityService.getVpnConfig(); + for (VpnInfo vpn : mConnectivityManagerService.getAllVpnInfo()) { + UserInfo user = mUserManager.getUserInfo(UserHandle.getUserId(vpn.ownerUid)); + int groupId = (user.profileGroupId != UserInfo.NO_PROFILE_GROUP_ID ? + user.profileGroupId : user.id); - if (mVpnConfig != null && !mVpnConfig.legacy) { - mVpnName = VpnConfig.getVpnLabel(mContext, mVpnConfig.user).toString(); + vpnUsers.put(groupId, Boolean.TRUE); } - } catch (RemoteException | NameNotFoundException e) { - Log.w(TAG, "Unable to get current VPN", e); + } catch (RemoteException rme) { + // Roll back to previous state + Log.e(TAG, "Unable to list active VPNs", rme); + return; } + mCurrentVpnUsers = vpnUsers; } private final NetworkCallback mNetworkCallback = new NetworkCallback() { @Override public void onAvailable(Network network) { - NetworkCapabilities networkCapabilities = - mConnectivityManager.getNetworkCapabilities(network); - if (DEBUG) Log.d(TAG, "onAvailable " + network.netId + " : " + networkCapabilities); - if (networkCapabilities != null && - networkCapabilities.hasTransport(NetworkCapabilities.TRANSPORT_VPN)) { - setCurrentNetid(network.netId); - } + if (DEBUG) Log.d(TAG, "onAvailable " + network.netId); + updateState(); + fireCallbacks(); }; // TODO Find another way to receive VPN lost. This may be delayed depending on @@ -201,9 +178,8 @@ public class SecurityControllerImpl implements SecurityController { @Override public void onLost(Network network) { if (DEBUG) Log.d(TAG, "onLost " + network.netId); - if (mCurrentVpnNetworkId == network.netId) { - setCurrentNetid(NO_NETWORK); - } + updateState(); + fireCallbacks(); }; }; |