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 static android.os.UserManager.DISALLOW_INSTALL_UNKNOWN_SOURCES; 20 21 import android.app.NotificationChannel; 22 import android.app.admin.DevicePolicyManager; 23 import android.app.KeyguardManager; 24 import android.app.Notification; 25 import android.app.NotificationManager; 26 import android.content.ComponentName; 27 import android.content.Context; 28 import android.content.Intent; 29 import android.content.pm.PackageManager; 30 import android.graphics.Color; 31 import android.net.Uri; 32 import android.os.Bundle; 33 import android.os.UserManager; 34 import android.provider.MediaStore; 35 import android.support.v4.content.FileProvider; 36 import android.support.v4.util.Pair; 37 import android.util.Log; 38 39 import java.io.File; 40 import java.util.ArrayList; 41 42 import com.android.cts.verifier.location.LocationListenerActivity; 43 import com.android.cts.verifier.R; 44 import com.android.cts.verifier.managedprovisioning.ByodPresentMediaDialog.DialogCallback; 45 46 /** 47 * A helper activity from the managed profile side that responds to requests from CTS verifier in 48 * primary user. Profile owner APIs are accessible inside this activity (given this activity is 49 * started within the work profile). Its current functionalities include making sure the profile 50 * owner is setup correctly, removing the work profile upon request, and verifying the image and 51 * video capture functionality. 52 * 53 * Note: We have to use a dummy activity because cross-profile intents only work for activities. 54 */ 55 public class ByodHelperActivity extends LocationListenerActivity 56 implements DialogCallback { 57 static final String TAG = "ByodHelperActivity"; 58 59 // Primary -> managed intent: query if the profile owner has been set up. 60 public static final String ACTION_QUERY_PROFILE_OWNER = "com.android.cts.verifier.managedprovisioning.BYOD_QUERY"; 61 // Managed -> primary intent: update profile owner test status in primary's CtsVerifer 62 public static final String ACTION_PROFILE_OWNER_STATUS = "com.android.cts.verifier.managedprovisioning.BYOD_STATUS"; 63 // Primary -> managed intent: request to delete the current profile 64 public static final String ACTION_REMOVE_MANAGED_PROFILE = "com.android.cts.verifier.managedprovisioning.BYOD_REMOVE"; 65 // Managed -> managed intent: provisioning completed successfully 66 public static final String ACTION_PROFILE_PROVISIONED = "com.android.cts.verifier.managedprovisioning.BYOD_PROVISIONED"; 67 // Primary -> managed intent: request to capture and check an image 68 public static final String ACTION_CAPTURE_AND_CHECK_IMAGE = "com.android.cts.verifier.managedprovisioning.BYOD_CAPTURE_AND_CHECK_IMAGE"; 69 // Primary -> managed intent: request to capture and check a video with custom output path 70 public static final String ACTION_CAPTURE_AND_CHECK_VIDEO_WITH_EXTRA_OUTPUT = "com.android.cts.verifier.managedprovisioning.BYOD_CAPTURE_AND_CHECK_VIDEO_WITH_EXTRA_OUTPUT"; 71 // Primary -> managed intent: request to capture and check a video without custom output path 72 public static final String ACTION_CAPTURE_AND_CHECK_VIDEO_WITHOUT_EXTRA_OUTPUT = "com.android.cts.verifier.managedprovisioning.BYOD_CAPTURE_AND_CHECK_VIDEO_WITHOUT_EXTRA_OUTPUT"; 73 // Primary -> managed intent: request to capture and check an audio recording 74 public static final String ACTION_CAPTURE_AND_CHECK_AUDIO = "com.android.cts.verifier.managedprovisioning.BYOD_CAPTURE_AND_CHECK_AUDIO"; 75 public static final String ACTION_KEYGUARD_DISABLED_FEATURES = 76 "com.android.cts.verifier.managedprovisioning.BYOD_KEYGUARD_DISABLED_FEATURES"; 77 public static final String ACTION_LOCKNOW = 78 "com.android.cts.verifier.managedprovisioning.BYOD_LOCKNOW"; 79 public static final String ACTION_TEST_NFC_BEAM = "com.android.cts.verifier.managedprovisioning.TEST_NFC_BEAM"; 80 81 public static final String EXTRA_PROVISIONED = "extra_provisioned"; 82 public static final String EXTRA_PARAMETER_1 = "extra_parameter_1"; 83 84 // Primary -> managed intent: check if the disk of the device is encrypted 85 public static final String ACTION_CHECK_DISK_ENCRYPTION = 86 "com.android.cts.verifier.managedprovisioning.action.BYOD_CHECK_DISK_ENCRYPTION"; 87 // Managed -> primary intent: update disk encryption status in primary's CtsVerifier 88 public static final String ACTION_DISK_ENCRYPTION_STATUS = 89 "com.android.cts.verifier.managedprovisioning.action.BYOD_DISK_ENCRYPTION_STATUS"; 90 // Int extra field indicating the encryption status of the device storage 91 public static final String EXTRA_ENCRYPTION_STATUS = "extra_encryption_status"; 92 93 // Primary -> managed intent: set unknown sources restriction and install package 94 public static final String ACTION_INSTALL_APK = "com.android.cts.verifier.managedprovisioning.BYOD_INSTALL_APK"; 95 public static final String EXTRA_ALLOW_NON_MARKET_APPS = "allow_non_market_apps"; 96 97 // Primary -> managed intent: check if the required cross profile intent filters are set. 98 public static final String ACTION_CHECK_INTENT_FILTERS = 99 "com.android.cts.verifier.managedprovisioning.action.CHECK_INTENT_FILTERS"; 100 101 // Primary -> managed intent: will send a cross profile intent and check if the user sees an 102 // intent picker dialog and can open the apps. 103 public static final String ACTION_TEST_CROSS_PROFILE_INTENTS_DIALOG = 104 "com.android.cts.verifier.managedprovisioning.action.TEST_CROSS_PROFILE_INTENTS_DIALOG"; 105 106 // Primary -> managed intent: will send an app link intent and check if the user sees a 107 // dialog and can open the apps. This test is extremely similar to 108 // ACTION_TEST_CROSS_PROFILE_INTENTS_DIALOG, but the intent used is a web intent, and there is 109 // some behavior which is specific to web intents. 110 public static final String ACTION_TEST_APP_LINKING_DIALOG = 111 "com.android.cts.verifier.managedprovisioning.action.TEST_APP_LINKING_DIALOG"; 112 113 // Primary -> managed intent: request to goto the location settings page and listen to updates. 114 public static final String ACTION_BYOD_SET_LOCATION_AND_CHECK_UPDATES = 115 "com.android.cts.verifier.managedprovisioning.BYOD_SET_LOCATION_AND_CHECK"; 116 public static final String ACTION_NOTIFICATION = 117 "com.android.cts.verifier.managedprovisioning.NOTIFICATION"; 118 public static final String ACTION_NOTIFICATION_ON_LOCKSCREEN = 119 "com.android.cts.verifier.managedprovisioning.LOCKSCREEN_NOTIFICATION"; 120 public static final String ACTION_CLEAR_NOTIFICATION = 121 "com.android.cts.verifier.managedprovisioning.CLEAR_NOTIFICATION"; 122 123 // Primary -> managed intent: set a user restriction 124 public static final String ACTION_SET_USER_RESTRICTION = 125 "com.android.cts.verifier.managedprovisioning.BYOD_SET_USER_RESTRICTION"; 126 127 // Primary -> managed intent: reset a user restriction 128 public static final String ACTION_CLEAR_USER_RESTRICTION = 129 "com.android.cts.verifier.managedprovisioning.BYOD_CLEAR_USER_RESTRICTION"; 130 131 // Primary -> managed intent: Start the selection of a work challenge 132 public static final String ACTION_TEST_SELECT_WORK_CHALLENGE = 133 "com.android.cts.verifier.managedprovisioning.TEST_SELECT_WORK_CHALLENGE"; 134 135 // Primary -> managed intent: Start the selection of a parent profile password. 136 public static final String ACTION_TEST_PARENT_PROFILE_PASSWORD = 137 "com.android.cts.verifier.managedprovisioning.TEST_PARENT_PROFILE_PASSWORD"; 138 139 // Primary -> managed intent: Start the confirm credentials screen for the managed profile 140 public static final String ACTION_LAUNCH_CONFIRM_WORK_CREDENTIALS = 141 "com.android.cts.verifier.managedprovisioning.LAUNCH_CONFIRM_WORK_CREDENTIALS"; 142 143 public static final String ACTION_SET_ORGANIZATION_INFO = 144 "com.android.cts.verifier.managedprovisioning.TEST_ORGANIZATION_INFO"; 145 146 public static final int RESULT_FAILED = RESULT_FIRST_USER; 147 148 private static final int REQUEST_INSTALL_PACKAGE = 2; 149 private static final int REQUEST_IMAGE_CAPTURE = 3; 150 private static final int REQUEST_VIDEO_CAPTURE_WITH_EXTRA_OUTPUT = 4; 151 private static final int REQUEST_VIDEO_CAPTURE_WITHOUT_EXTRA_OUTPUT = 5; 152 private static final int REQUEST_AUDIO_CAPTURE = 6; 153 private static final int REQUEST_LOCATION_UPDATE = 7; 154 155 private static final String ORIGINAL_RESTRICTIONS_NAME = "original restrictions"; 156 157 private static final int NOTIFICATION_ID = 7; 158 private static final String NOTIFICATION_CHANNEL_ID = TAG; 159 160 private NotificationManager mNotificationManager; 161 private Bundle mOriginalRestrictions; 162 163 private ComponentName mAdminReceiverComponent; 164 private DevicePolicyManager mDevicePolicyManager; 165 166 private Uri mImageUri; 167 private Uri mVideoUri; 168 private File mImageFile; 169 170 private ArrayList<File> mTempFiles = new ArrayList<File>(); 171 showNotification(int visibility)172 private void showNotification(int visibility) { 173 final Notification notification = new Notification.Builder(this, NOTIFICATION_CHANNEL_ID) 174 .setSmallIcon(R.drawable.icon) 175 .setContentTitle(getString(R.string.provisioning_byod_notification_title)) 176 .setContentText(getString(R.string.provisioning_byod_notification_title)) 177 .setVisibility(visibility) 178 .setAutoCancel(true) 179 .build(); 180 mNotificationManager.notify(NOTIFICATION_ID, notification); 181 } 182 183 184 @Override onCreate(Bundle savedInstanceState)185 protected void onCreate(Bundle savedInstanceState) { 186 super.onCreate(savedInstanceState); 187 if (savedInstanceState != null) { 188 Log.w(TAG, "Restored state"); 189 mOriginalRestrictions = savedInstanceState.getBundle(ORIGINAL_RESTRICTIONS_NAME); 190 } else { 191 mOriginalRestrictions = new Bundle(); 192 } 193 194 mAdminReceiverComponent = new ComponentName(this, DeviceAdminTestReceiver.class.getName()); 195 mDevicePolicyManager = (DevicePolicyManager) getSystemService( 196 Context.DEVICE_POLICY_SERVICE); 197 mNotificationManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE); 198 Intent intent = getIntent(); 199 String action = intent.getAction(); 200 Log.d(TAG, "ByodHelperActivity.onCreate: " + action); 201 mNotificationManager.createNotificationChannel(new NotificationChannel( 202 NOTIFICATION_CHANNEL_ID, NOTIFICATION_CHANNEL_ID, 203 NotificationManager.IMPORTANCE_DEFAULT)); 204 205 // we are explicitly started by {@link DeviceAdminTestReceiver} after a successful provisioning. 206 if (action.equals(ACTION_PROFILE_PROVISIONED)) { 207 // Jump back to CTS verifier with result. 208 Intent response = new Intent(ACTION_PROFILE_OWNER_STATUS); 209 response.putExtra(EXTRA_PROVISIONED, isProfileOwner()); 210 startActivityInPrimary(response); 211 // Queried by CtsVerifier in the primary side using startActivityForResult. 212 } else if (action.equals(ACTION_QUERY_PROFILE_OWNER)) { 213 Intent response = new Intent(); 214 response.putExtra(EXTRA_PROVISIONED, isProfileOwner()); 215 setResult(RESULT_OK, response); 216 // Request to delete work profile. 217 } else if (action.equals(ACTION_REMOVE_MANAGED_PROFILE)) { 218 if (isProfileOwner()) { 219 Log.d(TAG, "Clearing cross profile intents"); 220 mDevicePolicyManager.clearCrossProfileIntentFilters(mAdminReceiverComponent); 221 mDevicePolicyManager.wipeData(0); 222 showToast(R.string.provisioning_byod_profile_deleted); 223 } 224 } else if (action.equals(ACTION_CHECK_DISK_ENCRYPTION)) { 225 final int status = mDevicePolicyManager.getStorageEncryptionStatus(); 226 final Intent response = new Intent(ACTION_DISK_ENCRYPTION_STATUS) 227 .putExtra(EXTRA_ENCRYPTION_STATUS, status); 228 setResult(RESULT_OK, response); 229 } else if (action.equals(ACTION_INSTALL_APK)) { 230 boolean allowNonMarket = intent.getBooleanExtra(EXTRA_ALLOW_NON_MARKET_APPS, false); 231 boolean wasAllowed = !isUnknownSourcesRestrictionSet(); 232 233 if (wasAllowed != allowNonMarket) { 234 setUnknownSourcesRestriction(!allowNonMarket); 235 mOriginalRestrictions.putBoolean(DISALLOW_INSTALL_UNKNOWN_SOURCES, !wasAllowed); 236 } 237 238 // Request to install a non-market application- easiest way is to reinstall ourself 239 final Intent installIntent = new Intent(Intent.ACTION_INSTALL_PACKAGE) 240 .setData(Uri.parse("package:" + getPackageName())) 241 .putExtra(Intent.EXTRA_NOT_UNKNOWN_SOURCE, true) 242 .putExtra(Intent.EXTRA_RETURN_RESULT, true); 243 startActivityForResult(installIntent, REQUEST_INSTALL_PACKAGE); 244 245 // Not yet ready to finish- wait until the result comes back 246 return; 247 // Queried by CtsVerifier in the primary side using startActivityForResult. 248 } else if (action.equals(ACTION_CHECK_INTENT_FILTERS)) { 249 final boolean intentFiltersSetForManagedIntents = 250 new IntentFiltersTestHelper(this).checkCrossProfileIntentFilters( 251 IntentFiltersTestHelper.FLAG_INTENTS_FROM_MANAGED); 252 setResult(intentFiltersSetForManagedIntents? RESULT_OK : RESULT_FAILED, null); 253 } else if (action.equals(ACTION_CAPTURE_AND_CHECK_IMAGE)) { 254 // We need the camera permission to send the image capture intent. 255 grantCameraPermissionToSelf(); 256 Intent captureImageIntent = getCaptureImageIntent(); 257 Pair<File, Uri> pair = getTempUri("image.jpg"); 258 mImageFile = pair.first; 259 mImageUri = pair.second; 260 captureImageIntent.putExtra(MediaStore.EXTRA_OUTPUT, mImageUri); 261 if (captureImageIntent.resolveActivity(getPackageManager()) != null) { 262 startActivityForResult(captureImageIntent, REQUEST_IMAGE_CAPTURE); 263 } else { 264 Log.e(TAG, "Capture image intent could not be resolved in managed profile."); 265 showToast(R.string.provisioning_byod_capture_media_error); 266 finish(); 267 } 268 return; 269 } else if (action.equals(ACTION_CAPTURE_AND_CHECK_VIDEO_WITH_EXTRA_OUTPUT) || 270 action.equals(ACTION_CAPTURE_AND_CHECK_VIDEO_WITHOUT_EXTRA_OUTPUT)) { 271 // We need the camera permission to send the video capture intent. 272 grantCameraPermissionToSelf(); 273 Intent captureVideoIntent = getCaptureVideoIntent(); 274 int videoCaptureRequestId; 275 if (action.equals(ACTION_CAPTURE_AND_CHECK_VIDEO_WITH_EXTRA_OUTPUT)) { 276 mVideoUri = getTempUri("video.mp4").second; 277 captureVideoIntent.putExtra(MediaStore.EXTRA_OUTPUT, mVideoUri); 278 videoCaptureRequestId = REQUEST_VIDEO_CAPTURE_WITH_EXTRA_OUTPUT; 279 } else { 280 videoCaptureRequestId = REQUEST_VIDEO_CAPTURE_WITHOUT_EXTRA_OUTPUT; 281 } 282 if (captureVideoIntent.resolveActivity(getPackageManager()) != null) { 283 startActivityForResult(captureVideoIntent, videoCaptureRequestId); 284 } else { 285 Log.e(TAG, "Capture video intent could not be resolved in managed profile."); 286 showToast(R.string.provisioning_byod_capture_media_error); 287 finish(); 288 } 289 return; 290 } else if (action.equals(ACTION_CAPTURE_AND_CHECK_AUDIO)) { 291 Intent captureAudioIntent = getCaptureAudioIntent(); 292 if (captureAudioIntent.resolveActivity(getPackageManager()) != null) { 293 startActivityForResult(captureAudioIntent, REQUEST_AUDIO_CAPTURE); 294 } else { 295 Log.e(TAG, "Capture audio intent could not be resolved in managed profile."); 296 showToast(R.string.provisioning_byod_capture_media_error); 297 finish(); 298 } 299 return; 300 } else if (ACTION_KEYGUARD_DISABLED_FEATURES.equals(action)) { 301 final int value = intent.getIntExtra(EXTRA_PARAMETER_1, 302 DevicePolicyManager.KEYGUARD_DISABLE_FEATURES_NONE); 303 mDevicePolicyManager.setKeyguardDisabledFeatures(mAdminReceiverComponent, value); 304 } else if (ACTION_LOCKNOW.equals(action)) { 305 mDevicePolicyManager.lockNow(); 306 setResult(RESULT_OK); 307 } else if (action.equals(ACTION_TEST_NFC_BEAM)) { 308 Intent testNfcBeamIntent = new Intent(this, NfcTestActivity.class); 309 testNfcBeamIntent.putExtras(intent); 310 startActivity(testNfcBeamIntent); 311 finish(); 312 return; 313 } else if (action.equals(ACTION_TEST_CROSS_PROFILE_INTENTS_DIALOG)) { 314 sendIntentInsideChooser(new Intent( 315 CrossProfileTestActivity.ACTION_CROSS_PROFILE_TO_PERSONAL)); 316 } else if (action.equals(ACTION_TEST_APP_LINKING_DIALOG)) { 317 mDevicePolicyManager.addUserRestriction( 318 DeviceAdminTestReceiver.getReceiverComponentName(), 319 UserManager.ALLOW_PARENT_PROFILE_APP_LINKING); 320 Intent toSend = new Intent(Intent.ACTION_VIEW); 321 toSend.setData(Uri.parse("http://com.android.cts.verifier")); 322 sendIntentInsideChooser(toSend); 323 } else if (action.equals(ACTION_SET_USER_RESTRICTION)) { 324 final String restriction = intent.getStringExtra(EXTRA_PARAMETER_1); 325 if (restriction != null) { 326 mDevicePolicyManager.addUserRestriction( 327 DeviceAdminTestReceiver.getReceiverComponentName(), restriction); 328 } 329 } else if (action.equals(ACTION_CLEAR_USER_RESTRICTION)) { 330 final String restriction = intent.getStringExtra(EXTRA_PARAMETER_1); 331 if (restriction != null) { 332 mDevicePolicyManager.clearUserRestriction( 333 DeviceAdminTestReceiver.getReceiverComponentName(), restriction); 334 } 335 } else if (action.equals(ACTION_BYOD_SET_LOCATION_AND_CHECK_UPDATES)) { 336 handleLocationAction(); 337 return; 338 } else if (action.equals(ACTION_NOTIFICATION)) { 339 showNotification(Notification.VISIBILITY_PUBLIC); 340 } else if (ACTION_NOTIFICATION_ON_LOCKSCREEN.equals(action)) { 341 mDevicePolicyManager.lockNow(); 342 showNotification(Notification.VISIBILITY_PRIVATE); 343 } else if (ACTION_CLEAR_NOTIFICATION.equals(action)) { 344 mNotificationManager.cancel(NOTIFICATION_ID); 345 } else if (ACTION_TEST_SELECT_WORK_CHALLENGE.equals(action)) { 346 mDevicePolicyManager.setOrganizationColor(mAdminReceiverComponent, Color.BLUE); 347 mDevicePolicyManager.setOrganizationName(mAdminReceiverComponent, getResources() 348 .getString(R.string.provisioning_byod_confirm_work_credentials_header)); 349 startActivity(new Intent(DevicePolicyManager.ACTION_SET_NEW_PASSWORD)); 350 } else if (ACTION_LAUNCH_CONFIRM_WORK_CREDENTIALS.equals(action)) { 351 KeyguardManager keyguardManager = 352 (KeyguardManager) getSystemService(Context.KEYGUARD_SERVICE); 353 Intent launchIntent = keyguardManager.createConfirmDeviceCredentialIntent(null, null); 354 startActivity(launchIntent); 355 } else if (ACTION_SET_ORGANIZATION_INFO.equals(action)) { 356 if(intent.hasExtra(OrganizationInfoTestActivity.EXTRA_ORGANIZATION_NAME)) { 357 final String organizationName = intent 358 .getStringExtra(OrganizationInfoTestActivity.EXTRA_ORGANIZATION_NAME); 359 mDevicePolicyManager.setOrganizationName(mAdminReceiverComponent, organizationName); 360 } 361 final int organizationColor = intent.getIntExtra( 362 OrganizationInfoTestActivity.EXTRA_ORGANIZATION_COLOR, 363 mDevicePolicyManager.getOrganizationColor(mAdminReceiverComponent)); 364 mDevicePolicyManager.setOrganizationColor(mAdminReceiverComponent, organizationColor); 365 } else if (ACTION_TEST_PARENT_PROFILE_PASSWORD.equals(action)) { 366 startActivity(new Intent(DevicePolicyManager.ACTION_SET_NEW_PARENT_PROFILE_PASSWORD)); 367 } 368 // This activity has no UI and is only used to respond to CtsVerifier in the primary side. 369 finish(); 370 } 371 372 @Override onSaveInstanceState(final Bundle savedState)373 protected void onSaveInstanceState(final Bundle savedState) { 374 super.onSaveInstanceState(savedState); 375 376 savedState.putBundle(ORIGINAL_RESTRICTIONS_NAME, mOriginalRestrictions); 377 } 378 379 @Override onActivityResult(int requestCode, int resultCode, Intent data)380 protected void onActivityResult(int requestCode, int resultCode, Intent data) { 381 switch (requestCode) { 382 case REQUEST_INSTALL_PACKAGE: { 383 Log.w(TAG, "Received REQUEST_INSTALL_PACKAGE, resultCode = " + resultCode); 384 if (mOriginalRestrictions.containsKey(DISALLOW_INSTALL_UNKNOWN_SOURCES)) { 385 // Restore original setting 386 setUnknownSourcesRestriction( 387 mOriginalRestrictions.getBoolean(DISALLOW_INSTALL_UNKNOWN_SOURCES)); 388 mOriginalRestrictions.remove(DISALLOW_INSTALL_UNKNOWN_SOURCES); 389 } 390 finish(); 391 break; 392 } 393 case REQUEST_IMAGE_CAPTURE: { 394 if (resultCode == RESULT_OK) { 395 ByodPresentMediaDialog.newImageInstance(mImageFile) 396 .show(getFragmentManager(), "ViewImageDialogFragment"); 397 } else { 398 // Failed capturing image. 399 finish(); 400 } 401 break; 402 } 403 case REQUEST_VIDEO_CAPTURE_WITH_EXTRA_OUTPUT: { 404 if (resultCode == RESULT_OK) { 405 ByodPresentMediaDialog.newVideoInstance(mVideoUri) 406 .show(getFragmentManager(), "PlayVideoDialogFragment"); 407 } else { 408 // Failed capturing video. 409 finish(); 410 } 411 break; 412 } 413 case REQUEST_VIDEO_CAPTURE_WITHOUT_EXTRA_OUTPUT: { 414 if (resultCode == RESULT_OK) { 415 ByodPresentMediaDialog.newVideoInstance(data.getData()) 416 .show(getFragmentManager(), "PlayVideoDialogFragment"); 417 } else { 418 // Failed capturing video. 419 finish(); 420 } 421 break; 422 } 423 case REQUEST_AUDIO_CAPTURE: { 424 if (resultCode == RESULT_OK) { 425 ByodPresentMediaDialog.newAudioInstance(data.getData()) 426 .show(getFragmentManager(), "PlayAudioDialogFragment"); 427 } else { 428 // Failed capturing audio. 429 finish(); 430 } 431 break; 432 } 433 default: { 434 super.onActivityResult(requestCode, resultCode, data); 435 break; 436 } 437 } 438 } 439 440 @Override onDestroy()441 protected void onDestroy() { 442 cleanUpTempUris(); 443 super.onDestroy(); 444 } 445 getCaptureImageIntent()446 public static Intent getCaptureImageIntent() { 447 return new Intent(MediaStore.ACTION_IMAGE_CAPTURE); 448 } 449 getCaptureVideoIntent()450 public static Intent getCaptureVideoIntent() { 451 return new Intent(MediaStore.ACTION_VIDEO_CAPTURE); 452 } 453 getCaptureAudioIntent()454 public static Intent getCaptureAudioIntent() { 455 return new Intent(MediaStore.Audio.Media.RECORD_SOUND_ACTION); 456 } 457 createLockIntent()458 public static Intent createLockIntent() { 459 return new Intent(ACTION_LOCKNOW); 460 } 461 getTempUri(String fileName)462 private Pair<File, Uri> getTempUri(String fileName) { 463 final File file = new File(getFilesDir() + File.separator + "images" 464 + File.separator + fileName); 465 file.getParentFile().mkdirs(); //if the folder doesn't exists it is created 466 mTempFiles.add(file); 467 return new Pair<>(file, FileProvider.getUriForFile(this, 468 "com.android.cts.verifier.managedprovisioning.fileprovider", file)); 469 } 470 cleanUpTempUris()471 private void cleanUpTempUris() { 472 for (File file : mTempFiles) { 473 file.delete(); 474 } 475 } 476 isProfileOwner()477 private boolean isProfileOwner() { 478 return mDevicePolicyManager.isAdminActive(mAdminReceiverComponent) && 479 mDevicePolicyManager.isProfileOwnerApp(mAdminReceiverComponent.getPackageName()); 480 } 481 isUnknownSourcesRestrictionSet()482 private boolean isUnknownSourcesRestrictionSet() { 483 // We only care about restrictions set by Cts Verifier. In other cases, we cannot modify 484 // it and the test will fail anyway. 485 Bundle restrictions = mDevicePolicyManager.getUserRestrictions(mAdminReceiverComponent); 486 return restrictions.getBoolean(DISALLOW_INSTALL_UNKNOWN_SOURCES, false); 487 } 488 setUnknownSourcesRestriction(boolean enabled)489 private void setUnknownSourcesRestriction(boolean enabled) { 490 if (enabled) { 491 mDevicePolicyManager.addUserRestriction(mAdminReceiverComponent, 492 DISALLOW_INSTALL_UNKNOWN_SOURCES); 493 } else { 494 mDevicePolicyManager.clearUserRestriction(mAdminReceiverComponent, 495 DISALLOW_INSTALL_UNKNOWN_SOURCES); 496 } 497 } 498 startActivityInPrimary(Intent intent)499 private void startActivityInPrimary(Intent intent) { 500 // Disable app components in the current profile, so only the counterpart in the other 501 // profile can respond (via cross-profile intent filter) 502 getPackageManager().setComponentEnabledSetting(new ComponentName( 503 this, ByodFlowTestActivity.class), 504 PackageManager.COMPONENT_ENABLED_STATE_DISABLED, 505 PackageManager.DONT_KILL_APP); 506 startActivity(intent); 507 } 508 grantCameraPermissionToSelf()509 private void grantCameraPermissionToSelf() { 510 mDevicePolicyManager.setPermissionGrantState(mAdminReceiverComponent, getPackageName(), 511 android.Manifest.permission.CAMERA, 512 DevicePolicyManager.PERMISSION_GRANT_STATE_GRANTED); 513 } 514 sendIntentInsideChooser(Intent toSend)515 private void sendIntentInsideChooser(Intent toSend) { 516 toSend.putExtra(CrossProfileTestActivity.EXTRA_STARTED_FROM_WORK, true); 517 Intent chooser = Intent.createChooser(toSend, 518 getResources().getString(R.string.provisioning_cross_profile_chooser)); 519 startActivity(chooser); 520 } 521 522 @Override handleLocationAction()523 protected void handleLocationAction() { 524 // Grant the locaiton permission to the provile owner on cts-verifier. 525 // The permission state does not have to be reverted at the end since the profile onwer 526 // is going to be deleted when BYOD tests ends. 527 grantLocationPermissionToSelf(); 528 super.handleLocationAction(); 529 } 530 grantLocationPermissionToSelf()531 private void grantLocationPermissionToSelf() { 532 mDevicePolicyManager.setPermissionGrantState(mAdminReceiverComponent, getPackageName(), 533 android.Manifest.permission.ACCESS_FINE_LOCATION, 534 DevicePolicyManager.PERMISSION_GRANT_STATE_GRANTED); 535 } 536 537 @Override onDialogClose()538 public void onDialogClose() { 539 finish(); 540 } 541 542 @Override getLogTag()543 protected String getLogTag() { 544 return TAG; 545 } 546 } 547