Utils.java revision 74d6c14da5117ffd3458602f9f6946c531143436
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
1984e56f5cfc1d45b3983dd553096182e774d8cb2cJoe Delfinoimport android.app.admin.DevicePolicyManager;
209a42f2b64dada715248aec7c898f983375a395eeAlan Treadwayimport android.content.ComponentName;
210b4472570d93aeeda5a33dc05c0dcf03f2d3538bNicolas Prevotimport android.content.Context;
229a42f2b64dada715248aec7c898f983375a395eeAlan Treadwayimport android.content.Intent;
230b4472570d93aeeda5a33dc05c0dcf03f2d3538bNicolas Prevotimport android.content.pm.ActivityInfo;
24d5e4c42542dd96d8940912cc20dff20fa48da0d9Sander Alewijnseimport android.content.pm.ApplicationInfo;
25d5e4c42542dd96d8940912cc20dff20fa48da0d9Sander Alewijnseimport android.content.pm.IPackageManager;
260b4472570d93aeeda5a33dc05c0dcf03f2d3538bNicolas Prevotimport android.content.pm.PackageInfo;
27d5e4c42542dd96d8940912cc20dff20fa48da0d9Sander Alewijnseimport android.content.pm.PackageManager;
280b4472570d93aeeda5a33dc05c0dcf03f2d3538bNicolas Prevotimport android.content.pm.PackageManager.NameNotFoundException;
2984e56f5cfc1d45b3983dd553096182e774d8cb2cJoe Delfinoimport android.content.pm.UserInfo;
309a42f2b64dada715248aec7c898f983375a395eeAlan Treadwayimport android.graphics.drawable.Drawable;
3184e56f5cfc1d45b3983dd553096182e774d8cb2cJoe Delfinoimport android.os.Binder;
32d5e4c42542dd96d8940912cc20dff20fa48da0d9Sander Alewijnseimport android.os.RemoteException;
33d5e4c42542dd96d8940912cc20dff20fa48da0d9Sander Alewijnseimport android.os.ServiceManager;
34d0f2928a28d38ce8344b7f15fbfec97aebec0db6Joe Delfinoimport android.os.UserHandle;
3584e56f5cfc1d45b3983dd553096182e774d8cb2cJoe Delfinoimport android.os.UserManager;
360b4472570d93aeeda5a33dc05c0dcf03f2d3538bNicolas Prevotimport android.text.TextUtils;
37d5e4c42542dd96d8940912cc20dff20fa48da0d9Sander Alewijnse
38d5e4c42542dd96d8940912cc20dff20fa48da0d9Sander Alewijnseimport java.util.HashSet;
399a42f2b64dada715248aec7c898f983375a395eeAlan Treadwayimport java.util.List;
40d5e4c42542dd96d8940912cc20dff20fa48da0d9Sander Alewijnseimport java.util.Set;
41d5e4c42542dd96d8940912cc20dff20fa48da0d9Sander Alewijnse
429a42f2b64dada715248aec7c898f983375a395eeAlan Treadwayimport static android.app.admin.DevicePolicyManager.EXTRA_PROVISIONING_DEVICE_ADMIN_COMPONENT_NAME;
439a42f2b64dada715248aec7c898f983375a395eeAlan Treadwayimport static android.app.admin.DevicePolicyManager.EXTRA_PROVISIONING_DEVICE_ADMIN_PACKAGE_NAME;
449a42f2b64dada715248aec7c898f983375a395eeAlan Treadway
45d5e4c42542dd96d8940912cc20dff20fa48da0d9Sander Alewijnse/**
46d5e4c42542dd96d8940912cc20dff20fa48da0d9Sander Alewijnse * Class containing various auxiliary methods.
47d5e4c42542dd96d8940912cc20dff20fa48da0d9Sander Alewijnse */
48d5e4c42542dd96d8940912cc20dff20fa48da0d9Sander Alewijnsepublic class Utils {
499a42f2b64dada715248aec7c898f983375a395eeAlan Treadway    private Utils() {}
509a42f2b64dada715248aec7c898f983375a395eeAlan Treadway
51d5e4c42542dd96d8940912cc20dff20fa48da0d9Sander Alewijnse    public static Set<String> getCurrentSystemApps(int userId) {
52d5e4c42542dd96d8940912cc20dff20fa48da0d9Sander Alewijnse        IPackageManager ipm = IPackageManager.Stub.asInterface(ServiceManager
53d5e4c42542dd96d8940912cc20dff20fa48da0d9Sander Alewijnse                .getService("package"));
54d5e4c42542dd96d8940912cc20dff20fa48da0d9Sander Alewijnse        Set<String> apps = new HashSet<String>();
55d5e4c42542dd96d8940912cc20dff20fa48da0d9Sander Alewijnse        List<ApplicationInfo> aInfos = null;
56d5e4c42542dd96d8940912cc20dff20fa48da0d9Sander Alewijnse        try {
57d5e4c42542dd96d8940912cc20dff20fa48da0d9Sander Alewijnse            aInfos = ipm.getInstalledApplications(
58d5e4c42542dd96d8940912cc20dff20fa48da0d9Sander Alewijnse                    PackageManager.GET_UNINSTALLED_PACKAGES, userId).getList();
59d5e4c42542dd96d8940912cc20dff20fa48da0d9Sander Alewijnse        } catch (RemoteException neverThrown) {
60d5e4c42542dd96d8940912cc20dff20fa48da0d9Sander Alewijnse            ProvisionLogger.loge("This should not happen.", neverThrown);
61d5e4c42542dd96d8940912cc20dff20fa48da0d9Sander Alewijnse        }
62d5e4c42542dd96d8940912cc20dff20fa48da0d9Sander Alewijnse        for (ApplicationInfo aInfo : aInfos) {
63d5e4c42542dd96d8940912cc20dff20fa48da0d9Sander Alewijnse            if ((aInfo.flags & ApplicationInfo.FLAG_SYSTEM) != 0) {
64d5e4c42542dd96d8940912cc20dff20fa48da0d9Sander Alewijnse                apps.add(aInfo.packageName);
65d5e4c42542dd96d8940912cc20dff20fa48da0d9Sander Alewijnse            }
66d5e4c42542dd96d8940912cc20dff20fa48da0d9Sander Alewijnse        }
67d5e4c42542dd96d8940912cc20dff20fa48da0d9Sander Alewijnse        return apps;
68d5e4c42542dd96d8940912cc20dff20fa48da0d9Sander Alewijnse    }
69d5e4c42542dd96d8940912cc20dff20fa48da0d9Sander Alewijnse
70d5e4c42542dd96d8940912cc20dff20fa48da0d9Sander Alewijnse    public static void disableComponent(ComponentName toDisable, int userId) {
71d5e4c42542dd96d8940912cc20dff20fa48da0d9Sander Alewijnse        try {
72d5e4c42542dd96d8940912cc20dff20fa48da0d9Sander Alewijnse            IPackageManager ipm = IPackageManager.Stub.asInterface(ServiceManager
73d5e4c42542dd96d8940912cc20dff20fa48da0d9Sander Alewijnse                .getService("package"));
74d5e4c42542dd96d8940912cc20dff20fa48da0d9Sander Alewijnse
75d5e4c42542dd96d8940912cc20dff20fa48da0d9Sander Alewijnse            ipm.setComponentEnabledSetting(toDisable,
76d5e4c42542dd96d8940912cc20dff20fa48da0d9Sander Alewijnse                    PackageManager.COMPONENT_ENABLED_STATE_DISABLED, PackageManager.DONT_KILL_APP,
77d5e4c42542dd96d8940912cc20dff20fa48da0d9Sander Alewijnse                    userId);
78d5e4c42542dd96d8940912cc20dff20fa48da0d9Sander Alewijnse        } catch (RemoteException neverThrown) {
79d5e4c42542dd96d8940912cc20dff20fa48da0d9Sander Alewijnse            ProvisionLogger.loge("This should not happen.", neverThrown);
80d5e4c42542dd96d8940912cc20dff20fa48da0d9Sander Alewijnse        } catch (Exception e) {
81d5e4c42542dd96d8940912cc20dff20fa48da0d9Sander Alewijnse            ProvisionLogger.logw("Component not found, not disabling it: "
82d5e4c42542dd96d8940912cc20dff20fa48da0d9Sander Alewijnse                + toDisable.toShortString());
83d5e4c42542dd96d8940912cc20dff20fa48da0d9Sander Alewijnse        }
84d5e4c42542dd96d8940912cc20dff20fa48da0d9Sander Alewijnse    }
850b4472570d93aeeda5a33dc05c0dcf03f2d3538bNicolas Prevot
860b4472570d93aeeda5a33dc05c0dcf03f2d3538bNicolas Prevot    public static ComponentName findDeviceAdminFromIntent(Intent intent, Context c)
870b4472570d93aeeda5a33dc05c0dcf03f2d3538bNicolas Prevot            throws IllegalProvisioningArgumentException {
880b4472570d93aeeda5a33dc05c0dcf03f2d3538bNicolas Prevot        ComponentName mdmComponentName = intent.getParcelableExtra(
890b4472570d93aeeda5a33dc05c0dcf03f2d3538bNicolas Prevot                EXTRA_PROVISIONING_DEVICE_ADMIN_COMPONENT_NAME);
900b4472570d93aeeda5a33dc05c0dcf03f2d3538bNicolas Prevot        String mdmPackageName = intent.getStringExtra(
910b4472570d93aeeda5a33dc05c0dcf03f2d3538bNicolas Prevot                EXTRA_PROVISIONING_DEVICE_ADMIN_PACKAGE_NAME);
920b4472570d93aeeda5a33dc05c0dcf03f2d3538bNicolas Prevot        return findDeviceAdmin(mdmPackageName, mdmComponentName, c);
930b4472570d93aeeda5a33dc05c0dcf03f2d3538bNicolas Prevot    }
940b4472570d93aeeda5a33dc05c0dcf03f2d3538bNicolas Prevot
950b4472570d93aeeda5a33dc05c0dcf03f2d3538bNicolas Prevot    /**
960b4472570d93aeeda5a33dc05c0dcf03f2d3538bNicolas Prevot     * Exception thrown when the provisioning has failed completely.
970b4472570d93aeeda5a33dc05c0dcf03f2d3538bNicolas Prevot     *
980b4472570d93aeeda5a33dc05c0dcf03f2d3538bNicolas Prevot     * We're using a custom exception to avoid catching subsequent exceptions that might be
990b4472570d93aeeda5a33dc05c0dcf03f2d3538bNicolas Prevot     * significant.
1000b4472570d93aeeda5a33dc05c0dcf03f2d3538bNicolas Prevot     */
1010b4472570d93aeeda5a33dc05c0dcf03f2d3538bNicolas Prevot    public static class IllegalProvisioningArgumentException extends Exception {
1020b4472570d93aeeda5a33dc05c0dcf03f2d3538bNicolas Prevot        public IllegalProvisioningArgumentException(String message) {
1030b4472570d93aeeda5a33dc05c0dcf03f2d3538bNicolas Prevot            super(message);
1040b4472570d93aeeda5a33dc05c0dcf03f2d3538bNicolas Prevot        }
1050b4472570d93aeeda5a33dc05c0dcf03f2d3538bNicolas Prevot
1060b4472570d93aeeda5a33dc05c0dcf03f2d3538bNicolas Prevot        public IllegalProvisioningArgumentException(String message, Throwable t) {
1070b4472570d93aeeda5a33dc05c0dcf03f2d3538bNicolas Prevot            super(message, t);
1080b4472570d93aeeda5a33dc05c0dcf03f2d3538bNicolas Prevot        }
1090b4472570d93aeeda5a33dc05c0dcf03f2d3538bNicolas Prevot    }
1100b4472570d93aeeda5a33dc05c0dcf03f2d3538bNicolas Prevot
1110b4472570d93aeeda5a33dc05c0dcf03f2d3538bNicolas Prevot    /**
1120b4472570d93aeeda5a33dc05c0dcf03f2d3538bNicolas Prevot     * Check the validity of the admin component name supplied, or try to infer this componentName
1130b4472570d93aeeda5a33dc05c0dcf03f2d3538bNicolas Prevot     * from the package.
1140b4472570d93aeeda5a33dc05c0dcf03f2d3538bNicolas Prevot     *
1150b4472570d93aeeda5a33dc05c0dcf03f2d3538bNicolas Prevot     * We are supporting lookup by package name for legacy reasons.
1160b4472570d93aeeda5a33dc05c0dcf03f2d3538bNicolas Prevot     *
1170b4472570d93aeeda5a33dc05c0dcf03f2d3538bNicolas Prevot     * If mdmComponentName is supplied (not null):
1180b4472570d93aeeda5a33dc05c0dcf03f2d3538bNicolas Prevot     * mdmPackageName is ignored.
1190b4472570d93aeeda5a33dc05c0dcf03f2d3538bNicolas Prevot     * Check that the package of mdmComponentName is installed, that mdmComponentName is a
1200b4472570d93aeeda5a33dc05c0dcf03f2d3538bNicolas Prevot     * receiver in this package, and return it.
1210b4472570d93aeeda5a33dc05c0dcf03f2d3538bNicolas Prevot     *
1220b4472570d93aeeda5a33dc05c0dcf03f2d3538bNicolas Prevot     * Otherwise:
1230b4472570d93aeeda5a33dc05c0dcf03f2d3538bNicolas Prevot     * mdmPackageName must be supplied (not null).
1240b4472570d93aeeda5a33dc05c0dcf03f2d3538bNicolas Prevot     * Check that this package is installed, try to infer a potential device admin in this package,
1250b4472570d93aeeda5a33dc05c0dcf03f2d3538bNicolas Prevot     * and return it.
1260b4472570d93aeeda5a33dc05c0dcf03f2d3538bNicolas Prevot     */
1270b4472570d93aeeda5a33dc05c0dcf03f2d3538bNicolas Prevot    public static ComponentName findDeviceAdmin(String mdmPackageName,
1280b4472570d93aeeda5a33dc05c0dcf03f2d3538bNicolas Prevot            ComponentName mdmComponentName, Context c) throws IllegalProvisioningArgumentException {
1290b4472570d93aeeda5a33dc05c0dcf03f2d3538bNicolas Prevot        if (mdmComponentName != null) {
1300b4472570d93aeeda5a33dc05c0dcf03f2d3538bNicolas Prevot            mdmPackageName = mdmComponentName.getPackageName();
1310b4472570d93aeeda5a33dc05c0dcf03f2d3538bNicolas Prevot        }
1320b4472570d93aeeda5a33dc05c0dcf03f2d3538bNicolas Prevot        if (mdmPackageName == null) {
1330b4472570d93aeeda5a33dc05c0dcf03f2d3538bNicolas Prevot            throw new IllegalProvisioningArgumentException("Neither the package name nor the"
1340b4472570d93aeeda5a33dc05c0dcf03f2d3538bNicolas Prevot                    + " component name of the admin are supplied");
1350b4472570d93aeeda5a33dc05c0dcf03f2d3538bNicolas Prevot        }
1360b4472570d93aeeda5a33dc05c0dcf03f2d3538bNicolas Prevot        PackageInfo pi;
1370b4472570d93aeeda5a33dc05c0dcf03f2d3538bNicolas Prevot        try {
1380b4472570d93aeeda5a33dc05c0dcf03f2d3538bNicolas Prevot            pi = c.getPackageManager().getPackageInfo(mdmPackageName,
1390b4472570d93aeeda5a33dc05c0dcf03f2d3538bNicolas Prevot                    PackageManager.GET_RECEIVERS);
1400b4472570d93aeeda5a33dc05c0dcf03f2d3538bNicolas Prevot        } catch (NameNotFoundException e) {
1410b4472570d93aeeda5a33dc05c0dcf03f2d3538bNicolas Prevot            throw new IllegalProvisioningArgumentException("Mdm "+ mdmPackageName
1420b4472570d93aeeda5a33dc05c0dcf03f2d3538bNicolas Prevot                    + " is not installed. ", e);
1430b4472570d93aeeda5a33dc05c0dcf03f2d3538bNicolas Prevot        }
1440b4472570d93aeeda5a33dc05c0dcf03f2d3538bNicolas Prevot        if (mdmComponentName != null) {
1450b4472570d93aeeda5a33dc05c0dcf03f2d3538bNicolas Prevot            // If the component was specified in the intent: check that it is in the manifest.
1460b4472570d93aeeda5a33dc05c0dcf03f2d3538bNicolas Prevot            checkAdminComponent(mdmComponentName, pi);
1470b4472570d93aeeda5a33dc05c0dcf03f2d3538bNicolas Prevot            return mdmComponentName;
1480b4472570d93aeeda5a33dc05c0dcf03f2d3538bNicolas Prevot        } else {
1490b4472570d93aeeda5a33dc05c0dcf03f2d3538bNicolas Prevot            // Otherwise: try to find a potential device admin in the manifest.
1500b4472570d93aeeda5a33dc05c0dcf03f2d3538bNicolas Prevot            return findDeviceAdminInPackage(mdmPackageName, pi);
1510b4472570d93aeeda5a33dc05c0dcf03f2d3538bNicolas Prevot        }
1520b4472570d93aeeda5a33dc05c0dcf03f2d3538bNicolas Prevot    }
1530b4472570d93aeeda5a33dc05c0dcf03f2d3538bNicolas Prevot
1540b4472570d93aeeda5a33dc05c0dcf03f2d3538bNicolas Prevot    private static void checkAdminComponent(ComponentName mdmComponentName, PackageInfo pi)
1550b4472570d93aeeda5a33dc05c0dcf03f2d3538bNicolas Prevot            throws IllegalProvisioningArgumentException{
1560b4472570d93aeeda5a33dc05c0dcf03f2d3538bNicolas Prevot        for (ActivityInfo ai : pi.receivers) {
1570b4472570d93aeeda5a33dc05c0dcf03f2d3538bNicolas Prevot            if (mdmComponentName.getClassName().equals(ai.name)) {
1580b4472570d93aeeda5a33dc05c0dcf03f2d3538bNicolas Prevot                return;
1590b4472570d93aeeda5a33dc05c0dcf03f2d3538bNicolas Prevot            }
1600b4472570d93aeeda5a33dc05c0dcf03f2d3538bNicolas Prevot        }
1610b4472570d93aeeda5a33dc05c0dcf03f2d3538bNicolas Prevot        throw new IllegalProvisioningArgumentException("The component " + mdmComponentName
1620b4472570d93aeeda5a33dc05c0dcf03f2d3538bNicolas Prevot                + " cannot be found");
1630b4472570d93aeeda5a33dc05c0dcf03f2d3538bNicolas Prevot    }
1640b4472570d93aeeda5a33dc05c0dcf03f2d3538bNicolas Prevot
1650b4472570d93aeeda5a33dc05c0dcf03f2d3538bNicolas Prevot    private static ComponentName findDeviceAdminInPackage(String mdmPackageName, PackageInfo pi)
1660b4472570d93aeeda5a33dc05c0dcf03f2d3538bNicolas Prevot            throws IllegalProvisioningArgumentException {
1670b4472570d93aeeda5a33dc05c0dcf03f2d3538bNicolas Prevot        ComponentName mdmComponentName = null;
1680b4472570d93aeeda5a33dc05c0dcf03f2d3538bNicolas Prevot        for (ActivityInfo ai : pi.receivers) {
1690b4472570d93aeeda5a33dc05c0dcf03f2d3538bNicolas Prevot            if (!TextUtils.isEmpty(ai.permission) &&
1700b4472570d93aeeda5a33dc05c0dcf03f2d3538bNicolas Prevot                    ai.permission.equals(android.Manifest.permission.BIND_DEVICE_ADMIN)) {
1710b4472570d93aeeda5a33dc05c0dcf03f2d3538bNicolas Prevot                if (mdmComponentName != null) {
1720b4472570d93aeeda5a33dc05c0dcf03f2d3538bNicolas Prevot                    throw new IllegalProvisioningArgumentException("There are several "
1730b4472570d93aeeda5a33dc05c0dcf03f2d3538bNicolas Prevot                            + "device admins in " + mdmPackageName + " but no one in specified");
1740b4472570d93aeeda5a33dc05c0dcf03f2d3538bNicolas Prevot                } else {
1750b4472570d93aeeda5a33dc05c0dcf03f2d3538bNicolas Prevot                    mdmComponentName = new ComponentName(mdmPackageName, ai.name);
1760b4472570d93aeeda5a33dc05c0dcf03f2d3538bNicolas Prevot                }
1770b4472570d93aeeda5a33dc05c0dcf03f2d3538bNicolas Prevot            }
1780b4472570d93aeeda5a33dc05c0dcf03f2d3538bNicolas Prevot        }
1790b4472570d93aeeda5a33dc05c0dcf03f2d3538bNicolas Prevot        if (mdmComponentName == null) {
1800b4472570d93aeeda5a33dc05c0dcf03f2d3538bNicolas Prevot            throw new IllegalProvisioningArgumentException("There are no device admins in"
1810b4472570d93aeeda5a33dc05c0dcf03f2d3538bNicolas Prevot                    + mdmPackageName);
1820b4472570d93aeeda5a33dc05c0dcf03f2d3538bNicolas Prevot        }
1830b4472570d93aeeda5a33dc05c0dcf03f2d3538bNicolas Prevot        return mdmComponentName;
1840b4472570d93aeeda5a33dc05c0dcf03f2d3538bNicolas Prevot    }
1859a42f2b64dada715248aec7c898f983375a395eeAlan Treadway
1869a42f2b64dada715248aec7c898f983375a395eeAlan Treadway    public static MdmPackageInfo getMdmPackageInfo(PackageManager pm, String packageName) {
1879a42f2b64dada715248aec7c898f983375a395eeAlan Treadway        if (packageName != null) {
1889a42f2b64dada715248aec7c898f983375a395eeAlan Treadway            try {
1899a42f2b64dada715248aec7c898f983375a395eeAlan Treadway                ApplicationInfo ai = pm.getApplicationInfo(packageName, /* default flags */ 0);
1909a42f2b64dada715248aec7c898f983375a395eeAlan Treadway                if (ai != null) {
1919a42f2b64dada715248aec7c898f983375a395eeAlan Treadway                    return new MdmPackageInfo(pm.getApplicationIcon(packageName),
1929a42f2b64dada715248aec7c898f983375a395eeAlan Treadway                            pm.getApplicationLabel(ai).toString());
1939a42f2b64dada715248aec7c898f983375a395eeAlan Treadway                }
1949a42f2b64dada715248aec7c898f983375a395eeAlan Treadway            } catch (PackageManager.NameNotFoundException e) {
1959a42f2b64dada715248aec7c898f983375a395eeAlan Treadway                // Package does not exist, ignore. Should never happen.
1969a42f2b64dada715248aec7c898f983375a395eeAlan Treadway                ProvisionLogger.loge("Package does not exist. Should never happen.");
1979a42f2b64dada715248aec7c898f983375a395eeAlan Treadway            }
1989a42f2b64dada715248aec7c898f983375a395eeAlan Treadway        }
1999a42f2b64dada715248aec7c898f983375a395eeAlan Treadway
2009a42f2b64dada715248aec7c898f983375a395eeAlan Treadway        return null;
2019a42f2b64dada715248aec7c898f983375a395eeAlan Treadway    }
2029a42f2b64dada715248aec7c898f983375a395eeAlan Treadway
2039a42f2b64dada715248aec7c898f983375a395eeAlan Treadway    /**
2049a42f2b64dada715248aec7c898f983375a395eeAlan Treadway     * Information relating to the currently installed MDM package manager.
2059a42f2b64dada715248aec7c898f983375a395eeAlan Treadway     */
2069a42f2b64dada715248aec7c898f983375a395eeAlan Treadway    public static final class MdmPackageInfo {
2079a42f2b64dada715248aec7c898f983375a395eeAlan Treadway        private final Drawable packageIcon;
2089a42f2b64dada715248aec7c898f983375a395eeAlan Treadway        private final String appLabel;
2099a42f2b64dada715248aec7c898f983375a395eeAlan Treadway
2109a42f2b64dada715248aec7c898f983375a395eeAlan Treadway        private MdmPackageInfo(Drawable packageIcon, String appLabel) {
2119a42f2b64dada715248aec7c898f983375a395eeAlan Treadway            this.packageIcon = packageIcon;
2129a42f2b64dada715248aec7c898f983375a395eeAlan Treadway            this.appLabel = appLabel;
2139a42f2b64dada715248aec7c898f983375a395eeAlan Treadway        }
2149a42f2b64dada715248aec7c898f983375a395eeAlan Treadway
2159a42f2b64dada715248aec7c898f983375a395eeAlan Treadway        public String getAppLabel() {
2169a42f2b64dada715248aec7c898f983375a395eeAlan Treadway            return appLabel;
2179a42f2b64dada715248aec7c898f983375a395eeAlan Treadway        }
2189a42f2b64dada715248aec7c898f983375a395eeAlan Treadway
2199a42f2b64dada715248aec7c898f983375a395eeAlan Treadway        public Drawable getPackageIcon() {
2209a42f2b64dada715248aec7c898f983375a395eeAlan Treadway            return packageIcon;
2219a42f2b64dada715248aec7c898f983375a395eeAlan Treadway        }
2229a42f2b64dada715248aec7c898f983375a395eeAlan Treadway    }
223d0f2928a28d38ce8344b7f15fbfec97aebec0db6Joe Delfino
224d0f2928a28d38ce8344b7f15fbfec97aebec0db6Joe Delfino    public static boolean isCurrentUserOwner() {
225d0f2928a28d38ce8344b7f15fbfec97aebec0db6Joe Delfino        return UserHandle.myUserId() == UserHandle.USER_OWNER;
226d0f2928a28d38ce8344b7f15fbfec97aebec0db6Joe Delfino    }
22784e56f5cfc1d45b3983dd553096182e774d8cb2cJoe Delfino
22884e56f5cfc1d45b3983dd553096182e774d8cb2cJoe Delfino    public static boolean hasDeviceOwner(Context context) {
22984e56f5cfc1d45b3983dd553096182e774d8cb2cJoe Delfino        DevicePolicyManager dpm =
23084e56f5cfc1d45b3983dd553096182e774d8cb2cJoe Delfino                (DevicePolicyManager) context.getSystemService(Context.DEVICE_POLICY_SERVICE);
23184e56f5cfc1d45b3983dd553096182e774d8cb2cJoe Delfino        return !TextUtils.isEmpty(dpm.getDeviceOwner());
23284e56f5cfc1d45b3983dd553096182e774d8cb2cJoe Delfino    }
23384e56f5cfc1d45b3983dd553096182e774d8cb2cJoe Delfino
23484e56f5cfc1d45b3983dd553096182e774d8cb2cJoe Delfino    public static boolean isManagedProfile(Context context) {
23584e56f5cfc1d45b3983dd553096182e774d8cb2cJoe Delfino        UserManager um = (UserManager) context.getSystemService(Context.USER_SERVICE);
23684e56f5cfc1d45b3983dd553096182e774d8cb2cJoe Delfino        UserInfo user = um.getUserInfo(UserHandle.myUserId());
23784e56f5cfc1d45b3983dd553096182e774d8cb2cJoe Delfino        return user != null ? user.isManagedProfile() : false;
23884e56f5cfc1d45b3983dd553096182e774d8cb2cJoe Delfino    }
23984e56f5cfc1d45b3983dd553096182e774d8cb2cJoe Delfino
24074d6c14da5117ffd3458602f9f6946c531143436Sander Alewijnse    /**
24174d6c14da5117ffd3458602f9f6946c531143436Sander Alewijnse     * Returns true if the given package does not exist on the device or if its version code is less
24274d6c14da5117ffd3458602f9f6946c531143436Sander Alewijnse     * than the given version, and false otherwise.
24374d6c14da5117ffd3458602f9f6946c531143436Sander Alewijnse     */
24474d6c14da5117ffd3458602f9f6946c531143436Sander Alewijnse    public static boolean packageRequiresUpdate(String packageName, int minSupportedVersion,
24574d6c14da5117ffd3458602f9f6946c531143436Sander Alewijnse            Context context) {
24674d6c14da5117ffd3458602f9f6946c531143436Sander Alewijnse        try {
24774d6c14da5117ffd3458602f9f6946c531143436Sander Alewijnse            PackageInfo packageInfo = context.getPackageManager().getPackageInfo(packageName, 0);
24874d6c14da5117ffd3458602f9f6946c531143436Sander Alewijnse            if (packageInfo.versionCode >= minSupportedVersion) {
24974d6c14da5117ffd3458602f9f6946c531143436Sander Alewijnse                return false;
25074d6c14da5117ffd3458602f9f6946c531143436Sander Alewijnse            }
25174d6c14da5117ffd3458602f9f6946c531143436Sander Alewijnse        } catch (NameNotFoundException e) {
25274d6c14da5117ffd3458602f9f6946c531143436Sander Alewijnse            // Package not on device.
25374d6c14da5117ffd3458602f9f6946c531143436Sander Alewijnse        }
25474d6c14da5117ffd3458602f9f6946c531143436Sander Alewijnse
25574d6c14da5117ffd3458602f9f6946c531143436Sander Alewijnse        return true;
25674d6c14da5117ffd3458602f9f6946c531143436Sander Alewijnse    }
25774d6c14da5117ffd3458602f9f6946c531143436Sander Alewijnse
258d5e4c42542dd96d8940912cc20dff20fa48da0d9Sander Alewijnse}
259