Utils.java revision e35cc9733194b380637728d39c14dcfc0adee84b
1d5e4c42542dd96d8940912cc20dff20fa48da0d9Sander Alewijnse/* 2d5e4c42542dd96d8940912cc20dff20fa48da0d9Sander Alewijnse * Copyright 2014, The Android Open Source Project 3d5e4c42542dd96d8940912cc20dff20fa48da0d9Sander Alewijnse * 4d5e4c42542dd96d8940912cc20dff20fa48da0d9Sander Alewijnse * Licensed under the Apache License, Version 2.0 (the "License"); 5d5e4c42542dd96d8940912cc20dff20fa48da0d9Sander Alewijnse * you may not use this file except in compliance with the License. 6d5e4c42542dd96d8940912cc20dff20fa48da0d9Sander Alewijnse * You may obtain a copy of the License at 7d5e4c42542dd96d8940912cc20dff20fa48da0d9Sander Alewijnse * 8d5e4c42542dd96d8940912cc20dff20fa48da0d9Sander Alewijnse * http://www.apache.org/licenses/LICENSE-2.0 9d5e4c42542dd96d8940912cc20dff20fa48da0d9Sander Alewijnse * 10d5e4c42542dd96d8940912cc20dff20fa48da0d9Sander Alewijnse * Unless required by applicable law or agreed to in writing, software 11d5e4c42542dd96d8940912cc20dff20fa48da0d9Sander Alewijnse * distributed under the License is distributed on an "AS IS" BASIS, 12d5e4c42542dd96d8940912cc20dff20fa48da0d9Sander Alewijnse * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13d5e4c42542dd96d8940912cc20dff20fa48da0d9Sander Alewijnse * See the License for the specific language governing permissions and 14d5e4c42542dd96d8940912cc20dff20fa48da0d9Sander Alewijnse * limitations under the License. 15d5e4c42542dd96d8940912cc20dff20fa48da0d9Sander Alewijnse */ 16d5e4c42542dd96d8940912cc20dff20fa48da0d9Sander Alewijnse 17d5e4c42542dd96d8940912cc20dff20fa48da0d9Sander Alewijnsepackage com.android.managedprovisioning; 18d5e4c42542dd96d8940912cc20dff20fa48da0d9Sander Alewijnse 193128ba4542f3c4c90790af0564e75950c8900961Alan Treadwayimport static android.app.admin.DevicePolicyManager.ACTION_PROVISION_MANAGED_DEVICE; 203128ba4542f3c4c90790af0564e75950c8900961Alan Treadwayimport static android.app.admin.DevicePolicyManager.ACTION_PROVISION_MANAGED_PROFILE; 213128ba4542f3c4c90790af0564e75950c8900961Alan Treadwayimport static android.app.admin.DevicePolicyManager.ACTION_PROVISION_MANAGED_SHAREABLE_DEVICE; 223128ba4542f3c4c90790af0564e75950c8900961Alan Treadwayimport static android.app.admin.DevicePolicyManager.ACTION_PROVISION_MANAGED_USER; 233128ba4542f3c4c90790af0564e75950c8900961Alan Treadwayimport static android.app.admin.DevicePolicyManager.MIME_TYPE_PROVISIONING_NFC; 243128ba4542f3c4c90790af0564e75950c8900961Alan Treadwayimport static android.nfc.NfcAdapter.ACTION_NDEF_DISCOVERED; 253128ba4542f3c4c90790af0564e75950c8900961Alan Treadwayimport static java.nio.charset.StandardCharsets.UTF_8; 263128ba4542f3c4c90790af0564e75950c8900961Alan Treadway 273128ba4542f3c4c90790af0564e75950c8900961Alan Treadwayimport android.accounts.Account; 283128ba4542f3c4c90790af0564e75950c8900961Alan Treadwayimport android.accounts.AccountManager; 293128ba4542f3c4c90790af0564e75950c8900961Alan Treadwayimport android.accounts.AccountManagerFuture; 303128ba4542f3c4c90790af0564e75950c8900961Alan Treadwayimport android.accounts.AuthenticatorException; 313128ba4542f3c4c90790af0564e75950c8900961Alan Treadwayimport android.accounts.OperationCanceledException; 3284e56f5cfc1d45b3983dd553096182e774d8cb2cJoe Delfinoimport android.app.admin.DevicePolicyManager; 339a42f2b64dada715248aec7c898f983375a395eeAlan Treadwayimport android.content.ComponentName; 340b4472570d93aeeda5a33dc05c0dcf03f2d3538bNicolas Prevotimport android.content.Context; 359a42f2b64dada715248aec7c898f983375a395eeAlan Treadwayimport android.content.Intent; 360b4472570d93aeeda5a33dc05c0dcf03f2d3538bNicolas Prevotimport android.content.pm.ActivityInfo; 37d5e4c42542dd96d8940912cc20dff20fa48da0d9Sander Alewijnseimport android.content.pm.ApplicationInfo; 38d5e4c42542dd96d8940912cc20dff20fa48da0d9Sander Alewijnseimport android.content.pm.IPackageManager; 390b4472570d93aeeda5a33dc05c0dcf03f2d3538bNicolas Prevotimport android.content.pm.PackageInfo; 40d5e4c42542dd96d8940912cc20dff20fa48da0d9Sander Alewijnseimport android.content.pm.PackageManager; 410b4472570d93aeeda5a33dc05c0dcf03f2d3538bNicolas Prevotimport android.content.pm.PackageManager.NameNotFoundException; 4284e56f5cfc1d45b3983dd553096182e774d8cb2cJoe Delfinoimport android.content.pm.UserInfo; 439a42f2b64dada715248aec7c898f983375a395eeAlan Treadwayimport android.graphics.drawable.Drawable; 443128ba4542f3c4c90790af0564e75950c8900961Alan Treadwayimport android.nfc.NdefMessage; 453128ba4542f3c4c90790af0564e75950c8900961Alan Treadwayimport android.nfc.NdefRecord; 463128ba4542f3c4c90790af0564e75950c8900961Alan Treadwayimport android.nfc.NfcAdapter; 47a5daf2dfdbb7c1b1ea5b930cc7836cf67778dde4Sudheer Shankaimport android.os.Bundle; 483128ba4542f3c4c90790af0564e75950c8900961Alan Treadwayimport android.os.Parcelable; 49d5e4c42542dd96d8940912cc20dff20fa48da0d9Sander Alewijnseimport android.os.RemoteException; 50d5e4c42542dd96d8940912cc20dff20fa48da0d9Sander Alewijnseimport android.os.ServiceManager; 51d0f2928a28d38ce8344b7f15fbfec97aebec0db6Joe Delfinoimport android.os.UserHandle; 5284e56f5cfc1d45b3983dd553096182e774d8cb2cJoe Delfinoimport android.os.UserManager; 53a5daf2dfdbb7c1b1ea5b930cc7836cf67778dde4Sudheer Shankaimport android.provider.Settings.Global; 54a5daf2dfdbb7c1b1ea5b930cc7836cf67778dde4Sudheer Shankaimport android.provider.Settings.Secure; 550b4472570d93aeeda5a33dc05c0dcf03f2d3538bNicolas Prevotimport android.text.TextUtils; 563efa83ac5074f40be2e1f275d492cf4175e7eb4bSander Alewijnseimport android.util.Base64; 57d5e4c42542dd96d8940912cc20dff20fa48da0d9Sander Alewijnse 58a5daf2dfdbb7c1b1ea5b930cc7836cf67778dde4Sudheer Shankaimport java.io.IOException; 593128ba4542f3c4c90790af0564e75950c8900961Alan Treadwayimport java.lang.String; 603128ba4542f3c4c90790af0564e75950c8900961Alan Treadwayimport java.nio.charset.StandardCharsets; 61d5e4c42542dd96d8940912cc20dff20fa48da0d9Sander Alewijnseimport java.util.HashSet; 629a42f2b64dada715248aec7c898f983375a395eeAlan Treadwayimport java.util.List; 63d5e4c42542dd96d8940912cc20dff20fa48da0d9Sander Alewijnseimport java.util.Set; 64d5e4c42542dd96d8940912cc20dff20fa48da0d9Sander Alewijnse 65d5e4c42542dd96d8940912cc20dff20fa48da0d9Sander Alewijnse/** 66d5e4c42542dd96d8940912cc20dff20fa48da0d9Sander Alewijnse * Class containing various auxiliary methods. 67d5e4c42542dd96d8940912cc20dff20fa48da0d9Sander Alewijnse */ 68d5e4c42542dd96d8940912cc20dff20fa48da0d9Sander Alewijnsepublic class Utils { 699a42f2b64dada715248aec7c898f983375a395eeAlan Treadway private Utils() {} 709a42f2b64dada715248aec7c898f983375a395eeAlan Treadway 71e36926b4933d60a31858fd8c15249ac400d16752Nicolas Prevot public static Set<String> getCurrentSystemApps(IPackageManager ipm, int userId) { 72d5e4c42542dd96d8940912cc20dff20fa48da0d9Sander Alewijnse Set<String> apps = new HashSet<String>(); 73d5e4c42542dd96d8940912cc20dff20fa48da0d9Sander Alewijnse List<ApplicationInfo> aInfos = null; 74d5e4c42542dd96d8940912cc20dff20fa48da0d9Sander Alewijnse try { 75d5e4c42542dd96d8940912cc20dff20fa48da0d9Sander Alewijnse aInfos = ipm.getInstalledApplications( 76d5e4c42542dd96d8940912cc20dff20fa48da0d9Sander Alewijnse PackageManager.GET_UNINSTALLED_PACKAGES, userId).getList(); 77d5e4c42542dd96d8940912cc20dff20fa48da0d9Sander Alewijnse } catch (RemoteException neverThrown) { 78d5e4c42542dd96d8940912cc20dff20fa48da0d9Sander Alewijnse ProvisionLogger.loge("This should not happen.", neverThrown); 79d5e4c42542dd96d8940912cc20dff20fa48da0d9Sander Alewijnse } 80d5e4c42542dd96d8940912cc20dff20fa48da0d9Sander Alewijnse for (ApplicationInfo aInfo : aInfos) { 81d5e4c42542dd96d8940912cc20dff20fa48da0d9Sander Alewijnse if ((aInfo.flags & ApplicationInfo.FLAG_SYSTEM) != 0) { 82d5e4c42542dd96d8940912cc20dff20fa48da0d9Sander Alewijnse apps.add(aInfo.packageName); 83d5e4c42542dd96d8940912cc20dff20fa48da0d9Sander Alewijnse } 84d5e4c42542dd96d8940912cc20dff20fa48da0d9Sander Alewijnse } 85d5e4c42542dd96d8940912cc20dff20fa48da0d9Sander Alewijnse return apps; 86d5e4c42542dd96d8940912cc20dff20fa48da0d9Sander Alewijnse } 87d5e4c42542dd96d8940912cc20dff20fa48da0d9Sander Alewijnse 88d5e4c42542dd96d8940912cc20dff20fa48da0d9Sander Alewijnse public static void disableComponent(ComponentName toDisable, int userId) { 89d5e4c42542dd96d8940912cc20dff20fa48da0d9Sander Alewijnse try { 90d5e4c42542dd96d8940912cc20dff20fa48da0d9Sander Alewijnse IPackageManager ipm = IPackageManager.Stub.asInterface(ServiceManager 91d5e4c42542dd96d8940912cc20dff20fa48da0d9Sander Alewijnse .getService("package")); 92d5e4c42542dd96d8940912cc20dff20fa48da0d9Sander Alewijnse 93d5e4c42542dd96d8940912cc20dff20fa48da0d9Sander Alewijnse ipm.setComponentEnabledSetting(toDisable, 94d5e4c42542dd96d8940912cc20dff20fa48da0d9Sander Alewijnse PackageManager.COMPONENT_ENABLED_STATE_DISABLED, PackageManager.DONT_KILL_APP, 95d5e4c42542dd96d8940912cc20dff20fa48da0d9Sander Alewijnse userId); 96d5e4c42542dd96d8940912cc20dff20fa48da0d9Sander Alewijnse } catch (RemoteException neverThrown) { 97d5e4c42542dd96d8940912cc20dff20fa48da0d9Sander Alewijnse ProvisionLogger.loge("This should not happen.", neverThrown); 98d5e4c42542dd96d8940912cc20dff20fa48da0d9Sander Alewijnse } catch (Exception e) { 99d5e4c42542dd96d8940912cc20dff20fa48da0d9Sander Alewijnse ProvisionLogger.logw("Component not found, not disabling it: " 100d5e4c42542dd96d8940912cc20dff20fa48da0d9Sander Alewijnse + toDisable.toShortString()); 101d5e4c42542dd96d8940912cc20dff20fa48da0d9Sander Alewijnse } 102d5e4c42542dd96d8940912cc20dff20fa48da0d9Sander Alewijnse } 1030b4472570d93aeeda5a33dc05c0dcf03f2d3538bNicolas Prevot 1040b4472570d93aeeda5a33dc05c0dcf03f2d3538bNicolas Prevot /** 1050b4472570d93aeeda5a33dc05c0dcf03f2d3538bNicolas Prevot * Exception thrown when the provisioning has failed completely. 1060b4472570d93aeeda5a33dc05c0dcf03f2d3538bNicolas Prevot * 1070b4472570d93aeeda5a33dc05c0dcf03f2d3538bNicolas Prevot * We're using a custom exception to avoid catching subsequent exceptions that might be 1080b4472570d93aeeda5a33dc05c0dcf03f2d3538bNicolas Prevot * significant. 1090b4472570d93aeeda5a33dc05c0dcf03f2d3538bNicolas Prevot */ 1100b4472570d93aeeda5a33dc05c0dcf03f2d3538bNicolas Prevot public static class IllegalProvisioningArgumentException extends Exception { 1110b4472570d93aeeda5a33dc05c0dcf03f2d3538bNicolas Prevot public IllegalProvisioningArgumentException(String message) { 1120b4472570d93aeeda5a33dc05c0dcf03f2d3538bNicolas Prevot super(message); 1130b4472570d93aeeda5a33dc05c0dcf03f2d3538bNicolas Prevot } 1140b4472570d93aeeda5a33dc05c0dcf03f2d3538bNicolas Prevot 1150b4472570d93aeeda5a33dc05c0dcf03f2d3538bNicolas Prevot public IllegalProvisioningArgumentException(String message, Throwable t) { 1160b4472570d93aeeda5a33dc05c0dcf03f2d3538bNicolas Prevot super(message, t); 1170b4472570d93aeeda5a33dc05c0dcf03f2d3538bNicolas Prevot } 1180b4472570d93aeeda5a33dc05c0dcf03f2d3538bNicolas Prevot } 1190b4472570d93aeeda5a33dc05c0dcf03f2d3538bNicolas Prevot 1200b4472570d93aeeda5a33dc05c0dcf03f2d3538bNicolas Prevot /** 1210b4472570d93aeeda5a33dc05c0dcf03f2d3538bNicolas Prevot * Check the validity of the admin component name supplied, or try to infer this componentName 1220b4472570d93aeeda5a33dc05c0dcf03f2d3538bNicolas Prevot * from the package. 1230b4472570d93aeeda5a33dc05c0dcf03f2d3538bNicolas Prevot * 1240b4472570d93aeeda5a33dc05c0dcf03f2d3538bNicolas Prevot * We are supporting lookup by package name for legacy reasons. 1250b4472570d93aeeda5a33dc05c0dcf03f2d3538bNicolas Prevot * 1260b4472570d93aeeda5a33dc05c0dcf03f2d3538bNicolas Prevot * If mdmComponentName is supplied (not null): 1270b4472570d93aeeda5a33dc05c0dcf03f2d3538bNicolas Prevot * mdmPackageName is ignored. 1280b4472570d93aeeda5a33dc05c0dcf03f2d3538bNicolas Prevot * Check that the package of mdmComponentName is installed, that mdmComponentName is a 1290b4472570d93aeeda5a33dc05c0dcf03f2d3538bNicolas Prevot * receiver in this package, and return it. 1300b4472570d93aeeda5a33dc05c0dcf03f2d3538bNicolas Prevot * 1310b4472570d93aeeda5a33dc05c0dcf03f2d3538bNicolas Prevot * Otherwise: 1320b4472570d93aeeda5a33dc05c0dcf03f2d3538bNicolas Prevot * mdmPackageName must be supplied (not null). 1330b4472570d93aeeda5a33dc05c0dcf03f2d3538bNicolas Prevot * Check that this package is installed, try to infer a potential device admin in this package, 1340b4472570d93aeeda5a33dc05c0dcf03f2d3538bNicolas Prevot * and return it. 1350b4472570d93aeeda5a33dc05c0dcf03f2d3538bNicolas Prevot */ 1360b4472570d93aeeda5a33dc05c0dcf03f2d3538bNicolas Prevot public static ComponentName findDeviceAdmin(String mdmPackageName, 1370b4472570d93aeeda5a33dc05c0dcf03f2d3538bNicolas Prevot ComponentName mdmComponentName, Context c) throws IllegalProvisioningArgumentException { 1380b4472570d93aeeda5a33dc05c0dcf03f2d3538bNicolas Prevot if (mdmComponentName != null) { 1390b4472570d93aeeda5a33dc05c0dcf03f2d3538bNicolas Prevot mdmPackageName = mdmComponentName.getPackageName(); 1400b4472570d93aeeda5a33dc05c0dcf03f2d3538bNicolas Prevot } 1410b4472570d93aeeda5a33dc05c0dcf03f2d3538bNicolas Prevot if (mdmPackageName == null) { 1420b4472570d93aeeda5a33dc05c0dcf03f2d3538bNicolas Prevot throw new IllegalProvisioningArgumentException("Neither the package name nor the" 1430b4472570d93aeeda5a33dc05c0dcf03f2d3538bNicolas Prevot + " component name of the admin are supplied"); 1440b4472570d93aeeda5a33dc05c0dcf03f2d3538bNicolas Prevot } 1450b4472570d93aeeda5a33dc05c0dcf03f2d3538bNicolas Prevot PackageInfo pi; 1460b4472570d93aeeda5a33dc05c0dcf03f2d3538bNicolas Prevot try { 1470b4472570d93aeeda5a33dc05c0dcf03f2d3538bNicolas Prevot pi = c.getPackageManager().getPackageInfo(mdmPackageName, 1480b4472570d93aeeda5a33dc05c0dcf03f2d3538bNicolas Prevot PackageManager.GET_RECEIVERS); 1490b4472570d93aeeda5a33dc05c0dcf03f2d3538bNicolas Prevot } catch (NameNotFoundException e) { 1500b4472570d93aeeda5a33dc05c0dcf03f2d3538bNicolas Prevot throw new IllegalProvisioningArgumentException("Mdm "+ mdmPackageName 1510b4472570d93aeeda5a33dc05c0dcf03f2d3538bNicolas Prevot + " is not installed. ", e); 1520b4472570d93aeeda5a33dc05c0dcf03f2d3538bNicolas Prevot } 1530b4472570d93aeeda5a33dc05c0dcf03f2d3538bNicolas Prevot if (mdmComponentName != null) { 1540b4472570d93aeeda5a33dc05c0dcf03f2d3538bNicolas Prevot // If the component was specified in the intent: check that it is in the manifest. 1550b4472570d93aeeda5a33dc05c0dcf03f2d3538bNicolas Prevot checkAdminComponent(mdmComponentName, pi); 1560b4472570d93aeeda5a33dc05c0dcf03f2d3538bNicolas Prevot return mdmComponentName; 1570b4472570d93aeeda5a33dc05c0dcf03f2d3538bNicolas Prevot } else { 1580b4472570d93aeeda5a33dc05c0dcf03f2d3538bNicolas Prevot // Otherwise: try to find a potential device admin in the manifest. 1590b4472570d93aeeda5a33dc05c0dcf03f2d3538bNicolas Prevot return findDeviceAdminInPackage(mdmPackageName, pi); 1600b4472570d93aeeda5a33dc05c0dcf03f2d3538bNicolas Prevot } 1610b4472570d93aeeda5a33dc05c0dcf03f2d3538bNicolas Prevot } 1620b4472570d93aeeda5a33dc05c0dcf03f2d3538bNicolas Prevot 1630b4472570d93aeeda5a33dc05c0dcf03f2d3538bNicolas Prevot private static void checkAdminComponent(ComponentName mdmComponentName, PackageInfo pi) 1640b4472570d93aeeda5a33dc05c0dcf03f2d3538bNicolas Prevot throws IllegalProvisioningArgumentException{ 1650b4472570d93aeeda5a33dc05c0dcf03f2d3538bNicolas Prevot for (ActivityInfo ai : pi.receivers) { 1660b4472570d93aeeda5a33dc05c0dcf03f2d3538bNicolas Prevot if (mdmComponentName.getClassName().equals(ai.name)) { 1670b4472570d93aeeda5a33dc05c0dcf03f2d3538bNicolas Prevot return; 1680b4472570d93aeeda5a33dc05c0dcf03f2d3538bNicolas Prevot } 1690b4472570d93aeeda5a33dc05c0dcf03f2d3538bNicolas Prevot } 1700b4472570d93aeeda5a33dc05c0dcf03f2d3538bNicolas Prevot throw new IllegalProvisioningArgumentException("The component " + mdmComponentName 1710b4472570d93aeeda5a33dc05c0dcf03f2d3538bNicolas Prevot + " cannot be found"); 1720b4472570d93aeeda5a33dc05c0dcf03f2d3538bNicolas Prevot } 1730b4472570d93aeeda5a33dc05c0dcf03f2d3538bNicolas Prevot 1740b4472570d93aeeda5a33dc05c0dcf03f2d3538bNicolas Prevot private static ComponentName findDeviceAdminInPackage(String mdmPackageName, PackageInfo pi) 1750b4472570d93aeeda5a33dc05c0dcf03f2d3538bNicolas Prevot throws IllegalProvisioningArgumentException { 1760b4472570d93aeeda5a33dc05c0dcf03f2d3538bNicolas Prevot ComponentName mdmComponentName = null; 1770b4472570d93aeeda5a33dc05c0dcf03f2d3538bNicolas Prevot for (ActivityInfo ai : pi.receivers) { 1780b4472570d93aeeda5a33dc05c0dcf03f2d3538bNicolas Prevot if (!TextUtils.isEmpty(ai.permission) && 1790b4472570d93aeeda5a33dc05c0dcf03f2d3538bNicolas Prevot ai.permission.equals(android.Manifest.permission.BIND_DEVICE_ADMIN)) { 1800b4472570d93aeeda5a33dc05c0dcf03f2d3538bNicolas Prevot if (mdmComponentName != null) { 1810b4472570d93aeeda5a33dc05c0dcf03f2d3538bNicolas Prevot throw new IllegalProvisioningArgumentException("There are several " 1820b4472570d93aeeda5a33dc05c0dcf03f2d3538bNicolas Prevot + "device admins in " + mdmPackageName + " but no one in specified"); 1830b4472570d93aeeda5a33dc05c0dcf03f2d3538bNicolas Prevot } else { 1840b4472570d93aeeda5a33dc05c0dcf03f2d3538bNicolas Prevot mdmComponentName = new ComponentName(mdmPackageName, ai.name); 1850b4472570d93aeeda5a33dc05c0dcf03f2d3538bNicolas Prevot } 1860b4472570d93aeeda5a33dc05c0dcf03f2d3538bNicolas Prevot } 1870b4472570d93aeeda5a33dc05c0dcf03f2d3538bNicolas Prevot } 1880b4472570d93aeeda5a33dc05c0dcf03f2d3538bNicolas Prevot if (mdmComponentName == null) { 1890b4472570d93aeeda5a33dc05c0dcf03f2d3538bNicolas Prevot throw new IllegalProvisioningArgumentException("There are no device admins in" 1900b4472570d93aeeda5a33dc05c0dcf03f2d3538bNicolas Prevot + mdmPackageName); 1910b4472570d93aeeda5a33dc05c0dcf03f2d3538bNicolas Prevot } 1920b4472570d93aeeda5a33dc05c0dcf03f2d3538bNicolas Prevot return mdmComponentName; 1930b4472570d93aeeda5a33dc05c0dcf03f2d3538bNicolas Prevot } 1949a42f2b64dada715248aec7c898f983375a395eeAlan Treadway 1959a42f2b64dada715248aec7c898f983375a395eeAlan Treadway public static MdmPackageInfo getMdmPackageInfo(PackageManager pm, String packageName) { 1969a42f2b64dada715248aec7c898f983375a395eeAlan Treadway if (packageName != null) { 1979a42f2b64dada715248aec7c898f983375a395eeAlan Treadway try { 1989a42f2b64dada715248aec7c898f983375a395eeAlan Treadway ApplicationInfo ai = pm.getApplicationInfo(packageName, /* default flags */ 0); 1999a42f2b64dada715248aec7c898f983375a395eeAlan Treadway if (ai != null) { 2009a42f2b64dada715248aec7c898f983375a395eeAlan Treadway return new MdmPackageInfo(pm.getApplicationIcon(packageName), 2019a42f2b64dada715248aec7c898f983375a395eeAlan Treadway pm.getApplicationLabel(ai).toString()); 2029a42f2b64dada715248aec7c898f983375a395eeAlan Treadway } 2039a42f2b64dada715248aec7c898f983375a395eeAlan Treadway } catch (PackageManager.NameNotFoundException e) { 2049a42f2b64dada715248aec7c898f983375a395eeAlan Treadway // Package does not exist, ignore. Should never happen. 2059a42f2b64dada715248aec7c898f983375a395eeAlan Treadway ProvisionLogger.loge("Package does not exist. Should never happen."); 2069a42f2b64dada715248aec7c898f983375a395eeAlan Treadway } 2079a42f2b64dada715248aec7c898f983375a395eeAlan Treadway } 2089a42f2b64dada715248aec7c898f983375a395eeAlan Treadway 2099a42f2b64dada715248aec7c898f983375a395eeAlan Treadway return null; 2109a42f2b64dada715248aec7c898f983375a395eeAlan Treadway } 2119a42f2b64dada715248aec7c898f983375a395eeAlan Treadway 2129a42f2b64dada715248aec7c898f983375a395eeAlan Treadway /** 2139a42f2b64dada715248aec7c898f983375a395eeAlan Treadway * Information relating to the currently installed MDM package manager. 2149a42f2b64dada715248aec7c898f983375a395eeAlan Treadway */ 2159a42f2b64dada715248aec7c898f983375a395eeAlan Treadway public static final class MdmPackageInfo { 2169a42f2b64dada715248aec7c898f983375a395eeAlan Treadway private final Drawable packageIcon; 2179a42f2b64dada715248aec7c898f983375a395eeAlan Treadway private final String appLabel; 2189a42f2b64dada715248aec7c898f983375a395eeAlan Treadway 2199a42f2b64dada715248aec7c898f983375a395eeAlan Treadway private MdmPackageInfo(Drawable packageIcon, String appLabel) { 2209a42f2b64dada715248aec7c898f983375a395eeAlan Treadway this.packageIcon = packageIcon; 2219a42f2b64dada715248aec7c898f983375a395eeAlan Treadway this.appLabel = appLabel; 2229a42f2b64dada715248aec7c898f983375a395eeAlan Treadway } 2239a42f2b64dada715248aec7c898f983375a395eeAlan Treadway 2249a42f2b64dada715248aec7c898f983375a395eeAlan Treadway public String getAppLabel() { 2259a42f2b64dada715248aec7c898f983375a395eeAlan Treadway return appLabel; 2269a42f2b64dada715248aec7c898f983375a395eeAlan Treadway } 2279a42f2b64dada715248aec7c898f983375a395eeAlan Treadway 2289a42f2b64dada715248aec7c898f983375a395eeAlan Treadway public Drawable getPackageIcon() { 2299a42f2b64dada715248aec7c898f983375a395eeAlan Treadway return packageIcon; 2309a42f2b64dada715248aec7c898f983375a395eeAlan Treadway } 2319a42f2b64dada715248aec7c898f983375a395eeAlan Treadway } 232d0f2928a28d38ce8344b7f15fbfec97aebec0db6Joe Delfino 2332a71ac51b3ae8cf0f284d69e57c763cbce8423d7Xiaohui Chen public static boolean isCurrentUserSystem() { 2342a71ac51b3ae8cf0f284d69e57c763cbce8423d7Xiaohui Chen return UserHandle.myUserId() == UserHandle.USER_SYSTEM; 235d0f2928a28d38ce8344b7f15fbfec97aebec0db6Joe Delfino } 23684e56f5cfc1d45b3983dd553096182e774d8cb2cJoe Delfino 237981e55496221c55a77c0fe01031624cfecf75a54Makoto Onuki public static boolean isDeviceManaged(Context context) { 23884e56f5cfc1d45b3983dd553096182e774d8cb2cJoe Delfino DevicePolicyManager dpm = 23984e56f5cfc1d45b3983dd553096182e774d8cb2cJoe Delfino (DevicePolicyManager) context.getSystemService(Context.DEVICE_POLICY_SERVICE); 240981e55496221c55a77c0fe01031624cfecf75a54Makoto Onuki return dpm.isDeviceManaged(); 24184e56f5cfc1d45b3983dd553096182e774d8cb2cJoe Delfino } 24284e56f5cfc1d45b3983dd553096182e774d8cb2cJoe Delfino 24384e56f5cfc1d45b3983dd553096182e774d8cb2cJoe Delfino public static boolean isManagedProfile(Context context) { 24484e56f5cfc1d45b3983dd553096182e774d8cb2cJoe Delfino UserManager um = (UserManager) context.getSystemService(Context.USER_SERVICE); 24584e56f5cfc1d45b3983dd553096182e774d8cb2cJoe Delfino UserInfo user = um.getUserInfo(UserHandle.myUserId()); 24684e56f5cfc1d45b3983dd553096182e774d8cb2cJoe Delfino return user != null ? user.isManagedProfile() : false; 24784e56f5cfc1d45b3983dd553096182e774d8cb2cJoe Delfino } 24884e56f5cfc1d45b3983dd553096182e774d8cb2cJoe Delfino 24974d6c14da5117ffd3458602f9f6946c531143436Sander Alewijnse /** 25074d6c14da5117ffd3458602f9f6946c531143436Sander Alewijnse * Returns true if the given package does not exist on the device or if its version code is less 25174d6c14da5117ffd3458602f9f6946c531143436Sander Alewijnse * than the given version, and false otherwise. 25274d6c14da5117ffd3458602f9f6946c531143436Sander Alewijnse */ 25374d6c14da5117ffd3458602f9f6946c531143436Sander Alewijnse public static boolean packageRequiresUpdate(String packageName, int minSupportedVersion, 25474d6c14da5117ffd3458602f9f6946c531143436Sander Alewijnse Context context) { 25574d6c14da5117ffd3458602f9f6946c531143436Sander Alewijnse try { 25674d6c14da5117ffd3458602f9f6946c531143436Sander Alewijnse PackageInfo packageInfo = context.getPackageManager().getPackageInfo(packageName, 0); 25774d6c14da5117ffd3458602f9f6946c531143436Sander Alewijnse if (packageInfo.versionCode >= minSupportedVersion) { 25874d6c14da5117ffd3458602f9f6946c531143436Sander Alewijnse return false; 25974d6c14da5117ffd3458602f9f6946c531143436Sander Alewijnse } 26074d6c14da5117ffd3458602f9f6946c531143436Sander Alewijnse } catch (NameNotFoundException e) { 26174d6c14da5117ffd3458602f9f6946c531143436Sander Alewijnse // Package not on device. 26274d6c14da5117ffd3458602f9f6946c531143436Sander Alewijnse } 26374d6c14da5117ffd3458602f9f6946c531143436Sander Alewijnse 26474d6c14da5117ffd3458602f9f6946c531143436Sander Alewijnse return true; 26574d6c14da5117ffd3458602f9f6946c531143436Sander Alewijnse } 26674d6c14da5117ffd3458602f9f6946c531143436Sander Alewijnse 2673efa83ac5074f40be2e1f275d492cf4175e7eb4bSander Alewijnse public static byte[] stringToByteArray(String s) 2683efa83ac5074f40be2e1f275d492cf4175e7eb4bSander Alewijnse throws NumberFormatException { 2693efa83ac5074f40be2e1f275d492cf4175e7eb4bSander Alewijnse try { 2703efa83ac5074f40be2e1f275d492cf4175e7eb4bSander Alewijnse return Base64.decode(s, Base64.URL_SAFE); 2713efa83ac5074f40be2e1f275d492cf4175e7eb4bSander Alewijnse } catch (IllegalArgumentException e) { 2723efa83ac5074f40be2e1f275d492cf4175e7eb4bSander Alewijnse throw new NumberFormatException("Incorrect format. Should be Url-safe Base64 encoded."); 2733efa83ac5074f40be2e1f275d492cf4175e7eb4bSander Alewijnse } 2743efa83ac5074f40be2e1f275d492cf4175e7eb4bSander Alewijnse } 2753efa83ac5074f40be2e1f275d492cf4175e7eb4bSander Alewijnse 2763efa83ac5074f40be2e1f275d492cf4175e7eb4bSander Alewijnse public static String byteArrayToString(byte[] bytes) { 2773efa83ac5074f40be2e1f275d492cf4175e7eb4bSander Alewijnse return Base64.encodeToString(bytes, Base64.URL_SAFE | Base64.NO_PADDING | Base64.NO_WRAP); 2783efa83ac5074f40be2e1f275d492cf4175e7eb4bSander Alewijnse } 279a5daf2dfdbb7c1b1ea5b930cc7836cf67778dde4Sudheer Shanka 280a5daf2dfdbb7c1b1ea5b930cc7836cf67778dde4Sudheer Shanka public static void markDeviceProvisioned(Context context) { 281c78162c71e63903c6f544544cc81d1128acb6eb0Craig Lafayette Global.putInt(context.getContentResolver(), Global.DEVICE_PROVISIONED, 1); 282a5daf2dfdbb7c1b1ea5b930cc7836cf67778dde4Sudheer Shanka 283a5daf2dfdbb7c1b1ea5b930cc7836cf67778dde4Sudheer Shanka // Setting this flag will either cause Setup Wizard to finish immediately when it starts (if 284a5daf2dfdbb7c1b1ea5b930cc7836cf67778dde4Sudheer Shanka // it is not already running), or when its next activity starts (if it is already running, 285a5daf2dfdbb7c1b1ea5b930cc7836cf67778dde4Sudheer Shanka // e.g. the non-NFC flow). 286a5daf2dfdbb7c1b1ea5b930cc7836cf67778dde4Sudheer Shanka // When either of these things happen, a home intent is fired. We catch that in 287a5daf2dfdbb7c1b1ea5b930cc7836cf67778dde4Sudheer Shanka // HomeReceiverActivity before sending the intent to notify the mdm that provisioning is 288a5daf2dfdbb7c1b1ea5b930cc7836cf67778dde4Sudheer Shanka // complete. 289bf793102707971d77950ad1a20dd082ae9ec18bcNicolas Prevot markUserSetupComplete(context, UserHandle.myUserId()); 290bf793102707971d77950ad1a20dd082ae9ec18bcNicolas Prevot } 291bf793102707971d77950ad1a20dd082ae9ec18bcNicolas Prevot 292bf793102707971d77950ad1a20dd082ae9ec18bcNicolas Prevot public static void markUserSetupComplete(Context context, int userId) { 293bf793102707971d77950ad1a20dd082ae9ec18bcNicolas Prevot Secure.putIntForUser(context.getContentResolver(), Secure.USER_SETUP_COMPLETE, 1, userId); 294a5daf2dfdbb7c1b1ea5b930cc7836cf67778dde4Sudheer Shanka } 295a5daf2dfdbb7c1b1ea5b930cc7836cf67778dde4Sudheer Shanka 296a5daf2dfdbb7c1b1ea5b930cc7836cf67778dde4Sudheer Shanka public static boolean isUserSetupCompleted(Context context) { 297a5daf2dfdbb7c1b1ea5b930cc7836cf67778dde4Sudheer Shanka return Secure.getInt(context.getContentResolver(), Secure.USER_SETUP_COMPLETE, 0) != 0; 298a5daf2dfdbb7c1b1ea5b930cc7836cf67778dde4Sudheer Shanka } 299a5daf2dfdbb7c1b1ea5b930cc7836cf67778dde4Sudheer Shanka 300a5daf2dfdbb7c1b1ea5b930cc7836cf67778dde4Sudheer Shanka public static UserHandle getManagedProfile(Context context) { 301a5daf2dfdbb7c1b1ea5b930cc7836cf67778dde4Sudheer Shanka UserManager userManager = (UserManager) context.getSystemService(Context.USER_SERVICE); 302a5daf2dfdbb7c1b1ea5b930cc7836cf67778dde4Sudheer Shanka int currentUserId = userManager.getUserHandle(); 303a5daf2dfdbb7c1b1ea5b930cc7836cf67778dde4Sudheer Shanka List<UserInfo> userProfiles = userManager.getProfiles(currentUserId); 304a5daf2dfdbb7c1b1ea5b930cc7836cf67778dde4Sudheer Shanka for (UserInfo profile : userProfiles) { 305a5daf2dfdbb7c1b1ea5b930cc7836cf67778dde4Sudheer Shanka if (profile.isManagedProfile()) { 306a5daf2dfdbb7c1b1ea5b930cc7836cf67778dde4Sudheer Shanka return new UserHandle(profile.id); 307a5daf2dfdbb7c1b1ea5b930cc7836cf67778dde4Sudheer Shanka } 308a5daf2dfdbb7c1b1ea5b930cc7836cf67778dde4Sudheer Shanka } 309a5daf2dfdbb7c1b1ea5b930cc7836cf67778dde4Sudheer Shanka return null; 310a5daf2dfdbb7c1b1ea5b930cc7836cf67778dde4Sudheer Shanka } 311a5daf2dfdbb7c1b1ea5b930cc7836cf67778dde4Sudheer Shanka 312a5daf2dfdbb7c1b1ea5b930cc7836cf67778dde4Sudheer Shanka /** 313a5daf2dfdbb7c1b1ea5b930cc7836cf67778dde4Sudheer Shanka * @return The User id of an already existing managed profile or -1 if none 314a5daf2dfdbb7c1b1ea5b930cc7836cf67778dde4Sudheer Shanka * exists 315a5daf2dfdbb7c1b1ea5b930cc7836cf67778dde4Sudheer Shanka */ 316a5daf2dfdbb7c1b1ea5b930cc7836cf67778dde4Sudheer Shanka public static int alreadyHasManagedProfile(Context context) { 317a5daf2dfdbb7c1b1ea5b930cc7836cf67778dde4Sudheer Shanka UserHandle managedUser = getManagedProfile(context); 318a5daf2dfdbb7c1b1ea5b930cc7836cf67778dde4Sudheer Shanka if (managedUser != null) { 319a5daf2dfdbb7c1b1ea5b930cc7836cf67778dde4Sudheer Shanka return managedUser.getIdentifier(); 320a5daf2dfdbb7c1b1ea5b930cc7836cf67778dde4Sudheer Shanka } else { 321a5daf2dfdbb7c1b1ea5b930cc7836cf67778dde4Sudheer Shanka return -1; 322a5daf2dfdbb7c1b1ea5b930cc7836cf67778dde4Sudheer Shanka } 323a5daf2dfdbb7c1b1ea5b930cc7836cf67778dde4Sudheer Shanka } 324a5daf2dfdbb7c1b1ea5b930cc7836cf67778dde4Sudheer Shanka 325a5daf2dfdbb7c1b1ea5b930cc7836cf67778dde4Sudheer Shanka public static void removeAccount(Context context, Account account) { 326a5daf2dfdbb7c1b1ea5b930cc7836cf67778dde4Sudheer Shanka try { 327a5daf2dfdbb7c1b1ea5b930cc7836cf67778dde4Sudheer Shanka AccountManager accountManager = 328a5daf2dfdbb7c1b1ea5b930cc7836cf67778dde4Sudheer Shanka (AccountManager) context.getSystemService(Context.ACCOUNT_SERVICE); 329a5daf2dfdbb7c1b1ea5b930cc7836cf67778dde4Sudheer Shanka AccountManagerFuture<Bundle> bundle = accountManager.removeAccount(account, 330a5daf2dfdbb7c1b1ea5b930cc7836cf67778dde4Sudheer Shanka null, null /* callback */, null /* handler */); 331a5daf2dfdbb7c1b1ea5b930cc7836cf67778dde4Sudheer Shanka // Block to get the result of the removeAccount operation 332a5daf2dfdbb7c1b1ea5b930cc7836cf67778dde4Sudheer Shanka if (bundle.getResult().getBoolean(AccountManager.KEY_BOOLEAN_RESULT, false)) { 333a5daf2dfdbb7c1b1ea5b930cc7836cf67778dde4Sudheer Shanka ProvisionLogger.logw("Account removed from the primary user."); 334a5daf2dfdbb7c1b1ea5b930cc7836cf67778dde4Sudheer Shanka } else { 335a5daf2dfdbb7c1b1ea5b930cc7836cf67778dde4Sudheer Shanka Intent removeIntent = (Intent) bundle.getResult().getParcelable( 336a5daf2dfdbb7c1b1ea5b930cc7836cf67778dde4Sudheer Shanka AccountManager.KEY_INTENT); 337a5daf2dfdbb7c1b1ea5b930cc7836cf67778dde4Sudheer Shanka if (removeIntent != null) { 338a5daf2dfdbb7c1b1ea5b930cc7836cf67778dde4Sudheer Shanka ProvisionLogger.logi("Starting activity to remove account"); 3390ed8f62fcb0c35402ccee0b93679ace2dc96a03bRubin Xu TrampolineActivity.startActivity(context, removeIntent); 340a5daf2dfdbb7c1b1ea5b930cc7836cf67778dde4Sudheer Shanka } else { 341a5daf2dfdbb7c1b1ea5b930cc7836cf67778dde4Sudheer Shanka ProvisionLogger.logw("Could not remove account from the primary user."); 342a5daf2dfdbb7c1b1ea5b930cc7836cf67778dde4Sudheer Shanka } 343a5daf2dfdbb7c1b1ea5b930cc7836cf67778dde4Sudheer Shanka } 344a5daf2dfdbb7c1b1ea5b930cc7836cf67778dde4Sudheer Shanka } catch (OperationCanceledException | AuthenticatorException | IOException e) { 345a5daf2dfdbb7c1b1ea5b930cc7836cf67778dde4Sudheer Shanka ProvisionLogger.logw("Exception removing account from the primary user.", e); 346a5daf2dfdbb7c1b1ea5b930cc7836cf67778dde4Sudheer Shanka } 347a5daf2dfdbb7c1b1ea5b930cc7836cf67778dde4Sudheer Shanka } 3486f4ef25d4d1c3473b293e1de7f07dbbc55dc4616Rubin Xu 3496f4ef25d4d1c3473b293e1de7f07dbbc55dc4616Rubin Xu public static boolean isFrpSupported(Context context) { 3506f4ef25d4d1c3473b293e1de7f07dbbc55dc4616Rubin Xu Object pdbManager = context.getSystemService(Context.PERSISTENT_DATA_BLOCK_SERVICE); 3516f4ef25d4d1c3473b293e1de7f07dbbc55dc4616Rubin Xu return pdbManager != null; 3526f4ef25d4d1c3473b293e1de7f07dbbc55dc4616Rubin Xu } 3536f4ef25d4d1c3473b293e1de7f07dbbc55dc4616Rubin Xu 3543128ba4542f3c4c90790af0564e75950c8900961Alan Treadway /** 3553128ba4542f3c4c90790af0564e75950c8900961Alan Treadway * @return the appropriate DevicePolicyManager declared action for the given incoming intent 3563128ba4542f3c4c90790af0564e75950c8900961Alan Treadway * @throws IllegalProvisioningArgumentException if intent is malformed 3573128ba4542f3c4c90790af0564e75950c8900961Alan Treadway */ 3583128ba4542f3c4c90790af0564e75950c8900961Alan Treadway public static String mapIntentToDpmAction(Intent intent) 3593128ba4542f3c4c90790af0564e75950c8900961Alan Treadway throws IllegalProvisioningArgumentException { 3603128ba4542f3c4c90790af0564e75950c8900961Alan Treadway if (intent == null || intent.getAction() == null) { 3613128ba4542f3c4c90790af0564e75950c8900961Alan Treadway throw new IllegalProvisioningArgumentException("Null intent action."); 3623128ba4542f3c4c90790af0564e75950c8900961Alan Treadway } 3633128ba4542f3c4c90790af0564e75950c8900961Alan Treadway 3643128ba4542f3c4c90790af0564e75950c8900961Alan Treadway // Map the incoming intent to a DevicePolicyManager.ACTION_*, as there is a N:1 mapping in 3653128ba4542f3c4c90790af0564e75950c8900961Alan Treadway // some cases. 3663128ba4542f3c4c90790af0564e75950c8900961Alan Treadway String dpmProvisioningAction; 3673128ba4542f3c4c90790af0564e75950c8900961Alan Treadway switch (intent.getAction()) { 3683128ba4542f3c4c90790af0564e75950c8900961Alan Treadway // Trivial cases. 3693128ba4542f3c4c90790af0564e75950c8900961Alan Treadway case ACTION_PROVISION_MANAGED_DEVICE: 3703128ba4542f3c4c90790af0564e75950c8900961Alan Treadway case ACTION_PROVISION_MANAGED_SHAREABLE_DEVICE: 3713128ba4542f3c4c90790af0564e75950c8900961Alan Treadway case ACTION_PROVISION_MANAGED_USER: 3723128ba4542f3c4c90790af0564e75950c8900961Alan Treadway case ACTION_PROVISION_MANAGED_PROFILE: 3733128ba4542f3c4c90790af0564e75950c8900961Alan Treadway dpmProvisioningAction = intent.getAction(); 3743128ba4542f3c4c90790af0564e75950c8900961Alan Treadway break; 3753128ba4542f3c4c90790af0564e75950c8900961Alan Treadway 3763128ba4542f3c4c90790af0564e75950c8900961Alan Treadway // NFC cases which need to take mime-type into account. 3773128ba4542f3c4c90790af0564e75950c8900961Alan Treadway case ACTION_NDEF_DISCOVERED: 3783128ba4542f3c4c90790af0564e75950c8900961Alan Treadway String mimeType = intent.getType(); 3793128ba4542f3c4c90790af0564e75950c8900961Alan Treadway switch (mimeType) { 3803128ba4542f3c4c90790af0564e75950c8900961Alan Treadway case MIME_TYPE_PROVISIONING_NFC: 3813128ba4542f3c4c90790af0564e75950c8900961Alan Treadway dpmProvisioningAction = ACTION_PROVISION_MANAGED_DEVICE; 3823128ba4542f3c4c90790af0564e75950c8900961Alan Treadway break; 3833128ba4542f3c4c90790af0564e75950c8900961Alan Treadway 3843128ba4542f3c4c90790af0564e75950c8900961Alan Treadway default: 3853128ba4542f3c4c90790af0564e75950c8900961Alan Treadway throw new IllegalProvisioningArgumentException( 3863128ba4542f3c4c90790af0564e75950c8900961Alan Treadway "Unknown NFC bump mime-type: " + mimeType); 3873128ba4542f3c4c90790af0564e75950c8900961Alan Treadway } 3883128ba4542f3c4c90790af0564e75950c8900961Alan Treadway break; 3893128ba4542f3c4c90790af0564e75950c8900961Alan Treadway 3903128ba4542f3c4c90790af0564e75950c8900961Alan Treadway default: 3913128ba4542f3c4c90790af0564e75950c8900961Alan Treadway throw new IllegalProvisioningArgumentException("Unknown intent action " 3923128ba4542f3c4c90790af0564e75950c8900961Alan Treadway + intent.getAction()); 3933128ba4542f3c4c90790af0564e75950c8900961Alan Treadway } 3943128ba4542f3c4c90790af0564e75950c8900961Alan Treadway return dpmProvisioningAction; 3953128ba4542f3c4c90790af0564e75950c8900961Alan Treadway } 3963128ba4542f3c4c90790af0564e75950c8900961Alan Treadway 3973128ba4542f3c4c90790af0564e75950c8900961Alan Treadway /** 3983128ba4542f3c4c90790af0564e75950c8900961Alan Treadway * @return the first {@link NdefRecord} found with a recognized MIME-type 3993128ba4542f3c4c90790af0564e75950c8900961Alan Treadway */ 4003128ba4542f3c4c90790af0564e75950c8900961Alan Treadway public static NdefRecord firstNdefRecord(Intent nfcIntent) { 4013128ba4542f3c4c90790af0564e75950c8900961Alan Treadway // Only one first message with NFC_MIME_TYPE is used. 4023128ba4542f3c4c90790af0564e75950c8900961Alan Treadway for (Parcelable rawMsg : nfcIntent.getParcelableArrayExtra( 4033128ba4542f3c4c90790af0564e75950c8900961Alan Treadway NfcAdapter.EXTRA_NDEF_MESSAGES)) { 4043128ba4542f3c4c90790af0564e75950c8900961Alan Treadway NdefMessage msg = (NdefMessage) rawMsg; 4053128ba4542f3c4c90790af0564e75950c8900961Alan Treadway for (NdefRecord record : msg.getRecords()) { 4063128ba4542f3c4c90790af0564e75950c8900961Alan Treadway String mimeType = new String(record.getType(), UTF_8); 4073128ba4542f3c4c90790af0564e75950c8900961Alan Treadway 4083128ba4542f3c4c90790af0564e75950c8900961Alan Treadway if (MIME_TYPE_PROVISIONING_NFC.equals(mimeType)) { 4093128ba4542f3c4c90790af0564e75950c8900961Alan Treadway return record; 4103128ba4542f3c4c90790af0564e75950c8900961Alan Treadway } 4113128ba4542f3c4c90790af0564e75950c8900961Alan Treadway 4123128ba4542f3c4c90790af0564e75950c8900961Alan Treadway // Assume only first record of message is used. 4133128ba4542f3c4c90790af0564e75950c8900961Alan Treadway break; 4143128ba4542f3c4c90790af0564e75950c8900961Alan Treadway } 4153128ba4542f3c4c90790af0564e75950c8900961Alan Treadway } 4163128ba4542f3c4c90790af0564e75950c8900961Alan Treadway return null; 4173128ba4542f3c4c90790af0564e75950c8900961Alan Treadway } 418aa435a10268c541f7bd61a0a254ab934e48fc875Sudheer Shanka 419aa435a10268c541f7bd61a0a254ab934e48fc875Sudheer Shanka public static void sendFactoryResetBroadcast(Context context, String reason) { 420aa435a10268c541f7bd61a0a254ab934e48fc875Sudheer Shanka Intent intent = new Intent(Intent.ACTION_MASTER_CLEAR); 421aa435a10268c541f7bd61a0a254ab934e48fc875Sudheer Shanka intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND); 422aa435a10268c541f7bd61a0a254ab934e48fc875Sudheer Shanka intent.putExtra(Intent.EXTRA_REASON, reason); 423aa435a10268c541f7bd61a0a254ab934e48fc875Sudheer Shanka context.sendBroadcast(intent); 424aa435a10268c541f7bd61a0a254ab934e48fc875Sudheer Shanka } 425e35cc9733194b380637728d39c14dcfc0adee84bNicolas Prevot 426e35cc9733194b380637728d39c14dcfc0adee84bNicolas Prevot public static boolean isProfileOwnerAction(String action) { 427e35cc9733194b380637728d39c14dcfc0adee84bNicolas Prevot return action.equals(ACTION_PROVISION_MANAGED_PROFILE) 428e35cc9733194b380637728d39c14dcfc0adee84bNicolas Prevot || action.equals(ACTION_PROVISION_MANAGED_USER); 429e35cc9733194b380637728d39c14dcfc0adee84bNicolas Prevot } 430e35cc9733194b380637728d39c14dcfc0adee84bNicolas Prevot 431e35cc9733194b380637728d39c14dcfc0adee84bNicolas Prevot public static boolean isDeviceOwnerAction(String action) { 432e35cc9733194b380637728d39c14dcfc0adee84bNicolas Prevot return action.equals(ACTION_PROVISION_MANAGED_DEVICE) 433e35cc9733194b380637728d39c14dcfc0adee84bNicolas Prevot || action.equals(ACTION_PROVISION_MANAGED_SHAREABLE_DEVICE); 434e35cc9733194b380637728d39c14dcfc0adee84bNicolas Prevot } 435e35cc9733194b380637728d39c14dcfc0adee84bNicolas Prevot 436d5e4c42542dd96d8940912cc20dff20fa48da0d9Sander Alewijnse} 437