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