1 /* 2 * Copyright (C) 2016 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 package com.android.cts.managedprofile; 18 19 import android.app.admin.DevicePolicyManager; 20 import android.util.Log; 21 22 import com.google.common.collect.ImmutableSet; 23 24 import java.lang.reflect.InvocationTargetException; 25 import java.lang.reflect.Method; 26 import java.util.Collection; 27 import java.util.ArrayList; 28 import java.util.List; 29 import java.util.Set; 30 import java.util.stream.Collectors; 31 32 /** 33 * Tests related to the parent profile of a managed profile. 34 * 35 * The parent profile is obtained by 36 * {@link android.app.admin.DevicePolicyManager#getParentProfileInstance}. 37 */ 38 public class ParentProfileTest extends BaseManagedProfileTest { 39 40 /** 41 * A whitelist of public API methods in {@link android.app.admin.DevicePolicyManager} 42 * that are supported on a parent profile. 43 */ 44 private static final ImmutableSet<String> SUPPORTED_APIS = new ImmutableSet.Builder<String>() 45 .add("getPasswordQuality") 46 .add("setPasswordQuality") 47 .add("getPasswordMinimumLength") 48 .add("setPasswordMinimumLength") 49 .add("getPasswordMinimumUpperCase") 50 .add("setPasswordMinimumUpperCase") 51 .add("getPasswordMinimumLowerCase") 52 .add("setPasswordMinimumLowerCase") 53 .add("getPasswordMinimumLetters") 54 .add("setPasswordMinimumLetters") 55 .add("getPasswordMinimumNumeric") 56 .add("setPasswordMinimumNumeric") 57 .add("getPasswordMinimumSymbols") 58 .add("setPasswordMinimumSymbols") 59 .add("getPasswordMinimumNonLetter") 60 .add("setPasswordMinimumNonLetter") 61 .add("getPasswordHistoryLength") 62 .add("setPasswordHistoryLength") 63 .add("getPasswordExpirationTimeout") 64 .add("setPasswordExpirationTimeout") 65 .add("getPasswordExpiration") 66 .add("getPasswordMaximumLength") 67 .add("isActivePasswordSufficient") 68 .add("getCurrentFailedPasswordAttempts") 69 .add("getMaximumFailedPasswordsForWipe") 70 .add("setMaximumFailedPasswordsForWipe") 71 .add("getMaximumTimeToLock") 72 .add("setMaximumTimeToLock") 73 .add("lockNow") 74 .add("getKeyguardDisabledFeatures") 75 .add("setKeyguardDisabledFeatures") 76 .add("getTrustAgentConfiguration") 77 .add("setTrustAgentConfiguration") 78 .add("getRequiredStrongAuthTimeout") 79 .add("setRequiredStrongAuthTimeout") 80 .add("isDeviceIdAttestationSupported") 81 .build(); 82 83 private static final String LOG_TAG = "ParentProfileTest"; 84 85 private static final String PACKAGE_NAME = DevicePolicyManager.class.getPackage().getName(); 86 private static final String CLASS_NAME = DevicePolicyManager.class.getSimpleName(); 87 88 /** 89 * Verify that all public API methods of {@link android.app.admin.DevicePolicyManager}, 90 * except those explicitly whitelisted in {@link #SUPPORTED_APIS}, 91 * throw a {@link SecurityException} when called on a parent profile. 92 * 93 * <p><b>Note:</b> System API methods (i.e. those with the 94 * {@link android.annotation.SystemApi} annotation) are NOT tested. 95 */ 96 public void testParentProfileApiDisabled() throws Exception { 97 List<Method> methods = CurrentApiHelper.getPublicApis(PACKAGE_NAME, CLASS_NAME); 98 assertValidMethodNames(SUPPORTED_APIS, methods); 99 100 ArrayList<String> failedMethods = new ArrayList<String>(); 101 102 for (Method method : methods) { 103 String methodName = method.getName(); 104 if (SUPPORTED_APIS.contains(methodName)) { 105 continue; 106 } 107 108 try { 109 int paramCount = method.getParameterCount(); 110 Object[] params = new Object[paramCount]; 111 Class[] paramTypes = method.getParameterTypes(); 112 for (int i = 0; i < paramCount; ++i) { 113 params[i] = CurrentApiHelper.instantiate(paramTypes[i]); 114 } 115 method.invoke(mParentDevicePolicyManager, params); 116 117 } catch (InvocationTargetException e) { 118 if (e.getCause() instanceof SecurityException) { 119 // Method throws SecurityException as expected 120 continue; 121 } else { 122 Log.e(LOG_TAG, 123 methodName + " throws exception other than SecurityException.", e); 124 } 125 } 126 127 // Either no exception is thrown, or the exception thrown is not a SecurityException 128 failedMethods.add(methodName); 129 Log.e(LOG_TAG, methodName + " failed to throw SecurityException"); 130 } 131 132 assertTrue("Some method(s) failed to throw SecurityException: " + failedMethods, 133 failedMethods.isEmpty()); 134 } 135 136 private void assertValidMethodNames(Collection<String> names, Collection<Method> allMethods) { 137 Set<String> allNames = allMethods.stream() 138 .map(Method::getName) 139 .collect(Collectors.toSet()); 140 141 for (String name : names) { 142 assertTrue(name + " is not found in the API list", allNames.contains(name)); 143 } 144 } 145 } 146