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