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 static android.app.admin.DevicePolicyManager.LOCK_TASK_FEATURE_HOME; 20 import static android.app.admin.DevicePolicyManager.MAKE_USER_EPHEMERAL; 21 import static android.app.admin.DevicePolicyManager.SKIP_SETUP_WIZARD; 22 23 import android.Manifest; 24 import android.app.Activity; 25 import android.app.KeyguardManager; 26 import android.app.PendingIntent; 27 import android.app.admin.DevicePolicyManager; 28 import android.content.ComponentName; 29 import android.content.Context; 30 import android.content.Intent; 31 import android.content.IntentFilter; 32 import android.content.pm.ApplicationInfo; 33 import android.content.pm.PackageInstaller; 34 import android.content.pm.PackageManager; 35 import android.content.pm.ResolveInfo; 36 import android.graphics.BitmapFactory; 37 import android.net.ProxyInfo; 38 import android.os.Bundle; 39 import android.os.PersistableBundle; 40 import android.os.UserHandle; 41 import android.os.UserManager; 42 import android.provider.ContactsContract; 43 import android.provider.MediaStore; 44 import android.provider.Settings; 45 import android.util.Log; 46 import android.view.inputmethod.InputMethodInfo; 47 import android.view.inputmethod.InputMethodManager; 48 import android.widget.Toast; 49 50 import com.android.bedstead.dpmwrapper.TestAppSystemServiceFactory; 51 import com.android.cts.verifier.R; 52 53 import java.io.File; 54 import java.io.FileInputStream; 55 import java.io.InputStream; 56 import java.io.OutputStream; 57 import java.util.ArrayList; 58 import java.util.Collections; 59 import java.util.List; 60 import java.util.concurrent.TimeUnit; 61 import java.util.stream.Collectors; 62 63 public class CommandReceiverActivity extends Activity { 64 private static final String TAG = "CommandReceiverActivity"; 65 66 public static final String ACTION_EXECUTE_COMMAND = 67 "com.android.cts.verifier.managedprovisioning.action.EXECUTE_COMMAND"; 68 public static final String EXTRA_COMMAND = 69 "com.android.cts.verifier.managedprovisioning.extra.COMMAND"; 70 71 public static final String COMMAND_SET_USER_RESTRICTION = "set-user_restriction"; 72 public static final String COMMAND_DISALLOW_KEYGUARD_UNREDACTED_NOTIFICATIONS = 73 "disallow-keyguard-unredacted-notifications"; 74 public static final String COMMAND_SET_AUTO_TIME_REQUIRED = "set-auto-time-required"; 75 public static final String COMMAND_SET_GLOBAL_SETTING = 76 "set-global-setting"; 77 public static final String COMMAND_SET_MAXIMUM_TO_LOCK = "set-maximum-time-to-lock"; 78 public static final String COMMAND_SET_KEYGUARD_DISABLED = "set-keyguard-disabled"; 79 public static final String COMMAND_SET_LOCK_SCREEN_INFO = "set-lock-screen-info"; 80 public static final String COMMAND_SET_STATUSBAR_DISABLED = "set-statusbar-disabled"; 81 public static final String COMMAND_SET_LOCK_TASK_FEATURES = "set-lock-task-features"; 82 public static final String COMMAND_ALLOW_ONLY_SYSTEM_INPUT_METHODS = 83 "allow-only-system-input-methods"; 84 public static final String COMMAND_ALLOW_ONLY_SYSTEM_ACCESSIBILITY_SERVICES = 85 "allow-only-system-accessibility-services"; 86 public static final String COMMAND_CLEAR_POLICIES = "clear-policies"; 87 public static final String COMMAND_REMOVE_DEVICE_OWNER = "remove-device-owner"; 88 public static final String COMMAND_REQUEST_BUGREPORT = "request-bugreport"; 89 public static final String COMMAND_SET_USER_ICON = "set-user-icon"; 90 public static final String COMMAND_RETRIEVE_NETWORK_LOGS = "retrieve-network-logs"; 91 public static final String COMMAND_RETRIEVE_SECURITY_LOGS = "retrieve-security-logs"; 92 public static final String COMMAND_SET_ORGANIZATION_NAME = "set-organization-name"; 93 public static final String COMMAND_ENABLE_NETWORK_LOGGING = "enable-network-logging"; 94 public static final String COMMAND_DISABLE_NETWORK_LOGGING = "disable-network-logging"; 95 public static final String COMMAND_INSTALL_HELPER_PACKAGE = "install-helper-package"; 96 public static final String COMMAND_UNINSTALL_HELPER_PACKAGE = "uninstall-helper-package"; 97 public static final String COMMAND_SET_PERMISSION_GRANT_STATE = "set-permission-grant-state"; 98 public static final String COMMAND_ADD_PERSISTENT_PREFERRED_ACTIVITIES = 99 "add-persistent-preferred-activities"; 100 public static final String COMMAND_CLEAR_PERSISTENT_PREFERRED_ACTIVITIES = 101 "clear-persistent-preferred-activities"; 102 public static final String COMMAND_CREATE_MANAGED_PROFILE = "create-managed-profile"; 103 public static final String COMMAND_REMOVE_MANAGED_PROFILE = "remove-managed-profile"; 104 public static final String COMMAND_SET_ALWAYS_ON_VPN = "set-always-on-vpn"; 105 public static final String COMMAND_CLEAR_ALWAYS_ON_VPN = "clear-always-on-vpn"; 106 public static final String COMMAND_SET_GLOBAL_HTTP_PROXY = "set-global-http-proxy"; 107 public static final String COMMAND_CLEAR_GLOBAL_HTTP_PROXY = "clear-global-http-proxy"; 108 public static final String COMMAND_INSTALL_CA_CERT = "install-ca-cert"; 109 public static final String COMMAND_CLEAR_CA_CERT = "clear-ca-cert"; 110 public static final String COMMAND_SET_MAXIMUM_PASSWORD_ATTEMPTS = 111 "set-maximum-password-attempts"; 112 public static final String COMMAND_CLEAR_MAXIMUM_PASSWORD_ATTEMPTS = 113 "clear-maximum-password-attempts"; 114 public static final String COMMAND_SET_DEFAULT_IME = "set-default-ime"; 115 public static final String COMMAND_CLEAR_DEFAULT_IME = "clear-default-ime"; 116 public static final String COMMAND_CREATE_MANAGED_USER = "create-managed-user"; 117 public static final String COMMAND_CREATE_MANAGED_USER_WITHOUT_SETUP = 118 "create-managed-user-without-setup"; 119 public static final String COMMAND_REMOVE_SECONDARY_USERS = "remove-secondary-users"; 120 public static final String COMMAND_WITH_USER_SWITCHER_MESSAGE = "with-user-switcher-message"; 121 public static final String COMMAND_WITHOUT_USER_SWITCHER_MESSAGE = 122 "without-user-switcher-message"; 123 public static final String COMMAND_ENABLE_LOGOUT = "enable-logout"; 124 public static final String COMMAND_DISABLE_USB_DATA_SIGNALING = "disable-usb-data-signaling"; 125 public static final String COMMAND_ENABLE_USB_DATA_SIGNALING = "enable-usb-data-signaling"; 126 public static final String COMMAND_SET_REQUIRED_PASSWORD_COMPLEXITY = 127 "set-required-password-complexity"; 128 129 public static final String EXTRA_USER_RESTRICTION = 130 "com.android.cts.verifier.managedprovisioning.extra.USER_RESTRICTION"; 131 public static final String EXTRA_USE_CURRENT_USER_DPM = 132 "com.android.cts.verifier.managedprovisioning.extra.USE_CURRENT_USER_DPM"; 133 public static final String EXTRA_SETTING = 134 "com.android.cts.verifier.managedprovisioning.extra.SETTING"; 135 // This extra can be used along with a command extra to set policy to 136 // specify if that policy is enforced or not. 137 public static final String EXTRA_ENFORCED = 138 "com.android.cts.verifier.managedprovisioning.extra.ENFORCED"; 139 public static final String EXTRA_VALUE = 140 "com.android.cts.verifier.managedprovisioning.extra.VALUE"; 141 public static final String EXTRA_ORGANIZATION_NAME = 142 "com.android.cts.verifier.managedprovisioning.extra.ORGANIZATION_NAME"; 143 public static final String EXTRA_PERMISSION = 144 "com.android.cts.verifier.managedprovisioning.extra.PERMISSION"; 145 public static final String EXTRA_GRANT_STATE = 146 "com.android.cts.verifier.managedprovisioning.extra.GRANT_STATE"; 147 148 // We care about installing and uninstalling only. It does not matter what apk is used. 149 // NotificationBot.apk is a good choice because it comes bundled with the CTS verifier. 150 protected static final String HELPER_APP_LOCATION = "/sdcard/NotificationBot.apk"; 151 protected static final String HELPER_APP_PKG = "com.android.cts.robot"; 152 153 public static final String ACTION_INSTALL_COMPLETE = 154 "com.android.cts.verifier.managedprovisioning.action.ACTION_INSTALL_COMPLETE"; 155 public static final String ACTION_UNINSTALL_COMPLETE = 156 "com.android.cts.verifier.managedprovisioning.action.ACTION_UNINSTALL_COMPLETE"; 157 158 /* 159 * The CA cert below is the content of cacert.pem as generated by: 160 * 161 * openssl req -new -x509 -days 3650 -extensions v3_ca -keyout cakey.pem -out cacert.pem 162 */ 163 private static final String TEST_CA = 164 "-----BEGIN CERTIFICATE-----\n" + 165 "MIIDXTCCAkWgAwIBAgIJAK9Tl/F9V8kSMA0GCSqGSIb3DQEBCwUAMEUxCzAJBgNV\n" + 166 "BAYTAkFVMRMwEQYDVQQIDApTb21lLVN0YXRlMSEwHwYDVQQKDBhJbnRlcm5ldCBX\n" + 167 "aWRnaXRzIFB0eSBMdGQwHhcNMTUwMzA2MTczMjExWhcNMjUwMzAzMTczMjExWjBF\n" + 168 "MQswCQYDVQQGEwJBVTETMBEGA1UECAwKU29tZS1TdGF0ZTEhMB8GA1UECgwYSW50\n" + 169 "ZXJuZXQgV2lkZ2l0cyBQdHkgTHRkMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIB\n" + 170 "CgKCAQEAvItOutsE75WBTgTyNAHt4JXQ3JoseaGqcC3WQij6vhrleWi5KJ0jh1/M\n" + 171 "Rpry7Fajtwwb4t8VZa0NuM2h2YALv52w1xivql88zce/HU1y7XzbXhxis9o6SCI+\n" + 172 "oVQSbPeXRgBPppFzBEh3ZqYTVhAqw451XhwdA4Aqs3wts7ddjwlUzyMdU44osCUg\n" + 173 "kVg7lfPf9sTm5IoHVcfLSCWH5n6Nr9sH3o2ksyTwxuOAvsN11F/a0mmUoPciYPp+\n" + 174 "q7DzQzdi7akRG601DZ4YVOwo6UITGvDyuAAdxl5isovUXqe6Jmz2/myTSpAKxGFs\n" + 175 "jk9oRoG6WXWB1kni490GIPjJ1OceyQIDAQABo1AwTjAdBgNVHQ4EFgQUH1QIlPKL\n" + 176 "p2OQ/AoLOjKvBW4zK3AwHwYDVR0jBBgwFoAUH1QIlPKLp2OQ/AoLOjKvBW4zK3Aw\n" + 177 "DAYDVR0TBAUwAwEB/zANBgkqhkiG9w0BAQsFAAOCAQEAcMi4voMMJHeQLjtq8Oky\n" + 178 "Azpyk8moDwgCd4llcGj7izOkIIFqq/lyqKdtykVKUWz2bSHO5cLrtaOCiBWVlaCV\n" + 179 "DYAnnVLM8aqaA6hJDIfaGs4zmwz0dY8hVMFCuCBiLWuPfiYtbEmjHGSmpQTG6Qxn\n" + 180 "ZJlaK5CZyt5pgh5EdNdvQmDEbKGmu0wpCq9qjZImwdyAul1t/B0DrsWApZMgZpeI\n" + 181 "d2od0VBrCICB1K4p+C51D93xyQiva7xQcCne+TAnGNy9+gjQ/MyR8MRpwRLv5ikD\n" + 182 "u0anJCN8pXo6IMglfMAsoton1J6o5/ae5uhC6caQU8bNUsCK570gpNfjkzo6rbP0\n" + 183 "wQ==\n" + 184 "-----END CERTIFICATE-----"; 185 186 private ComponentName mAdmin; 187 private DevicePolicyManager mDpm; 188 private UserManager mUm; 189 190 @Override onCreate(Bundle savedInstanceState)191 public void onCreate(Bundle savedInstanceState) { 192 super.onCreate(savedInstanceState); 193 final Intent intent = getIntent(); 194 try { 195 // On phones, the test runs on user 0, which is the Device Owner, but on headless system 196 // user mode it runs in a different user. 197 // Most DPM operations must be set on device owner user, but a few - like adding user 198 // restrictions - must be set in the current user. 199 200 boolean useCurrentUserDpm = intent.getBooleanExtra(EXTRA_USE_CURRENT_USER_DPM, false); 201 mDpm = useCurrentUserDpm 202 ? getSystemService(DevicePolicyManager.class) 203 : TestAppSystemServiceFactory.getDevicePolicyManager(this, 204 DeviceAdminTestReceiver.class); 205 206 mUm = (UserManager) getSystemService(Context.USER_SERVICE); 207 mAdmin = DeviceAdminTestReceiver.getReceiverComponentName(); 208 final String command = getIntent().getStringExtra(EXTRA_COMMAND); 209 Log.i(TAG, "Command: " + command); 210 switch (command) { 211 case COMMAND_SET_USER_RESTRICTION: { 212 String restrictionKey = intent.getStringExtra(EXTRA_USER_RESTRICTION); 213 boolean enforced = intent.getBooleanExtra(EXTRA_ENFORCED, false); 214 Log.i(TAG, "Setting '" + restrictionKey + "'=" + enforced + " using " + mDpm 215 + " on user " + UserHandle.myUserId()); 216 if (enforced) { 217 mDpm.addUserRestriction(mAdmin, restrictionKey); 218 } else { 219 mDpm.clearUserRestriction(mAdmin, restrictionKey); 220 } 221 } break; 222 case COMMAND_DISALLOW_KEYGUARD_UNREDACTED_NOTIFICATIONS: { 223 boolean enforced = intent.getBooleanExtra(EXTRA_ENFORCED, false); 224 mDpm.setKeyguardDisabledFeatures(mAdmin, enforced 225 ? DevicePolicyManager.KEYGUARD_DISABLE_UNREDACTED_NOTIFICATIONS 226 : 0); 227 } break; 228 case COMMAND_SET_AUTO_TIME_REQUIRED: { 229 mDpm.setAutoTimeRequired(mAdmin, 230 intent.getBooleanExtra(EXTRA_ENFORCED, false)); 231 break; 232 } 233 case COMMAND_SET_LOCK_SCREEN_INFO: { 234 mDpm.setDeviceOwnerLockScreenInfo(mAdmin, intent.getStringExtra(EXTRA_VALUE)); 235 break; 236 } 237 case COMMAND_SET_MAXIMUM_TO_LOCK: { 238 final long timeInSeconds = Long.parseLong(intent.getStringExtra(EXTRA_VALUE)); 239 mDpm.setMaximumTimeToLock(mAdmin, 240 TimeUnit.SECONDS.toMillis(timeInSeconds) /* in milliseconds */); 241 } break; 242 case COMMAND_SET_KEYGUARD_DISABLED: { 243 boolean enforced = intent.getBooleanExtra(EXTRA_ENFORCED, false); 244 KeyguardManager km = this.getSystemService(KeyguardManager.class); 245 if (km.isKeyguardSecure()) { 246 Toast.makeText(this, getString(R.string.device_owner_lockscreen_secure), 247 Toast.LENGTH_SHORT).show(); 248 } else { 249 mDpm.setKeyguardDisabled(mAdmin, enforced); 250 } 251 } break; 252 case COMMAND_SET_STATUSBAR_DISABLED: { 253 boolean enforced = intent.getBooleanExtra(EXTRA_ENFORCED, false); 254 mDpm.setStatusBarDisabled(mAdmin, enforced); 255 } break; 256 case COMMAND_SET_LOCK_TASK_FEATURES: { 257 int flags = intent.getIntExtra(EXTRA_VALUE, 258 DevicePolicyManager.LOCK_TASK_FEATURE_NONE); 259 mDpm.setLockTaskFeatures(mAdmin, flags); 260 // If feature HOME is used, we need to allow the current launcher 261 if ((flags & LOCK_TASK_FEATURE_HOME) != 0) { 262 mDpm.setLockTaskPackages(mAdmin, 263 new String[] {getPackageName(), getCurrentLauncherPackage()}); 264 } else { 265 mDpm.setLockTaskPackages(mAdmin, new String[] {getPackageName()}); 266 } 267 } break; 268 case COMMAND_ALLOW_ONLY_SYSTEM_INPUT_METHODS: { 269 boolean enforced = intent.getBooleanExtra(EXTRA_ENFORCED, false); 270 mDpm.setPermittedInputMethods(mAdmin, 271 enforced ? getEnabledNonSystemImes() : null); 272 } break; 273 case COMMAND_ALLOW_ONLY_SYSTEM_ACCESSIBILITY_SERVICES: { 274 boolean enforced = intent.getBooleanExtra(EXTRA_ENFORCED, false); 275 mDpm.setPermittedAccessibilityServices(mAdmin, 276 enforced ? new ArrayList() : null); 277 } break; 278 case COMMAND_SET_GLOBAL_SETTING: { 279 final String setting = intent.getStringExtra(EXTRA_SETTING); 280 final String value = intent.getStringExtra(EXTRA_VALUE); 281 mDpm.setGlobalSetting(mAdmin, setting, value); 282 } break; 283 case COMMAND_REMOVE_DEVICE_OWNER: { 284 if (!mDpm.isDeviceOwnerApp(getPackageName())) { 285 Log.e(TAG, COMMAND_REMOVE_DEVICE_OWNER + ": " + getPackageName() 286 + " is not DO for user " + UserHandle.myUserId()); 287 return; 288 } 289 clearAllPoliciesAndRestrictions(); 290 mDpm.clearDeviceOwnerApp(getPackageName()); 291 292 // TODO(b/179100903): temporarily removing PO, should be done automatically 293 if (UserManager.isHeadlessSystemUserMode()) { 294 Log.i(TAG, "Disabling PO on user " + UserHandle.myUserId()); 295 DevicePolicyManager localDpm = getSystemService(DevicePolicyManager.class); 296 localDpm.clearProfileOwner(mAdmin); 297 } 298 299 } break; 300 case COMMAND_REQUEST_BUGREPORT: { 301 if (!mDpm.isDeviceOwnerApp(getPackageName())) { 302 return; 303 } 304 final boolean bugreportStarted = mDpm.requestBugreport(mAdmin); 305 if (!bugreportStarted) { 306 Utils.showBugreportNotification(this, getString( 307 R.string.bugreport_already_in_progress), 308 Utils.BUGREPORT_NOTIFICATION_ID); 309 } 310 } break; 311 case COMMAND_CLEAR_POLICIES: { 312 int mode = intent.getIntExtra(PolicyTransparencyTestListActivity.EXTRA_MODE, 313 PolicyTransparencyTestListActivity.MODE_DEVICE_OWNER); 314 if (mode == PolicyTransparencyTestListActivity.MODE_DEVICE_OWNER) { 315 if (!mDpm.isDeviceOwnerApp(getPackageName())) { 316 return; 317 } 318 clearAllPoliciesAndRestrictions(); 319 } else if (mode == PolicyTransparencyTestListActivity.MODE_MANAGED_PROFILE 320 || mode == PolicyTransparencyTestListActivity.MODE_MANAGED_USER) { 321 if (!mDpm.isProfileOwnerApp(getPackageName())) { 322 return; 323 } 324 clearProfileOwnerRelatedPoliciesAndRestrictions(mode); 325 } 326 // No policies need to be cleared for COMP at the moment. 327 } break; 328 case COMMAND_SET_USER_ICON: { 329 if (!mDpm.isDeviceOwnerApp(getPackageName())) { 330 return; 331 } 332 int iconRes = intent.getIntExtra(EXTRA_VALUE, 333 com.android.cts.verifier.R.drawable.icon); 334 mDpm.setUserIcon(mAdmin, BitmapFactory.decodeResource(getResources(), iconRes)); 335 } break; 336 case COMMAND_RETRIEVE_NETWORK_LOGS: { 337 if (!mDpm.isDeviceOwnerApp(getPackageName())) { 338 return; 339 } 340 mDpm.setNetworkLoggingEnabled(mAdmin, true); 341 mDpm.retrieveNetworkLogs(mAdmin, 0 /* batchToken */); 342 mDpm.setNetworkLoggingEnabled(mAdmin, false); 343 } break; 344 case COMMAND_RETRIEVE_SECURITY_LOGS: { 345 if (!mDpm.isDeviceOwnerApp(getPackageName())) { 346 return; 347 } 348 mDpm.setSecurityLoggingEnabled(mAdmin, true); 349 mDpm.retrieveSecurityLogs(mAdmin); 350 mDpm.setSecurityLoggingEnabled(mAdmin, false); 351 } break; 352 case COMMAND_SET_ORGANIZATION_NAME: { 353 if (!mDpm.isDeviceOwnerApp(getPackageName())) { 354 return; 355 } 356 mDpm.setOrganizationName(mAdmin, 357 intent.getStringExtra(EXTRA_ORGANIZATION_NAME)); 358 } break; 359 case COMMAND_ENABLE_NETWORK_LOGGING: { 360 if (!mDpm.isDeviceOwnerApp(getPackageName())) { 361 return; 362 } 363 mDpm.setNetworkLoggingEnabled(mAdmin, true); 364 } break; 365 case COMMAND_DISABLE_NETWORK_LOGGING: { 366 if (!mDpm.isDeviceOwnerApp(getPackageName())) { 367 return; 368 } 369 mDpm.setNetworkLoggingEnabled(mAdmin, false); 370 } break; 371 case COMMAND_INSTALL_HELPER_PACKAGE: { 372 installHelperPackage(); 373 } break; 374 case COMMAND_UNINSTALL_HELPER_PACKAGE: { 375 uninstallHelperPackage(); 376 } break; 377 case COMMAND_SET_PERMISSION_GRANT_STATE: { 378 mDpm.setPermissionGrantState(mAdmin, getPackageName(), 379 intent.getStringExtra(EXTRA_PERMISSION), 380 intent.getIntExtra(EXTRA_GRANT_STATE, 381 DevicePolicyManager.PERMISSION_GRANT_STATE_DEFAULT)); 382 } break; 383 case COMMAND_ADD_PERSISTENT_PREFERRED_ACTIVITIES: { 384 final ComponentName componentName = 385 EnterprisePrivacyTestDefaultAppActivity.COMPONENT_NAME; 386 IntentFilter filter; 387 // Camera 388 filter = new IntentFilter(); 389 filter.addAction(MediaStore.ACTION_IMAGE_CAPTURE); 390 filter.addAction(MediaStore.ACTION_VIDEO_CAPTURE); 391 mDpm.addPersistentPreferredActivity(mAdmin, filter, componentName); 392 // Map 393 filter = new IntentFilter(); 394 filter.addAction(Intent.ACTION_VIEW); 395 filter.addDataScheme("geo"); 396 mDpm.addPersistentPreferredActivity(mAdmin, filter, componentName); 397 // E-mail 398 filter = new IntentFilter(); 399 filter.addAction(Intent.ACTION_SENDTO); 400 filter.addAction(Intent.ACTION_SEND); 401 filter.addAction(Intent.ACTION_SEND_MULTIPLE); 402 mDpm.addPersistentPreferredActivity(mAdmin, filter, componentName); 403 // Calendar 404 filter = new IntentFilter(); 405 filter.addAction(Intent.ACTION_INSERT); 406 filter.addDataType("vnd.android.cursor.dir/event"); 407 mDpm.addPersistentPreferredActivity(mAdmin, filter, componentName); 408 // Contacts 409 filter = new IntentFilter(); 410 filter.addAction(Intent.ACTION_PICK); 411 filter.addDataType(ContactsContract.Contacts.CONTENT_TYPE); 412 mDpm.addPersistentPreferredActivity(mAdmin, filter, componentName); 413 // Dialer 414 filter = new IntentFilter(); 415 filter.addAction(Intent.ACTION_DIAL); 416 filter.addAction(Intent.ACTION_CALL); 417 mDpm.addPersistentPreferredActivity(mAdmin, filter, componentName); 418 getPackageManager().setComponentEnabledSetting(componentName, 419 PackageManager.COMPONENT_ENABLED_STATE_ENABLED, 420 PackageManager.DONT_KILL_APP); 421 } break; 422 case COMMAND_CLEAR_PERSISTENT_PREFERRED_ACTIVITIES: { 423 mDpm.clearPackagePersistentPreferredActivities(mAdmin, getPackageName()); 424 getPackageManager().setComponentEnabledSetting( 425 EnterprisePrivacyTestDefaultAppActivity.COMPONENT_NAME, 426 PackageManager.COMPONENT_ENABLED_STATE_DEFAULT, 427 PackageManager.DONT_KILL_APP); 428 } break; 429 case COMMAND_SET_ALWAYS_ON_VPN: { 430 if (!mDpm.isDeviceOwnerApp(getPackageName())) { 431 return; 432 } 433 mDpm.setAlwaysOnVpnPackage(mAdmin, getPackageName(), 434 false /* lockdownEnabled */); 435 } break; 436 case COMMAND_CLEAR_ALWAYS_ON_VPN: { 437 if (!mDpm.isDeviceOwnerApp(getPackageName())) { 438 return; 439 } 440 mDpm.setAlwaysOnVpnPackage(mAdmin, null /* vpnPackage */, 441 false /* lockdownEnabled */); 442 } break; 443 case COMMAND_SET_GLOBAL_HTTP_PROXY: { 444 if (!mDpm.isDeviceOwnerApp(getPackageName())) { 445 return; 446 } 447 mDpm.setRecommendedGlobalProxy(mAdmin, 448 ProxyInfo.buildDirectProxy("example.com", 123)); 449 } break; 450 case COMMAND_CLEAR_GLOBAL_HTTP_PROXY: { 451 if (!mDpm.isDeviceOwnerApp(getPackageName())) { 452 return; 453 } 454 mDpm.setRecommendedGlobalProxy(mAdmin, null); 455 } break; 456 case COMMAND_INSTALL_CA_CERT: { 457 if (!mDpm.isDeviceOwnerApp(getPackageName())) { 458 return; 459 } 460 mDpm.installCaCert(mAdmin, TEST_CA.getBytes()); 461 } break; 462 case COMMAND_CLEAR_CA_CERT: { 463 if (!mDpm.isDeviceOwnerApp(getPackageName())) { 464 return; 465 } 466 mDpm.uninstallCaCert(mAdmin, TEST_CA.getBytes()); 467 } break; 468 case COMMAND_SET_MAXIMUM_PASSWORD_ATTEMPTS: { 469 if (!mDpm.isDeviceOwnerApp(getPackageName())) { 470 return; 471 } 472 mDpm.setMaximumFailedPasswordsForWipe(mAdmin, 100); 473 } break; 474 case COMMAND_CLEAR_MAXIMUM_PASSWORD_ATTEMPTS: { 475 if (!mDpm.isDeviceOwnerApp(getPackageName())) { 476 return; 477 } 478 mDpm.setMaximumFailedPasswordsForWipe(mAdmin, 0); 479 } break; 480 case COMMAND_SET_DEFAULT_IME: { 481 if (!mDpm.isDeviceOwnerApp(getPackageName())) { 482 return; 483 } 484 mDpm.setSecureSetting(mAdmin, Settings.Secure.DEFAULT_INPUT_METHOD, 485 getPackageName()); 486 } break; 487 case COMMAND_CLEAR_DEFAULT_IME: { 488 if (!mDpm.isDeviceOwnerApp(getPackageName())) { 489 return; 490 } 491 mDpm.setSecureSetting(mAdmin, Settings.Secure.DEFAULT_INPUT_METHOD, null); 492 } break; 493 case COMMAND_CREATE_MANAGED_USER:{ 494 if (!mDpm.isDeviceOwnerApp(getPackageName())) { 495 return; 496 } 497 PersistableBundle extras = new PersistableBundle(); 498 extras.putBoolean(DeviceAdminTestReceiver.EXTRA_MANAGED_USER_TEST, true); 499 UserHandle userHandle = mDpm.createAndManageUser(mAdmin, "managed user", mAdmin, 500 extras, 501 SKIP_SETUP_WIZARD | MAKE_USER_EPHEMERAL); 502 mDpm.setAffiliationIds(mAdmin, 503 Collections.singleton(DeviceAdminTestReceiver.AFFILIATION_ID)); 504 mDpm.startUserInBackground(mAdmin, userHandle); 505 } break; 506 case COMMAND_CREATE_MANAGED_USER_WITHOUT_SETUP:{ 507 if (!mDpm.isDeviceOwnerApp(getPackageName())) { 508 return; 509 } 510 PersistableBundle extras = new PersistableBundle(); 511 extras.putBoolean(DeviceAdminTestReceiver.EXTRA_MANAGED_USER_TEST, true); 512 mDpm.createAndManageUser(mAdmin, "managed user", mAdmin, extras, /* flags */ 0); 513 } break; 514 case COMMAND_REMOVE_SECONDARY_USERS: { 515 if (!mDpm.isDeviceOwnerApp(getPackageName())) { 516 return; 517 } 518 for (UserHandle secondaryUser : mDpm.getSecondaryUsers(mAdmin)) { 519 mDpm.removeUser(mAdmin, secondaryUser); 520 } 521 } break; 522 case COMMAND_WITH_USER_SWITCHER_MESSAGE: { 523 createAndSwitchUserWithMessage("Start user session", "End user session"); 524 } break; 525 case COMMAND_WITHOUT_USER_SWITCHER_MESSAGE: { 526 createAndSwitchUserWithMessage(null, null); 527 } break; 528 case COMMAND_ENABLE_LOGOUT: { 529 if (!mDpm.isDeviceOwnerApp(getPackageName())) { 530 return; 531 } 532 mDpm.addUserRestriction(mAdmin, UserManager.DISALLOW_USER_SWITCH); 533 mDpm.setLogoutEnabled(mAdmin, true); 534 UserHandle userHandle = mDpm.createAndManageUser(mAdmin, "managed user", mAdmin, 535 null, SKIP_SETUP_WIZARD | MAKE_USER_EPHEMERAL); 536 mDpm.switchUser(mAdmin, userHandle); 537 } break; 538 case COMMAND_DISABLE_USB_DATA_SIGNALING: { 539 mDpm.setUsbDataSignalingEnabled(false); 540 break; 541 } 542 case COMMAND_ENABLE_USB_DATA_SIGNALING: { 543 mDpm.setUsbDataSignalingEnabled(true); 544 break; 545 } 546 case COMMAND_SET_REQUIRED_PASSWORD_COMPLEXITY: { 547 int complexity = intent.getIntExtra(EXTRA_VALUE, 548 DevicePolicyManager.PASSWORD_COMPLEXITY_NONE); 549 mDpm.setRequiredPasswordComplexity(complexity); 550 } 551 } 552 } catch (Exception e) { 553 Log.e(TAG, "Failed to execute command: " + intent, e); 554 } finally { 555 finish(); 556 } 557 } 558 installHelperPackage()559 private void installHelperPackage() throws Exception { 560 LogAndSelfUnregisterBroadcastReceiver.register(this, ACTION_INSTALL_COMPLETE); 561 final PackageInstaller packageInstaller = getPackageManager().getPackageInstaller(); 562 final PackageInstaller.Session session = packageInstaller.openSession( 563 packageInstaller.createSession(new PackageInstaller.SessionParams( 564 PackageInstaller.SessionParams.MODE_FULL_INSTALL))); 565 final File file = new File(HELPER_APP_LOCATION); 566 Log.i(TAG, "installing helper package from " + file); 567 final InputStream in = new FileInputStream(file); 568 final OutputStream out = session.openWrite("CommandReceiverActivity", 0, file.length()); 569 final byte[] buffer = new byte[65536]; 570 int count; 571 while ((count = in.read(buffer)) != -1) { 572 out.write(buffer, 0, count); 573 } 574 session.fsync(out); 575 in.close(); 576 out.close(); 577 session.commit(PendingIntent 578 .getBroadcast(this, 0, new Intent(ACTION_INSTALL_COMPLETE), 579 PendingIntent.FLAG_MUTABLE_UNAUDITED) 580 .getIntentSender()); 581 } 582 uninstallHelperPackage()583 private void uninstallHelperPackage() { 584 LogAndSelfUnregisterBroadcastReceiver.register(this, ACTION_UNINSTALL_COMPLETE); 585 PackageInstaller packageInstaller = getPackageManager().getPackageInstaller(); 586 Log.i(TAG, "Uninstalling package " + HELPER_APP_PKG + " using " + packageInstaller); 587 try { 588 packageInstaller.uninstall(HELPER_APP_PKG, PendingIntent.getBroadcast(this, 589 /* requestCode= */ 0, new Intent(ACTION_UNINSTALL_COMPLETE), 590 PendingIntent.FLAG_MUTABLE_UNAUDITED).getIntentSender()); 591 } catch (IllegalArgumentException e) { 592 // The package is not installed: that's fine 593 } 594 } 595 clearAllPoliciesAndRestrictions()596 private void clearAllPoliciesAndRestrictions() throws Exception { 597 clearProfileOwnerRelatedPolicies(); 598 clearPolicyTransparencyUserRestriction( 599 PolicyTransparencyTestListActivity.MODE_DEVICE_OWNER); 600 601 // There are a few user restrictions that are used, but not for policy transparency 602 mDpm.clearUserRestriction(mAdmin, UserManager.DISALLOW_CONFIG_BLUETOOTH); 603 mDpm.clearUserRestriction(mAdmin, UserManager.DISALLOW_CONFIG_VPN); 604 mDpm.clearUserRestriction(mAdmin, UserManager.DISALLOW_DATA_ROAMING); 605 mDpm.clearUserRestriction(mAdmin, UserManager.DISALLOW_USER_SWITCH); 606 607 mDpm.setDeviceOwnerLockScreenInfo(mAdmin, null); 608 mDpm.setKeyguardDisabled(mAdmin, false); 609 mDpm.setAutoTimeRequired(mAdmin, false); 610 mDpm.setStatusBarDisabled(mAdmin, false); 611 mDpm.setOrganizationName(mAdmin, null); 612 mDpm.setNetworkLoggingEnabled(mAdmin, false); 613 mDpm.setSecurityLoggingEnabled(mAdmin, false); 614 mDpm.setPermissionGrantState(mAdmin, getPackageName(), 615 Manifest.permission.ACCESS_FINE_LOCATION, 616 DevicePolicyManager.PERMISSION_GRANT_STATE_DEFAULT); 617 mDpm.setPermissionGrantState(mAdmin, getPackageName(), Manifest.permission.RECORD_AUDIO, 618 DevicePolicyManager.PERMISSION_GRANT_STATE_DEFAULT); 619 mDpm.setPermissionGrantState(mAdmin, getPackageName(), Manifest.permission.CAMERA, 620 DevicePolicyManager.PERMISSION_GRANT_STATE_DEFAULT); 621 mDpm.clearPackagePersistentPreferredActivities(mAdmin, getPackageName()); 622 mDpm.setAlwaysOnVpnPackage(mAdmin, null, false); 623 mDpm.setRecommendedGlobalProxy(mAdmin, null); 624 mDpm.uninstallCaCert(mAdmin, TEST_CA.getBytes()); 625 mDpm.setMaximumFailedPasswordsForWipe(mAdmin, 0); 626 mDpm.setSecureSetting(mAdmin, Settings.Secure.DEFAULT_INPUT_METHOD, null); 627 mDpm.setStartUserSessionMessage(mAdmin, null); 628 mDpm.setEndUserSessionMessage(mAdmin, null); 629 mDpm.setLogoutEnabled(mAdmin, false); 630 631 uninstallHelperPackage(); 632 633 // Must wait until package is uninstalled to reset affiliation ids, otherwise the package 634 // cannot be removed on headless system user mode (as caller must be an affiliated PO) 635 mDpm.setAffiliationIds(mAdmin, Collections.emptySet()); 636 637 removeManagedProfile(); 638 getPackageManager().setComponentEnabledSetting( 639 EnterprisePrivacyTestDefaultAppActivity.COMPONENT_NAME, 640 PackageManager.COMPONENT_ENABLED_STATE_DEFAULT, 641 PackageManager.DONT_KILL_APP); 642 } 643 clearProfileOwnerRelatedPoliciesAndRestrictions(int mode)644 private void clearProfileOwnerRelatedPoliciesAndRestrictions(int mode) { 645 clearPolicyTransparencyUserRestriction(mode); 646 clearProfileOwnerRelatedPolicies(); 647 } 648 clearProfileOwnerRelatedPolicies()649 private void clearProfileOwnerRelatedPolicies() { 650 mDpm.setKeyguardDisabledFeatures(mAdmin, 0); 651 mDpm.setPasswordQuality(mAdmin, 0); 652 mDpm.setMaximumTimeToLock(mAdmin, 0); 653 mDpm.setPermittedAccessibilityServices(mAdmin, null); 654 mDpm.setPermittedInputMethods(mAdmin, null); 655 } 656 clearPolicyTransparencyUserRestriction(int mode)657 private void clearPolicyTransparencyUserRestriction(int mode) { 658 for (String userRestriction : UserRestrictions.getUserRestrictionsForPolicyTransparency( 659 mode)) { 660 mDpm.clearUserRestriction(mAdmin, userRestriction); 661 } 662 } 663 removeManagedProfile()664 private void removeManagedProfile() { 665 for (final UserHandle userHandle : mUm.getUserProfiles()) { 666 mDpm.removeUser(mAdmin, userHandle); 667 } 668 } 669 670 /** 671 * Creates an intent to set the given user restriction using the device owner's {@code dpm}. 672 */ createSetDeviceOwnerUserRestrictionIntent(String restriction, boolean enforced)673 public static Intent createSetDeviceOwnerUserRestrictionIntent(String restriction, 674 boolean enforced) { 675 return createSetUserRestrictionIntent(restriction, enforced, /* currentUserDpm= */ false); 676 } 677 678 /** 679 * Creates an intent to set the given user restriction using the current user's {@code dpm}. 680 */ createSetCurrentUserRestrictionIntent(String restriction, boolean enforced)681 public static Intent createSetCurrentUserRestrictionIntent(String restriction, 682 boolean enforced) { 683 return createSetUserRestrictionIntent(restriction, enforced, /* currentUserDpm= */ true); 684 } 685 createSetUserRestrictionIntent(String restriction, boolean enforced, boolean forceCurrentUserDpm)686 private static Intent createSetUserRestrictionIntent(String restriction, boolean enforced, 687 boolean forceCurrentUserDpm) { 688 Intent intent = new Intent(ACTION_EXECUTE_COMMAND); 689 if (forceCurrentUserDpm) { 690 intent.putExtra(EXTRA_USE_CURRENT_USER_DPM, true); 691 } 692 return intent 693 .putExtra(EXTRA_COMMAND, COMMAND_SET_USER_RESTRICTION) 694 .putExtra(EXTRA_USER_RESTRICTION, restriction) 695 .putExtra(EXTRA_ENFORCED, enforced); 696 } 697 getEnabledNonSystemImes()698 private List<String> getEnabledNonSystemImes() { 699 InputMethodManager inputMethodManager = getSystemService(InputMethodManager.class); 700 final List<InputMethodInfo> inputMethods = inputMethodManager.getEnabledInputMethodList(); 701 return inputMethods.stream() 702 .filter(inputMethodInfo -> !isSystemInputMethodInfo(inputMethodInfo)) 703 .map(inputMethodInfo -> inputMethodInfo.getPackageName()) 704 .filter(packageName -> !packageName.equals(getPackageName())) 705 .distinct() 706 .collect(Collectors.toList()); 707 } 708 isSystemInputMethodInfo(InputMethodInfo inputMethodInfo)709 private boolean isSystemInputMethodInfo(InputMethodInfo inputMethodInfo) { 710 final ApplicationInfo applicationInfo = inputMethodInfo.getServiceInfo().applicationInfo; 711 return (applicationInfo.flags & ApplicationInfo.FLAG_SYSTEM) != 0; 712 } 713 createAndSwitchUserWithMessage(String startUserSessionMessage, String endUserSessionMessage)714 private void createAndSwitchUserWithMessage(String startUserSessionMessage, 715 String endUserSessionMessage) { 716 if (!mDpm.isDeviceOwnerApp(getPackageName())) { 717 return; 718 } 719 mDpm.setStartUserSessionMessage(mAdmin, startUserSessionMessage); 720 mDpm.setEndUserSessionMessage(mAdmin, endUserSessionMessage); 721 mDpm.setAffiliationIds(mAdmin, 722 Collections.singleton(DeviceAdminTestReceiver.AFFILIATION_ID)); 723 724 PersistableBundle extras = new PersistableBundle(); 725 extras.putBoolean(DeviceAdminTestReceiver.EXTRA_LOGOUT_ON_START, true); 726 UserHandle userHandle = mDpm.createAndManageUser(mAdmin, "managed user", mAdmin, 727 extras, 728 SKIP_SETUP_WIZARD | MAKE_USER_EPHEMERAL); 729 mDpm.switchUser(mAdmin, userHandle); 730 } 731 getCurrentLauncherPackage()732 private String getCurrentLauncherPackage() { 733 ResolveInfo resolveInfo = getPackageManager() 734 .resolveActivity(new Intent(Intent.ACTION_MAIN) 735 .addCategory(Intent.CATEGORY_HOME), PackageManager.MATCH_DEFAULT_ONLY); 736 if (resolveInfo == null || resolveInfo.activityInfo == null) { 737 return null; 738 } 739 740 return resolveInfo.activityInfo.packageName; 741 } 742 } 743