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.verifier.managedprovisioning; 18 19 import android.content.Intent; 20 import android.content.pm.PackageManager; 21 import android.database.DataSetObserver; 22 import android.os.Bundle; 23 import android.provider.Settings; 24 import android.util.Log; 25 import android.util.Pair; 26 import android.view.View; 27 28 import com.android.cts.verifier.ArrayTestListAdapter; 29 import com.android.cts.verifier.PassFailButtons; 30 import com.android.cts.verifier.R; 31 import com.android.cts.verifier.TestListAdapter.TestListItem; 32 import com.android.cts.verifier.features.FeatureUtil; 33 34 import java.util.Arrays; 35 import java.util.List; 36 37 /** 38 * Test class to verify transparency for policies enforced by device/profile owner. 39 */ 40 public final class PolicyTransparencyTestListActivity extends PassFailButtons.TestListActivity 41 implements View.OnClickListener { 42 43 private static final String TAG = PolicyTransparencyTestListActivity.class.getSimpleName(); 44 45 public static final String ACTION_CHECK_POLICY_TRANSPARENCY = 46 "com.android.cts.verifier.managedprovisioning.action.CHECK_POLICY_TRANSPARENCY"; 47 48 public static final String EXTRA_MODE = 49 "com.android.cts.verifier.managedprovisioning.extra.mode"; 50 51 public static final int MODE_DEVICE_OWNER = 1; 52 public static final int MODE_MANAGED_PROFILE = 2; 53 public static final int MODE_MANAGED_USER = 4; 54 55 /** 56 * Pairs of: 57 * <ul> 58 * <li>An intent to start {@link PolicyTransparencyTestActivity} 59 * <li>a label to show the user. 60 * </ul> 61 * These contain all the policies except for the user restriction ones. 62 */ 63 private static final Pair<Intent, Integer>[] POLICIES; 64 static { 65 final String[] policyTests = new String[] { 66 PolicyTransparencyTestActivity.TEST_CHECK_AUTO_TIME_REQUIRED, 67 PolicyTransparencyTestActivity.TEST_CHECK_KEYGURAD_UNREDACTED_NOTIFICATION, 68 PolicyTransparencyTestActivity.TEST_CHECK_LOCK_SCREEN_INFO, 69 PolicyTransparencyTestActivity.TEST_CHECK_MAXIMUM_TIME_TO_LOCK, 70 PolicyTransparencyTestActivity.TEST_CHECK_PERMITTED_ACCESSIBILITY_SERVICE, 71 PolicyTransparencyTestActivity.TEST_CHECK_PERMITTED_INPUT_METHOD 72 }; 73 final String[] settingsIntentActions = new String[] { 74 Settings.ACTION_DATE_SETTINGS, 75 Settings.ACTION_SETTINGS, 76 Settings.ACTION_DISPLAY_SETTINGS, 77 Settings.ACTION_DISPLAY_SETTINGS, 78 Settings.ACTION_ACCESSIBILITY_SETTINGS, 79 Settings.ACTION_SETTINGS 80 }; 81 final int[] policyLabels = new int[] { 82 R.string.set_auto_time_required, 83 R.string.disallow_keyguard_unredacted_notifications, 84 R.string.set_lock_screen_info, 85 R.string.set_maximum_time_to_lock, 86 R.string.set_permitted_accessibility_services, 87 R.string.set_permitted_input_methods 88 }; 89 if (policyTests.length != settingsIntentActions.length || 90 policyTests.length != policyLabels.length) { 91 throw new AssertionError("Number of items in policyTests, " 92 + " settingsIntentActions and policyLabels do not match"); 93 } 94 POLICIES = new Pair[policyTests.length]; 95 for (int i = 0; i < policyTests.length; ++i) { 96 final Intent intent = 97 new Intent(PolicyTransparencyTestActivity.ACTION_SHOW_POLICY_TRANSPARENCY_TEST) 98 .putExtra(PolicyTransparencyTestActivity.EXTRA_TEST, policyTests[i]) 99 .putExtra(PolicyTransparencyTestActivity.EXTRA_SETTINGS_INTENT_ACTION, 100 settingsIntentActions[i]); 101 POLICIES[i] = Pair.create(intent, policyLabels[i]); 102 } 103 } 104 105 private static final List<String> ALSO_VALID_FOR_MANAGED_PROFILE = Arrays.asList( 106 PolicyTransparencyTestActivity.TEST_CHECK_PERMITTED_ACCESSIBILITY_SERVICE, 107 PolicyTransparencyTestActivity.TEST_CHECK_PERMITTED_INPUT_METHOD); 108 private static final List<String> ALSO_VALID_FOR_MANAGED_USER = Arrays.asList( 109 PolicyTransparencyTestActivity.TEST_CHECK_PERMITTED_ACCESSIBILITY_SERVICE, 110 PolicyTransparencyTestActivity.TEST_CHECK_PERMITTED_INPUT_METHOD); 111 112 private int mMode; 113 114 @Override onCreate(Bundle savedInstanceState)115 protected void onCreate(Bundle savedInstanceState) { 116 super.onCreate(savedInstanceState); 117 setContentView(R.layout.policy_transparency_test_list); 118 setInfoResources(R.string.device_profile_owner_policy_transparency_test, 119 R.string.device_profile_owner_policy_transparency_test_info, 0); 120 setPassFailButtonClickListeners(); 121 setSupportMsgButtonClickListeners(); 122 123 if (!getIntent().hasExtra(EXTRA_MODE)) { 124 throw new RuntimeException("PolicyTransparencyTestListActivity started without extra " 125 + EXTRA_MODE); 126 } 127 mMode = getIntent().getIntExtra(EXTRA_MODE, MODE_DEVICE_OWNER); 128 129 Log.d(TAG, "onCreate(): mode=" + mMode); 130 131 if (mMode != MODE_DEVICE_OWNER && mMode != MODE_MANAGED_PROFILE 132 && mMode != MODE_MANAGED_USER) { 133 throw new RuntimeException("Unknown mode " + mMode); 134 } 135 136 final ArrayTestListAdapter adapter = new ArrayTestListAdapter(this); 137 addTestsToAdapter(adapter); 138 adapter.registerDataSetObserver(new DataSetObserver() { 139 @Override 140 public void onChanged() { 141 updatePassButton(); 142 } 143 }); 144 145 setTestListAdapter(adapter); 146 } 147 addTestsToAdapter(final ArrayTestListAdapter adapter)148 private void addTestsToAdapter(final ArrayTestListAdapter adapter) { 149 for (String restriction : 150 UserRestrictions.getUserRestrictionsForPolicyTransparency(mMode)) { 151 Intent intent = 152 UserRestrictions.getUserRestrictionTestIntent(this, restriction, mMode); 153 if (!UserRestrictions.isRestrictionValid(this, restriction)) { 154 continue; 155 } 156 String title = UserRestrictions.getRestrictionLabel(this, restriction); 157 String testId = getTestId(title); 158 intent.putExtra(PolicyTransparencyTestActivity.EXTRA_TEST_ID, testId); 159 adapter.add(TestListItem.newTest(title, testId, intent, null)); 160 } 161 for (Pair<Intent, Integer> policy : POLICIES) { 162 Intent intent = policy.first; 163 String test = intent.getStringExtra(PolicyTransparencyTestActivity.EXTRA_TEST); 164 Log.d(TAG, "addTestsToAdapter(): policy=" + policy + ", mode=" + mMode 165 + ", test=" + test); 166 if (!isPolicyValid(test)) { 167 continue; 168 } 169 170 if (mMode == MODE_MANAGED_PROFILE && !ALSO_VALID_FOR_MANAGED_PROFILE.contains(test)) { 171 Log.d(TAG, "addTestsToAdapter(): skipping " + test + " on managed profile"); 172 continue; 173 } 174 if (mMode == MODE_MANAGED_USER && !ALSO_VALID_FOR_MANAGED_USER.contains(test)) { 175 Log.d(TAG, "addTestsToAdapter(): skipping " + test + " on managed user"); 176 continue; 177 } 178 String title = getString(policy.second); 179 String testId = getTestId(title); 180 intent.putExtra(PolicyTransparencyTestActivity.EXTRA_TITLE, title); 181 intent.putExtra(PolicyTransparencyTestActivity.EXTRA_TEST_ID, testId); 182 // This restriction is set per user so current user's DPM should be used instead of 183 // device owner's DPM. 184 if (mMode == MODE_DEVICE_OWNER || ALSO_VALID_FOR_MANAGED_USER.contains(test)) { 185 intent.putExtra(CommandReceiverActivity.EXTRA_USE_CURRENT_USER_DPM, true); 186 } 187 adapter.add(TestListItem.newTest(title, testId, intent, null)); 188 } 189 } 190 getTestId(String title)191 private String getTestId(String title) { 192 if (mMode == MODE_DEVICE_OWNER) { 193 return "DO_" + title; 194 } else if (mMode == MODE_MANAGED_PROFILE) { 195 return "MP_" + title; 196 } else if (mMode == MODE_MANAGED_USER) { 197 return "MU_" + title; 198 } 199 throw new RuntimeException("Unknown mode " + mMode); 200 } 201 isPolicyValid(String test)202 private boolean isPolicyValid(String test) { 203 final PackageManager pm = getPackageManager(); 204 switch (test) { 205 case PolicyTransparencyTestActivity.TEST_CHECK_PERMITTED_INPUT_METHOD: 206 return pm.hasSystemFeature(PackageManager.FEATURE_INPUT_METHODS); 207 case PolicyTransparencyTestActivity.TEST_CHECK_PERMITTED_ACCESSIBILITY_SERVICE: 208 return (pm.hasSystemFeature(PackageManager.FEATURE_AUDIO_OUTPUT) 209 && FeatureUtil.isThirdPartyAccessibilityServiceSupported(this)); 210 case PolicyTransparencyTestActivity.TEST_CHECK_KEYGURAD_UNREDACTED_NOTIFICATION: 211 case PolicyTransparencyTestActivity.TEST_CHECK_LOCK_SCREEN_INFO: 212 case PolicyTransparencyTestActivity.TEST_CHECK_MAXIMUM_TIME_TO_LOCK: 213 return (pm.hasSystemFeature(PackageManager.FEATURE_SECURE_LOCK_SCREEN) 214 && FeatureUtil.isConfigLockScreenSupported(this)); 215 default: 216 return true; 217 } 218 } 219 setSupportMsgButtonClickListeners()220 private void setSupportMsgButtonClickListeners() { 221 findViewById(R.id.short_msg_button).setOnClickListener(this); 222 } 223 224 @Override onClick(View view)225 public void onClick(View view) { 226 if (view.getId() == R.id.short_msg_button) { 227 final Intent intent = new Intent(SetSupportMessageActivity.ACTION_SET_SUPPORT_MSG); 228 intent.putExtra(SetSupportMessageActivity.EXTRA_SUPPORT_MSG_TYPE, 229 SetSupportMessageActivity.TYPE_SHORT_MSG); 230 startActivity(intent); 231 } 232 } 233 234 @Override getTestId()235 public String getTestId() { 236 return getIntent().getStringExtra(PolicyTransparencyTestActivity.EXTRA_TEST_ID); 237 } 238 239 @Override finish()240 public void finish() { 241 super.finish(); 242 final Intent intent = new Intent(CommandReceiverActivity.ACTION_EXECUTE_COMMAND); 243 intent.putExtra(CommandReceiverActivity.EXTRA_COMMAND, 244 CommandReceiverActivity.COMMAND_CLEAR_POLICIES); 245 intent.putExtra(CommandReceiverActivity.EXTRA_USE_CURRENT_USER_DPM, true); 246 intent.putExtra(PolicyTransparencyTestListActivity.EXTRA_MODE, mMode); 247 Log.d(TAG, "finish(): starting activity using " + intent); 248 startActivity(intent); 249 } 250 } 251