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