• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2012 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 android.app.KeyguardManager;
20 import android.app.admin.DevicePolicyManager;
21 import android.content.ActivityNotFoundException;
22 import android.content.ComponentName;
23 import android.content.Context;
24 import android.content.Intent;
25 import android.content.pm.PackageManager;
26 import android.net.ConnectivityManager;
27 import android.os.Bundle;
28 import android.provider.Settings;
29 import android.util.Log;
30 import android.widget.Toast;
31 
32 import com.android.cts.verifier.ArrayTestListAdapter;
33 import com.android.cts.verifier.DialogTestListActivity;
34 import com.android.cts.verifier.R;
35 import com.android.cts.verifier.TestListActivity;
36 import com.android.cts.verifier.TestListAdapter.TestListItem;
37 import com.android.cts.verifier.TestResult;
38 import com.android.cts.verifier.location.LocationListenerActivity;
39 
40 /**
41  * CTS verifier test for BYOD managed provisioning flow
42  *
43  * This activity is responsible for starting the managed provisioning flow and verify the outcome of
44  * provisioning. It performs the following verifications:
45  *   Full disk encryption is enabled.
46  *   Profile owner is correctly installed.
47  *   Profile owner shows up in the Settings app.
48  *   Badged work apps show up in launcher.
49  * The first two verifications are performed automatically, by interacting with profile owner using
50  * cross-profile intents, while the last two are carried out manually by the user.
51  */
52 public class ByodFlowTestActivity extends DialogTestListActivity {
53 
54     // Action for delivering sub-test result from the profile.
55     public static final String ACTION_TEST_RESULT =
56             "com.android.cts.verifier.managedprovisioning.BYOD_TEST_RESULT";
57     // Extra for ACTION_TEST_RESULT containing test result.
58     public static final String EXTRA_RESULT = "extra-result";
59     protected static final String HELPER_APP_PATH = "/data/local/tmp/NotificationBot.apk";
60 
61     private static final String TAG = "ByodFlowTestActivity";
62     private static ConnectivityManager mCm;
63     private static final int REQUEST_MANAGED_PROVISIONING = 0;
64     private static final int REQUEST_PROFILE_OWNER_STATUS = 1;
65     private static final int REQUEST_INTENT_FILTERS_STATUS = 2;
66     private static final int REQUEST_CHECK_DISK_ENCRYPTION = 3;
67     private static final int REQUEST_SET_LOCK_FOR_ENCRYPTION = 4;
68 
69     private ComponentName mAdminReceiverComponent;
70     private KeyguardManager mKeyguardManager;
71     private ByodFlowTestHelper mByodFlowTestHelper;
72 
73     private DialogTestListItem mProfileOwnerInstalled;
74     private DialogTestListItem mDiskEncryptionTest;
75     private DialogTestListItem mProfileAccountVisibleTest;
76     private DialogTestListItem mDeviceAdminVisibleTest;
77     private DialogTestListItem mWorkAppVisibleTest;
78     private DialogTestListItem mCrossProfileIntentFiltersTestFromPersonal;
79     private DialogTestListItem mCrossProfileIntentFiltersTestFromWork;
80     private DialogTestListItem mAppLinkingTest;
81     private TestListItem mNonMarketAppsTest;
82     private DialogTestListItem mWorkNotificationBadgedTest;
83     private DialogTestListItem mWorkStatusBarIconTest;
84     private DialogTestListItem mWorkStatusBarToastTest;
85     private DialogTestListItem mUserSettingsVisibleTest;
86     private DialogTestListItem mAppSettingsVisibleTest;
87     private DialogTestListItem mLocationSettingsVisibleTest;
88     private DialogTestListItem mWiFiDataUsageSettingsVisibleTest;
89     private DialogTestListItem mCellularDataUsageSettingsVisibleTest;
90     private DialogTestListItem mCredSettingsVisibleTest;
91     private DialogTestListItem mPrintSettingsVisibleTest;
92     private DialogTestListItem mIntentFiltersTest;
93     private DialogTestListItem mPermissionLockdownTest;
94     private DialogTestListItem mCrossProfileImageCaptureSupportTest;
95     private DialogTestListItem mCrossProfileVideoCaptureWithExtraOutputSupportTest;
96     private DialogTestListItem mCrossProfileVideoCaptureWithoutExtraOutputSupportTest;
97     private DialogTestListItem mCrossProfileAudioCaptureSupportTest;
98     private TestListItem mKeyguardDisabledFeaturesTest;
99     private DialogTestListItem mDisableNfcBeamTest;
100     private TestListItem mAuthenticationBoundKeyTest;
101     private DialogTestListItem mEnableLocationModeTest;
102     private DialogTestListItem mDisableLocationModeThroughMainSwitchTest;
103     private DialogTestListItem mDisableLocationModeThroughWorkSwitchTest;
104     private DialogTestListItem mPrimaryLocationWhenWorkDisabledTest;
105     private DialogTestListItem mSelectWorkChallenge;
106     private DialogTestListItem mConfirmWorkCredentials;
107     private DialogTestListItem mPatternWorkChallenge;
108     private DialogTestListItem mParentProfilePassword;
109     private DialogTestListItem mPersonalRingtonesTest;
110     private TestListItem mVpnTest;
111     private TestListItem mKeyChainTest;
112     private TestListItem mAlwaysOnVpnSettingsTest;
113     private TestListItem mRecentsTest;
114     private TestListItem mDisallowAppsControlTest;
115     private TestListItem mOrganizationInfoTest;
116     private TestListItem mPolicyTransparencyTest;
117     private TestListItem mTurnOffWorkFeaturesTest;
118     private TestListItem mWidgetTest;
119 
ByodFlowTestActivity()120     public ByodFlowTestActivity() {
121         super(R.layout.provisioning_byod,
122                 R.string.provisioning_byod, R.string.provisioning_byod_info,
123                 R.string.provisioning_byod_instructions);
124     }
125 
126     @Override
onCreate(Bundle savedInstanceState)127     protected void onCreate(Bundle savedInstanceState) {
128         super.onCreate(savedInstanceState);
129         mByodFlowTestHelper = new ByodFlowTestHelper(this);
130         mAdminReceiverComponent = new ComponentName(this, DeviceAdminTestReceiver.class.getName());
131         mKeyguardManager = (KeyguardManager) getSystemService(KEYGUARD_SERVICE);
132 
133         mByodFlowTestHelper.setup();
134 
135         mPrepareTestButton.setText(R.string.provisioning_byod_start);
136         mPrepareTestButton.setOnClickListener(v -> Utils.provisionManagedProfile(
137                 ByodFlowTestActivity.this, mAdminReceiverComponent,
138                 REQUEST_MANAGED_PROVISIONING));
139 
140         // If we are started by managed provisioning (fresh managed provisioning after encryption
141         // reboot), redirect the user back to the main test list. This is because the test result
142         // is only saved by the parent TestListActivity, and if we did allow the user to proceed
143         // here, the test result would be lost when this activity finishes.
144         if (ByodHelperActivity.ACTION_PROFILE_OWNER_STATUS.equals(getIntent().getAction())) {
145             startActivity(new Intent(this, TestListActivity.class));
146             // Calling super.finish() because we delete managed profile in our overridden of finish(),
147             // which is not what we want to do here.
148             super.finish();
149         } else {
150             queryProfileOwner(false);
151         }
152     }
153 
154     @Override
onNewIntent(Intent intent)155     protected void onNewIntent(Intent intent) {
156         super.onNewIntent(intent);
157         if (ByodHelperActivity.ACTION_PROFILE_OWNER_STATUS.equals(intent.getAction())) {
158             // This is called when managed provisioning completes successfully without reboot.
159             handleStatusUpdate(RESULT_OK, intent);
160         } else if (ACTION_TEST_RESULT.equals(intent.getAction())) {
161             // Called when subtest cannot communicate test result from the profile via setResult().
162             handleLaunchTestResult(RESULT_OK, intent.getParcelableExtra(EXTRA_RESULT));
163         }
164     }
165 
166     @Override
handleActivityResult(int requestCode, int resultCode, Intent data)167     protected void handleActivityResult(int requestCode, int resultCode, Intent data) {
168         switch (requestCode) {
169             case REQUEST_MANAGED_PROVISIONING:
170                 return;
171             case REQUEST_PROFILE_OWNER_STATUS:
172                 // Called after queryProfileOwner()
173                 handleStatusUpdate(resultCode, data);
174                 break;
175             case REQUEST_CHECK_DISK_ENCRYPTION:
176                 // Called after checkDiskEncryption()
177                 handleDiskEncryptionStatus(resultCode, data);
178                 break;
179             case REQUEST_SET_LOCK_FOR_ENCRYPTION:
180                 // Called after handleDiskEncryptionStatus() to set screen lock if necessary
181                 handleSetLockForEncryption();
182                 break;
183             case REQUEST_INTENT_FILTERS_STATUS:
184                 // Called after checkIntentFilters()
185                 handleIntentFiltersStatus(resultCode);
186                 break;
187             default:
188                 super.handleActivityResult(requestCode, resultCode, data);
189         }
190     }
191 
handleStatusUpdate(int resultCode, Intent data)192     private void handleStatusUpdate(int resultCode, Intent data) {
193         boolean provisioned = data != null &&
194                 data.getBooleanExtra(ByodHelperActivity.EXTRA_PROVISIONED, false);
195         setTestResult(mProfileOwnerInstalled, (provisioned && resultCode == RESULT_OK) ?
196                 TestResult.TEST_RESULT_PASSED : TestResult.TEST_RESULT_FAILED);
197     }
198 
199     @Override
finish()200     public void finish() {
201         // Pass and fail buttons are known to call finish() when clicked, and this is when we want to
202         // clean up the provisioned profile.
203         mByodFlowTestHelper.tearDown();
204         super.finish();
205     }
206 
207     @Override
setupTests(ArrayTestListAdapter adapter)208     protected void setupTests(ArrayTestListAdapter adapter) {
209         mProfileOwnerInstalled = new DialogTestListItem(this,
210                 R.string.provisioning_byod_profileowner,
211                 "BYOD_ProfileOwnerInstalled") {
212             @Override
213             public void performTest(DialogTestListActivity activity) {
214                 queryProfileOwner(true);
215             }
216         };
217 
218         mDiskEncryptionTest = new DialogTestListItem(this,
219                 R.string.provisioning_byod_disk_encryption,
220                 "BYOD_DiskEncryptionTest") {
221             @Override
222             public void performTest(DialogTestListActivity activity) {
223                 checkDiskEncryption();
224             }
225         };
226 
227         /*
228          * To keep the image in this test up to date, use the instructions in
229          * {@link ByodIconSamplerActivity}.
230          */
231 
232         if (!getPackageManager().hasSystemFeature(PackageManager.FEATURE_AUTOMOTIVE)) {
233             mWorkAppVisibleTest = new DialogTestListItemWithIcon(this,
234                     R.string.provisioning_byod_workapps_visible,
235                     "BYOD_WorkAppVisibleTest",
236                     R.string.provisioning_byod_workapps_visible_instruction,
237                     new Intent(Intent.ACTION_MAIN).addCategory(Intent.CATEGORY_HOME),
238                     R.drawable.badged_icon);
239 
240             mConfirmWorkCredentials = new DialogTestListItem(this,
241                     R.string.provisioning_byod_confirm_work_credentials,
242                     "BYOD_ConfirmWorkCredentials",
243                     R.string.provisioning_byod_confirm_work_credentials_description,
244                     new Intent(Intent.ACTION_MAIN).addCategory(Intent.CATEGORY_HOME));
245 
246             mPatternWorkChallenge = new DialogTestListItem(this,
247                     R.string.provisioning_byod_pattern_work_challenge,
248                     "BYOD_PatternWorkChallenge",
249                     R.string.provisioning_byod_pattern_work_challenge_description,
250                     new Intent(ByodHelperActivity.ACTION_TEST_PATTERN_WORK_CHALLENGE));
251 
252             mWiFiDataUsageSettingsVisibleTest = new DialogTestListItem(this,
253                     R.string.provisioning_byod_wifi_data_usage_settings,
254                     "BYOD_WiFiDataUsageSettingsVisibleTest",
255                     R.string.provisioning_byod_wifi_data_usage_settings_instruction,
256                     new Intent(Settings.ACTION_SETTINGS));
257         }
258 
259         mWorkNotificationBadgedTest = new DialogTestListItemWithIcon(this,
260                 R.string.provisioning_byod_work_notification,
261                 "BYOD_WorkNotificationBadgedTest",
262                 R.string.provisioning_byod_work_notification_instruction,
263                 new Intent(ByodHelperActivity.ACTION_NOTIFICATION),
264                 R.drawable.ic_corp_icon);
265 
266         Intent workStatusIcon = new Intent(WorkStatusTestActivity.ACTION_WORK_STATUS_ICON);
267         workStatusIcon.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
268         mWorkStatusBarIconTest = new DialogTestListItemWithIcon(this,
269                 R.string.provisioning_byod_work_status_icon,
270                 "BYOD_WorkStatusBarIconTest",
271                 R.string.provisioning_byod_work_status_icon_instruction,
272                 workStatusIcon,
273                 R.drawable.stat_sys_managed_profile_status);
274 
275         /* Disable due to b/111734436.
276         Intent workStatusToast = new Intent(WorkStatusTestActivity.ACTION_WORK_STATUS_TOAST);
277         workStatusToast.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
278         mWorkStatusBarToastTest = new DialogTestListItem(this,
279                 R.string.provisioning_byod_work_status_toast,
280                 "BYOD_WorkStatusBarToastTest",
281                 R.string.provisioning_byod_work_status_toast_instruction,
282                 workStatusToast);
283         */
284 
285         mNonMarketAppsTest = TestListItem.newTest(this,
286                 R.string.provisioning_byod_non_market_apps,
287                 NonMarketAppsActivity.class.getName(),
288                 new Intent(this, NonMarketAppsActivity.class), null);
289 
290         mProfileAccountVisibleTest = new DialogTestListItem(this,
291                 R.string.provisioning_byod_profile_visible,
292                 "BYOD_ProfileAccountVisibleTest",
293                 R.string.provisioning_byod_profile_visible_instruction,
294                 new Intent(Settings.ACTION_SETTINGS));
295 
296         mUserSettingsVisibleTest = new DialogTestListItem(this,
297             R.string.provisioning_byod_user_settings,
298             "BYOD_UserSettingsVisibleTest",
299             R.string.provisioning_byod_user_settings_instruction,
300             new Intent(Settings.ACTION_SETTINGS));
301 
302         mAppSettingsVisibleTest = new DialogTestListItem(this,
303                 R.string.provisioning_byod_app_settings,
304                 "BYOD_AppSettingsVisibleTest",
305                 R.string.provisioning_byod_app_settings_instruction,
306                 new Intent(Settings.ACTION_APPLICATION_SETTINGS));
307 
308         mDeviceAdminVisibleTest = new DialogTestListItem(this,
309                 R.string.provisioning_byod_admin_visible,
310                 "BYOD_DeviceAdminVisibleTest",
311                 R.string.provisioning_byod_admin_visible_instruction,
312                 new Intent(Settings.ACTION_SECURITY_SETTINGS));
313 
314         mCredSettingsVisibleTest = new DialogTestListItem(this,
315                 R.string.provisioning_byod_cred_settings,
316                 "BYOD_CredSettingsVisibleTest",
317                 R.string.provisioning_byod_cred_settings_instruction,
318                 new Intent(Settings.ACTION_SECURITY_SETTINGS));
319 
320         mLocationSettingsVisibleTest = new DialogTestListItem(this,
321                 R.string.provisioning_byod_location_settings,
322                 "BYOD_LocationSettingsVisibleTest",
323                 R.string.provisioning_byod_location_settings_instruction,
324                 new Intent(Settings.ACTION_LOCATION_SOURCE_SETTINGS));
325 
326         mCellularDataUsageSettingsVisibleTest = new DialogTestListItem(this,
327                 R.string.provisioning_byod_cellular_data_usage_settings,
328                 "BYOD_CellularDataUsageSettingsVisibleTest",
329                 R.string.provisioning_byod_cellular_data_usage_settings_instruction,
330                 new Intent(Settings.ACTION_SETTINGS));
331 
332         mPrintSettingsVisibleTest = new DialogTestListItem(this,
333                 R.string.provisioning_byod_print_settings,
334                 "BYOD_PrintSettingsVisibleTest",
335                 R.string.provisioning_byod_print_settings_instruction,
336                 new Intent(Settings.ACTION_PRINT_SETTINGS));
337 
338         Intent intent = new Intent(CrossProfileTestActivity.ACTION_CROSS_PROFILE_TO_WORK);
339         intent.putExtra(CrossProfileTestActivity.EXTRA_STARTED_FROM_WORK, false);
340         Intent chooser = Intent.createChooser(intent,
341                 getResources().getString(R.string.provisioning_cross_profile_chooser));
342         mCrossProfileIntentFiltersTestFromPersonal = new DialogTestListItem(this,
343                 R.string.provisioning_byod_cross_profile_from_personal,
344                 "BYOD_CrossProfileIntentFiltersTestFromPersonal",
345                 R.string.provisioning_byod_cross_profile_from_personal_instruction,
346                 chooser);
347 
348         mCrossProfileIntentFiltersTestFromWork = new DialogTestListItem(this,
349                 R.string.provisioning_byod_cross_profile_from_work,
350                 "BYOD_CrossProfileIntentFiltersTestFromWork",
351                 R.string.provisioning_byod_cross_profile_from_work_instruction,
352                 new Intent(ByodHelperActivity.ACTION_TEST_CROSS_PROFILE_INTENTS_DIALOG));
353 
354         /* Disable due to b/33571176
355         mAppLinkingTest = new DialogTestListItem(this,
356                 R.string.provisioning_app_linking,
357                 "BYOD_AppLinking",
358                 R.string.provisioning_byod_app_linking_instruction,
359                 new Intent(ByodHelperActivity.ACTION_TEST_APP_LINKING_DIALOG));
360         */
361 
362         mKeyguardDisabledFeaturesTest = TestListItem.newTest(this,
363                 R.string.provisioning_byod_keyguard_disabled_features,
364                 KeyguardDisabledFeaturesActivity.class.getName(),
365                 new Intent(this, KeyguardDisabledFeaturesActivity.class), null);
366 
367         mAuthenticationBoundKeyTest = TestListItem.newTest(this,
368                 R.string.provisioning_byod_auth_bound_key,
369                 AuthenticationBoundKeyTestActivity.class.getName(),
370                 new Intent(AuthenticationBoundKeyTestActivity.ACTION_AUTH_BOUND_KEY_TEST),
371                 null);
372 
373         mVpnTest = TestListItem.newTest(this,
374                 R.string.provisioning_byod_vpn,
375                 VpnTestActivity.class.getName(),
376                 new Intent(VpnTestActivity.ACTION_VPN),
377                 null);
378 
379         mAlwaysOnVpnSettingsTest = TestListItem.newTest(this,
380                 R.string.provisioning_byod_always_on_vpn,
381                 AlwaysOnVpnSettingsTestActivity.class.getName(),
382                 new Intent(AlwaysOnVpnSettingsTestActivity.ACTION_ALWAYS_ON_VPN_SETTINGS_TEST),
383                 null);
384 
385         mDisallowAppsControlTest = TestListItem.newTest(this,
386                 R.string.provisioning_byod_disallow_apps_control,
387                 DisallowAppsControlActivity.class.getName(),
388                 new Intent(this, DisallowAppsControlActivity.class), null);
389 
390         // Test for checking if the required intent filters are set during managed provisioning.
391         mIntentFiltersTest = new DialogTestListItem(this,
392                 R.string.provisioning_byod_cross_profile_intent_filters,
393                 "BYOD_IntentFiltersTest") {
394             @Override
395             public void performTest(DialogTestListActivity activity) {
396                 checkIntentFilters();
397             }
398         };
399 
400         mTurnOffWorkFeaturesTest = TestListItem.newTest(this,
401                 R.string.provisioning_byod_turn_off_work,
402                 TurnOffWorkActivity.class.getName(),
403                 new Intent(this, TurnOffWorkActivity.class), null);
404 
405         Intent permissionCheckIntent = new Intent(
406                 PermissionLockdownTestActivity.ACTION_MANAGED_PROFILE_CHECK_PERMISSION_LOCKDOWN);
407         mPermissionLockdownTest = new DialogTestListItem(this,
408                 R.string.device_profile_owner_permission_lockdown_test,
409                 "BYOD_PermissionLockdownTest",
410                 R.string.profile_owner_permission_lockdown_test_info,
411                 permissionCheckIntent);
412 
413         mSelectWorkChallenge = new DialogTestListItem(this,
414                 R.string.provisioning_byod_select_work_challenge,
415                 "BYOD_SelectWorkChallenge",
416                 R.string.provisioning_byod_select_work_challenge_description,
417                 new Intent(ByodHelperActivity.ACTION_TEST_SELECT_WORK_CHALLENGE));
418 
419         mRecentsTest = TestListItem.newTest(this,
420                 R.string.provisioning_byod_recents,
421                 RecentsRedactionActivity.class.getName(),
422                 new Intent(RecentsRedactionActivity.ACTION_RECENTS).setFlags(
423                         Intent.FLAG_ACTIVITY_NEW_TASK),
424                 null);
425 
426         mOrganizationInfoTest = TestListItem.newTest(this,
427                 R.string.provisioning_byod_organization_info,
428                 OrganizationInfoTestActivity.class.getName(),
429                 new Intent(this, OrganizationInfoTestActivity.class),
430                 null);
431 
432         mKeyChainTest = TestListItem.newTest(this,
433                 R.string.provisioning_byod_keychain,
434                 KeyChainTestActivity.class.getName(),
435                 new Intent(KeyChainTestActivity.ACTION_KEYCHAIN),
436                 null);
437 
438         mParentProfilePassword = new DialogTestListItem(this,
439                 R.string.provisioning_byod_parent_profile_password,
440                 "BYOD_ParentProfilePasswordTest",
441                 R.string.provisioning_byod_parent_profile_password_description,
442                 new Intent(ByodHelperActivity.ACTION_TEST_PARENT_PROFILE_PASSWORD));
443 
444         mPersonalRingtonesTest = new DialogTestListItem(this,
445                 R.string.provisioning_byod_personal_ringtones,
446                 "BYOD_PersonalRingtones",
447                 R.string.provisioning_byod_personal_ringtones_instruction,
448                 new Intent(Settings.ACTION_SOUND_SETTINGS));
449 
450         final Intent policyTransparencyTestIntent = new Intent(this,
451                 PolicyTransparencyTestListActivity.class);
452         policyTransparencyTestIntent.putExtra(
453                 PolicyTransparencyTestListActivity.EXTRA_MODE,
454                 PolicyTransparencyTestListActivity.MODE_MANAGED_PROFILE);
455         policyTransparencyTestIntent.putExtra(
456                 PolicyTransparencyTestActivity.EXTRA_TEST_ID, "BYOD_PolicyTransparency");
457         mPolicyTransparencyTest = TestListItem.newTest(this,
458                 R.string.device_profile_owner_policy_transparency_test,
459                 "BYOD_PolicyTransparency",
460                 policyTransparencyTestIntent, null);
461 
462         adapter.add(mProfileOwnerInstalled);
463         adapter.add(mDiskEncryptionTest);
464 
465         // Badge related tests
466         if (!getPackageManager().hasSystemFeature(PackageManager.FEATURE_AUTOMOTIVE)) {
467             adapter.add(mWorkAppVisibleTest);
468         }
469 
470         adapter.add(mWorkNotificationBadgedTest);
471         adapter.add(mWorkStatusBarIconTest);
472 
473         /* Disable due to b/111734436.
474         adapter.add(mWorkStatusBarToastTest);
475         */
476 
477         // Settings related tests.
478         adapter.add(mProfileAccountVisibleTest);
479         adapter.add(mDeviceAdminVisibleTest);
480         adapter.add(mCredSettingsVisibleTest);
481         adapter.add(mUserSettingsVisibleTest);
482         adapter.add(mAppSettingsVisibleTest);
483         adapter.add(mLocationSettingsVisibleTest);
484         adapter.add(mPrintSettingsVisibleTest);
485         adapter.add(mPersonalRingtonesTest);
486 
487         adapter.add(mCrossProfileIntentFiltersTestFromPersonal);
488         adapter.add(mCrossProfileIntentFiltersTestFromWork);
489         /* Disable due to b/33571176
490         adapter.add(mAppLinkingTest);
491         */
492         adapter.add(mIntentFiltersTest);
493         adapter.add(mNonMarketAppsTest);
494         adapter.add(mPermissionLockdownTest);
495         adapter.add(mKeyguardDisabledFeaturesTest);
496         adapter.add(mAuthenticationBoundKeyTest);
497         adapter.add(mVpnTest);
498         adapter.add(mAlwaysOnVpnSettingsTest);
499         adapter.add(mTurnOffWorkFeaturesTest);
500         adapter.add(mSelectWorkChallenge);
501         if (!getPackageManager().hasSystemFeature(PackageManager.FEATURE_AUTOMOTIVE)) {
502             adapter.add(mConfirmWorkCredentials);
503             adapter.add(mPatternWorkChallenge);
504         }
505         adapter.add(mRecentsTest);
506         adapter.add(mOrganizationInfoTest);
507         adapter.add(mParentProfilePassword);
508         adapter.add(mPolicyTransparencyTest);
509 
510         if (!getPackageManager().hasSystemFeature(PackageManager.FEATURE_AUTOMOTIVE)) {
511             if (getPackageManager().hasSystemFeature(PackageManager.FEATURE_WIFI)) {
512                 adapter.add(mWiFiDataUsageSettingsVisibleTest);
513             }
514         }
515 
516         mCm = (ConnectivityManager)getSystemService(Context.CONNECTIVITY_SERVICE);
517         if(mCm.getNetworkInfo(ConnectivityManager.TYPE_MOBILE) != null) {
518             adapter.add(mCellularDataUsageSettingsVisibleTest);
519         }
520 
521         if (canResolveIntent(new Intent(Settings.ACTION_APPLICATION_SETTINGS))) {
522             adapter.add(mDisallowAppsControlTest);
523         }
524 
525         /* If there is an application that handles ACTION_IMAGE_CAPTURE, test that it handles it
526          * well.
527          */
528         if (canResolveIntent(ByodHelperActivity.getCaptureImageIntent())) {
529             // Capture image intent can be resolved in primary profile, so test.
530             mCrossProfileImageCaptureSupportTest = new DialogTestListItem(this,
531                     R.string.provisioning_byod_capture_image_support,
532                     "BYOD_CrossProfileImageCaptureSupportTest",
533                     R.string.provisioning_byod_capture_image_support_info,
534                     new Intent(ByodHelperActivity.ACTION_CAPTURE_AND_CHECK_IMAGE));
535             adapter.add(mCrossProfileImageCaptureSupportTest);
536         } else {
537             // Capture image intent cannot be resolved in primary profile, so skip test.
538             Toast.makeText(ByodFlowTestActivity.this,
539                     R.string.provisioning_byod_no_image_capture_resolver, Toast.LENGTH_SHORT)
540                     .show();
541         }
542 
543         /* If there is an application that handles ACTION_VIDEO_CAPTURE, test that it handles it
544          * well.
545          */
546         if (canResolveIntent(ByodHelperActivity.getCaptureVideoIntent())) {
547             // Capture video intent can be resolved in primary profile, so test.
548             mCrossProfileVideoCaptureWithExtraOutputSupportTest = new DialogTestListItem(this,
549                     R.string.provisioning_byod_capture_video_support_with_extra_output,
550                     "BYOD_CrossProfileVideoCaptureWithExtraOutputSupportTest",
551                     R.string.provisioning_byod_capture_video_support_info,
552                     new Intent(ByodHelperActivity.ACTION_CAPTURE_AND_CHECK_VIDEO_WITH_EXTRA_OUTPUT));
553             adapter.add(mCrossProfileVideoCaptureWithExtraOutputSupportTest);
554             mCrossProfileVideoCaptureWithoutExtraOutputSupportTest = new DialogTestListItem(this,
555                     R.string.provisioning_byod_capture_video_support_without_extra_output,
556                     "BYOD_CrossProfileVideoCaptureWithoutExtraOutputSupportTest",
557                     R.string.provisioning_byod_capture_video_support_info,
558                     new Intent(ByodHelperActivity.ACTION_CAPTURE_AND_CHECK_VIDEO_WITHOUT_EXTRA_OUTPUT));
559             adapter.add(mCrossProfileVideoCaptureWithoutExtraOutputSupportTest);
560         } else {
561             // Capture video intent cannot be resolved in primary profile, so skip test.
562             Toast.makeText(ByodFlowTestActivity.this,
563                     R.string.provisioning_byod_no_video_capture_resolver, Toast.LENGTH_SHORT)
564                     .show();
565         }
566 
567         if (getPackageManager().hasSystemFeature(PackageManager.FEATURE_NFC)
568                 && getPackageManager().hasSystemFeature(PackageManager.FEATURE_NFC_BEAM)) {
569             mDisableNfcBeamTest = new DialogTestListItem(this, R.string.provisioning_byod_nfc_beam,
570                     "BYOD_DisableNfcBeamTest",
571                     R.string.provisioning_byod_nfc_beam_allowed_instruction,
572                     new Intent(ByodHelperActivity.ACTION_TEST_NFC_BEAM)) {
573                 @Override
574                 public void performTest(final DialogTestListActivity activity) {
575                     activity.showManualTestDialog(mDisableNfcBeamTest,
576                             new DefaultTestCallback(mDisableNfcBeamTest) {
577                         @Override
578                         public void onPass() {
579                             // Start a second test with beam disallowed by policy.
580                             Intent testNfcBeamIntent = new Intent(
581                                     ByodHelperActivity.ACTION_TEST_NFC_BEAM);
582                             testNfcBeamIntent.putExtra(NfcTestActivity.EXTRA_DISALLOW_BY_POLICY,
583                                     true);
584                             DialogTestListItem disableNfcBeamTest2 =
585                                     new DialogTestListItem(activity,
586                                     R.string.provisioning_byod_nfc_beam,
587                                     "BYOD_DisableNfcBeamTest",
588                                     R.string.provisioning_byod_nfc_beam_disallowed_instruction,
589                                     testNfcBeamIntent);
590                             // The result should be reflected on the original test.
591                             activity.showManualTestDialog(disableNfcBeamTest2,
592                                     new DefaultTestCallback(mDisableNfcBeamTest));
593                         }
594                     });
595                 }
596             };
597             adapter.add(mDisableNfcBeamTest);
598         }
599 
600         adapter.add(mKeyChainTest);
601 
602         /* If there is an application that handles RECORD_SOUND_ACTION, test that it handles it
603          * well.
604          */
605         if (canResolveIntent(ByodHelperActivity.getCaptureAudioIntent())) {
606             // Capture audio intent can be resolved in primary profile, so test.
607             mCrossProfileAudioCaptureSupportTest = new DialogTestListItem(this,
608                     R.string.provisioning_byod_capture_audio_support,
609                     "BYOD_CrossProfileAudioCaptureSupportTest",
610                     R.string.provisioning_byod_capture_audio_support_info,
611                     new Intent(ByodHelperActivity.ACTION_CAPTURE_AND_CHECK_AUDIO));
612             adapter.add(mCrossProfileAudioCaptureSupportTest);
613         } else {
614             // Capture audio intent cannot be resolved in primary profile, so skip test.
615             Toast.makeText(ByodFlowTestActivity.this,
616                     R.string.provisioning_byod_no_audio_capture_resolver, Toast.LENGTH_SHORT)
617                     .show();
618         }
619 
620         if (getPackageManager().hasSystemFeature(PackageManager.FEATURE_LOCATION_GPS)) {
621             mEnableLocationModeTest = new DialogTestListItem(this,
622                     R.string.provisioning_byod_location_mode_enable,
623                     "BYOD_LocationModeEnableTest",
624                     R.string.provisioning_byod_location_mode_enable_instruction,
625                     new Intent(ByodHelperActivity.ACTION_BYOD_SET_LOCATION_AND_CHECK_UPDATES));
626             mDisableLocationModeThroughMainSwitchTest = new DialogTestListItem(this,
627                     R.string.provisioning_byod_location_mode_disable,
628                     "BYOD_LocationModeDisableMainTest",
629                     R.string.provisioning_byod_location_mode_disable_instruction,
630                     new Intent(ByodHelperActivity.ACTION_BYOD_SET_LOCATION_AND_CHECK_UPDATES));
631             mDisableLocationModeThroughWorkSwitchTest = new DialogTestListItem(this,
632                     R.string.provisioning_byod_work_location_mode_disable,
633                     "BYOD_LocationModeDisableWorkTest",
634                     R.string.provisioning_byod_work_location_mode_disable_instruction,
635                     new Intent(ByodHelperActivity.ACTION_BYOD_SET_LOCATION_AND_CHECK_UPDATES));
636             mPrimaryLocationWhenWorkDisabledTest = new DialogTestListItem(this,
637                     R.string.provisioning_byod_primary_location_when_work_disabled,
638                     "BYOD_PrimaryLocationWhenWorkDisabled",
639                     R.string.provisioning_byod_primary_location_when_work_disabled_instruction,
640                     new Intent(LocationListenerActivity.ACTION_SET_LOCATION_AND_CHECK_UPDATES));
641             adapter.add(mEnableLocationModeTest);
642             adapter.add(mDisableLocationModeThroughMainSwitchTest);
643             adapter.add(mDisableLocationModeThroughWorkSwitchTest);
644             adapter.add(mPrimaryLocationWhenWorkDisabledTest);
645         } else {
646             // The system does not support GPS feature, so skip test.
647             Toast.makeText(ByodFlowTestActivity.this,
648                     R.string.provisioning_byod_no_gps_location_feature, Toast.LENGTH_SHORT)
649                     .show();
650         }
651 
652         if (getPackageManager().hasSystemFeature(PackageManager.FEATURE_APP_WIDGETS)) {
653             mWidgetTest = TestListItem.newTest(this,
654                     R.string.provisioning_byod_work_profile_widget,
655                     WorkProfileWidgetActivity.class.getName(),
656                     new Intent(WorkProfileWidgetActivity.ACTION_TEST_WORK_PROFILE_WIDGET),
657                     new String[]{PackageManager.FEATURE_APP_WIDGETS});
658             adapter.add(mWidgetTest);
659         }
660 
661         adapter.add(new DialogTestListItem(this,
662                 R.string.provisioning_byod_uninstall_work_app,
663                 "BYOD_UninstallWorkApp",
664                 R.string.provisioning_byod_uninstall_work_app_instruction,
665                 createInstallWorkProfileAppIntent()));
666     }
667 
createInstallWorkProfileAppIntent()668     private Intent createInstallWorkProfileAppIntent() {
669         // We place the APK file in /data/local/tmp to make it visible from the work profile.
670         return new Intent(ByodHelperActivity.ACTION_INSTALL_APK)
671                 .putExtra(ByodHelperActivity.EXTRA_ALLOW_NON_MARKET_APPS, true)
672                 .putExtra(ByodHelperActivity.EXTRA_PARAMETER_1, HELPER_APP_PATH);
673     }
674 
675     // Return whether the intent can be resolved in the current profile
canResolveIntent(Intent intent)676     private boolean canResolveIntent(Intent intent) {
677         return intent.resolveActivity(getPackageManager()) != null;
678     }
679 
680     @Override
clearRemainingState(final DialogTestListItem test)681     protected void clearRemainingState(final DialogTestListItem test) {
682         super.clearRemainingState(test);
683         if (ByodHelperActivity.ACTION_NOTIFICATION.equals(
684                 test.getManualTestIntent().getAction())) {
685             try {
686                 startActivity(new Intent(
687                         ByodHelperActivity.ACTION_CLEAR_NOTIFICATION));
688             } catch (ActivityNotFoundException e) {
689                 // User shouldn't run this test before work profile is set up.
690             }
691         }
692     }
693 
queryProfileOwner(boolean showToast)694     private void queryProfileOwner(boolean showToast) {
695         try {
696             Intent intent = new Intent(ByodHelperActivity.ACTION_QUERY_PROFILE_OWNER);
697             startActivityForResult(intent, REQUEST_PROFILE_OWNER_STATUS);
698         }
699         catch (ActivityNotFoundException e) {
700             Log.d(TAG, "queryProfileOwner: ActivityNotFoundException", e);
701             setTestResult(mProfileOwnerInstalled, TestResult.TEST_RESULT_FAILED);
702             if (showToast) {
703                 Utils.showToast(this, R.string.provisioning_byod_no_activity);
704             }
705         }
706     }
707 
checkDiskEncryption()708     private void checkDiskEncryption() {
709         try {
710             Intent intent = new Intent(ByodHelperActivity.ACTION_CHECK_DISK_ENCRYPTION);
711             startActivityForResult(intent, REQUEST_CHECK_DISK_ENCRYPTION);
712         } catch (ActivityNotFoundException e) {
713             Log.d(TAG, "checkDiskEncryption: ActivityNotFoundException", e);
714             setTestResult(mDiskEncryptionTest, TestResult.TEST_RESULT_FAILED);
715             Utils.showToast(this, R.string.provisioning_byod_no_activity);
716         }
717     }
718 
handleDiskEncryptionStatus(int resultCode, Intent data)719     private void handleDiskEncryptionStatus(int resultCode, Intent data) {
720         if (resultCode != RESULT_OK || data == null) {
721             Log.e(TAG, "Failed to get result for disk encryption, result code: " + resultCode);
722             setTestResult(mDiskEncryptionTest, TestResult.TEST_RESULT_FAILED);
723             return;
724         }
725 
726         final int status = data.getIntExtra(ByodHelperActivity.EXTRA_ENCRYPTION_STATUS,
727                 DevicePolicyManager.ENCRYPTION_STATUS_UNSUPPORTED);
728         switch (status) {
729             case DevicePolicyManager.ENCRYPTION_STATUS_ACTIVE:
730             case DevicePolicyManager.ENCRYPTION_STATUS_ACTIVE_PER_USER:
731                 setTestResult(mDiskEncryptionTest, TestResult.TEST_RESULT_PASSED);
732                 break;
733             case DevicePolicyManager.ENCRYPTION_STATUS_ACTIVE_DEFAULT_KEY:
734                 if (!mKeyguardManager.isDeviceSecure()) {
735                     Utils.setScreenLock(this, REQUEST_SET_LOCK_FOR_ENCRYPTION);
736                     return;
737                 }
738                 Log.e(TAG, "Disk encryption key is not entangled with lock screen credentials");
739                 Toast.makeText(this, R.string.provisioning_byod_disk_encryption_default_key_toast,
740                         Toast.LENGTH_LONG).show();
741                 // fall through
742             default:
743                 setTestResult(mDiskEncryptionTest, TestResult.TEST_RESULT_FAILED);
744         }
745 
746         if (mKeyguardManager.isDeviceSecure()) {
747             Utils.removeScreenLock(this);
748         }
749     }
750 
handleSetLockForEncryption()751     private void handleSetLockForEncryption() {
752         if (mKeyguardManager.isDeviceSecure()) {
753             checkDiskEncryption();
754         } else {
755             setTestResult(mDiskEncryptionTest, TestResult.TEST_RESULT_FAILED);
756             Toast.makeText(this, R.string.provisioning_byod_disk_encryption_no_pin_toast,
757                     Toast.LENGTH_LONG).show();
758         }
759     }
760 
checkIntentFilters()761     private void checkIntentFilters() {
762         try {
763             // Enable component HandleIntentActivity before intent filters are checked.
764             setHandleIntentActivityEnabledSetting(PackageManager.COMPONENT_ENABLED_STATE_ENABLED);
765             // We disable the ByodHelperActivity in the primary profile. So, this intent
766             // will be handled by the ByodHelperActivity in the managed profile.
767             Intent intent = new Intent(ByodHelperActivity.ACTION_CHECK_INTENT_FILTERS);
768             startActivityForResult(intent, REQUEST_INTENT_FILTERS_STATUS);
769         } catch (ActivityNotFoundException e) {
770             // Disable component HandleIntentActivity if intent filters check fails.
771             setHandleIntentActivityEnabledSetting(PackageManager.COMPONENT_ENABLED_STATE_DISABLED);
772             Log.d(TAG, "checkIntentFilters: ActivityNotFoundException", e);
773             setTestResult(mIntentFiltersTest, TestResult.TEST_RESULT_FAILED);
774             Utils.showToast(this, R.string.provisioning_byod_no_activity);
775         }
776     }
777 
handleIntentFiltersStatus(int resultCode)778     private void handleIntentFiltersStatus(int resultCode) {
779         // Disable component HandleIntentActivity after intent filters are checked.
780         setHandleIntentActivityEnabledSetting(PackageManager.COMPONENT_ENABLED_STATE_DISABLED);
781         // we use the resultCode from ByodHelperActivity in the managed profile to know if certain
782         // intents fired from the managed profile are forwarded.
783         final boolean intentFiltersSetForManagedIntents = (resultCode == RESULT_OK);
784         // Since the ByodFlowTestActivity is running in the primary profile, we directly use
785         // the IntentFiltersTestHelper to know if certain intents fired from the primary profile
786         // are forwarded.
787         final boolean intentFiltersSetForPrimaryIntents =
788                 new IntentFiltersTestHelper(this).checkCrossProfileIntentFilters(
789                         IntentFiltersTestHelper.FLAG_INTENTS_FROM_PRIMARY);
790         final boolean intentFiltersSet =
791                 intentFiltersSetForPrimaryIntents & intentFiltersSetForManagedIntents;
792         setTestResult(mIntentFiltersTest,
793                 intentFiltersSet ? TestResult.TEST_RESULT_PASSED : TestResult.TEST_RESULT_FAILED);
794     }
795 
setHandleIntentActivityEnabledSetting(final int enableState)796     private void setHandleIntentActivityEnabledSetting(final int enableState) {
797         getPackageManager().setComponentEnabledSetting(
798             new ComponentName(ByodFlowTestActivity.this, HandleIntentActivity.class.getName()),
799             enableState, PackageManager.DONT_KILL_APP);
800     }
801 }
802