summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRobin Lee <rgl@google.com>2015-05-12 18:35:37 +0100
committerRobin Lee <rgl@google.com>2015-05-18 22:55:15 +0100
commit01b35bcae307907bd8aaaa9cf23fa50f70e5f491 (patch)
tree5b0dd918f5aa299b7bcb1ec7bde7f3bc6063843f
parentfd210786eab8c4aacbbb3aad5a206c57a732d2dc (diff)
downloadpackages_apps_Settings-01b35bcae307907bd8aaaa9cf23fa50f70e5f491.zip
packages_apps_Settings-01b35bcae307907bd8aaaa9cf23fa50f70e5f491.tar.gz
packages_apps_Settings-01b35bcae307907bd8aaaa9cf23fa50f70e5f491.tar.bz2
VPN: UI for forgetting disconnected VPNs
Made possible by expanded internal VPN APIs. Bug: 20872408 Bug: 20692490 Bug: 20747154 Change-Id: Idc87084a130afa18b27c85cc9d4b5033dcedaabe
-rw-r--r--src/com/android/settings/vpn2/AppDialog.java21
-rw-r--r--src/com/android/settings/vpn2/AppDialogFragment.java49
-rw-r--r--src/com/android/settings/vpn2/ConfigDialogFragment.java10
-rw-r--r--src/com/android/settings/vpn2/VpnSettings.java120
-rw-r--r--tests/src/com/android/settings/vpn2/VpnTests.java3
5 files changed, 99 insertions, 104 deletions
diff --git a/src/com/android/settings/vpn2/AppDialog.java b/src/com/android/settings/vpn2/AppDialog.java
index cd6a16c..c06de14 100644
--- a/src/com/android/settings/vpn2/AppDialog.java
+++ b/src/com/android/settings/vpn2/AppDialog.java
@@ -41,28 +41,25 @@ import com.android.settings.R;
*/
class AppDialog extends AlertDialog implements DialogInterface.OnClickListener {
private final Listener mListener;
- private final PackageInfo mPkgInfo;
+ private final PackageInfo mPackageInfo;
private final String mLabel;
- private final boolean mConnected;
- AppDialog(Context context, Listener listener, PackageInfo pkgInfo, String label,
- boolean connected) {
+ AppDialog(Context context, Listener listener, PackageInfo pkgInfo, String label) {
super(context);
mListener = listener;
- mPkgInfo = pkgInfo;
+ mPackageInfo = pkgInfo;
mLabel = label;
- mConnected = connected;
}
public final PackageInfo getPackageInfo() {
- return mPkgInfo;
+ return mPackageInfo;
}
@Override
protected void onCreate(Bundle savedState) {
setTitle(mLabel);
- setMessage(getContext().getString(R.string.vpn_version, mPkgInfo.versionName));
+ setMessage(getContext().getString(R.string.vpn_version, mPackageInfo.versionName));
createButtons();
super.onCreate(savedState);
@@ -71,11 +68,9 @@ class AppDialog extends AlertDialog implements DialogInterface.OnClickListener {
protected void createButtons() {
Context context = getContext();
- if (mConnected) {
- // Forget the network
- setButton(DialogInterface.BUTTON_NEGATIVE,
- context.getString(R.string.vpn_forget), this);
- }
+ // Forget the network
+ setButton(DialogInterface.BUTTON_NEGATIVE,
+ context.getString(R.string.vpn_forget), this);
// Dismiss
setButton(DialogInterface.BUTTON_POSITIVE,
diff --git a/src/com/android/settings/vpn2/AppDialogFragment.java b/src/com/android/settings/vpn2/AppDialogFragment.java
index 6ac4fb5..906f896 100644
--- a/src/com/android/settings/vpn2/AppDialogFragment.java
+++ b/src/com/android/settings/vpn2/AppDialogFragment.java
@@ -27,6 +27,7 @@ import android.net.IConnectivityManager;
import android.os.Bundle;
import android.os.RemoteException;
import android.os.ServiceManager;
+import android.os.UserHandle;
import android.util.Log;
import com.android.internal.net.VpnConfig;
@@ -41,18 +42,20 @@ public class AppDialogFragment extends DialogFragment implements AppDialog.Liste
private static final String ARG_MANAGING = "managing";
private static final String ARG_LABEL = "label";
- private static final String ARG_PACKAGE = "package";
private static final String ARG_CONNECTED = "connected";
+ private static final String ARG_PACKAGE = "package";
+
+ private PackageInfo mPackageInfo;
private final IConnectivityManager mService = IConnectivityManager.Stub.asInterface(
ServiceManager.getService(Context.CONNECTIVITY_SERVICE));
- public static void show(VpnSettings parent, PackageInfo pkgInfo, String label, boolean managing,
- boolean connected) {
+ public static void show(VpnSettings parent, PackageInfo packageInfo, String label,
+ boolean managing, boolean connected) {
if (!parent.isAdded()) return;
Bundle args = new Bundle();
- args.putParcelable(ARG_PACKAGE, pkgInfo);
+ args.putParcelable(ARG_PACKAGE, packageInfo);
args.putString(ARG_LABEL, label);
args.putBoolean(ARG_MANAGING, managing);
args.putBoolean(ARG_CONNECTED, connected);
@@ -66,13 +69,13 @@ public class AppDialogFragment extends DialogFragment implements AppDialog.Liste
@Override
public Dialog onCreateDialog(Bundle savedInstanceState) {
Bundle args = getArguments();
- PackageInfo pkgInfo = (PackageInfo) args.getParcelable(ARG_PACKAGE);
- String label = args.getString(ARG_LABEL);
+ final String label = args.getString(ARG_LABEL);
boolean managing = args.getBoolean(ARG_MANAGING);
boolean connected = args.getBoolean(ARG_CONNECTED);
+ mPackageInfo = (PackageInfo) args.getParcelable(ARG_PACKAGE);
if (managing) {
- return new AppDialog(getActivity(), this, pkgInfo, label, connected);
+ return new AppDialog(getActivity(), this, mPackageInfo, label);
} else {
// Build an AlertDialog with an option to disconnect.
AlertDialog.Builder dlog = new AlertDialog.Builder(getActivity())
@@ -94,12 +97,6 @@ public class AppDialogFragment extends DialogFragment implements AppDialog.Liste
}
@Override
- public void dismiss() {
- ((VpnSettings) getTargetFragment()).update();
- super.dismiss();
- }
-
- @Override
public void onCancel(DialogInterface dialog) {
dismiss();
super.onCancel(dialog);
@@ -107,25 +104,29 @@ public class AppDialogFragment extends DialogFragment implements AppDialog.Liste
@Override
public void onForget(final DialogInterface dialog) {
- PackageInfo pkgInfo = (PackageInfo) getArguments().getParcelable(ARG_PACKAGE);
- final String pkg = pkgInfo.packageName;
+ final int userId = UserHandle.getUserId(mPackageInfo.applicationInfo.uid);
try {
- VpnConfig vpnConfig = mService.getVpnConfig();
- if (vpnConfig != null && pkg.equals(vpnConfig.user) && !vpnConfig.legacy) {
- mService.setVpnPackageAuthorization(false);
- onDisconnect(dialog);
- }
+ mService.setVpnPackageAuthorization(mPackageInfo.packageName, userId, false);
+ onDisconnect(dialog);
} catch (RemoteException e) {
- Log.e(TAG, "Failed to forget authorization for " + pkg, e);
+ Log.e(TAG, "Failed to forget authorization of " + mPackageInfo.packageName +
+ " for user " + userId, e);
}
}
private void onDisconnect(final DialogInterface dialog) {
- PackageInfo pkgInfo = (PackageInfo) getArguments().getParcelable(ARG_PACKAGE);
+ final int userId = UserHandle.getUserId(mPackageInfo.applicationInfo.uid);
try {
- mService.prepareVpn(pkgInfo.packageName, VpnConfig.LEGACY_VPN);
+ final VpnConfig vpnConfig = mService.getVpnConfig(userId);
+ if (vpnConfig == null || vpnConfig.legacy) {
+ return;
+ }
+ if (mPackageInfo.packageName.equals(vpnConfig.user)) {
+ mService.prepareVpn(mPackageInfo.packageName, VpnConfig.LEGACY_VPN, userId);
+ }
} catch (RemoteException e) {
- Log.e(TAG, "Failed to disconnect package " + pkgInfo.packageName, e);
+ Log.e(TAG, "Failed to disconnect package " + mPackageInfo.packageName +
+ " for user " + userId, e);
}
}
}
diff --git a/src/com/android/settings/vpn2/ConfigDialogFragment.java b/src/com/android/settings/vpn2/ConfigDialogFragment.java
index 42e1614..26b7982 100644
--- a/src/com/android/settings/vpn2/ConfigDialogFragment.java
+++ b/src/com/android/settings/vpn2/ConfigDialogFragment.java
@@ -24,6 +24,7 @@ import android.net.IConnectivityManager;
import android.os.Bundle;
import android.os.RemoteException;
import android.os.ServiceManager;
+import android.os.UserHandle;
import android.security.Credentials;
import android.security.KeyStore;
import android.util.Log;
@@ -128,12 +129,6 @@ public class ConfigDialogFragment extends DialogFragment implements
}
@Override
- public void dismiss() {
- ((VpnSettings) getTargetFragment()).update();
- super.dismiss();
- }
-
- @Override
public void onCancel(DialogInterface dialog) {
dismiss();
super.onCancel(dialog);
@@ -151,7 +146,8 @@ public class ConfigDialogFragment extends DialogFragment implements
try {
LegacyVpnInfo connected = mService.getLegacyVpnInfo();
if (connected != null && profile.key.equals(connected.key)) {
- mService.prepareVpn(VpnConfig.LEGACY_VPN, VpnConfig.LEGACY_VPN);
+ mService.prepareVpn(VpnConfig.LEGACY_VPN, VpnConfig.LEGACY_VPN,
+ UserHandle.myUserId());
}
} catch (RemoteException e) {
Log.e(TAG, "Failed to disconnect", e);
diff --git a/src/com/android/settings/vpn2/VpnSettings.java b/src/com/android/settings/vpn2/VpnSettings.java
index e60a262..a82585d 100644
--- a/src/com/android/settings/vpn2/VpnSettings.java
+++ b/src/com/android/settings/vpn2/VpnSettings.java
@@ -71,6 +71,9 @@ public class VpnSettings extends SettingsPreferenceFragment implements
Handler.Callback, Preference.OnPreferenceClickListener {
private static final String LOG_TAG = "VpnSettings";
+ private static final int RESCAN_MESSAGE = 0;
+ private static final int RESCAN_INTERVAL_MS = 1000;
+
private static final String EXTRA_PICK_LOCKDOWN = "android.net.vpn.PICK_LOCKDOWN";
private static final NetworkRequest VPN_REQUEST = new NetworkRequest.Builder()
.removeCapability(NetworkCapabilities.NET_CAPABILITY_NOT_VPN)
@@ -90,7 +93,6 @@ public class VpnSettings extends SettingsPreferenceFragment implements
private Handler mUpdater;
private LegacyVpnInfo mConnectedLegacyVpn;
- private HashSet<String> mConnectedVpns = new HashSet<>();
private boolean mUnavailable;
@@ -111,7 +113,6 @@ public class VpnSettings extends SettingsPreferenceFragment implements
}
mConnectivityManager = (ConnectivityManager) getSystemService(Context.CONNECTIVITY_SERVICE);
- mConnectivityManager.registerNetworkCallback(VPN_REQUEST, mNetworkCallback);
setHasOptionsMenu(true);
addPreferencesFromResource(R.xml.vpn_settings2);
@@ -179,10 +180,32 @@ public class VpnSettings extends SettingsPreferenceFragment implements
LockdownConfigFragment.show(this);
}
- update();
+ // Start monitoring
+ mConnectivityManager.registerNetworkCallback(VPN_REQUEST, mNetworkCallback);
+
+ // Trigger a refresh
+ if (mUpdater == null) {
+ mUpdater = new Handler(this);
+ }
+ mUpdater.sendEmptyMessage(RESCAN_MESSAGE);
+ }
+
+ @Override
+ public void onPause() {
+ // Pause monitoring
+ mConnectivityManager.unregisterNetworkCallback(mNetworkCallback);
+
+ if (mUpdater != null) {
+ mUpdater.removeCallbacksAndMessages(null);
+ }
+
+ super.onPause();
}
- public void update() {
+ @Override
+ public boolean handleMessage(Message message) {
+ mUpdater.removeMessages(RESCAN_MESSAGE);
+
// Pref group within which to list VPNs
PreferenceGroup vpnGroup = getPreferenceScreen();
vpnGroup.removeAll();
@@ -200,18 +223,43 @@ public class VpnSettings extends SettingsPreferenceFragment implements
// 3rd-party VPN apps can change elsewhere. Reload them every time.
for (AppOpsManager.PackageOps pkg : getVpnApps()) {
+ String key = getVpnIdentifier(UserHandle.getUserId(pkg.getUid()), pkg.getPackageName());
final AppPreference pref = new AppPreference(getActivity(), mManageListener,
pkg.getPackageName(), pkg.getUid());
pref.setOnPreferenceClickListener(this);
- mAppPreferences.put(pkg.getPackageName(), pref);
+ mAppPreferences.put(key, pref);
vpnGroup.addPreference(pref);
}
- // Start monitoring.
- if (mUpdater == null) {
- mUpdater = new Handler(this);
+ // Mark out connections with a subtitle
+ try {
+ // Legacy VPNs
+ LegacyVpnInfo info = mConnectivityService.getLegacyVpnInfo();
+ if (info != null) {
+ ConfigPreference preference = mConfigPreferences.get(info.key);
+ if (preference != null) {
+ preference.setState(info.state);
+ mConnectedLegacyVpn = info;
+ }
+ }
+
+ // Third-party VPNs
+ for (UserHandle profile : mUserManager.getUserProfiles()) {
+ VpnConfig cfg = mConnectivityService.getVpnConfig(profile.getIdentifier());
+ if (cfg != null) {
+ final String key = getVpnIdentifier(profile.getIdentifier(), cfg.user);
+ final AppPreference preference = mAppPreferences.get(key);
+ if (preference != null) {
+ preference.setState(AppPreference.STATE_CONNECTED);
+ }
+ }
+ }
+ } catch (RemoteException e) {
+ // ignore
}
- mUpdater.sendEmptyMessage(0);
+
+ mUpdater.sendEmptyMessageDelayed(RESCAN_MESSAGE, RESCAN_INTERVAL_MS);
+ return true;
}
@Override
@@ -275,68 +323,22 @@ public class VpnSettings extends SettingsPreferenceFragment implements
}
};
- @Override
- public boolean handleMessage(Message message) {
- mUpdater.removeMessages(0);
-
- if (isResumed()) {
- try {
- // Legacy VPNs
- LegacyVpnInfo info = mConnectivityService.getLegacyVpnInfo();
- if (mConnectedLegacyVpn != null) {
- ConfigPreference preference = mConfigPreferences.get(mConnectedLegacyVpn.key);
- if (preference != null) {
- preference.setState(-1);
- }
- mConnectedLegacyVpn = null;
- }
- if (info != null) {
- ConfigPreference preference = mConfigPreferences.get(info.key);
- if (preference != null) {
- preference.setState(info.state);
- mConnectedLegacyVpn = info;
- }
- }
-
- // VPN apps
- for (String key : mConnectedVpns) {
- AppPreference preference = mAppPreferences.get(key);
- if (preference != null) {
- preference.setState(AppPreference.STATE_DISCONNECTED);
- }
- }
- mConnectedVpns.clear();
- // TODO: also query VPN services in user profiles STOPSHIP
- VpnConfig cfg = mConnectivityService.getVpnConfig();
- if (cfg != null) {
- mConnectedVpns.add(cfg.user);
- }
- for (String key : mConnectedVpns) {
- AppPreference preference = mAppPreferences.get(key);
- if (preference != null) {
- preference.setState(AppPreference.STATE_CONNECTED);
- }
- }
- } catch (RemoteException e) {
- // ignore
- }
- mUpdater.sendEmptyMessageDelayed(0, 1000);
- }
- return true;
+ private static String getVpnIdentifier(int userId, String packageName) {
+ return Integer.toString(userId)+ "_" + packageName;
}
private NetworkCallback mNetworkCallback = new NetworkCallback() {
@Override
public void onAvailable(Network network) {
if (mUpdater != null) {
- mUpdater.sendEmptyMessage(0);
+ mUpdater.sendEmptyMessage(RESCAN_MESSAGE);
}
}
@Override
public void onLost(Network network) {
if (mUpdater != null) {
- mUpdater.sendEmptyMessage(0);
+ mUpdater.sendEmptyMessage(RESCAN_MESSAGE);
}
}
};
diff --git a/tests/src/com/android/settings/vpn2/VpnTests.java b/tests/src/com/android/settings/vpn2/VpnTests.java
index 8300534..26cfc9b 100644
--- a/tests/src/com/android/settings/vpn2/VpnTests.java
+++ b/tests/src/com/android/settings/vpn2/VpnTests.java
@@ -22,6 +22,7 @@ import android.os.Bundle;
import android.os.Environment;
import android.os.RemoteException;
import android.os.ServiceManager;
+import android.os.UserHandle;
import android.security.Credentials;
import android.security.KeyStore;
import android.security.NetworkSecurityPolicy;
@@ -214,7 +215,7 @@ public class VpnTests extends InstrumentationTestCase {
*/
private void disconnect() throws Exception {
try {
- mService.prepareVpn(VpnConfig.LEGACY_VPN, VpnConfig.LEGACY_VPN);
+ mService.prepareVpn(VpnConfig.LEGACY_VPN, VpnConfig.LEGACY_VPN, UserHandle.myUserId());
} catch (RemoteException e) {
Log.e(TAG, String.format("disconnect VPN exception: %s", e.toString()));
}