Ensure VPN consent is not revoked in prepare/establish.

Covers cases where VPN is prepared, but the consent bit has been lost,
e.g. because updates were uninstalled on the current VPN app. In this
case we want prepare to re-trigger the consent flow, and we do not
want establish() to work.

So, when prepare(package, null) is called, as VpnService.prepare()
will do, if we would have otherwise taken no action and returned true
because the VPN was already prepared, we now check if package has lost
its consent and unprepare the VPN (so that it can be prepared by the
VpnSettings ConfirmDialog).

Bug: 18491424
Change-Id: I8fa60dbc2b95e15f9ce61f9b7e6735db745babba
diff --git a/services/core/java/com/android/server/connectivity/Vpn.java b/services/core/java/com/android/server/connectivity/Vpn.java
index ac55292..aeecdf3 100644
--- a/services/core/java/com/android/server/connectivity/Vpn.java
+++ b/services/core/java/com/android/server/connectivity/Vpn.java
@@ -217,14 +217,21 @@
      * @return true if the operation is succeeded.
      */
     public synchronized boolean prepare(String oldPackage, String newPackage) {
-        if (oldPackage != null && getAppUid(oldPackage, mUserHandle) != mOwnerUID) {
-            // The package doesn't match. We return false (to obtain user consent) unless the user
-            // has already consented to that VPN package.
-            if (!oldPackage.equals(VpnConfig.LEGACY_VPN) && isVpnUserPreConsented(oldPackage)) {
-                prepareInternal(oldPackage);
-                return true;
+        if (oldPackage != null) {
+            if (getAppUid(oldPackage, mUserHandle) != mOwnerUID) {
+                // The package doesn't match. We return false (to obtain user consent) unless the
+                // user has already consented to that VPN package.
+                if (!oldPackage.equals(VpnConfig.LEGACY_VPN) && isVpnUserPreConsented(oldPackage)) {
+                    prepareInternal(oldPackage);
+                    return true;
+                }
+                return false;
+            } else if (!oldPackage.equals(VpnConfig.LEGACY_VPN)
+                    && !isVpnUserPreConsented(oldPackage)) {
+                // Currently prepared VPN is revoked, so unprepare it and return false.
+                prepareInternal(VpnConfig.LEGACY_VPN);
+                return false;
             }
-            return false;
         }
 
         // Return true if we do not need to revoke.
@@ -481,6 +488,10 @@
         if (Binder.getCallingUid() != mOwnerUID) {
             return null;
         }
+        // Check to ensure consent hasn't been revoked since we were prepared.
+        if (!isVpnUserPreConsented(mPackage)) {
+            return null;
+        }
         // Check if the service is properly declared.
         Intent intent = new Intent(VpnConfig.SERVICE_INTERFACE);
         intent.setClassName(mPackage, config.user);