• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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                     if (com.android.providers.media.flags.Flags.motionPhotoIntent()) {
435                         filter.addAction(MediaStore.ACTION_MOTION_PHOTO_CAPTURE);
436                     }
437                     mDpm.addPersistentPreferredActivity(mAdmin, filter, componentName);
438                     // Map
439                     filter = new IntentFilter();
440                     filter.addAction(Intent.ACTION_VIEW);
441                     filter.addDataScheme("geo");
442                     mDpm.addPersistentPreferredActivity(mAdmin, filter, componentName);
443                     // E-mail
444                     filter = new IntentFilter();
445                     filter.addAction(Intent.ACTION_SENDTO);
446                     filter.addAction(Intent.ACTION_SEND);
447                     filter.addAction(Intent.ACTION_SEND_MULTIPLE);
448                     mDpm.addPersistentPreferredActivity(mAdmin, filter, componentName);
449                     // Calendar
450                     filter = new IntentFilter();
451                     filter.addAction(Intent.ACTION_INSERT);
452                     filter.addDataType("vnd.android.cursor.dir/event");
453                     mDpm.addPersistentPreferredActivity(mAdmin, filter, componentName);
454                     // Contacts
455                     filter = new IntentFilter();
456                     filter.addAction(Intent.ACTION_PICK);
457                     filter.addDataType(ContactsContract.Contacts.CONTENT_TYPE);
458                     mDpm.addPersistentPreferredActivity(mAdmin, filter, componentName);
459                     // Dialer
460                     filter = new IntentFilter();
461                     filter.addAction(Intent.ACTION_DIAL);
462                     filter.addAction(Intent.ACTION_CALL);
463                     mDpm.addPersistentPreferredActivity(mAdmin, filter, componentName);
464                     getPackageManager().setComponentEnabledSetting(componentName,
465                             PackageManager.COMPONENT_ENABLED_STATE_ENABLED,
466                             PackageManager.DONT_KILL_APP);
467                 } break;
468                 case COMMAND_CLEAR_PERSISTENT_PREFERRED_ACTIVITIES: {
469                     mDpm.clearPackagePersistentPreferredActivities(mAdmin, getPackageName());
470                     getPackageManager().setComponentEnabledSetting(
471                             EnterprisePrivacyTestDefaultAppActivity.COMPONENT_NAME,
472                             PackageManager.COMPONENT_ENABLED_STATE_DEFAULT,
473                             PackageManager.DONT_KILL_APP);
474                 } break;
475                 case COMMAND_SET_ALWAYS_ON_VPN: {
476                     if (!isDeviceOwnerAppOrEquivalent(getPackageName())) {
477                         return;
478                     }
479                     mDpm.setAlwaysOnVpnPackage(mAdmin, getPackageName(),
480                             false /* lockdownEnabled */);
481                 } break;
482                 case COMMAND_CLEAR_ALWAYS_ON_VPN: {
483                     if (!isDeviceOwnerAppOrEquivalent(getPackageName())) {
484                         return;
485                     }
486                     mDpm.setAlwaysOnVpnPackage(mAdmin, null /* vpnPackage */,
487                             false /* lockdownEnabled */);
488                 } break;
489                 case COMMAND_SET_GLOBAL_HTTP_PROXY: {
490                     if (!mDpm.isDeviceOwnerApp(getPackageName())) {
491                         return;
492                     }
493                     mDpm.setRecommendedGlobalProxy(mAdmin,
494                             ProxyInfo.buildDirectProxy("example.com", 123));
495                 } break;
496                 case COMMAND_CLEAR_GLOBAL_HTTP_PROXY: {
497                     if (!mDpm.isDeviceOwnerApp(getPackageName())) {
498                         return;
499                     }
500                     mDpm.setRecommendedGlobalProxy(mAdmin, null);
501                 } break;
502                 case COMMAND_INSTALL_CA_CERT: {
503                     if (!isDeviceOwnerAppOrEquivalent(getPackageName())) {
504                         return;
505                     }
506                     mDpm.installCaCert(mAdmin, TEST_CA.getBytes());
507                 } break;
508                 case COMMAND_CLEAR_CA_CERT: {
509                     if (!isDeviceOwnerAppOrEquivalent(getPackageName())) {
510                         return;
511                     }
512                     mDpm.uninstallCaCert(mAdmin, TEST_CA.getBytes());
513                 } break;
514                 case COMMAND_SET_MAXIMUM_PASSWORD_ATTEMPTS: {
515                     if (!isDeviceOwner()) return;
516                     int max = 100;
517                     Log.d(TAG, "Setting maximum password attempts to " + max + " using" + mDpm);
518                     mDpm.setMaximumFailedPasswordsForWipe(mAdmin, max);
519                 } break;
520                 case COMMAND_CLEAR_MAXIMUM_PASSWORD_ATTEMPTS: {
521                     if (!isDeviceOwner()) return;
522                     Log.d(TAG, "Clearing maximum password attempts using" + mDpm);
523                     mDpm.setMaximumFailedPasswordsForWipe(mAdmin, 0);
524                 } break;
525                 case COMMAND_SET_DEFAULT_IME: {
526                     if (!isDeviceOwner()) return;
527                     Log.d(TAG, "Setting " + Settings.Secure.DEFAULT_INPUT_METHOD + " using "
528                             + mDpm);
529                     mDpm.setSecureSetting(mAdmin, Settings.Secure.DEFAULT_INPUT_METHOD,
530                             getPackageName());
531                 } break;
532                 case COMMAND_CLEAR_DEFAULT_IME: {
533                     if (!isDeviceOwner()) return;
534                     Log.d(TAG, "Clearing " + Settings.Secure.DEFAULT_INPUT_METHOD + " using "
535                             + mDpm);
536                     mDpm.setSecureSetting(mAdmin, Settings.Secure.DEFAULT_INPUT_METHOD, null);
537                 } break;
538                 case COMMAND_CREATE_MANAGED_USER:{
539                     if (!mDpm.isDeviceOwnerApp(getPackageName())) {
540                         return;
541                     }
542                     PersistableBundle extras = new PersistableBundle();
543                     extras.putBoolean(DeviceAdminTestReceiver.EXTRA_MANAGED_USER_TEST, true);
544                     UserHandle userHandle = mDpm.createAndManageUser(mAdmin, "managed user", mAdmin,
545                             extras,
546                             SKIP_SETUP_WIZARD | MAKE_USER_EPHEMERAL);
547                     Log.i(TAG, "Created user " + userHandle + "; setting affiliation ids to "
548                             + DeviceAdminTestReceiver.AFFILIATION_ID);
549                     mDpm.setAffiliationIds(mAdmin,
550                             Collections.singleton(DeviceAdminTestReceiver.AFFILIATION_ID));
551                     // TODO(b/204483021): move to helper class / restore after user is logged out
552                     if (UserManager.isHeadlessSystemUserMode()) {
553                         mAm.setStopUserOnSwitch(ActivityManager.STOP_USER_ON_SWITCH_FALSE);
554                     }
555                     Log.d(TAG, "Starting user " + userHandle);
556                     mDpm.startUserInBackground(mAdmin, userHandle);
557                 } break;
558                 case COMMAND_CREATE_MANAGED_USER_WITHOUT_SETUP:{
559                     if (!mDpm.isDeviceOwnerApp(getPackageName())) {
560                         return;
561                     }
562                     PersistableBundle extras = new PersistableBundle();
563                     extras.putBoolean(DeviceAdminTestReceiver.EXTRA_MANAGED_USER_TEST, true);
564                     mDpm.createAndManageUser(mAdmin, "managed user", mAdmin, extras, /* flags */ 0);
565                 } break;
566                 case COMMAND_REMOVE_SECONDARY_USERS: {
567                     if (!mDpm.isDeviceOwnerApp(getPackageName())) {
568                         return;
569                     }
570                     for (UserHandle secondaryUser : mDpm.getSecondaryUsers(mAdmin)) {
571                         mDpm.removeUser(mAdmin, secondaryUser);
572                     }
573                 } break;
574                 case COMMAND_WITH_USER_SWITCHER_MESSAGE: {
575                     createAndSwitchUserWithMessage("Start user session", "End user session");
576                 } break;
577                 case COMMAND_WITHOUT_USER_SWITCHER_MESSAGE: {
578                     createAndSwitchUserWithMessage(null, null);
579                 } break;
580                 case COMMAND_ENABLE_LOGOUT: {
581                     if (!mDpm.isDeviceOwnerApp(getPackageName())) {
582                         return;
583                     }
584                     mDpm.addUserRestriction(mAdmin, UserManager.DISALLOW_USER_SWITCH);
585                     mDpm.setLogoutEnabled(mAdmin, true);
586                     UserHandle userHandle = mDpm.createAndManageUser(mAdmin, "managed user", mAdmin,
587                             null, SKIP_SETUP_WIZARD | MAKE_USER_EPHEMERAL);
588                     mDpm.switchUser(mAdmin, userHandle);
589                 } break;
590                 case COMMAND_DISABLE_USB_DATA_SIGNALING: {
591                     mDpm.setUsbDataSignalingEnabled(false);
592                     break;
593                 }
594                 case COMMAND_ENABLE_USB_DATA_SIGNALING: {
595                     mDpm.setUsbDataSignalingEnabled(true);
596                     break;
597                 }
598                 case COMMAND_SET_REQUIRED_PASSWORD_COMPLEXITY: {
599                     int complexity = intent.getIntExtra(EXTRA_VALUE,
600                             DevicePolicyManager.PASSWORD_COMPLEXITY_NONE);
601                     Log.d(TAG, "calling setRequiredPasswordComplexity(" + complexity + ")");
602                     mDpm.setRequiredPasswordComplexity(complexity);
603                 } break;
604                 case COMMAND_SET_WIFI_SECURITY_LEVEL: {
605                     int level = intent.getIntExtra(EXTRA_VALUE,
606                             DevicePolicyManager.WIFI_SECURITY_OPEN);
607                     Log.d(TAG, "calling setWifiSecurityLevel(" + level + ")");
608                     mDpm.setMinimumRequiredWifiSecurityLevel(level);
609                 } break;
610                 case COMMAND_SET_SSID_ALLOWLIST: {
611                     String ssid = intent.getStringExtra(EXTRA_VALUE);
612                     WifiSsidPolicy policy;
613                     if (ssid.isEmpty()) {
614                         policy = null;
615                     } else {
616                         Set<WifiSsid> ssids = new ArraySet<>(Arrays.asList(
617                                 WifiSsid.fromBytes(ssid.getBytes(StandardCharsets.UTF_8))));
618                         policy = new WifiSsidPolicy(
619                                 WifiSsidPolicy.WIFI_SSID_POLICY_TYPE_ALLOWLIST, ssids);
620                     }
621                     mDpm.setWifiSsidPolicy(policy);
622                 } break;
623                 case COMMAND_SET_SSID_DENYLIST: {
624                     String ssid = intent.getStringExtra(EXTRA_VALUE);
625                     WifiSsidPolicy policy;
626                     if (ssid.isEmpty()) {
627                         policy = null;
628                     } else {
629                         Set<WifiSsid> ssids = new ArraySet<>(Arrays.asList(
630                                 WifiSsid.fromBytes(ssid.getBytes(StandardCharsets.UTF_8))));
631                         policy = new WifiSsidPolicy(
632                                 WifiSsidPolicy.WIFI_SSID_POLICY_TYPE_DENYLIST, ssids);
633                     }
634                     mDpm.setWifiSsidPolicy(policy);
635                 } break;
636             }
637         } catch (Exception e) {
638             Log.e(TAG, "Failed to execute command: " + intent, e);
639         } finally {
640             finish();
641         }
642     }
643 
644     /**
645      * Checks if {@code CtsVerifier} is the device owner.
646      */
isDeviceOwner()647     private boolean isDeviceOwner() {
648         // Cannot use mDpm as it would be the DPM of the current user on headless system user mode,
649         // which would return false
650         DevicePolicyManager dpm = TestAppSystemServiceFactory.getDevicePolicyManager(this,
651                 DeviceAdminTestReceiver.class, /* forDeviceOwner= */ true,
652                 /* isSingleUser = */ false);
653         boolean isIt = dpm.isDeviceOwnerApp(getPackageName());
654         Log.v(TAG, "is " + getPackageName() + " DO, using " + dpm + "? " + isIt);
655         return isIt;
656     }
657 
658     /**
659      * Checks if the {@code packageName} is a device owner app, or a profile owner app in the
660      * headless system user mode.
661       */
isDeviceOwnerAppOrEquivalent(String packageName)662     private boolean isDeviceOwnerAppOrEquivalent(String packageName) {
663         return mDpm.isDeviceOwnerApp(packageName)
664                 || (UserManager.isHeadlessSystemUserMode() && mDpm.isProfileOwnerApp(packageName));
665     }
666 
installHelperPackage()667     private void installHelperPackage() throws Exception {
668         if (UserManager.isHeadlessSystemUserMode()) {
669             // App was already installed on user 0 (as instructed), so we just install it for the
670             // current user - installing directly to current user would be harder as it would
671             // require a custom ContentProvider to push the APK into a secondary user using adb
672             Log.i(TAG, "installing existing helper app (" + HELPER_APP_PKG + ") using " + mDpm);
673             mDpm.installExistingPackage(mAdmin, HELPER_APP_PKG);
674             return;
675         }
676         LogAndSelfUnregisterBroadcastReceiver.register(this, ACTION_INSTALL_COMPLETE);
677         final PackageInstaller packageInstaller = getPackageManager().getPackageInstaller();
678         final PackageInstaller.Session session = packageInstaller.openSession(
679                 packageInstaller.createSession(new PackageInstaller.SessionParams(
680                         PackageInstaller.SessionParams.MODE_FULL_INSTALL)));
681         final File file = new File(HELPER_APP_LOCATION);
682         Log.i(TAG, "installing helper package from " + file);
683         final InputStream in = new FileInputStream(file);
684         final OutputStream out = session.openWrite("CommandReceiverActivity", 0, file.length());
685         final byte[] buffer = new byte[65536];
686         int count;
687         while ((count = in.read(buffer)) != -1) {
688             out.write(buffer, 0, count);
689         }
690         session.fsync(out);
691         in.close();
692         out.close();
693         session.commit(PendingIntent
694                 .getBroadcast(this, 0,
695                         new Intent(ACTION_INSTALL_COMPLETE).setPackage(getPackageName()),
696                         PendingIntent.FLAG_MUTABLE)
697                 .getIntentSender());
698     }
699 
uninstallHelperPackage()700     private void uninstallHelperPackage() {
701         LogAndSelfUnregisterBroadcastReceiver.register(this, ACTION_UNINSTALL_COMPLETE);
702         PackageInstaller packageInstaller = getPackageManager().getPackageInstaller();
703         Log.i(TAG, "Uninstalling package " + HELPER_APP_PKG + " using " + packageInstaller);
704         try {
705             packageInstaller.uninstall(HELPER_APP_PKG, PendingIntent.getBroadcast(this,
706                     /* requestCode= */ 0,
707                     new Intent(ACTION_UNINSTALL_COMPLETE).setPackage(getPackageName()),
708                     PendingIntent.FLAG_MUTABLE).getIntentSender());
709         } catch (IllegalArgumentException e) {
710             // The package is not installed: that's fine
711         }
712     }
713 
clearAllPoliciesAndRestrictions()714     private void clearAllPoliciesAndRestrictions() throws Exception {
715         Log.d(TAG, "clearAllPoliciesAndRestrictions() started");
716         clearProfileOwnerRelatedPolicies();
717         clearPolicyTransparencyUserRestriction(
718                 PolicyTransparencyTestListActivity.MODE_DEVICE_OWNER);
719 
720         // There are a few user restrictions that are used, but not for policy transparency
721         mDpm.clearUserRestriction(mAdmin, UserManager.DISALLOW_CONFIG_BLUETOOTH);
722         mDpm.clearUserRestriction(mAdmin, UserManager.DISALLOW_CONFIG_VPN);
723         mDpm.clearUserRestriction(mAdmin, UserManager.DISALLOW_DATA_ROAMING);
724         mDpm.clearUserRestriction(mAdmin, UserManager.DISALLOW_USER_SWITCH);
725 
726         mDpm.setDeviceOwnerLockScreenInfo(mAdmin, null);
727         mDpm.setKeyguardDisabled(mAdmin, false);
728         mDpm.setAutoTimeRequired(mAdmin, false);
729         mDpm.setStatusBarDisabled(mAdmin, false);
730         mDpm.setOrganizationName(mAdmin, null);
731         mDpm.setNetworkLoggingEnabled(mAdmin, false);
732         mDpm.setSecurityLoggingEnabled(mAdmin, false);
733         mDpm.setPermissionGrantState(mAdmin, getPackageName(),
734                 Manifest.permission.ACCESS_FINE_LOCATION,
735                 DevicePolicyManager.PERMISSION_GRANT_STATE_DEFAULT);
736         mDpm.setPermissionGrantState(mAdmin, getPackageName(), Manifest.permission.RECORD_AUDIO,
737                 DevicePolicyManager.PERMISSION_GRANT_STATE_DEFAULT);
738         mDpm.setPermissionGrantState(mAdmin, getPackageName(), Manifest.permission.CAMERA,
739                 DevicePolicyManager.PERMISSION_GRANT_STATE_DEFAULT);
740         mDpm.clearPackagePersistentPreferredActivities(mAdmin, getPackageName());
741         mDpm.setAlwaysOnVpnPackage(mAdmin, null, false);
742         mDpm.setRecommendedGlobalProxy(mAdmin, null);
743         mDpm.uninstallCaCert(mAdmin, TEST_CA.getBytes());
744         mDpm.setMaximumFailedPasswordsForWipe(mAdmin, 0);
745         mDpm.setSecureSetting(mAdmin, Settings.Secure.DEFAULT_INPUT_METHOD, null);
746         mDpm.setStartUserSessionMessage(mAdmin, null);
747         mDpm.setEndUserSessionMessage(mAdmin, null);
748         mDpm.setLogoutEnabled(mAdmin, false);
749 
750         uninstallHelperPackage();
751 
752         // Must wait until package is uninstalled to reset affiliation ids, otherwise the package
753         // cannot be removed on headless system user mode (as caller must be an affiliated PO)
754         Log.d(TAG, "resetting affiliation ids");
755         mDpm.setAffiliationIds(mAdmin, Collections.emptySet());
756 
757         removeManagedProfile();
758         getPackageManager().setComponentEnabledSetting(
759                 EnterprisePrivacyTestDefaultAppActivity.COMPONENT_NAME,
760                 PackageManager.COMPONENT_ENABLED_STATE_DEFAULT,
761                 PackageManager.DONT_KILL_APP);
762         Log.d(TAG, "clearAllPoliciesAndRestrictions() finished");
763     }
764 
clearProfileOwnerRelatedPoliciesAndRestrictions(int mode)765     private void clearProfileOwnerRelatedPoliciesAndRestrictions(int mode) {
766         clearPolicyTransparencyUserRestriction(mode);
767         clearProfileOwnerRelatedPolicies();
768     }
769 
clearProfileOwnerRelatedPolicies()770     private void clearProfileOwnerRelatedPolicies() {
771         Log.d(TAG, "clearProfileOwnerRelatedPolicies() started");
772         mDpm.setKeyguardDisabledFeatures(mAdmin, 0);
773         mDpm.setPasswordQuality(mAdmin, 0);
774         mDpm.setMaximumTimeToLock(mAdmin, 0);
775         mDpm.setPermittedAccessibilityServices(mAdmin, null);
776         mDpm.setPermittedInputMethods(mAdmin, null);
777         Log.d(TAG, "clearProfileOwnerRelatedPolicies() finished");
778     }
779 
clearPolicyTransparencyUserRestriction(int mode)780     private void clearPolicyTransparencyUserRestriction(int mode) {
781         for (String userRestriction : UserRestrictions.getUserRestrictionsForPolicyTransparency(
782                 mode)) {
783             mDpm.clearUserRestriction(mAdmin, userRestriction);
784         }
785     }
786 
removeManagedProfile()787     private void removeManagedProfile() {
788         for (UserHandle userHandle : mUm.getUserProfiles()) {
789             Log.d(TAG, "removing managed profile for " + userHandle);
790             mDpm.removeUser(mAdmin, userHandle);
791         }
792     }
793 
794     /**
795      * Creates an intent to set the given user restriction using the device owner's {@code dpm}.
796      */
createSetDeviceOwnerUserRestrictionIntent(String restriction, boolean enforced)797     public static Intent createSetDeviceOwnerUserRestrictionIntent(String restriction,
798             boolean enforced) {
799         return createSetUserRestrictionIntent(restriction, enforced, /* currentUserDpm= */ false);
800     }
801 
802     /**
803      * Creates an intent to set the given user restriction using the current user's {@code dpm}.
804      */
createSetCurrentUserRestrictionIntent(String restriction, boolean enforced)805     public static Intent createSetCurrentUserRestrictionIntent(String restriction,
806             boolean enforced) {
807         return createSetUserRestrictionIntent(restriction, enforced, /* currentUserDpm= */ true);
808     }
809 
createSetUserRestrictionIntent(String restriction, boolean enforced, boolean forceCurrentUserDpm)810     private static Intent createSetUserRestrictionIntent(String restriction, boolean enforced,
811             boolean forceCurrentUserDpm) {
812         Log.d(TAG, "createSetUserRestrictionIntent(): restriction=" + restriction
813                 + ", enforced=" + enforced + ", forceCurrentUserDpm=" + forceCurrentUserDpm);
814         Intent intent = new Intent(ACTION_EXECUTE_COMMAND);
815         if (forceCurrentUserDpm) {
816             intent.putExtra(EXTRA_USE_CURRENT_USER_DPM, true);
817         }
818         return intent
819                 .putExtra(EXTRA_COMMAND, COMMAND_SET_USER_RESTRICTION)
820                 .putExtra(EXTRA_USER_RESTRICTION, restriction)
821                 .putExtra(EXTRA_ENFORCED, enforced);
822     }
823 
getEnabledNonSystemImes()824     private List<String> getEnabledNonSystemImes() {
825         InputMethodManager inputMethodManager = getSystemService(InputMethodManager.class);
826         final List<InputMethodInfo> inputMethods = inputMethodManager.getEnabledInputMethodList();
827         return inputMethods.stream()
828                 .filter(inputMethodInfo -> !isSystemInputMethodInfo(inputMethodInfo))
829                 .map(inputMethodInfo -> inputMethodInfo.getPackageName())
830                 .filter(packageName -> !packageName.equals(getPackageName()))
831                 .distinct()
832                 .collect(Collectors.toList());
833     }
834 
isSystemInputMethodInfo(InputMethodInfo inputMethodInfo)835     private boolean isSystemInputMethodInfo(InputMethodInfo inputMethodInfo) {
836         final ApplicationInfo applicationInfo = inputMethodInfo.getServiceInfo().applicationInfo;
837         return (applicationInfo.flags & ApplicationInfo.FLAG_SYSTEM) != 0;
838     }
839 
createAndSwitchUserWithMessage(String startUserSessionMessage, String endUserSessionMessage)840     private void createAndSwitchUserWithMessage(String startUserSessionMessage,
841             String endUserSessionMessage) {
842         if (!mDpm.isDeviceOwnerApp(getPackageName())) {
843             return;
844         }
845         mDpm.setStartUserSessionMessage(mAdmin, startUserSessionMessage);
846         mDpm.setEndUserSessionMessage(mAdmin, endUserSessionMessage);
847         mDpm.setAffiliationIds(mAdmin,
848                 Collections.singleton(DeviceAdminTestReceiver.AFFILIATION_ID));
849 
850         PersistableBundle extras = new PersistableBundle();
851         extras.putBoolean(DeviceAdminTestReceiver.EXTRA_LOGOUT_ON_START, true);
852         UserHandle userHandle = mDpm.createAndManageUser(mAdmin, "managed user", mAdmin,
853                 extras,
854                 SKIP_SETUP_WIZARD | MAKE_USER_EPHEMERAL);
855         // TODO(b/204483021): move to helper class / restore after user is logged out
856         if (UserManager.isHeadlessSystemUserMode()) {
857             mAm.setStopUserOnSwitch(ActivityManager.STOP_USER_ON_SWITCH_FALSE);
858         }
859         Log.d(TAG, "Switching to user " + userHandle);
860         mDpm.switchUser(mAdmin, userHandle);
861     }
862 
getCurrentLauncherPackage()863     private String getCurrentLauncherPackage() {
864         ResolveInfo resolveInfo = getPackageManager()
865             .resolveActivity(new Intent(Intent.ACTION_MAIN)
866                 .addCategory(Intent.CATEGORY_HOME), PackageManager.MATCH_DEFAULT_ONLY);
867         if (resolveInfo == null || resolveInfo.activityInfo == null) {
868             return null;
869         }
870 
871         return resolveInfo.activityInfo.packageName;
872     }
873 
createIntentForDisablingKeyguardOrStatusBar(Context context, String command, boolean disabled)874     static Intent createIntentForDisablingKeyguardOrStatusBar(Context context, String command,
875             boolean disabled) {
876         return new Intent(context, CommandReceiverActivity.class)
877                 .putExtra(CommandReceiverActivity.EXTRA_USE_CURRENT_USER_DPM, true)
878                 .putExtra(CommandReceiverActivity.EXTRA_COMMAND, command)
879                 .putExtra(CommandReceiverActivity.EXTRA_ENFORCED, disabled);
880     }
881 }
882