Java tutorial
/* * Copyright (C) 2015 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package com.afwsamples.testdpc.policy; import android.accessibilityservice.AccessibilityServiceInfo; import android.annotation.SuppressLint; import android.annotation.TargetApi; import android.app.Activity; import android.app.AlertDialog; import android.app.DialogFragment; import android.app.Fragment; import android.app.FragmentManager; import android.app.admin.DevicePolicyManager; import android.content.ActivityNotFoundException; import android.content.ComponentName; import android.content.Context; import android.content.DialogInterface; import android.content.Intent; import android.content.pm.ApplicationInfo; import android.content.pm.PackageManager; import android.content.pm.ResolveInfo; import android.net.Uri; import android.os.AsyncTask; import android.os.BatteryManager; import android.os.Build; import android.os.Bundle; import android.os.UserHandle; import android.os.UserManager; import android.provider.MediaStore; import android.provider.Settings; import android.security.KeyChain; import android.security.KeyChainAliasCallback; import android.support.v14.preference.SwitchPreference; import android.support.v4.content.FileProvider; import android.support.v4.os.BuildCompat; import android.support.v7.preference.EditTextPreference; import android.support.v7.preference.Preference; import android.telephony.TelephonyManager; import android.text.InputType; import android.text.TextUtils; import android.util.Log; import android.view.LayoutInflater; import android.view.View; import android.view.accessibility.AccessibilityManager; import android.view.inputmethod.InputMethodInfo; import android.view.inputmethod.InputMethodManager; import android.widget.AdapterView; import android.widget.ArrayAdapter; import android.widget.CheckBox; import android.widget.EditText; import android.widget.LinearLayout; import android.widget.ListView; import android.widget.RadioButton; import android.widget.RadioGroup; import android.widget.Toast; import com.afwsamples.testdpc.DeviceAdminReceiver; import com.afwsamples.testdpc.R; import com.afwsamples.testdpc.common.AppInfoArrayAdapter; import com.afwsamples.testdpc.common.BaseSearchablePolicyPreferenceFragment; import com.afwsamples.testdpc.common.CertificateUtil; import com.afwsamples.testdpc.common.MediaDisplayFragment; import com.afwsamples.testdpc.common.Util; import com.afwsamples.testdpc.common.preference.DpcPreference; import com.afwsamples.testdpc.common.preference.DpcSwitchPreference; import com.afwsamples.testdpc.policy.blockuninstallation.BlockUninstallationInfoArrayAdapter; import com.afwsamples.testdpc.policy.certificate.DelegatedCertInstallerFragment; import com.afwsamples.testdpc.policy.keyguard.LockScreenPolicyFragment; import com.afwsamples.testdpc.policy.keyguard.PasswordConstraintsFragment; import com.afwsamples.testdpc.policy.locktask.KioskModeActivity; import com.afwsamples.testdpc.policy.locktask.LockTaskAppInfoArrayAdapter; import com.afwsamples.testdpc.policy.networking.AlwaysOnVpnFragment; import com.afwsamples.testdpc.policy.networking.NetworkUsageStatsFragment; import com.afwsamples.testdpc.policy.systemupdatepolicy.SystemUpdatePolicyFragment; import com.afwsamples.testdpc.policy.wifimanagement.WifiConfigCreationDialog; import com.afwsamples.testdpc.policy.wifimanagement.WifiEapTlsCreateDialogFragment; import com.afwsamples.testdpc.policy.wifimanagement.WifiModificationFragment; import com.afwsamples.testdpc.profilepolicy.ProfilePolicyManagementFragment; import com.afwsamples.testdpc.profilepolicy.addsystemapps.EnableSystemAppsByIntentFragment; import com.afwsamples.testdpc.profilepolicy.apprestrictions.AppRestrictionsManagingPackageFragment; import com.afwsamples.testdpc.profilepolicy.apprestrictions.ManageAppRestrictionsFragment; import com.afwsamples.testdpc.profilepolicy.permission.ManageAppPermissionsFragment; import com.afwsamples.testdpc.safetynet.SafetyNetFragment; import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.io.File; import java.io.FileNotFoundException; import java.io.IOException; import java.io.InputStream; import java.security.KeyStoreException; import java.security.NoSuchAlgorithmException; import java.security.PrivateKey; import java.security.UnrecoverableKeyException; import java.security.cert.Certificate; import java.security.cert.CertificateException; import java.security.cert.CertificateFactory; import java.security.cert.X509Certificate; import java.text.DateFormat; import java.text.ParseException; import java.text.SimpleDateFormat; import java.util.ArrayList; import java.util.Arrays; import java.util.Collections; import java.util.Date; import java.util.HashSet; import java.util.List; import java.util.Set; import static android.os.UserManager.DISALLOW_INSTALL_UNKNOWN_SOURCES; /** * Provides several device management functions. * * These include: * <ul> * <li> {@link DevicePolicyManager#setLockTaskPackages(android.content.ComponentName, String[])} </li> * <li> {@link DevicePolicyManager#isLockTaskPermitted(String)} </li> * <li> {@link UserManager#DISALLOW_DEBUGGING_FEATURES} </li> * <li> {@link UserManager#DISALLOW_INSTALL_UNKNOWN_SOURCES} </li> * <li> {@link UserManager#DISALLOW_REMOVE_USER} </li> * <li> {@link UserManager#DISALLOW_ADD_USER} </li> * <li> {@link UserManager#DISALLOW_FACTORY_RESET} </li> * <li> {@link UserManager#DISALLOW_CONFIG_CREDENTIALS} </li> * <li> {@link UserManager#DISALLOW_SHARE_LOCATION} </li> * <li> {@link UserManager#DISALLOW_CONFIG_TETHERING} </li> * <li> {@link UserManager#DISALLOW_ADJUST_VOLUME} </li> * <li> {@link UserManager#DISALLOW_UNMUTE_MICROPHONE} </li> * <li> {@link UserManager#DISALLOW_MODIFY_ACCOUNTS} </li> * <li> {@link UserManager#DISALLOW_SAFE_BOOT} </li> * <li> {@link UserManager#DISALLOW_OUTGOING_BEAM}} </li> * <li> {@link UserManager#DISALLOW_CREATE_WINDOWS}} </li> * <li> {@link DevicePolicyManager#clearDeviceOwnerApp(String)} </li> * <li> {@link DevicePolicyManager#getPermittedAccessibilityServices(android.content.ComponentName)} * </li> * <li> {@link DevicePolicyManager#getPermittedInputMethods(android.content.ComponentName)} </li> * <li> {@link DevicePolicyManager#setAccountManagementDisabled(android.content.ComponentName, * String, boolean)} </li> * <li> {@link DevicePolicyManager#getAccountTypesWithManagementDisabled()} </li> * <li> {@link DevicePolicyManager#removeUser(android.content.ComponentName, android.os.UserHandle)} </li> * <li> {@link DevicePolicyManager#setUninstallBlocked(android.content.ComponentName, String, * boolean)} </li> * <li> {@link DevicePolicyManager#isUninstallBlocked(android.content.ComponentName, String)} </li> * <li> {@link DevicePolicyManager#setCameraDisabled(android.content.ComponentName, boolean)} </li> * <li> {@link DevicePolicyManager#getCameraDisabled(android.content.ComponentName)} </li> * <li> {@link DevicePolicyManager#enableSystemApp(android.content.ComponentName, * android.content.Intent)} </li> * <li> {@link DevicePolicyManager#enableSystemApp(android.content.ComponentName, String)} </li> * <li> {@link DevicePolicyManager#setApplicationRestrictions(android.content.ComponentName, String, * android.os.Bundle)} </li> * <li> {@link DevicePolicyManager#installKeyPair(android.content.ComponentName, * java.security.PrivateKey, java.security.cert.Certificate, String)} </li> * <li> {@link DevicePolicyManager#removeKeyPair(android.content.ComponentName, String)} </li> * <li> {@link DevicePolicyManager#installCaCert(android.content.ComponentName, byte[])} </li> * <li> {@link DevicePolicyManager#uninstallAllUserCaCerts(android.content.ComponentName)} </li> * <li> {@link DevicePolicyManager#getInstalledCaCerts(android.content.ComponentName)} </li> * <li> {@link DevicePolicyManager#setStatusBarDisabled(ComponentName, boolean)} </li> * <li> {@link DevicePolicyManager#setKeyguardDisabled(ComponentName, boolean)} </li> * <li> {@link DevicePolicyManager#setPermissionPolicy(android.content.ComponentName, int)} </li> * <li> {@link DevicePolicyManager#getPermissionPolicy(android.content.ComponentName)} </li> * <li> {@link DevicePolicyManager#setPermissionGrantState(ComponentName, String, String, int) ( * android.content.ComponentName, String, String, boolean)} </li> * <li> {@link DevicePolicyManager#setScreenCaptureDisabled(ComponentName, boolean)} </li> * <li> {@link DevicePolicyManager#getScreenCaptureDisabled(ComponentName)} </li> * <li> {@link DevicePolicyManager#setMaximumTimeToLock(ComponentName, long)} </li> * <li> {@link DevicePolicyManager#setMaximumFailedPasswordsForWipe(ComponentName, int)} </li> * <li> {@link DevicePolicyManager#setApplicationHidden(ComponentName, String, boolean)} </li> * <li> {@link DevicePolicyManager#setShortSupportMessage(ComponentName, String)} </li> * <li> {@link DevicePolicyManager#setLongSupportMessage(ComponentName, String)} </li> * <li> {@link UserManager#DISALLOW_CONFIG_WIFI} </li> * </ul> */ public class PolicyManagementFragment extends BaseSearchablePolicyPreferenceFragment implements Preference.OnPreferenceClickListener, Preference.OnPreferenceChangeListener { // Tag for creating this fragment. This tag can be used to retrieve this fragment. public static final String FRAGMENT_TAG = "PolicyManagementFragment"; private static final int INSTALL_KEY_CERTIFICATE_REQUEST_CODE = 7689; private static final int INSTALL_CA_CERTIFICATE_REQUEST_CODE = 7690; private static final int CAPTURE_IMAGE_REQUEST_CODE = 7691; private static final int CAPTURE_VIDEO_REQUEST_CODE = 7692; public static final int DEFAULT_BUFFER_SIZE = 4096; public static final String X509_CERT_TYPE = "X.509"; public static final String TAG = "PolicyManagement"; public static final String OVERRIDE_KEY_SELECTION_KEY = "override_key_selection"; private static final String APP_RESTRICTIONS_MANAGING_PACKAGE_KEY = "app_restrictions_managing_package"; private static final String BLOCK_UNINSTALLATION_BY_PKG_KEY = "block_uninstallation_by_pkg"; private static final String BLOCK_UNINSTALLATION_LIST_KEY = "block_uninstallation_list"; private static final String CAPTURE_IMAGE_KEY = "capture_image"; private static final String CAPTURE_VIDEO_KEY = "capture_video"; private static final String CHECK_LOCK_TASK_PERMITTED_KEY = "check_lock_task_permitted"; private static final String CREATE_AND_MANAGE_USER_KEY = "create_and_manage_user"; private static final String DELEGATED_CERT_INSTALLER_KEY = "manage_cert_installer"; private static final String DEVICE_OWNER_STATUS_KEY = "device_owner_status"; private static final String SECURITY_PATCH_KEY = "security_patch"; private static final String DISABLE_CAMERA_KEY = "disable_camera"; private static final String DISABLE_KEYGUARD = "disable_keyguard"; private static final String DISABLE_SCREEN_CAPTURE_KEY = "disable_screen_capture"; private static final String DISABLE_STATUS_BAR = "disable_status_bar"; private static final String ENABLE_PROCESS_LOGGING = "enable_process_logging"; private static final String ENABLE_SYSTEM_APPS_BY_INTENT_KEY = "enable_system_apps_by_intent"; private static final String ENABLE_SYSTEM_APPS_BY_PACKAGE_NAME_KEY = "enable_system_apps_by_package_name"; private static final String ENABLE_SYSTEM_APPS_KEY = "enable_system_apps"; private static final String GET_CA_CERTIFICATES_KEY = "get_ca_certificates"; private static final String GET_DISABLE_ACCOUNT_MANAGEMENT_KEY = "get_disable_account_management"; private static final String HIDE_APPS_KEY = "hide_apps"; private static final String INSTALL_CA_CERTIFICATE_KEY = "install_ca_certificate"; private static final String INSTALL_KEY_CERTIFICATE_KEY = "install_key_certificate"; private static final String INSTALL_NONMARKET_APPS_KEY = "install_nonmarket_apps"; private static final String LOCK_SCREEN_POLICY_KEY = "lock_screen_policy"; private static final String MANAGE_APP_PERMISSIONS_KEY = "manage_app_permissions"; private static final String MANAGE_APP_RESTRICTIONS_KEY = "manage_app_restrictions"; private static final String MANAGED_PROFILE_SPECIFIC_POLICIES_KEY = "managed_profile_policies"; private static final String MANAGE_LOCK_TASK_LIST_KEY = "manage_lock_task"; private static final String MUTE_AUDIO_KEY = "mute_audio"; private static final String NETWORK_STATS_KEY = "network_stats"; private static final String PASSWORD_CONSTRAINTS_KEY = "password_constraints"; private static final String REBOOT_KEY = "reboot"; private static final String REENABLE_KEYGUARD = "reenable_keyguard"; private static final String REENABLE_STATUS_BAR = "reenable_status_bar"; private static final String REMOVE_ALL_CERTIFICATES_KEY = "remove_all_ca_certificates"; private static final String REMOVE_DEVICE_OWNER_KEY = "remove_device_owner"; private static final String REMOVE_KEY_CERTIFICATE_KEY = "remove_key_certificate"; private static final String REMOVE_USER_KEY = "remove_user"; private static final String REQUEST_BUGREPORT_KEY = "request_bugreport"; private static final String REQUEST_PROCESS_LOGS = "request_process_logs"; private static final String RESET_PASSWORD_KEY = "reset_password"; private static final String LOCK_NOW_KEY = "lock_now"; private static final String SET_ACCESSIBILITY_SERVICES_KEY = "set_accessibility_services"; private static final String SET_ALWAYS_ON_VPN_KEY = "set_always_on_vpn"; private static final String SET_AUTO_TIME_REQUIRED_KEY = "set_auto_time_required"; private static final String SET_DISABLE_ACCOUNT_MANAGEMENT_KEY = "set_disable_account_management"; private static final String SET_INPUT_METHODS_KEY = "set_input_methods"; private static final String SET_LONG_SUPPORT_MESSAGE_KEY = "set_long_support_message"; private static final String SET_PERMISSION_POLICY_KEY = "set_permission_policy"; private static final String SET_SHORT_SUPPORT_MESSAGE_KEY = "set_short_support_message"; private static final String SET_USER_RESTRICTIONS_KEY = "set_user_restrictions"; private static final String SHOW_WIFI_MAC_ADDRESS_KEY = "show_wifi_mac_address"; private static final String START_KIOSK_MODE = "start_kiosk_mode"; private static final String START_LOCK_TASK = "start_lock_task"; private static final String STAY_ON_WHILE_PLUGGED_IN = "stay_on_while_plugged_in"; private static final String STOP_LOCK_TASK = "stop_lock_task"; private static final String SUSPEND_APPS_KEY = "suspend_apps"; private static final String SYSTEM_UPDATE_POLICY_KEY = "system_update_policy"; private static final String UNHIDE_APPS_KEY = "unhide_apps"; private static final String UNSUSPEND_APPS_KEY = "unsuspend_apps"; private static final String WIPE_DATA_KEY = "wipe_data"; private static final String CREATE_WIFI_CONFIGURATION_KEY = "create_wifi_configuration"; private static final String CREATE_EAP_TLS_WIFI_CONFIGURATION_KEY = "create_eap_tls_wifi_configuration"; private static final String WIFI_CONFIG_LOCKDOWN_ENABLE_KEY = "enable_wifi_config_lockdown"; private static final String MODIFY_WIFI_CONFIGURATION_KEY = "modify_wifi_configuration"; private static final String TAG_WIFI_CONFIG_CREATION = "wifi_config_creation"; private static final String WIFI_CONFIG_LOCKDOWN_ON = "1"; private static final String WIFI_CONFIG_LOCKDOWN_OFF = "0"; private static final String SAFETYNET_ATTEST = "safetynet_attest"; private static final String SECURITY_PATCH_FORMAT = "yyyy-MM-dd"; private static final String BATTERY_PLUGGED_ANY = Integer.toString(BatteryManager.BATTERY_PLUGGED_AC | BatteryManager.BATTERY_PLUGGED_USB | BatteryManager.BATTERY_PLUGGED_WIRELESS); private static final String DONT_STAY_ON = "0"; private DevicePolicyManager mDevicePolicyManager; private PackageManager mPackageManager; private String mPackageName; private ComponentName mAdminComponentName; private UserManager mUserManager; private TelephonyManager mTelephonyManager; private SwitchPreference mDisableCameraSwitchPreference; private SwitchPreference mDisableScreenCaptureSwitchPreference; private SwitchPreference mMuteAudioSwitchPreference; private SwitchPreference mStayOnWhilePluggedInSwitchPreference; private DpcSwitchPreference mInstallNonMarketAppsPreference; private SwitchPreference mEnableProcessLoggingPreference; private SwitchPreference mSetAutoTimeRequiredPreference; private GetAccessibilityServicesTask mGetAccessibilityServicesTask = null; private GetInputMethodsTask mGetInputMethodsTask = null; private ShowCaCertificateListTask mShowCaCertificateListTask = null; private Uri mImageUri; private Uri mVideoUri; @Override public void onCreate(Bundle savedInstanceState) { mAdminComponentName = DeviceAdminReceiver.getComponentName(getActivity()); mDevicePolicyManager = (DevicePolicyManager) getActivity().getSystemService(Context.DEVICE_POLICY_SERVICE); mUserManager = (UserManager) getActivity().getSystemService(Context.USER_SERVICE); mTelephonyManager = (TelephonyManager) getActivity().getSystemService(Context.TELEPHONY_SERVICE); mPackageManager = getActivity().getPackageManager(); mPackageName = getActivity().getPackageName(); mImageUri = getStorageUri("image.jpg"); mVideoUri = getStorageUri("video.mp4"); super.onCreate(savedInstanceState); } @Override public void onCreatePreferences(Bundle savedInstanceState, String rootKey) { addPreferencesFromResource(getPreferenceXml()); EditTextPreference overrideKeySelectionPreference = (EditTextPreference) findPreference( OVERRIDE_KEY_SELECTION_KEY); overrideKeySelectionPreference.setOnPreferenceChangeListener(this); overrideKeySelectionPreference.setSummary(overrideKeySelectionPreference.getText()); findPreference(MANAGE_LOCK_TASK_LIST_KEY).setOnPreferenceClickListener(this); findPreference(CHECK_LOCK_TASK_PERMITTED_KEY).setOnPreferenceClickListener(this); findPreference(START_LOCK_TASK).setOnPreferenceClickListener(this); findPreference(STOP_LOCK_TASK).setOnPreferenceClickListener(this); findPreference(CREATE_AND_MANAGE_USER_KEY).setOnPreferenceClickListener(this); findPreference(REMOVE_USER_KEY).setOnPreferenceClickListener(this); mDisableCameraSwitchPreference = (SwitchPreference) findPreference(DISABLE_CAMERA_KEY); findPreference(CAPTURE_IMAGE_KEY).setOnPreferenceClickListener(this); findPreference(CAPTURE_VIDEO_KEY).setOnPreferenceClickListener(this); mDisableCameraSwitchPreference.setOnPreferenceChangeListener(this); mDisableScreenCaptureSwitchPreference = (SwitchPreference) findPreference(DISABLE_SCREEN_CAPTURE_KEY); mDisableScreenCaptureSwitchPreference.setOnPreferenceChangeListener(this); mMuteAudioSwitchPreference = (SwitchPreference) findPreference(MUTE_AUDIO_KEY); mMuteAudioSwitchPreference.setOnPreferenceChangeListener(this); findPreference(LOCK_SCREEN_POLICY_KEY).setOnPreferenceClickListener(this); findPreference(PASSWORD_CONSTRAINTS_KEY).setOnPreferenceClickListener(this); findPreference(RESET_PASSWORD_KEY).setOnPreferenceClickListener(this); findPreference(LOCK_NOW_KEY).setOnPreferenceClickListener(this); findPreference(SYSTEM_UPDATE_POLICY_KEY).setOnPreferenceClickListener(this); findPreference(SET_ALWAYS_ON_VPN_KEY).setOnPreferenceClickListener(this); findPreference(NETWORK_STATS_KEY).setOnPreferenceClickListener(this); findPreference(DELEGATED_CERT_INSTALLER_KEY).setOnPreferenceClickListener(this); findPreference(DISABLE_STATUS_BAR).setOnPreferenceClickListener(this); findPreference(REENABLE_STATUS_BAR).setOnPreferenceClickListener(this); findPreference(DISABLE_KEYGUARD).setOnPreferenceClickListener(this); findPreference(REENABLE_KEYGUARD).setOnPreferenceClickListener(this); findPreference(START_KIOSK_MODE).setOnPreferenceClickListener(this); mStayOnWhilePluggedInSwitchPreference = (SwitchPreference) findPreference(STAY_ON_WHILE_PLUGGED_IN); mStayOnWhilePluggedInSwitchPreference.setOnPreferenceChangeListener(this); findPreference(WIPE_DATA_KEY).setOnPreferenceClickListener(this); findPreference(REMOVE_DEVICE_OWNER_KEY).setOnPreferenceClickListener(this); findPreference(REQUEST_BUGREPORT_KEY).setOnPreferenceClickListener(this); mEnableProcessLoggingPreference = (SwitchPreference) findPreference(ENABLE_PROCESS_LOGGING); mEnableProcessLoggingPreference.setOnPreferenceChangeListener(this); findPreference(REQUEST_PROCESS_LOGS).setOnPreferenceClickListener(this); findPreference(SET_ACCESSIBILITY_SERVICES_KEY).setOnPreferenceClickListener(this); findPreference(SET_INPUT_METHODS_KEY).setOnPreferenceClickListener(this); findPreference(SET_DISABLE_ACCOUNT_MANAGEMENT_KEY).setOnPreferenceClickListener(this); findPreference(GET_DISABLE_ACCOUNT_MANAGEMENT_KEY).setOnPreferenceClickListener(this); findPreference(BLOCK_UNINSTALLATION_BY_PKG_KEY).setOnPreferenceClickListener(this); findPreference(BLOCK_UNINSTALLATION_LIST_KEY).setOnPreferenceClickListener(this); findPreference(ENABLE_SYSTEM_APPS_KEY).setOnPreferenceClickListener(this); findPreference(ENABLE_SYSTEM_APPS_BY_PACKAGE_NAME_KEY).setOnPreferenceClickListener(this); findPreference(ENABLE_SYSTEM_APPS_BY_INTENT_KEY).setOnPreferenceClickListener(this); findPreference(HIDE_APPS_KEY).setOnPreferenceClickListener(this); findPreference(UNHIDE_APPS_KEY).setOnPreferenceClickListener(this); findPreference(SUSPEND_APPS_KEY).setOnPreferenceClickListener(this); findPreference(UNSUSPEND_APPS_KEY).setOnPreferenceClickListener(this); findPreference(MANAGE_APP_RESTRICTIONS_KEY).setOnPreferenceClickListener(this); findPreference(APP_RESTRICTIONS_MANAGING_PACKAGE_KEY).setOnPreferenceClickListener(this); findPreference(INSTALL_KEY_CERTIFICATE_KEY).setOnPreferenceClickListener(this); findPreference(REMOVE_KEY_CERTIFICATE_KEY).setOnPreferenceClickListener(this); findPreference(INSTALL_CA_CERTIFICATE_KEY).setOnPreferenceClickListener(this); findPreference(GET_CA_CERTIFICATES_KEY).setOnPreferenceClickListener(this); findPreference(REMOVE_ALL_CERTIFICATES_KEY).setOnPreferenceClickListener(this); findPreference(MANAGED_PROFILE_SPECIFIC_POLICIES_KEY).setOnPreferenceClickListener(this); findPreference(SET_PERMISSION_POLICY_KEY).setOnPreferenceClickListener(this); findPreference(MANAGE_APP_PERMISSIONS_KEY).setOnPreferenceClickListener(this); findPreference(CREATE_WIFI_CONFIGURATION_KEY).setOnPreferenceClickListener(this); findPreference(CREATE_EAP_TLS_WIFI_CONFIGURATION_KEY).setOnPreferenceClickListener(this); findPreference(WIFI_CONFIG_LOCKDOWN_ENABLE_KEY).setOnPreferenceChangeListener(this); findPreference(MODIFY_WIFI_CONFIGURATION_KEY).setOnPreferenceClickListener(this); findPreference(SHOW_WIFI_MAC_ADDRESS_KEY).setOnPreferenceClickListener(this); mInstallNonMarketAppsPreference = (DpcSwitchPreference) findPreference(INSTALL_NONMARKET_APPS_KEY); mInstallNonMarketAppsPreference.setOnPreferenceChangeListener(this); findPreference(SET_USER_RESTRICTIONS_KEY).setOnPreferenceClickListener(this); findPreference(REBOOT_KEY).setOnPreferenceClickListener(this); findPreference(SET_SHORT_SUPPORT_MESSAGE_KEY).setOnPreferenceClickListener(this); findPreference(SET_LONG_SUPPORT_MESSAGE_KEY).setOnPreferenceClickListener(this); findPreference(SAFETYNET_ATTEST).setOnPreferenceClickListener(this); mSetAutoTimeRequiredPreference = (SwitchPreference) findPreference(SET_AUTO_TIME_REQUIRED_KEY); mSetAutoTimeRequiredPreference.setOnPreferenceChangeListener(this); constrainSpecialCasePreferences(); loadAppStatus(); loadSecurityPatch(); reloadCameraDisableUi(); reloadScreenCaptureDisableUi(); reloadMuteAudioUi(); reloadEnableProcessLoggingUi(); reloadSetAutoTimeRequiredUi(); } private void constrainSpecialCasePreferences() { // Reset password can be used in all contexts since N if (BuildCompat.isAtLeastN()) { ((DpcPreference) findPreference(RESET_PASSWORD_KEY)).clearNonCustomConstraints(); } } @Override public int getPreferenceXml() { return R.xml.device_policy_header; } @Override public boolean isAvailable(Context context) { DevicePolicyManager dpm = (DevicePolicyManager) context.getSystemService(Context.DEVICE_POLICY_SERVICE); String packageName = context.getPackageName(); return dpm.isProfileOwnerApp(packageName) || dpm.isDeviceOwnerApp(packageName); } @Override public void onResume() { super.onResume(); getActivity().getActionBar().setTitle(R.string.policies_management); if (!isAvailable(getActivity())) { showToast(R.string.this_is_not_a_device_owner); getActivity().finish(); } // The settings might get changed outside the device policy app, // so, we need to make sure the preference gets updated accordingly. updateStayOnWhilePluggedInPreference(); updateInstallNonMarketAppsPreference(); } @Override public boolean onPreferenceClick(Preference preference) { String key = preference.getKey(); switch (key) { case MANAGE_LOCK_TASK_LIST_KEY: showManageLockTaskListPrompt(R.string.lock_task_title, new ManageLockTaskListCallback() { @Override public void onPositiveButtonClicked(String[] lockTaskArray) { mDevicePolicyManager.setLockTaskPackages(DeviceAdminReceiver.getComponentName(getActivity()), lockTaskArray); } }); return true; case CHECK_LOCK_TASK_PERMITTED_KEY: showCheckLockTaskPermittedPrompt(); return true; case RESET_PASSWORD_KEY: showResetPasswordPrompt(); return false; case LOCK_NOW_KEY: lockNow(); return true; case START_LOCK_TASK: getActivity().startLockTask(); return true; case STOP_LOCK_TASK: try { getActivity().stopLockTask(); } catch (IllegalStateException e) { // no lock task present, ignore } return true; case WIPE_DATA_KEY: showWipeDataPrompt(); return true; case REMOVE_DEVICE_OWNER_KEY: showRemoveDeviceOwnerPrompt(); return true; case REQUEST_BUGREPORT_KEY: requestBugReport(); return true; case REQUEST_PROCESS_LOGS: showFragment(new ProcessLogsFragment()); return true; case SET_ACCESSIBILITY_SERVICES_KEY: // Avoid starting the same task twice. if (mGetAccessibilityServicesTask != null && !mGetAccessibilityServicesTask.isCancelled()) { mGetAccessibilityServicesTask.cancel(true); } mGetAccessibilityServicesTask = new GetAccessibilityServicesTask(); mGetAccessibilityServicesTask.execute(); return true; case SET_INPUT_METHODS_KEY: // Avoid starting the same task twice. if (mGetInputMethodsTask != null && !mGetInputMethodsTask.isCancelled()) { mGetInputMethodsTask.cancel(true); } mGetInputMethodsTask = new GetInputMethodsTask(); mGetInputMethodsTask.execute(); return true; case SET_DISABLE_ACCOUNT_MANAGEMENT_KEY: showSetDisableAccountManagementPrompt(); return true; case GET_DISABLE_ACCOUNT_MANAGEMENT_KEY: showDisableAccountTypeList(); return true; case CREATE_AND_MANAGE_USER_KEY: showCreateAndManageUserPrompt(); return true; case REMOVE_USER_KEY: showRemoveUserPrompt(); return true; case BLOCK_UNINSTALLATION_BY_PKG_KEY: showBlockUninstallationByPackageNamePrompt(); return true; case BLOCK_UNINSTALLATION_LIST_KEY: showBlockUninstallationPrompt(); return true; case ENABLE_SYSTEM_APPS_KEY: showEnableSystemAppsPrompt(); return true; case ENABLE_SYSTEM_APPS_BY_PACKAGE_NAME_KEY: showEnableSystemAppByPackageNamePrompt(); return true; case ENABLE_SYSTEM_APPS_BY_INTENT_KEY: showFragment(new EnableSystemAppsByIntentFragment()); return true; case HIDE_APPS_KEY: showHideAppsPrompt(false); return true; case UNHIDE_APPS_KEY: showHideAppsPrompt(true); return true; case SUSPEND_APPS_KEY: showSuspendAppsPrompt(false); return true; case UNSUSPEND_APPS_KEY: showSuspendAppsPrompt(true); return true; case MANAGE_APP_RESTRICTIONS_KEY: showFragment(new ManageAppRestrictionsFragment()); return true; case APP_RESTRICTIONS_MANAGING_PACKAGE_KEY: showFragment(new AppRestrictionsManagingPackageFragment()); return true; case SET_PERMISSION_POLICY_KEY: showSetPermissionPolicyDialog(); return true; case MANAGE_APP_PERMISSIONS_KEY: showFragment(new ManageAppPermissionsFragment()); return true; case INSTALL_KEY_CERTIFICATE_KEY: showFileViewerForImportingCertificate(INSTALL_KEY_CERTIFICATE_REQUEST_CODE); return true; case REMOVE_KEY_CERTIFICATE_KEY: choosePrivateKeyForRemoval(); return true; case INSTALL_CA_CERTIFICATE_KEY: showFileViewerForImportingCertificate(INSTALL_CA_CERTIFICATE_REQUEST_CODE); return true; case GET_CA_CERTIFICATES_KEY: showCaCertificateList(); return true; case REMOVE_ALL_CERTIFICATES_KEY: mDevicePolicyManager.uninstallAllUserCaCerts(mAdminComponentName); showToast(R.string.all_ca_certificates_removed); return true; case MANAGED_PROFILE_SPECIFIC_POLICIES_KEY: showFragment(new ProfilePolicyManagementFragment(), ProfilePolicyManagementFragment.FRAGMENT_TAG); return true; case LOCK_SCREEN_POLICY_KEY: showFragment(new LockScreenPolicyFragment.Container()); return true; case PASSWORD_CONSTRAINTS_KEY: showFragment(new PasswordConstraintsFragment.Container()); return true; case SYSTEM_UPDATE_POLICY_KEY: showFragment(new SystemUpdatePolicyFragment()); return true; case SET_ALWAYS_ON_VPN_KEY: showFragment(new AlwaysOnVpnFragment()); return true; case NETWORK_STATS_KEY: showFragment(new NetworkUsageStatsFragment()); return true; case DELEGATED_CERT_INSTALLER_KEY: showFragment(new DelegatedCertInstallerFragment()); return true; case DISABLE_STATUS_BAR: setStatusBarDisabled(true); return true; case REENABLE_STATUS_BAR: setStatusBarDisabled(false); return true; case DISABLE_KEYGUARD: setKeyGuardDisabled(true); return true; case REENABLE_KEYGUARD: setKeyGuardDisabled(false); return true; case START_KIOSK_MODE: showManageLockTaskListPrompt(R.string.kiosk_select_title, new ManageLockTaskListCallback() { @Override public void onPositiveButtonClicked(String[] lockTaskArray) { startKioskMode(lockTaskArray); } }); return true; case CAPTURE_IMAGE_KEY: dispatchCaptureIntent(MediaStore.ACTION_IMAGE_CAPTURE, CAPTURE_IMAGE_REQUEST_CODE, mImageUri); return true; case CAPTURE_VIDEO_KEY: dispatchCaptureIntent(MediaStore.ACTION_VIDEO_CAPTURE, CAPTURE_VIDEO_REQUEST_CODE, mVideoUri); return true; case CREATE_WIFI_CONFIGURATION_KEY: showWifiConfigCreationDialog(); return true; case CREATE_EAP_TLS_WIFI_CONFIGURATION_KEY: showEapTlsWifiConfigCreationDialog(); return true; case MODIFY_WIFI_CONFIGURATION_KEY: showFragment(new WifiModificationFragment()); return true; case SHOW_WIFI_MAC_ADDRESS_KEY: showWifiMacAddress(); return true; case SET_USER_RESTRICTIONS_KEY: showFragment(new UserRestrictionsDisplayFragment()); return true; case REBOOT_KEY: reboot(); return true; case SET_SHORT_SUPPORT_MESSAGE_KEY: showFragment(SetSupportMessageFragment.newInstance(SetSupportMessageFragment.TYPE_SHORT)); return true; case SET_LONG_SUPPORT_MESSAGE_KEY: showFragment(SetSupportMessageFragment.newInstance(SetSupportMessageFragment.TYPE_LONG)); return true; case SAFETYNET_ATTEST: DialogFragment safetynetFragment = new SafetyNetFragment(); safetynetFragment.show(getFragmentManager(), SafetyNetFragment.class.getName()); return true; } return false; } @TargetApi(Build.VERSION_CODES.N) private void lockNow() { if (Util.isBeforeN() || !Util.isManagedProfile(getActivity(), mAdminComponentName)) { mDevicePolicyManager.lockNow(); } else { // In N for work profiles we should call lockNow on the parent instance to // lock the device. DevicePolicyManager parentDpm = mDevicePolicyManager.getParentProfileInstance(mAdminComponentName); parentDpm.lockNow(); } } @Override @SuppressLint("NewApi") public boolean onPreferenceChange(Preference preference, Object newValue) { String key = preference.getKey(); switch (key) { case OVERRIDE_KEY_SELECTION_KEY: preference.setSummary((String) newValue); return true; case DISABLE_CAMERA_KEY: setCameraDisabled((Boolean) newValue); // Reload UI to verify the camera is enable / disable correctly. reloadCameraDisableUi(); return true; case ENABLE_PROCESS_LOGGING: setSecurityLoggingEnabled((Boolean) newValue); reloadEnableProcessLoggingUi(); return true; case DISABLE_SCREEN_CAPTURE_KEY: setScreenCaptureDisabled((Boolean) newValue); // Reload UI to verify that screen capture was enabled / disabled correctly. reloadScreenCaptureDisableUi(); return true; case MUTE_AUDIO_KEY: mDevicePolicyManager.setMasterVolumeMuted(mAdminComponentName, (Boolean) newValue); reloadMuteAudioUi(); return true; case STAY_ON_WHILE_PLUGGED_IN: mDevicePolicyManager.setGlobalSetting(mAdminComponentName, Settings.Global.STAY_ON_WHILE_PLUGGED_IN, newValue.equals(true) ? BATTERY_PLUGGED_ANY : DONT_STAY_ON); updateStayOnWhilePluggedInPreference(); return true; case WIFI_CONFIG_LOCKDOWN_ENABLE_KEY: mDevicePolicyManager.setGlobalSetting(mAdminComponentName, Settings.Global.WIFI_DEVICE_OWNER_CONFIGS_LOCKDOWN, newValue.equals(Boolean.TRUE) ? WIFI_CONFIG_LOCKDOWN_ON : WIFI_CONFIG_LOCKDOWN_OFF); return true; case INSTALL_NONMARKET_APPS_KEY: mDevicePolicyManager.setSecureSetting(mAdminComponentName, Settings.Secure.INSTALL_NON_MARKET_APPS, newValue.equals(true) ? "1" : "0"); updateInstallNonMarketAppsPreference(); return true; case SET_AUTO_TIME_REQUIRED_KEY: mDevicePolicyManager.setAutoTimeRequired(mAdminComponentName, newValue.equals(true)); reloadSetAutoTimeRequiredUi(); return true; } return false; } @TargetApi(Build.VERSION_CODES.M) private void setCameraDisabled(boolean disabled) { mDevicePolicyManager.setCameraDisabled(mAdminComponentName, disabled); } @TargetApi(Build.VERSION_CODES.N) private void setSecurityLoggingEnabled(boolean enabled) { mDevicePolicyManager.setSecurityLoggingEnabled(mAdminComponentName, enabled); } @TargetApi(Build.VERSION_CODES.M) private void setKeyGuardDisabled(boolean disabled) { if (!mDevicePolicyManager.setKeyguardDisabled(mAdminComponentName, disabled)) { // this should not happen if (disabled) { showToast(R.string.unable_disable_keyguard); } else { showToast(R.string.unable_enable_keyguard); } } } @TargetApi(Build.VERSION_CODES.LOLLIPOP) private void setScreenCaptureDisabled(boolean disabled) { mDevicePolicyManager.setScreenCaptureDisabled(mAdminComponentName, disabled); } private void setMasterVolumeMuted(boolean muted) { } @TargetApi(Build.VERSION_CODES.N) private void requestBugReport() { boolean startedSuccessfully = mDevicePolicyManager.requestBugreport(mAdminComponentName); if (!startedSuccessfully) { Context context = getActivity(); Util.showNotification(context, R.string.bugreport_title, context.getString(R.string.bugreport_failure_throttled), Util.BUGREPORT_NOTIFICATION_ID); } } @TargetApi(Build.VERSION_CODES.M) private void setStatusBarDisabled(boolean disable) { if (!mDevicePolicyManager.setStatusBarDisabled(mAdminComponentName, disable)) { if (disable) { showToast("Unable to disable status bar when lock password is set."); } } } /** * Dispatches an intent to capture image or video. */ private void dispatchCaptureIntent(String action, int requestCode, Uri storageUri) { final Intent captureIntent = new Intent(action); if (captureIntent.resolveActivity(mPackageManager) != null) { captureIntent.putExtra(MediaStore.EXTRA_OUTPUT, storageUri); startActivityForResult(captureIntent, requestCode); } else { showToast(R.string.camera_app_not_found); } } /** * Creates a content uri to be used with the capture intent. */ private Uri getStorageUri(String fileName) { final String filePath = getActivity().getFilesDir() + File.separator + "media" + File.separator + fileName; final File file = new File(filePath); // Create the folder if it doesn't exist. file.getParentFile().mkdirs(); return FileProvider.getUriForFile(getActivity(), "com.afwsamples.testdpc.fileprovider", file); } /** * Shows a list of primary user apps in a dialog. * * @param dialogTitle the title to show for the dialog * @param callback will be called with the list apps that the user has selected when he closes * the dialog. The callback is not fired if the user cancels. */ private void showManageLockTaskListPrompt(int dialogTitle, final ManageLockTaskListCallback callback) { if (getActivity() == null || getActivity().isFinishing()) { return; } Intent launcherIntent = new Intent(Intent.ACTION_MAIN); launcherIntent.addCategory(Intent.CATEGORY_LAUNCHER); final List<ResolveInfo> primaryUserAppList = mPackageManager.queryIntentActivities(launcherIntent, 0); if (primaryUserAppList.isEmpty()) { showToast(R.string.no_primary_app_available); } else { Collections.sort(primaryUserAppList, new ResolveInfo.DisplayNameComparator(mPackageManager)); final LockTaskAppInfoArrayAdapter appInfoArrayAdapter = new LockTaskAppInfoArrayAdapter(getActivity(), R.id.pkg_name, primaryUserAppList); ListView listView = new ListView(getActivity()); listView.setAdapter(appInfoArrayAdapter); listView.setOnItemClickListener(new AdapterView.OnItemClickListener() { @Override public void onItemClick(AdapterView<?> parent, View view, int position, long id) { appInfoArrayAdapter.onItemClick(parent, view, position, id); } }); new AlertDialog.Builder(getActivity()).setTitle(getString(dialogTitle)).setView(listView) .setPositiveButton(android.R.string.ok, new DialogInterface.OnClickListener() { @Override public void onClick(DialogInterface dialog, int which) { String[] lockTaskEnabledArray = appInfoArrayAdapter.getLockTaskList(); callback.onPositiveButtonClicked(lockTaskEnabledArray); } }).setNegativeButton(android.R.string.cancel, new DialogInterface.OnClickListener() { @Override public void onClick(DialogInterface dialog, int which) { dialog.dismiss(); } }).show(); } } /** * Shows a prompt to collect a package name and checks whether the lock task for the * corresponding app is permitted or not. */ private void showCheckLockTaskPermittedPrompt() { if (getActivity() == null || getActivity().isFinishing()) { return; } View view = getActivity().getLayoutInflater().inflate(R.layout.simple_edittext, null); final EditText input = (EditText) view.findViewById(R.id.input); input.setHint(getString(R.string.input_package_name_hints)); new AlertDialog.Builder(getActivity()).setTitle(getString(R.string.check_lock_task_permitted)).setView(view) .setPositiveButton(android.R.string.ok, new DialogInterface.OnClickListener() { @Override public void onClick(DialogInterface dialog, int which) { String packageName = input.getText().toString(); boolean isLockTaskPermitted = mDevicePolicyManager.isLockTaskPermitted(packageName); showToast(isLockTaskPermitted ? R.string.check_lock_task_permitted_result_permitted : R.string.check_lock_task_permitted_result_not_permitted); dialog.dismiss(); } }).setNegativeButton(android.R.string.cancel, new DialogInterface.OnClickListener() { @Override public void onClick(DialogInterface dialog, int which) { dialog.dismiss(); } }).show(); } /** * Shows a prompt to ask for a password to reset to and to set whether this requires * re-entry before any further changes and/or whether the password needs to be entered during * boot to start the user. */ private void showResetPasswordPrompt() { View dialogView = getActivity().getLayoutInflater().inflate(R.layout.reset_password_dialog, null); final EditText passwordView = (EditText) dialogView.findViewById(R.id.password); final CheckBox requireEntry = (CheckBox) dialogView.findViewById(R.id.require_password_entry_checkbox); final CheckBox requireOnBoot = (CheckBox) dialogView.findViewById(R.id.require_password_on_boot_checkbox); DialogInterface.OnClickListener resetListener = new DialogInterface.OnClickListener() { @Override public void onClick(DialogInterface dialogInterface, int which) { String password = passwordView.getText().toString(); if (TextUtils.isEmpty(password)) { password = null; } int flags = 0; flags |= requireEntry.isChecked() ? DevicePolicyManager.RESET_PASSWORD_REQUIRE_ENTRY : 0; flags |= requireOnBoot.isChecked() ? DevicePolicyManager.RESET_PASSWORD_DO_NOT_ASK_CREDENTIALS_ON_BOOT : 0; boolean ok = false; try { ok = mDevicePolicyManager.resetPassword(password, flags); } catch (IllegalArgumentException | IllegalStateException | SecurityException e) { // Not allowed to set password or trying to set a bad password, eg. 2 characters // where system minimum length is 4. Log.w(TAG, "Failed to reset password", e); } showToast(ok ? R.string.password_reset_success : R.string.password_reset_failed); } }; new AlertDialog.Builder(getActivity()).setTitle(R.string.reset_password).setView(dialogView) .setPositiveButton(android.R.string.ok, resetListener) .setNegativeButton(android.R.string.cancel, null).show(); } /** * Shows a prompt to ask for confirmation on wiping the data and also provide an option * to set if external storage and factory reset protection data also needs to wiped. */ private void showWipeDataPrompt() { final LayoutInflater inflater = getActivity().getLayoutInflater(); final View dialogView = inflater.inflate(R.layout.wipe_data_dialog_prompt, null); final CheckBox externalStorageCheckBox = (CheckBox) dialogView.findViewById(R.id.external_storage_checkbox); final CheckBox resetProtectionCheckBox = (CheckBox) dialogView.findViewById(R.id.reset_protection_checkbox); new AlertDialog.Builder(getActivity()).setTitle(R.string.wipe_data_title).setView(dialogView) .setPositiveButton(android.R.string.ok, new DialogInterface.OnClickListener() { @Override public void onClick(DialogInterface dialogInterface, int i) { int flags = 0; flags |= (externalStorageCheckBox.isChecked() ? DevicePolicyManager.WIPE_EXTERNAL_STORAGE : 0); flags |= (resetProtectionCheckBox.isChecked() ? DevicePolicyManager.WIPE_RESET_PROTECTION_DATA : 0); mDevicePolicyManager.wipeData(flags); } }).setNegativeButton(android.R.string.cancel, null).show(); } /** * Shows a prompt to ask for confirmation on removing device owner. */ private void showRemoveDeviceOwnerPrompt() { new AlertDialog.Builder(getActivity()).setTitle(R.string.remove_device_owner_title) .setMessage(R.string.remove_device_owner_confirmation) .setPositiveButton(android.R.string.ok, new DialogInterface.OnClickListener() { @Override public void onClick(DialogInterface dialogInterface, int i) { mDevicePolicyManager.clearDeviceOwnerApp(mPackageName); if (getActivity() != null && !getActivity().isFinishing()) { showToast(R.string.device_owner_removed); getActivity().finish(); } } }).setNegativeButton(android.R.string.cancel, null).show(); } /** * Shows a message box with the device wifi mac address. */ @TargetApi(Build.VERSION_CODES.N) private void showWifiMacAddress() { final String macAddress = mDevicePolicyManager.getWifiMacAddress(mAdminComponentName); final String message = macAddress != null ? macAddress : getResources().getString(R.string.show_wifi_mac_address_not_available_msg); new AlertDialog.Builder(getActivity()).setTitle(R.string.show_wifi_mac_address_title).setMessage(message) .setPositiveButton(android.R.string.ok, null).show(); } private void setPreferenceChangeListeners(String[] preferenceKeys) { for (String key : preferenceKeys) { findPreference(key).setOnPreferenceChangeListener(this); } } /** * Update the preference switch for {@link Settings.Global#STAY_ON_WHILE_PLUGGED_IN} setting. * * <p> * If either one of the {@link BatteryManager#BATTERY_PLUGGED_AC}, * {@link BatteryManager#BATTERY_PLUGGED_USB}, {@link BatteryManager#BATTERY_PLUGGED_WIRELESS} * values is set, we toggle the preference to true and update the setting value to * {@link #BATTERY_PLUGGED_ANY} * </p> */ private void updateStayOnWhilePluggedInPreference() { if (!mStayOnWhilePluggedInSwitchPreference.isEnabled()) { return; } boolean checked = false; final int currentState = Settings.Global.getInt(getActivity().getContentResolver(), Settings.Global.STAY_ON_WHILE_PLUGGED_IN, 0); checked = (currentState & (BatteryManager.BATTERY_PLUGGED_AC | BatteryManager.BATTERY_PLUGGED_USB | BatteryManager.BATTERY_PLUGGED_WIRELESS)) != 0; mDevicePolicyManager.setGlobalSetting(mAdminComponentName, Settings.Global.STAY_ON_WHILE_PLUGGED_IN, checked ? BATTERY_PLUGGED_ANY : DONT_STAY_ON); mStayOnWhilePluggedInSwitchPreference.setChecked(checked); } /** * Update the preference switch for {@link Settings.Secure#INSTALL_NON_MARKET_APPS} setting. * * <p> * If the user restriction {@link UserManager#DISALLOW_INSTALL_UNKNOWN_SOURCES} is set, then * we disable this preference. * </p> */ public void updateInstallNonMarketAppsPreference() { if (mUserManager.hasUserRestriction(DISALLOW_INSTALL_UNKNOWN_SOURCES)) { mInstallNonMarketAppsPreference.setCustomConstraint(R.string.user_restricted); } else { mInstallNonMarketAppsPreference.clearCustomConstraint(); } int isInstallNonMarketAppsAllowed = Settings.Secure.getInt(getActivity().getContentResolver(), Settings.Secure.INSTALL_NON_MARKET_APPS, 0); mInstallNonMarketAppsPreference.setChecked(isInstallNonMarketAppsAllowed == 0 ? false : true); } /** * Shows the default response for future runtime permission requests by applications, and lets * the user change the default value. */ @TargetApi(Build.VERSION_CODES.M) private void showSetPermissionPolicyDialog() { if (getActivity() == null || getActivity().isFinishing()) { return; } View setPermissionPolicyView = getActivity().getLayoutInflater().inflate(R.layout.set_permission_policy, null); final RadioGroup permissionGroup = (RadioGroup) setPermissionPolicyView .findViewById(R.id.set_permission_group); int permissionPolicy = mDevicePolicyManager.getPermissionPolicy(mAdminComponentName); switch (permissionPolicy) { case DevicePolicyManager.PERMISSION_POLICY_PROMPT: ((RadioButton) permissionGroup.findViewById(R.id.prompt)).toggle(); break; case DevicePolicyManager.PERMISSION_POLICY_AUTO_GRANT: ((RadioButton) permissionGroup.findViewById(R.id.accept)).toggle(); break; case DevicePolicyManager.PERMISSION_POLICY_AUTO_DENY: ((RadioButton) permissionGroup.findViewById(R.id.deny)).toggle(); break; } new AlertDialog.Builder(getActivity()).setTitle(getString(R.string.set_default_permission_policy)) .setView(setPermissionPolicyView) .setPositiveButton(android.R.string.ok, new DialogInterface.OnClickListener() { @Override public void onClick(DialogInterface dialog, int which) { int policy = 0; int checked = permissionGroup.getCheckedRadioButtonId(); switch (checked) { case (R.id.prompt): policy = DevicePolicyManager.PERMISSION_POLICY_PROMPT; break; case (R.id.accept): policy = DevicePolicyManager.PERMISSION_POLICY_AUTO_GRANT; break; case (R.id.deny): policy = DevicePolicyManager.PERMISSION_POLICY_AUTO_DENY; break; } mDevicePolicyManager.setPermissionPolicy(mAdminComponentName, policy); dialog.dismiss(); } }).show(); } /** * Shows a prompt that allows entering the account type for which account management should be * disabled or enabled. */ private void showSetDisableAccountManagementPrompt() { if (getActivity() == null || getActivity().isFinishing()) { return; } View view = LayoutInflater.from(getActivity()).inflate(R.layout.simple_edittext, null); final EditText input = (EditText) view.findViewById(R.id.input); input.setHint(R.string.account_type_hint); new AlertDialog.Builder(getActivity()).setTitle(R.string.set_disable_account_management).setView(view) .setPositiveButton(R.string.disable, new DialogInterface.OnClickListener() { @Override public void onClick(DialogInterface dialogInterface, int i) { String accountType = input.getText().toString(); setDisableAccountManagement(accountType, true); } }).setNeutralButton(R.string.enable, new DialogInterface.OnClickListener() { @Override public void onClick(DialogInterface dialogInterface, int i) { String accountType = input.getText().toString(); setDisableAccountManagement(accountType, false); } }).setNegativeButton(android.R.string.cancel, null /* Nothing to do */).show(); } private void setDisableAccountManagement(String accountType, boolean disabled) { if (!TextUtils.isEmpty(accountType)) { mDevicePolicyManager.setAccountManagementDisabled(mAdminComponentName, accountType, disabled); showToast(disabled ? R.string.account_management_disabled : R.string.account_management_enabled, accountType); return; } showToast(R.string.fail_to_set_account_management); } /** * Shows a list of account types that is disabled for account management. */ private void showDisableAccountTypeList() { if (getActivity() == null || getActivity().isFinishing()) { return; } String[] disabledAccountTypeList = mDevicePolicyManager.getAccountTypesWithManagementDisabled(); Arrays.sort(disabledAccountTypeList, String.CASE_INSENSITIVE_ORDER); if (disabledAccountTypeList == null || disabledAccountTypeList.length == 0) { showToast(R.string.no_disabled_account); } else { new AlertDialog.Builder(getActivity()).setTitle(R.string.list_of_disabled_account_types) .setAdapter(new ArrayAdapter<String>(getActivity(), android.R.layout.simple_list_item_1, android.R.id.text1, disabledAccountTypeList), null) .setPositiveButton(android.R.string.ok, null).show(); } } /** * For user creation: * Shows a prompt asking for the username of the new user and whether the setup wizard should * be skipped. */ @TargetApi(Build.VERSION_CODES.N) private void showCreateAndManageUserPrompt() { if (getActivity() == null || getActivity().isFinishing()) { return; } final View dialogView = getActivity().getLayoutInflater() .inflate(R.layout.create_and_manage_user_dialog_prompt, null); final EditText userNameEditText = (EditText) dialogView.findViewById(R.id.user_name); userNameEditText.setHint(R.string.enter_username_hint); final CheckBox skipSetupWizardCheckBox = (CheckBox) dialogView .findViewById(R.id.skip_setup_wizard_checkbox); new AlertDialog.Builder(getActivity()).setTitle(R.string.create_and_manage_user).setView(dialogView) .setPositiveButton(android.R.string.ok, new DialogInterface.OnClickListener() { @Override public void onClick(DialogInterface dialogInterface, int i) { String name = userNameEditText.getText().toString(); if (!TextUtils.isEmpty(name)) { int flags = skipSetupWizardCheckBox.isChecked() ? DevicePolicyManager.SKIP_SETUP_WIZARD : 0; UserHandle userHandle = mDevicePolicyManager.createAndManageUser(mAdminComponentName, name, mAdminComponentName, null, flags); if (userHandle != null) { long serialNumber = mUserManager.getSerialNumberForUser(userHandle); showToast(R.string.user_created, serialNumber); return; } showToast(R.string.failed_to_create_user); } } }).setNegativeButton(android.R.string.cancel, null).show(); } /** * For user removal: * Shows a prompt for a user serial number. The associated user will be removed. */ private void showRemoveUserPrompt() { if (getActivity() == null || getActivity().isFinishing()) { return; } View view = LayoutInflater.from(getActivity()).inflate(R.layout.simple_edittext, null); final EditText input = (EditText) view.findViewById(R.id.input); input.setHint(R.string.enter_user_id); input.setRawInputType(InputType.TYPE_CLASS_NUMBER | InputType.TYPE_NUMBER_FLAG_SIGNED); new AlertDialog.Builder(getActivity()).setTitle(R.string.remove_user).setView(view) .setPositiveButton(android.R.string.ok, new DialogInterface.OnClickListener() { @Override public void onClick(DialogInterface dialogInterface, int i) { boolean success = false; long serialNumber = -1; try { serialNumber = Long.parseLong(input.getText().toString()); UserHandle userHandle = mUserManager.getUserForSerialNumber(serialNumber); if (userHandle != null) { success = mDevicePolicyManager.removeUser(mAdminComponentName, userHandle); } } catch (NumberFormatException e) { // Error message is printed in the next line. } showToast(success ? R.string.user_removed : R.string.failed_to_remove_user); } }).show(); } /** * Asks for the package name whose uninstallation should be blocked / unblocked. */ private void showBlockUninstallationByPackageNamePrompt() { Activity activity = getActivity(); if (activity == null || activity.isFinishing()) { return; } View view = LayoutInflater.from(activity).inflate(R.layout.simple_edittext, null); final EditText input = (EditText) view.findViewById(R.id.input); input.setHint(getString(R.string.input_package_name_hints)); AlertDialog.Builder builder = new AlertDialog.Builder(activity); builder.setTitle(R.string.block_uninstallation_title).setView(view) .setPositiveButton(R.string.block, new DialogInterface.OnClickListener() { @Override public void onClick(DialogInterface dialogInterface, int i) { String pkgName = input.getText().toString(); if (!TextUtils.isEmpty(pkgName)) { mDevicePolicyManager.setUninstallBlocked(mAdminComponentName, pkgName, true); showToast(R.string.uninstallation_blocked, pkgName); } else { showToast(R.string.block_uninstallation_failed_invalid_pkgname); } } }).setNeutralButton(R.string.unblock, new DialogInterface.OnClickListener() { @Override public void onClick(DialogInterface dialogInterface, int i) { String pkgName = input.getText().toString(); if (!TextUtils.isEmpty(pkgName)) { mDevicePolicyManager.setUninstallBlocked(mAdminComponentName, pkgName, false); showToast(R.string.uninstallation_allowed, pkgName); } else { showToast(R.string.block_uninstallation_failed_invalid_pkgname); } } }).setNegativeButton(android.R.string.cancel, null).show(); } private void loadAppStatus() { boolean isProfileOwner = mDevicePolicyManager.isProfileOwnerApp(mPackageName); boolean isDeviceOwner = mDevicePolicyManager.isDeviceOwnerApp(mPackageName); int deviceOwnerStatusStringId = R.string.this_is_not_a_device_owner; if (isProfileOwner) { deviceOwnerStatusStringId = R.string.this_is_a_profile_owner; } else if (isDeviceOwner) { deviceOwnerStatusStringId = R.string.this_is_a_device_owner; } findPreference(DEVICE_OWNER_STATUS_KEY).setSummary(deviceOwnerStatusStringId); } @TargetApi(Build.VERSION_CODES.M) private void loadSecurityPatch() { Preference securityPatchPreference = findPreference(SECURITY_PATCH_KEY); if (!securityPatchPreference.isEnabled()) { return; } String buildSecurityPatch = Build.VERSION.SECURITY_PATCH; final Date date; try { date = new SimpleDateFormat(SECURITY_PATCH_FORMAT).parse(buildSecurityPatch); } catch (ParseException e) { securityPatchPreference.setSummary(getString(R.string.invalid_security_patch, buildSecurityPatch)); return; } String display = DateFormat.getDateInstance(DateFormat.MEDIUM).format(date); securityPatchPreference.setSummary(display); } @TargetApi(Build.VERSION_CODES.LOLLIPOP) private void reloadCameraDisableUi() { boolean isCameraDisabled = mDevicePolicyManager.getCameraDisabled(mAdminComponentName); mDisableCameraSwitchPreference.setChecked(isCameraDisabled); } @TargetApi(Build.VERSION_CODES.N) private void reloadEnableProcessLoggingUi() { if (mEnableProcessLoggingPreference.isEnabled()) { boolean isProcessLoggingEnabled = mDevicePolicyManager.isSecurityLoggingEnabled(mAdminComponentName); mEnableProcessLoggingPreference.setChecked(isProcessLoggingEnabled); DpcPreference requestLogs = (DpcPreference) findPreference((REQUEST_PROCESS_LOGS)); if (isProcessLoggingEnabled) { requestLogs.clearCustomConstraint(); } else { requestLogs.setCustomConstraint(R.string.requires_process_logs); } } } @TargetApi(Build.VERSION_CODES.LOLLIPOP) private void reloadScreenCaptureDisableUi() { boolean isScreenCaptureDisabled = mDevicePolicyManager.getScreenCaptureDisabled(mAdminComponentName); mDisableScreenCaptureSwitchPreference.setChecked(isScreenCaptureDisabled); } @TargetApi(Build.VERSION_CODES.LOLLIPOP) private void reloadSetAutoTimeRequiredUi() { if (mDevicePolicyManager.isDeviceOwnerApp(mPackageName)) { boolean isAutoTimeRequired = mDevicePolicyManager.getAutoTimeRequired(); mSetAutoTimeRequiredPreference.setChecked(isAutoTimeRequired); } } @TargetApi(Build.VERSION_CODES.LOLLIPOP) private void reloadMuteAudioUi() { final boolean isAudioMuted = mDevicePolicyManager.isMasterVolumeMuted(mAdminComponentName); mMuteAudioSwitchPreference.setChecked(isAudioMuted); } /** * Shows a prompt to ask for package name which is used to enable a system app. */ private void showEnableSystemAppByPackageNamePrompt() { if (getActivity() == null || getActivity().isFinishing()) { return; } LinearLayout inputContainer = (LinearLayout) getActivity().getLayoutInflater() .inflate(R.layout.simple_edittext, null); final EditText editText = (EditText) inputContainer.findViewById(R.id.input); editText.setHint(getString(R.string.enable_system_apps_by_package_name_hints)); new AlertDialog.Builder(getActivity()).setTitle(getString(R.string.enable_system_apps_title)) .setView(inputContainer) .setPositiveButton(android.R.string.ok, new DialogInterface.OnClickListener() { @Override public void onClick(DialogInterface dialog, int which) { final String packageName = editText.getText().toString(); try { mDevicePolicyManager.enableSystemApp(mAdminComponentName, packageName); showToast(R.string.enable_system_apps_by_package_name_success_msg, packageName); } catch (IllegalArgumentException e) { showToast(R.string.enable_system_apps_by_package_name_error); } finally { dialog.dismiss(); } } }).setNegativeButton(android.R.string.cancel, null).show(); } /** * Shows the file viewer for importing a certificate. */ private void showFileViewerForImportingCertificate(int requestCode) { Intent certIntent = new Intent(Intent.ACTION_GET_CONTENT); certIntent.setTypeAndNormalize("*/*"); try { startActivityForResult(certIntent, requestCode); } catch (ActivityNotFoundException e) { Log.e(TAG, "showFileViewerForImportingCertificate: ", e); } } /** * Imports a certificate to the managed profile. If the provided password failed to decrypt the * given certificate, shows a try again prompt. Otherwise, shows a prompt for the certificate * alias. * * @param intent Intent that contains the certificate data uri. * @param password The password to decrypt the certificate. */ private void importKeyCertificateFromIntent(Intent intent, String password) { importKeyCertificateFromIntent(intent, password, 0 /* first try */); } /** * Imports a certificate to the managed profile. If the provided decryption password is * incorrect, shows a try again prompt. Otherwise, shows a prompt for the certificate alias. * * @param intent Intent that contains the certificate data uri. * @param password The password to decrypt the certificate. * @param attempts The number of times user entered incorrect password. */ private void importKeyCertificateFromIntent(Intent intent, String password, int attempts) { if (getActivity() == null || getActivity().isFinishing()) { return; } Uri data = null; if (intent != null && (data = intent.getData()) != null) { // If the password is null, try to decrypt the certificate with an empty password. if (password == null) { password = ""; } try { CertificateUtil.PKCS12ParseInfo parseInfo = CertificateUtil .parsePKCS12Certificate(getActivity().getContentResolver(), data, password); showPromptForKeyCertificateAlias(parseInfo.privateKey, parseInfo.certificate, parseInfo.alias); } catch (KeyStoreException | FileNotFoundException | CertificateException | UnrecoverableKeyException | NoSuchAlgorithmException e) { Log.e(TAG, "Unable to load key", e); } catch (IOException e) { showPromptForCertificatePassword(intent, ++attempts); } catch (ClassCastException e) { showToast(R.string.not_a_key_certificate); } } } /** * Shows a prompt to ask for the certificate password. If the certificate password is correct, * import the private key and certificate. * * @param intent Intent that contains the certificate data uri. * @param attempts The number of times user entered incorrect password. */ private void showPromptForCertificatePassword(final Intent intent, final int attempts) { if (getActivity() == null || getActivity().isFinishing()) { return; } View passwordInputView = getActivity().getLayoutInflater().inflate(R.layout.certificate_password_prompt, null); final EditText input = (EditText) passwordInputView.findViewById(R.id.password_input); if (attempts > 1) { passwordInputView.findViewById(R.id.incorrect_password).setVisibility(View.VISIBLE); } new AlertDialog.Builder(getActivity()).setTitle(getString(R.string.certificate_password_prompt_title)) .setView(passwordInputView) .setPositiveButton(android.R.string.ok, new DialogInterface.OnClickListener() { @Override public void onClick(DialogInterface dialog, int which) { String userPassword = input.getText().toString(); importKeyCertificateFromIntent(intent, userPassword, attempts); dialog.dismiss(); } }).setNegativeButton(android.R.string.cancel, new DialogInterface.OnClickListener() { @Override public void onClick(DialogInterface dialog, int which) { dialog.cancel(); } }).show(); } /** * Shows a prompt to ask for the certificate alias. This alias will be imported together with * the private key and certificate. * * @param key The private key of a certificate. * @param certificate The certificate will be imported. * @param alias A name that represents the certificate in the profile. */ private void showPromptForKeyCertificateAlias(final PrivateKey key, final Certificate certificate, String alias) { if (getActivity() == null || getActivity().isFinishing() || key == null || certificate == null) { return; } View passwordInputView = getActivity().getLayoutInflater().inflate(R.layout.certificate_alias_prompt, null); final EditText input = (EditText) passwordInputView.findViewById(R.id.alias_input); if (!TextUtils.isEmpty(alias)) { input.setText(alias); input.selectAll(); } new AlertDialog.Builder(getActivity()).setTitle(getString(R.string.certificate_alias_prompt_title)) .setView(passwordInputView) .setPositiveButton(android.R.string.ok, new DialogInterface.OnClickListener() { @Override public void onClick(DialogInterface dialog, int which) { String alias = input.getText().toString(); if (mDevicePolicyManager.installKeyPair(mAdminComponentName, key, certificate, alias) == true) { showToast(R.string.certificate_added, alias); } else { showToast(R.string.certificate_add_failed, alias); } dialog.dismiss(); } }).setNegativeButton(android.R.string.cancel, new DialogInterface.OnClickListener() { @Override public void onClick(DialogInterface dialog, int which) { dialog.cancel(); } }).show(); } /** * Selects a private/public key pair to uninstall, using the system dialog to choose * an alias. * * Once the alias is chosen and deleted, a {@link Toast} shows status- success or failure. */ @TargetApi(Build.VERSION_CODES.N) private void choosePrivateKeyForRemoval() { KeyChain.choosePrivateKeyAlias(getActivity(), new KeyChainAliasCallback() { @Override public void alias(String alias) { if (alias == null) { // No value was chosen. return; } final boolean removed = mDevicePolicyManager.removeKeyPair(mAdminComponentName, alias); getActivity().runOnUiThread(new Runnable() { @Override public void run() { if (removed) { showToast(R.string.remove_keypair_successfully); } else { showToast(R.string.remove_keypair_fail); } } }); } }, /* keyTypes[] */ null, /* issuers[] */ null, /* uri */ null, /* alias */ null); } /** * Imports a CA certificate from the given data URI. * * @param intent Intent that contains the CA data URI. */ private void importCaCertificateFromIntent(Intent intent) { if (getActivity() == null || getActivity().isFinishing()) { return; } Uri data = null; if (intent != null && (data = intent.getData()) != null) { boolean isCaInstalled = false; try { InputStream certificateInputStream = getActivity().getContentResolver().openInputStream(data); if (certificateInputStream != null) { ByteArrayOutputStream byteBuffer = new ByteArrayOutputStream(); byte[] buffer = new byte[DEFAULT_BUFFER_SIZE]; int len = 0; while ((len = certificateInputStream.read(buffer)) > 0) { byteBuffer.write(buffer, 0, len); } isCaInstalled = mDevicePolicyManager.installCaCert(mAdminComponentName, byteBuffer.toByteArray()); } } catch (IOException e) { Log.e(TAG, "importCaCertificateFromIntent: ", e); } showToast(isCaInstalled ? R.string.install_ca_successfully : R.string.install_ca_fail); } } @Override public void onActivityResult(int requestCode, int resultCode, Intent data) { super.onActivityResult(requestCode, resultCode, data); if (resultCode == Activity.RESULT_OK) { switch (requestCode) { case INSTALL_KEY_CERTIFICATE_REQUEST_CODE: importKeyCertificateFromIntent(data, ""); break; case INSTALL_CA_CERTIFICATE_REQUEST_CODE: importCaCertificateFromIntent(data); break; case CAPTURE_IMAGE_REQUEST_CODE: showFragment( MediaDisplayFragment.newInstance(MediaDisplayFragment.REQUEST_DISPLAY_IMAGE, mImageUri)); break; case CAPTURE_VIDEO_REQUEST_CODE: showFragment( MediaDisplayFragment.newInstance(MediaDisplayFragment.REQUEST_DISPLAY_VIDEO, mVideoUri)); break; } } } /** * Shows a list of installed CA certificates. */ private void showCaCertificateList() { if (getActivity() == null || getActivity().isFinishing()) { return; } // Avoid starting the same task twice. if (mShowCaCertificateListTask != null && !mShowCaCertificateListTask.isCancelled()) { mShowCaCertificateListTask.cancel(true); } mShowCaCertificateListTask = new ShowCaCertificateListTask(); mShowCaCertificateListTask.execute(); } /** * Displays an alert dialog that allows the user to select applications from all non-system * applications installed on the current profile. After the user selects an app, this app can't * be uninstallation. */ private void showBlockUninstallationPrompt() { Activity activity = getActivity(); if (activity == null || activity.isFinishing()) { return; } List<ApplicationInfo> applicationInfoList = mPackageManager.getInstalledApplications(0 /* No flag */); List<ResolveInfo> resolveInfoList = new ArrayList<ResolveInfo>(); Collections.sort(applicationInfoList, new ApplicationInfo.DisplayNameComparator(mPackageManager)); for (ApplicationInfo applicationInfo : applicationInfoList) { // Ignore system apps because they can't be uninstalled. if ((applicationInfo.flags & ApplicationInfo.FLAG_SYSTEM) == 0) { ResolveInfo resolveInfo = new ResolveInfo(); resolveInfo.resolvePackageName = applicationInfo.packageName; resolveInfoList.add(resolveInfo); } } final BlockUninstallationInfoArrayAdapter blockUninstallationInfoArrayAdapter = new BlockUninstallationInfoArrayAdapter( getActivity(), R.id.pkg_name, resolveInfoList); ListView listview = new ListView(getActivity()); listview.setAdapter(blockUninstallationInfoArrayAdapter); listview.setOnItemClickListener(new AdapterView.OnItemClickListener() { public void onItemClick(AdapterView<?> parent, View view, int pos, long id) { blockUninstallationInfoArrayAdapter.onItemClick(parent, view, pos, id); } }); new AlertDialog.Builder(getActivity()).setTitle(R.string.block_uninstallation_title).setView(listview) .setPositiveButton(R.string.close, null /* Nothing to do */).show(); } /** * Shows an alert dialog which displays a list of disabled system apps. Clicking an app in the * dialog enables the app. */ private void showEnableSystemAppsPrompt() { // Disabled system apps list = {All system apps} - {Enabled system apps} final List<String> disabledSystemApps = new ArrayList<String>(); // This list contains both enabled and disabled apps. List<ApplicationInfo> allApps = mPackageManager .getInstalledApplications(PackageManager.GET_UNINSTALLED_PACKAGES); Collections.sort(allApps, new ApplicationInfo.DisplayNameComparator(mPackageManager)); // This list contains all enabled apps. List<ApplicationInfo> enabledApps = mPackageManager.getInstalledApplications(0 /* Default flags */); Set<String> enabledAppsPkgNames = new HashSet<String>(); for (ApplicationInfo applicationInfo : enabledApps) { enabledAppsPkgNames.add(applicationInfo.packageName); } for (ApplicationInfo applicationInfo : allApps) { // Interested in disabled system apps only. if (!enabledAppsPkgNames.contains(applicationInfo.packageName) && (applicationInfo.flags & ApplicationInfo.FLAG_SYSTEM) != 0) { disabledSystemApps.add(applicationInfo.packageName); } } if (disabledSystemApps.isEmpty()) { showToast(R.string.no_disabled_system_apps); } else { AppInfoArrayAdapter appInfoArrayAdapter = new AppInfoArrayAdapter(getActivity(), R.id.pkg_name, disabledSystemApps, true); new AlertDialog.Builder(getActivity()).setTitle(getString(R.string.enable_system_apps_title)) .setAdapter(appInfoArrayAdapter, new DialogInterface.OnClickListener() { @Override public void onClick(DialogInterface dialog, int position) { String packageName = disabledSystemApps.get(position); mDevicePolicyManager.enableSystemApp(mAdminComponentName, packageName); showToast(R.string.enable_system_apps_by_package_name_success_msg, packageName); } }).show(); } } /** * Shows an alert dialog which displays a list hidden / non-hidden apps. Clicking an app in the * dialog enables the app. */ private void showHideAppsPrompt(final boolean showHiddenApps) { final List<String> showApps = new ArrayList<>(); if (showHiddenApps) { // Find all hidden packages using the GET_UNINSTALLED_PACKAGES flag for (ApplicationInfo applicationInfo : getAllInstalledApplicationsSorted()) { if (mDevicePolicyManager.isApplicationHidden(mAdminComponentName, applicationInfo.packageName)) { showApps.add(applicationInfo.packageName); } } } else { // Find all non-hidden apps with a launcher icon for (ResolveInfo res : getAllLauncherIntentResolversSorted()) { if (!showApps.contains(res.activityInfo.packageName) && !mDevicePolicyManager .isApplicationHidden(mAdminComponentName, res.activityInfo.packageName)) { showApps.add(res.activityInfo.packageName); } } } if (showApps.isEmpty()) { showToast(showHiddenApps ? R.string.unhide_apps_empty : R.string.hide_apps_empty); } else { AppInfoArrayAdapter appInfoArrayAdapter = new AppInfoArrayAdapter(getActivity(), R.id.pkg_name, showApps, true); final int dialogTitleResId; final int successResId; final int failureResId; if (showHiddenApps) { // showing a dialog to unhide an app dialogTitleResId = R.string.unhide_apps_title; successResId = R.string.unhide_apps_success; failureResId = R.string.unhide_apps_failure; } else { // showing a dialog to hide an app dialogTitleResId = R.string.hide_apps_title; successResId = R.string.hide_apps_success; failureResId = R.string.hide_apps_failure; } new AlertDialog.Builder(getActivity()).setTitle(getString(dialogTitleResId)) .setAdapter(appInfoArrayAdapter, new DialogInterface.OnClickListener() { @Override public void onClick(DialogInterface dialog, int position) { String packageName = showApps.get(position); if (mDevicePolicyManager.setApplicationHidden(mAdminComponentName, packageName, !showHiddenApps)) { showToast(successResId, packageName); } else { showToast(getString(failureResId, packageName), Toast.LENGTH_LONG); } } }).show(); } } /** * Shows an alert dialog which displays a list of suspended/non-suspended apps. */ @TargetApi(Build.VERSION_CODES.N) private void showSuspendAppsPrompt(final boolean forUnsuspending) { final List<String> showApps = new ArrayList<>(); if (forUnsuspending) { // Find all suspended packages using the GET_UNINSTALLED_PACKAGES flag. for (ApplicationInfo applicationInfo : getAllInstalledApplicationsSorted()) { if (isPackageSuspended(applicationInfo.packageName)) { showApps.add(applicationInfo.packageName); } } } else { // Find all non-suspended apps with a launcher icon. for (ResolveInfo res : getAllLauncherIntentResolversSorted()) { if (!showApps.contains(res.activityInfo.packageName) && !isPackageSuspended(res.activityInfo.packageName)) { showApps.add(res.activityInfo.packageName); } } } if (showApps.isEmpty()) { showToast(forUnsuspending ? R.string.unsuspend_apps_empty : R.string.suspend_apps_empty); } else { AppInfoArrayAdapter appInfoArrayAdapter = new AppInfoArrayAdapter(getActivity(), R.id.pkg_name, showApps, true); final int dialogTitleResId; final int successResId; final int failureResId; if (forUnsuspending) { // Showing a dialog to unsuspend an app. dialogTitleResId = R.string.unsuspend_apps_title; successResId = R.string.unsuspend_apps_success; failureResId = R.string.unsuspend_apps_failure; } else { // Showing a dialog to suspend an app. dialogTitleResId = R.string.suspend_apps_title; successResId = R.string.suspend_apps_success; failureResId = R.string.suspend_apps_failure; } new AlertDialog.Builder(getActivity()).setTitle(getString(dialogTitleResId)) .setAdapter(appInfoArrayAdapter, new DialogInterface.OnClickListener() { @Override public void onClick(DialogInterface dialog, int position) { String packageName = showApps.get(position); if (mDevicePolicyManager.setPackagesSuspended(mAdminComponentName, new String[] { packageName }, !forUnsuspending).length == 0) { showToast(successResId, packageName); } else { showToast(getString(failureResId, packageName), Toast.LENGTH_LONG); } } }).show(); } } @TargetApi(Build.VERSION_CODES.N) private boolean isPackageSuspended(String packageName) { try { return mDevicePolicyManager.isPackageSuspended(mAdminComponentName, packageName); } catch (PackageManager.NameNotFoundException e) { Log.e(TAG, "Unable check if package is suspended", e); return false; } } private List<ResolveInfo> getAllLauncherIntentResolversSorted() { final Intent launcherIntent = new Intent(Intent.ACTION_MAIN); launcherIntent.addCategory(Intent.CATEGORY_LAUNCHER); final List<ResolveInfo> launcherIntentResolvers = mPackageManager.queryIntentActivities(launcherIntent, 0); Collections.sort(launcherIntentResolvers, new ResolveInfo.DisplayNameComparator(mPackageManager)); return launcherIntentResolvers; } private List<ApplicationInfo> getAllInstalledApplicationsSorted() { List<ApplicationInfo> allApps = mPackageManager .getInstalledApplications(PackageManager.GET_UNINSTALLED_PACKAGES); Collections.sort(allApps, new ApplicationInfo.DisplayNameComparator(mPackageManager)); return allApps; } private void showToast(int msgId, Object... args) { showToast(getString(msgId, args)); } private void showToast(String msg) { showToast(msg, Toast.LENGTH_SHORT); } private void showToast(String msg, int duration) { Activity activity = getActivity(); if (activity == null || activity.isFinishing()) { return; } Toast.makeText(activity, msg, duration).show(); } /** * Gets all the accessibility services. After all the accessibility services are retrieved, the * result is displayed in a popup. */ private class GetAccessibilityServicesTask extends GetAvailableComponentsTask<AccessibilityServiceInfo> { private AccessibilityManager mAccessibilityManager; public GetAccessibilityServicesTask() { super(getActivity(), R.string.set_accessibility_services); mAccessibilityManager = (AccessibilityManager) getActivity() .getSystemService(Context.ACCESSIBILITY_SERVICE); } @Override protected List<AccessibilityServiceInfo> doInBackground(Void... voids) { return mAccessibilityManager.getInstalledAccessibilityServiceList(); } @Override protected List<ResolveInfo> getResolveInfoListFromAvailableComponents( List<AccessibilityServiceInfo> accessibilityServiceInfoList) { HashSet<String> packageSet = new HashSet<>(); List<ResolveInfo> resolveInfoList = new ArrayList<>(); for (AccessibilityServiceInfo accessibilityServiceInfo : accessibilityServiceInfoList) { ResolveInfo resolveInfo = accessibilityServiceInfo.getResolveInfo(); // Some apps may contain multiple accessibility services. Make sure that the package // name is unique in the return list. if (!packageSet.contains(resolveInfo.serviceInfo.packageName)) { resolveInfoList.add(resolveInfo); packageSet.add(resolveInfo.serviceInfo.packageName); } } return resolveInfoList; } @Override protected List<String> getPermittedComponentsList() { return mDevicePolicyManager.getPermittedAccessibilityServices(mAdminComponentName); } @Override protected void setPermittedComponentsList(List<String> permittedAccessibilityServices) { boolean result = mDevicePolicyManager.setPermittedAccessibilityServices(mAdminComponentName, permittedAccessibilityServices); int successMsgId = (permittedAccessibilityServices == null) ? R.string.all_accessibility_services_enabled : R.string.set_accessibility_services_successful; showToast(result ? successMsgId : R.string.set_accessibility_services_fail); } } /** * Gets all the input methods and displays them in a prompt. */ private class GetInputMethodsTask extends GetAvailableComponentsTask<InputMethodInfo> { private InputMethodManager mInputMethodManager; public GetInputMethodsTask() { super(getActivity(), R.string.set_input_methods); mInputMethodManager = (InputMethodManager) getActivity().getSystemService(Context.INPUT_METHOD_SERVICE); } @Override protected List<InputMethodInfo> doInBackground(Void... voids) { return mInputMethodManager.getInputMethodList(); } @Override protected List<ResolveInfo> getResolveInfoListFromAvailableComponents( List<InputMethodInfo> inputMethodsInfoList) { List<ResolveInfo> inputMethodsResolveInfoList = new ArrayList<>(); for (InputMethodInfo inputMethodInfo : inputMethodsInfoList) { ResolveInfo resolveInfo = new ResolveInfo(); resolveInfo.serviceInfo = inputMethodInfo.getServiceInfo(); resolveInfo.resolvePackageName = inputMethodInfo.getPackageName(); inputMethodsResolveInfoList.add(resolveInfo); } return inputMethodsResolveInfoList; } @Override protected List<String> getPermittedComponentsList() { return mDevicePolicyManager.getPermittedInputMethods(mAdminComponentName); } @Override protected void setPermittedComponentsList(List<String> permittedInputMethods) { boolean result = mDevicePolicyManager.setPermittedInputMethods(mAdminComponentName, permittedInputMethods); int successMsgId = (permittedInputMethods == null) ? R.string.all_input_methods_enabled : R.string.set_input_methods_successful; showToast(result ? successMsgId : R.string.set_input_methods_fail); } } /** * Gets all CA certificates and displays them in a prompt. */ private class ShowCaCertificateListTask extends AsyncTask<Void, Void, String[]> { @Override protected String[] doInBackground(Void... params) { return getCaCertificateSubjectDnList(); } @Override protected void onPostExecute(String[] installedCaCertificateDnList) { if (getActivity() == null || getActivity().isFinishing()) { return; } if (installedCaCertificateDnList == null) { showToast(R.string.no_ca_certificate); } else { new AlertDialog.Builder(getActivity()).setTitle(getString(R.string.installed_ca_title)) .setItems(installedCaCertificateDnList, null).show(); } } private String[] getCaCertificateSubjectDnList() { List<byte[]> installedCaCerts = mDevicePolicyManager.getInstalledCaCerts(mAdminComponentName); String[] caSubjectDnList = null; if (installedCaCerts.size() > 0) { caSubjectDnList = new String[installedCaCerts.size()]; int i = 0; for (byte[] installedCaCert : installedCaCerts) { try { X509Certificate certificate = (X509Certificate) CertificateFactory .getInstance(X509_CERT_TYPE) .generateCertificate(new ByteArrayInputStream(installedCaCert)); caSubjectDnList[i++] = certificate.getSubjectDN().getName(); } catch (CertificateException e) { Log.e(TAG, "getCaCertificateSubjectDnList: ", e); } } } return caSubjectDnList; } } private void showFragment(final Fragment fragment) { FragmentManager fragmentManager = getFragmentManager(); fragmentManager.beginTransaction().addToBackStack(PolicyManagementFragment.class.getName()) .replace(R.id.container, fragment).commit(); } private void showFragment(final Fragment fragment, String tag) { FragmentManager fragmentManager = getFragmentManager(); fragmentManager.beginTransaction().addToBackStack(PolicyManagementFragment.class.getName()) .replace(R.id.container, fragment, tag).commit(); } private void startKioskMode(String[] lockTaskArray) { // start locked activity Intent launchIntent = new Intent(getActivity(), KioskModeActivity.class); launchIntent.putExtra(KioskModeActivity.LOCKED_APP_PACKAGE_LIST, lockTaskArray); launchIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); mPackageManager.setComponentEnabledSetting( new ComponentName(mPackageName, KioskModeActivity.class.getName()), PackageManager.COMPONENT_ENABLED_STATE_ENABLED, PackageManager.DONT_KILL_APP); startActivity(launchIntent); getActivity().finish(); } private void showWifiConfigCreationDialog() { WifiConfigCreationDialog dialog = WifiConfigCreationDialog.newInstance(); dialog.show(getFragmentManager(), TAG_WIFI_CONFIG_CREATION); } private void showEapTlsWifiConfigCreationDialog() { DialogFragment fragment = WifiEapTlsCreateDialogFragment.newInstance(null); fragment.show(getFragmentManager(), WifiEapTlsCreateDialogFragment.class.getName()); } @TargetApi(Build.VERSION_CODES.N) private void reboot() { if (mTelephonyManager.getCallState() != TelephonyManager.CALL_STATE_IDLE) { showToast(R.string.reboot_error_msg); return; } mDevicePolicyManager.reboot(mAdminComponentName); } abstract class ManageLockTaskListCallback { public abstract void onPositiveButtonClicked(String[] lockTaskArray); } }