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