17db5af124e551554f7a2f1abdd2a486c937910feFyodor Kupolov/*
27db5af124e551554f7a2f1abdd2a486c937910feFyodor Kupolov * Copyright (C) 2015 The Android Open Source Project
37db5af124e551554f7a2f1abdd2a486c937910feFyodor Kupolov *
47db5af124e551554f7a2f1abdd2a486c937910feFyodor Kupolov * Licensed under the Apache License, Version 2.0 (the "License");
57db5af124e551554f7a2f1abdd2a486c937910feFyodor Kupolov * you may not use this file except in compliance with the License.
67db5af124e551554f7a2f1abdd2a486c937910feFyodor Kupolov * You may obtain a copy of the License at
77db5af124e551554f7a2f1abdd2a486c937910feFyodor Kupolov *
87db5af124e551554f7a2f1abdd2a486c937910feFyodor Kupolov *      http://www.apache.org/licenses/LICENSE-2.0
97db5af124e551554f7a2f1abdd2a486c937910feFyodor Kupolov *
107db5af124e551554f7a2f1abdd2a486c937910feFyodor Kupolov * Unless required by applicable law or agreed to in writing, software
117db5af124e551554f7a2f1abdd2a486c937910feFyodor Kupolov * distributed under the License is distributed on an "AS IS" BASIS,
127db5af124e551554f7a2f1abdd2a486c937910feFyodor Kupolov * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
137db5af124e551554f7a2f1abdd2a486c937910feFyodor Kupolov * See the License for the specific language governing permissions and
147db5af124e551554f7a2f1abdd2a486c937910feFyodor Kupolov * limitations under the License
157db5af124e551554f7a2f1abdd2a486c937910feFyodor Kupolov */
167db5af124e551554f7a2f1abdd2a486c937910feFyodor Kupolov
177db5af124e551554f7a2f1abdd2a486c937910feFyodor Kupolovpackage android.content.pm;
187db5af124e551554f7a2f1abdd2a486c937910feFyodor Kupolov
197db5af124e551554f7a2f1abdd2a486c937910feFyodor Kupolovimport android.Manifest;
207db5af124e551554f7a2f1abdd2a486c937910feFyodor Kupolovimport android.app.AppGlobals;
217db5af124e551554f7a2f1abdd2a486c937910feFyodor Kupolovimport android.content.Intent;
227db5af124e551554f7a2f1abdd2a486c937910feFyodor Kupolovimport android.os.RemoteException;
237db5af124e551554f7a2f1abdd2a486c937910feFyodor Kupolovimport android.os.UserHandle;
247db5af124e551554f7a2f1abdd2a486c937910feFyodor Kupolovimport android.util.ArraySet;
251682dad7ed303fc43a07e70d0bb5cb42103a7624Fyodor Kupolovimport android.view.inputmethod.InputMethod;
267db5af124e551554f7a2f1abdd2a486c937910feFyodor Kupolov
277db5af124e551554f7a2f1abdd2a486c937910feFyodor Kupolovimport com.android.internal.annotations.VisibleForTesting;
287db5af124e551554f7a2f1abdd2a486c937910feFyodor Kupolov
297db5af124e551554f7a2f1abdd2a486c937910feFyodor Kupolovimport java.util.ArrayList;
307db5af124e551554f7a2f1abdd2a486c937910feFyodor Kupolovimport java.util.List;
317db5af124e551554f7a2f1abdd2a486c937910feFyodor Kupolov
327db5af124e551554f7a2f1abdd2a486c937910feFyodor Kupolov/**
337db5af124e551554f7a2f1abdd2a486c937910feFyodor Kupolov * Helper class for querying installed applications using multiple criteria.
347db5af124e551554f7a2f1abdd2a486c937910feFyodor Kupolov *
357db5af124e551554f7a2f1abdd2a486c937910feFyodor Kupolov * @hide
367db5af124e551554f7a2f1abdd2a486c937910feFyodor Kupolov */
377db5af124e551554f7a2f1abdd2a486c937910feFyodor Kupolovpublic class AppsQueryHelper {
387db5af124e551554f7a2f1abdd2a486c937910feFyodor Kupolov
397db5af124e551554f7a2f1abdd2a486c937910feFyodor Kupolov    /**
407db5af124e551554f7a2f1abdd2a486c937910feFyodor Kupolov     * Return apps without launcher icon
417db5af124e551554f7a2f1abdd2a486c937910feFyodor Kupolov     */
427db5af124e551554f7a2f1abdd2a486c937910feFyodor Kupolov    public static int GET_NON_LAUNCHABLE_APPS = 1;
437db5af124e551554f7a2f1abdd2a486c937910feFyodor Kupolov
447db5af124e551554f7a2f1abdd2a486c937910feFyodor Kupolov    /**
451682dad7ed303fc43a07e70d0bb5cb42103a7624Fyodor Kupolov     * Return apps with {@link Manifest.permission#INTERACT_ACROSS_USERS} permission
467db5af124e551554f7a2f1abdd2a486c937910feFyodor Kupolov     */
477db5af124e551554f7a2f1abdd2a486c937910feFyodor Kupolov    public static int GET_APPS_WITH_INTERACT_ACROSS_USERS_PERM = 1 << 1;
487db5af124e551554f7a2f1abdd2a486c937910feFyodor Kupolov
49b3b4f61525a3547920d642841202730f3cb16151Fyodor Kupolov    /**
501682dad7ed303fc43a07e70d0bb5cb42103a7624Fyodor Kupolov     * Return all input methods available for the current user.
51b3b4f61525a3547920d642841202730f3cb16151Fyodor Kupolov     */
521682dad7ed303fc43a07e70d0bb5cb42103a7624Fyodor Kupolov    public static int GET_IMES = 1 << 2;
53b3b4f61525a3547920d642841202730f3cb16151Fyodor Kupolov
54bdbc9692c7cb365d9d3f239baa2377724a6f7bc8Fyodor Kupolov    /**
55bdbc9692c7cb365d9d3f239baa2377724a6f7bc8Fyodor Kupolov     * Return all apps that are flagged as required for the system user.
56bdbc9692c7cb365d9d3f239baa2377724a6f7bc8Fyodor Kupolov     */
57bdbc9692c7cb365d9d3f239baa2377724a6f7bc8Fyodor Kupolov    public static int GET_REQUIRED_FOR_SYSTEM_USER = 1 << 3;
58bdbc9692c7cb365d9d3f239baa2377724a6f7bc8Fyodor Kupolov
591682dad7ed303fc43a07e70d0bb5cb42103a7624Fyodor Kupolov    private final IPackageManager mPackageManager;
607db5af124e551554f7a2f1abdd2a486c937910feFyodor Kupolov    private List<ApplicationInfo> mAllApps;
617db5af124e551554f7a2f1abdd2a486c937910feFyodor Kupolov
621682dad7ed303fc43a07e70d0bb5cb42103a7624Fyodor Kupolov    public AppsQueryHelper(IPackageManager packageManager) {
631682dad7ed303fc43a07e70d0bb5cb42103a7624Fyodor Kupolov        mPackageManager = packageManager;
641682dad7ed303fc43a07e70d0bb5cb42103a7624Fyodor Kupolov    }
651682dad7ed303fc43a07e70d0bb5cb42103a7624Fyodor Kupolov
661682dad7ed303fc43a07e70d0bb5cb42103a7624Fyodor Kupolov    public AppsQueryHelper() {
671682dad7ed303fc43a07e70d0bb5cb42103a7624Fyodor Kupolov        this(AppGlobals.getPackageManager());
687db5af124e551554f7a2f1abdd2a486c937910feFyodor Kupolov    }
697db5af124e551554f7a2f1abdd2a486c937910feFyodor Kupolov
707db5af124e551554f7a2f1abdd2a486c937910feFyodor Kupolov    /**
717db5af124e551554f7a2f1abdd2a486c937910feFyodor Kupolov     * Return a List of all packages that satisfy a specified criteria.
727db5af124e551554f7a2f1abdd2a486c937910feFyodor Kupolov     * @param flags search flags. Use any combination of {@link #GET_NON_LAUNCHABLE_APPS},
731682dad7ed303fc43a07e70d0bb5cb42103a7624Fyodor Kupolov     * {@link #GET_APPS_WITH_INTERACT_ACROSS_USERS_PERM} or {@link #GET_IMES}.
747db5af124e551554f7a2f1abdd2a486c937910feFyodor Kupolov     * @param systemAppsOnly if true, only system apps will be returned
757db5af124e551554f7a2f1abdd2a486c937910feFyodor Kupolov     * @param user user, whose apps are queried
767db5af124e551554f7a2f1abdd2a486c937910feFyodor Kupolov     */
777db5af124e551554f7a2f1abdd2a486c937910feFyodor Kupolov    public List<String> queryApps(int flags, boolean systemAppsOnly, UserHandle user) {
787db5af124e551554f7a2f1abdd2a486c937910feFyodor Kupolov        boolean nonLaunchableApps = (flags & GET_NON_LAUNCHABLE_APPS) > 0;
797db5af124e551554f7a2f1abdd2a486c937910feFyodor Kupolov        boolean interactAcrossUsers = (flags & GET_APPS_WITH_INTERACT_ACROSS_USERS_PERM) > 0;
801682dad7ed303fc43a07e70d0bb5cb42103a7624Fyodor Kupolov        boolean imes = (flags & GET_IMES) > 0;
81bdbc9692c7cb365d9d3f239baa2377724a6f7bc8Fyodor Kupolov        boolean requiredForSystemUser = (flags & GET_REQUIRED_FOR_SYSTEM_USER) > 0;
827db5af124e551554f7a2f1abdd2a486c937910feFyodor Kupolov        if (mAllApps == null) {
837db5af124e551554f7a2f1abdd2a486c937910feFyodor Kupolov            mAllApps = getAllApps(user.getIdentifier());
847db5af124e551554f7a2f1abdd2a486c937910feFyodor Kupolov        }
857db5af124e551554f7a2f1abdd2a486c937910feFyodor Kupolov
867db5af124e551554f7a2f1abdd2a486c937910feFyodor Kupolov        List<String> result = new ArrayList<>();
877db5af124e551554f7a2f1abdd2a486c937910feFyodor Kupolov        if (flags == 0) {
887db5af124e551554f7a2f1abdd2a486c937910feFyodor Kupolov            final int allAppsSize = mAllApps.size();
897db5af124e551554f7a2f1abdd2a486c937910feFyodor Kupolov            for (int i = 0; i < allAppsSize; i++) {
907db5af124e551554f7a2f1abdd2a486c937910feFyodor Kupolov                final ApplicationInfo appInfo = mAllApps.get(i);
917db5af124e551554f7a2f1abdd2a486c937910feFyodor Kupolov                if (systemAppsOnly && !appInfo.isSystemApp()) {
927db5af124e551554f7a2f1abdd2a486c937910feFyodor Kupolov                    continue;
937db5af124e551554f7a2f1abdd2a486c937910feFyodor Kupolov                }
947db5af124e551554f7a2f1abdd2a486c937910feFyodor Kupolov                result.add(appInfo.packageName);
957db5af124e551554f7a2f1abdd2a486c937910feFyodor Kupolov            }
967db5af124e551554f7a2f1abdd2a486c937910feFyodor Kupolov            return result;
977db5af124e551554f7a2f1abdd2a486c937910feFyodor Kupolov        }
987db5af124e551554f7a2f1abdd2a486c937910feFyodor Kupolov
997db5af124e551554f7a2f1abdd2a486c937910feFyodor Kupolov        if (nonLaunchableApps) {
1007db5af124e551554f7a2f1abdd2a486c937910feFyodor Kupolov            Intent intent = new Intent(Intent.ACTION_MAIN).addCategory(Intent.CATEGORY_LAUNCHER);
1017db5af124e551554f7a2f1abdd2a486c937910feFyodor Kupolov            final List<ResolveInfo> resolveInfos = queryIntentActivitiesAsUser(intent,
1027db5af124e551554f7a2f1abdd2a486c937910feFyodor Kupolov                    user.getIdentifier());
1037db5af124e551554f7a2f1abdd2a486c937910feFyodor Kupolov
1047db5af124e551554f7a2f1abdd2a486c937910feFyodor Kupolov            ArraySet<String> appsWithLaunchers = new ArraySet<>();
1057db5af124e551554f7a2f1abdd2a486c937910feFyodor Kupolov            final int resolveInfosSize = resolveInfos.size();
1067db5af124e551554f7a2f1abdd2a486c937910feFyodor Kupolov            for (int i = 0; i < resolveInfosSize; i++) {
1077db5af124e551554f7a2f1abdd2a486c937910feFyodor Kupolov                appsWithLaunchers.add(resolveInfos.get(i).activityInfo.packageName);
1087db5af124e551554f7a2f1abdd2a486c937910feFyodor Kupolov            }
1097db5af124e551554f7a2f1abdd2a486c937910feFyodor Kupolov            final int allAppsSize = mAllApps.size();
1107db5af124e551554f7a2f1abdd2a486c937910feFyodor Kupolov            for (int i = 0; i < allAppsSize; i++) {
1117db5af124e551554f7a2f1abdd2a486c937910feFyodor Kupolov                final ApplicationInfo appInfo = mAllApps.get(i);
1127db5af124e551554f7a2f1abdd2a486c937910feFyodor Kupolov                if (systemAppsOnly && !appInfo.isSystemApp()) {
1137db5af124e551554f7a2f1abdd2a486c937910feFyodor Kupolov                    continue;
1147db5af124e551554f7a2f1abdd2a486c937910feFyodor Kupolov                }
1157db5af124e551554f7a2f1abdd2a486c937910feFyodor Kupolov                final String packageName = appInfo.packageName;
1167db5af124e551554f7a2f1abdd2a486c937910feFyodor Kupolov                if (!appsWithLaunchers.contains(packageName)) {
1177db5af124e551554f7a2f1abdd2a486c937910feFyodor Kupolov                    result.add(packageName);
1187db5af124e551554f7a2f1abdd2a486c937910feFyodor Kupolov                }
1197db5af124e551554f7a2f1abdd2a486c937910feFyodor Kupolov            }
1207db5af124e551554f7a2f1abdd2a486c937910feFyodor Kupolov        }
1217db5af124e551554f7a2f1abdd2a486c937910feFyodor Kupolov        if (interactAcrossUsers) {
1227db5af124e551554f7a2f1abdd2a486c937910feFyodor Kupolov            final List<PackageInfo> packagesHoldingPermissions = getPackagesHoldingPermission(
1237db5af124e551554f7a2f1abdd2a486c937910feFyodor Kupolov                    Manifest.permission.INTERACT_ACROSS_USERS, user.getIdentifier());
1247db5af124e551554f7a2f1abdd2a486c937910feFyodor Kupolov            final int packagesHoldingPermissionsSize = packagesHoldingPermissions.size();
1257db5af124e551554f7a2f1abdd2a486c937910feFyodor Kupolov            for (int i = 0; i < packagesHoldingPermissionsSize; i++) {
1267db5af124e551554f7a2f1abdd2a486c937910feFyodor Kupolov                PackageInfo packageInfo = packagesHoldingPermissions.get(i);
1277db5af124e551554f7a2f1abdd2a486c937910feFyodor Kupolov                if (systemAppsOnly && !packageInfo.applicationInfo.isSystemApp()) {
1287db5af124e551554f7a2f1abdd2a486c937910feFyodor Kupolov                    continue;
1297db5af124e551554f7a2f1abdd2a486c937910feFyodor Kupolov                }
1307db5af124e551554f7a2f1abdd2a486c937910feFyodor Kupolov                if (!result.contains(packageInfo.packageName)) {
1317db5af124e551554f7a2f1abdd2a486c937910feFyodor Kupolov                    result.add(packageInfo.packageName);
1327db5af124e551554f7a2f1abdd2a486c937910feFyodor Kupolov                }
1337db5af124e551554f7a2f1abdd2a486c937910feFyodor Kupolov            }
1347db5af124e551554f7a2f1abdd2a486c937910feFyodor Kupolov        }
1357db5af124e551554f7a2f1abdd2a486c937910feFyodor Kupolov
1361682dad7ed303fc43a07e70d0bb5cb42103a7624Fyodor Kupolov        if (imes) {
1371682dad7ed303fc43a07e70d0bb5cb42103a7624Fyodor Kupolov            final List<ResolveInfo> resolveInfos = queryIntentServicesAsUser(
1381682dad7ed303fc43a07e70d0bb5cb42103a7624Fyodor Kupolov                    new Intent(InputMethod.SERVICE_INTERFACE), user.getIdentifier());
1391682dad7ed303fc43a07e70d0bb5cb42103a7624Fyodor Kupolov            final int resolveInfosSize = resolveInfos.size();
1401682dad7ed303fc43a07e70d0bb5cb42103a7624Fyodor Kupolov
1411682dad7ed303fc43a07e70d0bb5cb42103a7624Fyodor Kupolov            for (int i = 0; i < resolveInfosSize; i++) {
1421682dad7ed303fc43a07e70d0bb5cb42103a7624Fyodor Kupolov                ServiceInfo serviceInfo = resolveInfos.get(i).serviceInfo;
1431682dad7ed303fc43a07e70d0bb5cb42103a7624Fyodor Kupolov                if (systemAppsOnly && !serviceInfo.applicationInfo.isSystemApp()) {
144b3b4f61525a3547920d642841202730f3cb16151Fyodor Kupolov                    continue;
145b3b4f61525a3547920d642841202730f3cb16151Fyodor Kupolov                }
1461682dad7ed303fc43a07e70d0bb5cb42103a7624Fyodor Kupolov                if (!result.contains(serviceInfo.packageName)) {
1471682dad7ed303fc43a07e70d0bb5cb42103a7624Fyodor Kupolov                    result.add(serviceInfo.packageName);
148b3b4f61525a3547920d642841202730f3cb16151Fyodor Kupolov                }
149b3b4f61525a3547920d642841202730f3cb16151Fyodor Kupolov            }
150b3b4f61525a3547920d642841202730f3cb16151Fyodor Kupolov        }
151b3b4f61525a3547920d642841202730f3cb16151Fyodor Kupolov
152bdbc9692c7cb365d9d3f239baa2377724a6f7bc8Fyodor Kupolov        if (requiredForSystemUser) {
153bdbc9692c7cb365d9d3f239baa2377724a6f7bc8Fyodor Kupolov            final int allAppsSize = mAllApps.size();
154bdbc9692c7cb365d9d3f239baa2377724a6f7bc8Fyodor Kupolov            for (int i = 0; i < allAppsSize; i++) {
155bdbc9692c7cb365d9d3f239baa2377724a6f7bc8Fyodor Kupolov                final ApplicationInfo appInfo = mAllApps.get(i);
156bdbc9692c7cb365d9d3f239baa2377724a6f7bc8Fyodor Kupolov                if (systemAppsOnly && !appInfo.isSystemApp()) {
157bdbc9692c7cb365d9d3f239baa2377724a6f7bc8Fyodor Kupolov                    continue;
158bdbc9692c7cb365d9d3f239baa2377724a6f7bc8Fyodor Kupolov                }
159bdbc9692c7cb365d9d3f239baa2377724a6f7bc8Fyodor Kupolov                if (appInfo.isRequiredForSystemUser()) {
160bdbc9692c7cb365d9d3f239baa2377724a6f7bc8Fyodor Kupolov                    result.add(appInfo.packageName);
161bdbc9692c7cb365d9d3f239baa2377724a6f7bc8Fyodor Kupolov                }
162bdbc9692c7cb365d9d3f239baa2377724a6f7bc8Fyodor Kupolov            }
163bdbc9692c7cb365d9d3f239baa2377724a6f7bc8Fyodor Kupolov        }
1647db5af124e551554f7a2f1abdd2a486c937910feFyodor Kupolov        return result;
1657db5af124e551554f7a2f1abdd2a486c937910feFyodor Kupolov    }
1667db5af124e551554f7a2f1abdd2a486c937910feFyodor Kupolov
1677db5af124e551554f7a2f1abdd2a486c937910feFyodor Kupolov    @VisibleForTesting
1687db5af124e551554f7a2f1abdd2a486c937910feFyodor Kupolov    @SuppressWarnings("unchecked")
1697db5af124e551554f7a2f1abdd2a486c937910feFyodor Kupolov    protected List<ApplicationInfo> getAllApps(int userId) {
1707db5af124e551554f7a2f1abdd2a486c937910feFyodor Kupolov        try {
171bb803cf2f602d2b1302d0ce33a8066ac30aa471bXiaohui Chen            return mPackageManager.getInstalledApplications(
172bb803cf2f602d2b1302d0ce33a8066ac30aa471bXiaohui Chen                    PackageManager.MATCH_UNINSTALLED_PACKAGES
173bb803cf2f602d2b1302d0ce33a8066ac30aa471bXiaohui Chen                            | PackageManager.MATCH_DISABLED_COMPONENTS, userId).getList();
1747db5af124e551554f7a2f1abdd2a486c937910feFyodor Kupolov        } catch (RemoteException e) {
175d5896630f6a2f21da107031cab216dc93bdcd851Jeff Sharkey            throw e.rethrowFromSystemServer();
1767db5af124e551554f7a2f1abdd2a486c937910feFyodor Kupolov        }
1777db5af124e551554f7a2f1abdd2a486c937910feFyodor Kupolov    }
1787db5af124e551554f7a2f1abdd2a486c937910feFyodor Kupolov
1797db5af124e551554f7a2f1abdd2a486c937910feFyodor Kupolov    @VisibleForTesting
1807db5af124e551554f7a2f1abdd2a486c937910feFyodor Kupolov    protected List<ResolveInfo> queryIntentActivitiesAsUser(Intent intent, int userId) {
1811682dad7ed303fc43a07e70d0bb5cb42103a7624Fyodor Kupolov        try {
1821682dad7ed303fc43a07e70d0bb5cb42103a7624Fyodor Kupolov            return mPackageManager.queryIntentActivities(intent, null,
183bb803cf2f602d2b1302d0ce33a8066ac30aa471bXiaohui Chen                    PackageManager.MATCH_DISABLED_COMPONENTS
184bb803cf2f602d2b1302d0ce33a8066ac30aa471bXiaohui Chen                            | PackageManager.MATCH_UNINSTALLED_PACKAGES
185bb803cf2f602d2b1302d0ce33a8066ac30aa471bXiaohui Chen                            | PackageManager.MATCH_DIRECT_BOOT_AWARE
186bb803cf2f602d2b1302d0ce33a8066ac30aa471bXiaohui Chen                            | PackageManager.MATCH_DIRECT_BOOT_UNAWARE,
187d5896630f6a2f21da107031cab216dc93bdcd851Jeff Sharkey                    userId).getList();
1881682dad7ed303fc43a07e70d0bb5cb42103a7624Fyodor Kupolov        } catch (RemoteException e) {
189d5896630f6a2f21da107031cab216dc93bdcd851Jeff Sharkey            throw e.rethrowFromSystemServer();
1901682dad7ed303fc43a07e70d0bb5cb42103a7624Fyodor Kupolov        }
1917db5af124e551554f7a2f1abdd2a486c937910feFyodor Kupolov    }
1927db5af124e551554f7a2f1abdd2a486c937910feFyodor Kupolov
1937db5af124e551554f7a2f1abdd2a486c937910feFyodor Kupolov    @VisibleForTesting
1941682dad7ed303fc43a07e70d0bb5cb42103a7624Fyodor Kupolov    protected List<ResolveInfo> queryIntentServicesAsUser(Intent intent, int userId) {
1957db5af124e551554f7a2f1abdd2a486c937910feFyodor Kupolov        try {
1961682dad7ed303fc43a07e70d0bb5cb42103a7624Fyodor Kupolov            return mPackageManager.queryIntentServices(intent, null,
1971682dad7ed303fc43a07e70d0bb5cb42103a7624Fyodor Kupolov                    PackageManager.GET_META_DATA
198bb803cf2f602d2b1302d0ce33a8066ac30aa471bXiaohui Chen                            | PackageManager.MATCH_DISABLED_UNTIL_USED_COMPONENTS
199bb803cf2f602d2b1302d0ce33a8066ac30aa471bXiaohui Chen                            | PackageManager.MATCH_DIRECT_BOOT_AWARE
200bb803cf2f602d2b1302d0ce33a8066ac30aa471bXiaohui Chen                            | PackageManager.MATCH_DIRECT_BOOT_UNAWARE, userId)
201bb803cf2f602d2b1302d0ce33a8066ac30aa471bXiaohui Chen                    .getList();
2027db5af124e551554f7a2f1abdd2a486c937910feFyodor Kupolov        } catch (RemoteException e) {
203d5896630f6a2f21da107031cab216dc93bdcd851Jeff Sharkey            throw e.rethrowFromSystemServer();
2047db5af124e551554f7a2f1abdd2a486c937910feFyodor Kupolov        }
2057db5af124e551554f7a2f1abdd2a486c937910feFyodor Kupolov    }
206b3b4f61525a3547920d642841202730f3cb16151Fyodor Kupolov
207b3b4f61525a3547920d642841202730f3cb16151Fyodor Kupolov    @VisibleForTesting
208b3b4f61525a3547920d642841202730f3cb16151Fyodor Kupolov    @SuppressWarnings("unchecked")
2091682dad7ed303fc43a07e70d0bb5cb42103a7624Fyodor Kupolov    protected List<PackageInfo> getPackagesHoldingPermission(String perm, int userId) {
2101682dad7ed303fc43a07e70d0bb5cb42103a7624Fyodor Kupolov        try {
2111682dad7ed303fc43a07e70d0bb5cb42103a7624Fyodor Kupolov            return mPackageManager.getPackagesHoldingPermissions(new String[]{perm}, 0,
2121682dad7ed303fc43a07e70d0bb5cb42103a7624Fyodor Kupolov                    userId).getList();
2131682dad7ed303fc43a07e70d0bb5cb42103a7624Fyodor Kupolov        } catch (RemoteException e) {
214d5896630f6a2f21da107031cab216dc93bdcd851Jeff Sharkey            throw e.rethrowFromSystemServer();
2151682dad7ed303fc43a07e70d0bb5cb42103a7624Fyodor Kupolov        }
216b3b4f61525a3547920d642841202730f3cb16151Fyodor Kupolov    }
2177db5af124e551554f7a2f1abdd2a486c937910feFyodor Kupolov}
218