CTS: Tests for DISALLOW_CONFIG_VPN

Adding manual and programatic tests for DISALLOW_CONFIG_VPN for Device
owner in Cts verifier

Bug: 18928048
Change-Id: Ie8c59674b6256f08c0336ac1d99948a628f6dd74
diff --git a/apps/CtsVerifier/AndroidManifest.xml b/apps/CtsVerifier/AndroidManifest.xml
index 5e8ab901..b7c54cd 100644
--- a/apps/CtsVerifier/AndroidManifest.xml
+++ b/apps/CtsVerifier/AndroidManifest.xml
@@ -1379,6 +1379,17 @@
                 android:label="@string/device_owner_wifi_lockdown_test">
         </activity>
 
+        <activity android:name=".managedprovisioning.VpnTestActivity"
+                android:label="@string/device_owner_vpn_test">
+        </activity>
+
+        <service android:name=".managedprovisioning.VpnTestActivity$MyTestVpnService"
+                android:permission="android.permission.BIND_VPN_SERVICE">
+            <intent-filter>
+                <action android:name="android.net.VpnService"/>
+            </intent-filter>
+        </service>
+
         <activity android:name=".managedprovisioning.PermissionLockdownTestActivity"
                 android:label="@string/device_profile_owner_permission_lockdown_test">
             <intent-filter>
diff --git a/apps/CtsVerifier/res/layout/vpn_test.xml b/apps/CtsVerifier/res/layout/vpn_test.xml
new file mode 100644
index 0000000..83c0c1b
--- /dev/null
+++ b/apps/CtsVerifier/res/layout/vpn_test.xml
@@ -0,0 +1,36 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2015 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+        android:orientation="vertical"
+        android:layout_width="match_parent"
+        android:layout_height="match_parent">
+
+    <ScrollView
+            android:layout_width="match_parent"
+            android:layout_height="320dp"
+            android:layout_weight="2">
+        <TextView
+                android:id="@+id/device_owner_vpn_info"
+                android:layout_width="match_parent"
+                android:layout_height="wrap_content"
+                android:padding="10dip"
+                android:text="@string/device_owner_vpn_info_default"
+                android:textSize="18dip" />
+    </ScrollView>
+
+    <include layout="@layout/pass_fail_buttons" />
+
+</LinearLayout>
diff --git a/apps/CtsVerifier/res/layout/wifi_lockdown.xml b/apps/CtsVerifier/res/layout/wifi_lockdown.xml
index ae6ea0c..2ac337e 100644
--- a/apps/CtsVerifier/res/layout/wifi_lockdown.xml
+++ b/apps/CtsVerifier/res/layout/wifi_lockdown.xml
@@ -16,8 +16,7 @@
 <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
         android:orientation="vertical"
         android:layout_width="match_parent"
-        android:layout_height="match_parent"
-        >
+        android:layout_height="match_parent">
 
     <ScrollView
             android:layout_width="match_parent"
@@ -74,4 +73,4 @@
 
     <include layout="@layout/pass_fail_buttons" />
 
-</LinearLayout>
\ No newline at end of file
+</LinearLayout>
diff --git a/apps/CtsVerifier/res/values/strings.xml b/apps/CtsVerifier/res/values/strings.xml
index 18e3dbe..ea45c40 100644
--- a/apps/CtsVerifier/res/values/strings.xml
+++ b/apps/CtsVerifier/res/values/strings.xml
@@ -1854,14 +1854,38 @@
     <string name="device_owner_user_restriction_set">Set restriction</string>
     <string name="device_owner_settings_go">Go</string>
 
+    <string name="device_owner_vpn_connection">
+        Vpn connection has been established.\n
+        This is not as expected.\n
+        Mark this test as failed.\n
+    </string>
+    <string name="device_owner_vpn_connection_close_failed">
+        Established vpn connection cannot be closed.\n
+        This is not as expected.\n
+        Mark this test as failed.\n
+    </string>
+    <string name="device_owner_no_vpn_connection">
+        Cannot establish a VPN connection.\n
+        This was expected.\n
+        Mark this test as passed.\n
+    </string>
+    <string name="device_owner_vpn_connection_canceled">
+        Cannot establish a VPN connection.\n
+        Connection canceled by user.\n
+    </string>
+    <string name="device_owner_vpn_test">Check VPN</string>
+    <string name="device_owner_vpn_info_default">Vpn test message</string>
+
     <string name="device_owner_disallow_config_vpn">Disallow configuring VPN</string>
     <string name="device_owner_disallow_config_vpn_info">
         Please press the Set VPN restriction button to set the VPN restriction.
-        Then press Go to open the VPN page.\n\n
+        Perform tests in order. Mark test as passed if both test cases pass\n\n
+        1. Press Go to open the Vpn settings page.\n
         Confirm that:\n
         - You cannot add a new VPN network.\n
-        - You cannot edit, add or remove any existing VPNs.\n
-        \n
+        - You cannot edit, add or remove any existing VPNs.\n\n
+        2. Press Check VPN to check programmatic Vpn test.\n
+        - Check Vpn setup\n\n
         Use the Back button to return to this page.
     </string>
     <string name="device_owner_user_vpn_restriction_set">Set VPN restriction</string>
diff --git a/apps/CtsVerifier/src/com/android/cts/verifier/managedprovisioning/DeviceOwnerPositiveTestActivity.java b/apps/CtsVerifier/src/com/android/cts/verifier/managedprovisioning/DeviceOwnerPositiveTestActivity.java
index 79b9933..2a411f8 100644
--- a/apps/CtsVerifier/src/com/android/cts/verifier/managedprovisioning/DeviceOwnerPositiveTestActivity.java
+++ b/apps/CtsVerifier/src/com/android/cts/verifier/managedprovisioning/DeviceOwnerPositiveTestActivity.java
@@ -180,7 +180,10 @@
                                         UserManager.DISALLOW_CONFIG_VPN)),
                         new ButtonInfo(
                                 R.string.device_owner_settings_go,
-                                new Intent(ACTION_VPN_SETTINGS))}));
+                                new Intent(ACTION_VPN_SETTINGS)),
+                        new ButtonInfo(
+                                R.string.device_owner_vpn_test,
+                                new Intent(this, VpnTestActivity.class))}));
 
         // DISALLOW_CONFIG_BLUETOOTH
         if (packageManager.hasSystemFeature(PackageManager.FEATURE_BLUETOOTH)) {
diff --git a/apps/CtsVerifier/src/com/android/cts/verifier/managedprovisioning/VpnTestActivity.java b/apps/CtsVerifier/src/com/android/cts/verifier/managedprovisioning/VpnTestActivity.java
new file mode 100644
index 0000000..efe52e6
--- /dev/null
+++ b/apps/CtsVerifier/src/com/android/cts/verifier/managedprovisioning/VpnTestActivity.java
@@ -0,0 +1,125 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.cts.verifier.managedprovisioning;
+
+import android.app.AlertDialog;
+import android.app.admin.DevicePolicyManager;
+import android.content.ComponentName;
+import android.content.Context;
+import android.content.Intent;
+import android.net.VpnService;
+import android.net.VpnService.Builder;
+import android.os.Bundle;
+import android.os.ParcelFileDescriptor;
+import android.os.UserManager;
+import android.provider.Settings;
+import android.util.Log;
+import android.widget.TextView;
+import android.net.VpnService;
+import android.os.ParcelFileDescriptor;
+
+import com.android.cts.verifier.PassFailButtons;
+import com.android.cts.verifier.R;
+
+import java.io.IOException;
+
+/**
+ * Activity to test Vpn configuration
+ */
+public class VpnTestActivity extends PassFailButtons.Activity {
+
+    public static class MyTestVpnService extends VpnService {
+        /*
+         * MyVpnTestService is just a stub. This class exists because the framework needs a class
+         * inside the app to refer back to, just using VpnService itself won't work.
+         */
+    }
+
+    private ParcelFileDescriptor descriptor = null;
+    private ComponentName mAdminReceiverComponent;
+    private DevicePolicyManager mDevicePolicyManager;
+    private UserManager mUserManager;
+    private static final String TAG = "DeviceOwnerPositiveTestActivity";
+    private static final int REQUEST_VPN_CODE = 1;
+
+    @Override
+    protected void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+        setContentView(R.layout.vpn_test);
+        setPassFailButtonClickListeners();
+        mAdminReceiverComponent = new ComponentName(this, DeviceAdminTestReceiver.class.getName());
+        mDevicePolicyManager = (DevicePolicyManager) getSystemService(
+                Context.DEVICE_POLICY_SERVICE);
+        mDevicePolicyManager.addUserRestriction(mAdminReceiverComponent,
+                UserManager.DISALLOW_CONFIG_VPN);
+        mUserManager = (UserManager) getSystemService(Context.USER_SERVICE);
+        testVpnEstablishFails();
+    }
+
+    @Override
+    public void finish() {
+        mDevicePolicyManager.clearUserRestriction(mAdminReceiverComponent,
+                UserManager.DISALLOW_CONFIG_VPN);
+        super.finish();
+    }
+
+    @Override
+    protected void onActivityResult(int requestCode, int result, Intent data) {
+        if (requestCode == REQUEST_VPN_CODE && result == RESULT_OK) {
+            establishVpn();
+        } else {
+            // vpn connection canceled by user
+            Log.w(TAG, "Test failed, canceled by user");
+            populateInfo(R.string.device_owner_vpn_connection_canceled);
+        }
+    }
+
+    public void testVpnEstablishFails() {
+        Intent newIntent = VpnService.prepare(this);
+        if (newIntent != null) {
+            startActivityForResult(newIntent, REQUEST_VPN_CODE);
+        } else {
+            establishVpn();
+        }
+    }
+
+    public void establishVpn() {
+        MyTestVpnService service = new MyTestVpnService();
+        descriptor = service.new Builder().addAddress("8.8.8.8", 30).establish();
+        if (descriptor == null) {
+            // vpn connection not established, as expected, test case succeeds
+            Log.i(TAG, "Test succeeded: descriptor is null");
+            populateInfo(R.string.device_owner_no_vpn_connection);
+            return;
+        }
+        // vpn connection established, not expected, test case fails
+        Log.w(TAG, "vpn connection established, not expected, test case fails");
+        try {
+            descriptor.close();
+            populateInfo(R.string.device_owner_vpn_connection);
+        } catch (IOException e) {
+            Log.i(TAG, "Closing vpn connection failed. Caught exception: ", e);
+            populateInfo(R.string.device_owner_vpn_connection_close_failed);
+        }
+    }
+
+    private void populateInfo(int messageId) {
+        TextView vpnInfoTextView = (TextView) findViewById(R.id.device_owner_vpn_info);
+        vpnInfoTextView.setText(getString(messageId));
+    }
+
+}