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 
showNotification(int visibility)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
onCreate(Bundle savedInstanceState)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
onSaveInstanceState(final Bundle savedState)363     protected void onSaveInstanceState(final Bundle savedState) {
364         super.onSaveInstanceState(savedState);
365 
366         savedState.putBundle(ORIGINAL_SETTINGS_NAME, mOriginalSettings);
367     }
368 
369     @Override
onActivityResult(int requestCode, int resultCode, Intent data)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
onDestroy()430     protected void onDestroy() {
431         cleanUpTempUris();
432         super.onDestroy();
433     }
434 
getCaptureImageIntent()435     public static Intent getCaptureImageIntent() {
436         return new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
437     }
438 
getCaptureVideoIntent()439     public static Intent getCaptureVideoIntent() {
440         return new Intent(MediaStore.ACTION_VIDEO_CAPTURE);
441     }
442 
getCaptureAudioIntent()443     public static Intent getCaptureAudioIntent() {
444         return new Intent(MediaStore.Audio.Media.RECORD_SOUND_ACTION);
445     }
446 
createLockIntent()447     public static Intent createLockIntent() {
448         return new Intent(ACTION_LOCKNOW);
449     }
450 
getTempUri(String fileName)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 
cleanUpTempUris()460     private void cleanUpTempUris() {
461         for (File file : mTempFiles) {
462             file.delete();
463         }
464     }
465 
isProfileOwner()466     private boolean isProfileOwner() {
467         return mDevicePolicyManager.isAdminActive(mAdminReceiverComponent) &&
468                 mDevicePolicyManager.isProfileOwnerApp(mAdminReceiverComponent.getPackageName());
469     }
470 
getAllowNonMarket()471     private boolean getAllowNonMarket() {
472         String value = Settings.Secure.getString(getContentResolver(), INSTALL_NON_MARKET_APPS);
473         return "1".equals(value);
474     }
475 
setAllowNonMarket(boolean allow)476     private void setAllowNonMarket(boolean allow) {
477         mDevicePolicyManager.setSecureSetting(mAdminReceiverComponent, INSTALL_NON_MARKET_APPS,
478                 (allow ? "1" : "0"));
479     }
480 
startActivityInPrimary(Intent intent)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 
grantCameraPermissionToSelf()491     private void grantCameraPermissionToSelf() {
492         mDevicePolicyManager.setPermissionGrantState(mAdminReceiverComponent, getPackageName(),
493                 android.Manifest.permission.CAMERA,
494                 DevicePolicyManager.PERMISSION_GRANT_STATE_GRANTED);
495     }
496 
sendIntentInsideChooser(Intent toSend)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
handleLocationAction()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 
grantLocationPermissionToSelf()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
onDialogClose()520     public void onDialogClose() {
521         finish();
522     }
523 
524     @Override
getLogTag()525     protected String getLogTag() {
526         return TAG;
527     }
528 }
529