1014de02dd2e050c36f7e0d4f57690bd5d023b4f2Yorke Lee/*
2014de02dd2e050c36f7e0d4f57690bd5d023b4f2Yorke Lee * Copyright (C) 2015 The Android Open Source Project
3014de02dd2e050c36f7e0d4f57690bd5d023b4f2Yorke Lee *
4014de02dd2e050c36f7e0d4f57690bd5d023b4f2Yorke Lee * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
5014de02dd2e050c36f7e0d4f57690bd5d023b4f2Yorke Lee * in compliance with the License. You may obtain a copy of the License at
6014de02dd2e050c36f7e0d4f57690bd5d023b4f2Yorke Lee *
7014de02dd2e050c36f7e0d4f57690bd5d023b4f2Yorke Lee * http://www.apache.org/licenses/LICENSE-2.0
8014de02dd2e050c36f7e0d4f57690bd5d023b4f2Yorke Lee *
9014de02dd2e050c36f7e0d4f57690bd5d023b4f2Yorke Lee * Unless required by applicable law or agreed to in writing, software distributed under the License
10014de02dd2e050c36f7e0d4f57690bd5d023b4f2Yorke Lee * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
11014de02dd2e050c36f7e0d4f57690bd5d023b4f2Yorke Lee * or implied. See the License for the specific language governing permissions and limitations under
12014de02dd2e050c36f7e0d4f57690bd5d023b4f2Yorke Lee * the License.
13014de02dd2e050c36f7e0d4f57690bd5d023b4f2Yorke Lee */
14014de02dd2e050c36f7e0d4f57690bd5d023b4f2Yorke Lee
15014de02dd2e050c36f7e0d4f57690bd5d023b4f2Yorke Leepackage android.telecom;
16014de02dd2e050c36f7e0d4f57690bd5d023b4f2Yorke Lee
176526f67e45fc810b8f4c7419eecf599d228f674fYorke Leeimport android.app.ActivityManager;
18014de02dd2e050c36f7e0d4f57690bd5d023b4f2Yorke Leeimport android.content.Context;
19014de02dd2e050c36f7e0d4f57690bd5d023b4f2Yorke Leeimport android.content.Intent;
20014de02dd2e050c36f7e0d4f57690bd5d023b4f2Yorke Leeimport android.content.pm.ActivityInfo;
21014de02dd2e050c36f7e0d4f57690bd5d023b4f2Yorke Leeimport android.content.pm.PackageManager;
22014de02dd2e050c36f7e0d4f57690bd5d023b4f2Yorke Leeimport android.content.pm.ResolveInfo;
23856a5ac70474e9f57f71699ad934c701b01c1c7bYorke Leeimport android.net.Uri;
24b401a94d843bb12660bf4fd1f0d3e4d788e19faaTony Makimport android.os.Process;
25014de02dd2e050c36f7e0d4f57690bd5d023b4f2Yorke Leeimport android.provider.Settings;
26014de02dd2e050c36f7e0d4f57690bd5d023b4f2Yorke Leeimport android.text.TextUtils;
27014de02dd2e050c36f7e0d4f57690bd5d023b4f2Yorke Lee
28014de02dd2e050c36f7e0d4f57690bd5d023b4f2Yorke Leeimport java.util.ArrayList;
29014de02dd2e050c36f7e0d4f57690bd5d023b4f2Yorke Leeimport java.util.List;
30014de02dd2e050c36f7e0d4f57690bd5d023b4f2Yorke Lee
31014de02dd2e050c36f7e0d4f57690bd5d023b4f2Yorke Lee/**
32014de02dd2e050c36f7e0d4f57690bd5d023b4f2Yorke Lee * Class for managing the default dialer application that will receive incoming calls, and be
33014de02dd2e050c36f7e0d4f57690bd5d023b4f2Yorke Lee * allowed to make emergency outgoing calls.
34014de02dd2e050c36f7e0d4f57690bd5d023b4f2Yorke Lee *
35014de02dd2e050c36f7e0d4f57690bd5d023b4f2Yorke Lee * @hide
36014de02dd2e050c36f7e0d4f57690bd5d023b4f2Yorke Lee */
37014de02dd2e050c36f7e0d4f57690bd5d023b4f2Yorke Leepublic class DefaultDialerManager {
38014de02dd2e050c36f7e0d4f57690bd5d023b4f2Yorke Lee    private static final String TAG = "DefaultDialerManager";
39014de02dd2e050c36f7e0d4f57690bd5d023b4f2Yorke Lee
40014de02dd2e050c36f7e0d4f57690bd5d023b4f2Yorke Lee    /**
416526f67e45fc810b8f4c7419eecf599d228f674fYorke Lee     * Sets the specified package name as the default dialer application for the current user.
426526f67e45fc810b8f4c7419eecf599d228f674fYorke Lee     * The caller of this method needs to have permission to write to secure settings and
436526f67e45fc810b8f4c7419eecf599d228f674fYorke Lee     * manage users on the device.
44014de02dd2e050c36f7e0d4f57690bd5d023b4f2Yorke Lee     *
45db6da486217daa3418944cf93086a3bae549dad2Yorke Lee     * @return {@code true} if the default dialer application was successfully changed,
46db6da486217daa3418944cf93086a3bae549dad2Yorke Lee     *         {@code false} otherwise.
47db6da486217daa3418944cf93086a3bae549dad2Yorke Lee     *
48014de02dd2e050c36f7e0d4f57690bd5d023b4f2Yorke Lee     * @hide
49014de02dd2e050c36f7e0d4f57690bd5d023b4f2Yorke Lee     * */
50db6da486217daa3418944cf93086a3bae549dad2Yorke Lee    public static boolean setDefaultDialerApplication(Context context, String packageName) {
51db6da486217daa3418944cf93086a3bae549dad2Yorke Lee        return setDefaultDialerApplication(context, packageName, ActivityManager.getCurrentUser());
526526f67e45fc810b8f4c7419eecf599d228f674fYorke Lee    }
536526f67e45fc810b8f4c7419eecf599d228f674fYorke Lee
546526f67e45fc810b8f4c7419eecf599d228f674fYorke Lee    /**
556526f67e45fc810b8f4c7419eecf599d228f674fYorke Lee     * Sets the specified package name as the default dialer application for the specified user.
566526f67e45fc810b8f4c7419eecf599d228f674fYorke Lee     * The caller of this method needs to have permission to write to secure settings and
576526f67e45fc810b8f4c7419eecf599d228f674fYorke Lee     * manage users on the device.
586526f67e45fc810b8f4c7419eecf599d228f674fYorke Lee     *
59db6da486217daa3418944cf93086a3bae549dad2Yorke Lee     * @return {@code true} if the default dialer application was successfully changed,
60db6da486217daa3418944cf93086a3bae549dad2Yorke Lee     *         {@code false} otherwise.
61db6da486217daa3418944cf93086a3bae549dad2Yorke Lee     *
626526f67e45fc810b8f4c7419eecf599d228f674fYorke Lee     * @hide
636526f67e45fc810b8f4c7419eecf599d228f674fYorke Lee     * */
64db6da486217daa3418944cf93086a3bae549dad2Yorke Lee    public static boolean setDefaultDialerApplication(Context context, String packageName,
65db6da486217daa3418944cf93086a3bae549dad2Yorke Lee            int user) {
66014de02dd2e050c36f7e0d4f57690bd5d023b4f2Yorke Lee        // Get old package name
676526f67e45fc810b8f4c7419eecf599d228f674fYorke Lee        String oldPackageName = Settings.Secure.getStringForUser(context.getContentResolver(),
686526f67e45fc810b8f4c7419eecf599d228f674fYorke Lee                Settings.Secure.DIALER_DEFAULT_APPLICATION, user);
69014de02dd2e050c36f7e0d4f57690bd5d023b4f2Yorke Lee
70014de02dd2e050c36f7e0d4f57690bd5d023b4f2Yorke Lee        if (packageName != null && oldPackageName != null && packageName.equals(oldPackageName)) {
71014de02dd2e050c36f7e0d4f57690bd5d023b4f2Yorke Lee            // No change
72db6da486217daa3418944cf93086a3bae549dad2Yorke Lee            return false;
73014de02dd2e050c36f7e0d4f57690bd5d023b4f2Yorke Lee        }
74014de02dd2e050c36f7e0d4f57690bd5d023b4f2Yorke Lee
75014de02dd2e050c36f7e0d4f57690bd5d023b4f2Yorke Lee        // Only make the change if the new package belongs to a valid phone application
768e0207ba5b7ca3bca9d87847eef4d00aa89d7a7aYorke Lee        List<String> packageNames = getInstalledDialerApplications(context);
77014de02dd2e050c36f7e0d4f57690bd5d023b4f2Yorke Lee
788e0207ba5b7ca3bca9d87847eef4d00aa89d7a7aYorke Lee        if (packageNames.contains(packageName)) {
79014de02dd2e050c36f7e0d4f57690bd5d023b4f2Yorke Lee            // Update the secure setting.
806526f67e45fc810b8f4c7419eecf599d228f674fYorke Lee            Settings.Secure.putStringForUser(context.getContentResolver(),
816526f67e45fc810b8f4c7419eecf599d228f674fYorke Lee                    Settings.Secure.DIALER_DEFAULT_APPLICATION, packageName, user);
82db6da486217daa3418944cf93086a3bae549dad2Yorke Lee            return true;
83014de02dd2e050c36f7e0d4f57690bd5d023b4f2Yorke Lee        }
84db6da486217daa3418944cf93086a3bae549dad2Yorke Lee        return false;
85014de02dd2e050c36f7e0d4f57690bd5d023b4f2Yorke Lee    }
86014de02dd2e050c36f7e0d4f57690bd5d023b4f2Yorke Lee
87014de02dd2e050c36f7e0d4f57690bd5d023b4f2Yorke Lee    /**
886526f67e45fc810b8f4c7419eecf599d228f674fYorke Lee     * Returns the installed dialer application for the current user that will be used to receive
896526f67e45fc810b8f4c7419eecf599d228f674fYorke Lee     * incoming calls, and is allowed to make emergency calls.
90014de02dd2e050c36f7e0d4f57690bd5d023b4f2Yorke Lee     *
91014de02dd2e050c36f7e0d4f57690bd5d023b4f2Yorke Lee     * The application will be returned in order of preference:
92014de02dd2e050c36f7e0d4f57690bd5d023b4f2Yorke Lee     * 1) User selected phone application (if still installed)
93014de02dd2e050c36f7e0d4f57690bd5d023b4f2Yorke Lee     * 2) Pre-installed system dialer (if not disabled)
94014de02dd2e050c36f7e0d4f57690bd5d023b4f2Yorke Lee     * 3) Null
95014de02dd2e050c36f7e0d4f57690bd5d023b4f2Yorke Lee     *
966526f67e45fc810b8f4c7419eecf599d228f674fYorke Lee     * The caller of this method needs to have permission to manage users on the device.
976526f67e45fc810b8f4c7419eecf599d228f674fYorke Lee     *
98014de02dd2e050c36f7e0d4f57690bd5d023b4f2Yorke Lee     * @hide
99014de02dd2e050c36f7e0d4f57690bd5d023b4f2Yorke Lee     * */
1008e0207ba5b7ca3bca9d87847eef4d00aa89d7a7aYorke Lee    public static String getDefaultDialerApplication(Context context) {
10152153f4c0540a991b5b7214f4f14b5a891479a3cSvet Ganov        return getDefaultDialerApplication(context, context.getUserId());
1026526f67e45fc810b8f4c7419eecf599d228f674fYorke Lee    }
103014de02dd2e050c36f7e0d4f57690bd5d023b4f2Yorke Lee
1046526f67e45fc810b8f4c7419eecf599d228f674fYorke Lee    /**
1056526f67e45fc810b8f4c7419eecf599d228f674fYorke Lee     * Returns the installed dialer application for the specified user that will be used to receive
1066526f67e45fc810b8f4c7419eecf599d228f674fYorke Lee     * incoming calls, and is allowed to make emergency calls.
1076526f67e45fc810b8f4c7419eecf599d228f674fYorke Lee     *
1086526f67e45fc810b8f4c7419eecf599d228f674fYorke Lee     * The application will be returned in order of preference:
1096526f67e45fc810b8f4c7419eecf599d228f674fYorke Lee     * 1) User selected phone application (if still installed)
1106526f67e45fc810b8f4c7419eecf599d228f674fYorke Lee     * 2) Pre-installed system dialer (if not disabled)
1116526f67e45fc810b8f4c7419eecf599d228f674fYorke Lee     * 3) Null
1126526f67e45fc810b8f4c7419eecf599d228f674fYorke Lee     *
1136526f67e45fc810b8f4c7419eecf599d228f674fYorke Lee     * The caller of this method needs to have permission to manage users on the device.
1146526f67e45fc810b8f4c7419eecf599d228f674fYorke Lee     *
1156526f67e45fc810b8f4c7419eecf599d228f674fYorke Lee     * @hide
1166526f67e45fc810b8f4c7419eecf599d228f674fYorke Lee     * */
1176526f67e45fc810b8f4c7419eecf599d228f674fYorke Lee    public static String getDefaultDialerApplication(Context context, int user) {
1186526f67e45fc810b8f4c7419eecf599d228f674fYorke Lee        String defaultPackageName = Settings.Secure.getStringForUser(context.getContentResolver(),
1196526f67e45fc810b8f4c7419eecf599d228f674fYorke Lee                Settings.Secure.DIALER_DEFAULT_APPLICATION, user);
1208e0207ba5b7ca3bca9d87847eef4d00aa89d7a7aYorke Lee
1218e0207ba5b7ca3bca9d87847eef4d00aa89d7a7aYorke Lee        final List<String> packageNames = getInstalledDialerApplications(context);
1228e0207ba5b7ca3bca9d87847eef4d00aa89d7a7aYorke Lee
1238e0207ba5b7ca3bca9d87847eef4d00aa89d7a7aYorke Lee        // Verify that the default dialer has not been disabled or uninstalled.
1248e0207ba5b7ca3bca9d87847eef4d00aa89d7a7aYorke Lee        if (packageNames.contains(defaultPackageName)) {
1258e0207ba5b7ca3bca9d87847eef4d00aa89d7a7aYorke Lee            return defaultPackageName;
126014de02dd2e050c36f7e0d4f57690bd5d023b4f2Yorke Lee        }
127014de02dd2e050c36f7e0d4f57690bd5d023b4f2Yorke Lee
128014de02dd2e050c36f7e0d4f57690bd5d023b4f2Yorke Lee        // No user-set dialer found, fallback to system dialer
1298e0207ba5b7ca3bca9d87847eef4d00aa89d7a7aYorke Lee        String systemDialerPackageName = getTelecomManager(context).getSystemDialerPackage();
130014de02dd2e050c36f7e0d4f57690bd5d023b4f2Yorke Lee
1318e0207ba5b7ca3bca9d87847eef4d00aa89d7a7aYorke Lee        if (TextUtils.isEmpty(systemDialerPackageName)) {
132014de02dd2e050c36f7e0d4f57690bd5d023b4f2Yorke Lee            // No system dialer configured at build time
133014de02dd2e050c36f7e0d4f57690bd5d023b4f2Yorke Lee            return null;
134014de02dd2e050c36f7e0d4f57690bd5d023b4f2Yorke Lee        }
135014de02dd2e050c36f7e0d4f57690bd5d023b4f2Yorke Lee
1368e0207ba5b7ca3bca9d87847eef4d00aa89d7a7aYorke Lee        if (packageNames.contains(systemDialerPackageName)) {
1378e0207ba5b7ca3bca9d87847eef4d00aa89d7a7aYorke Lee            return systemDialerPackageName;
1388e0207ba5b7ca3bca9d87847eef4d00aa89d7a7aYorke Lee        } else {
1398e0207ba5b7ca3bca9d87847eef4d00aa89d7a7aYorke Lee            return null;
1408e0207ba5b7ca3bca9d87847eef4d00aa89d7a7aYorke Lee        }
141014de02dd2e050c36f7e0d4f57690bd5d023b4f2Yorke Lee    }
142014de02dd2e050c36f7e0d4f57690bd5d023b4f2Yorke Lee
143014de02dd2e050c36f7e0d4f57690bd5d023b4f2Yorke Lee    /**
144014de02dd2e050c36f7e0d4f57690bd5d023b4f2Yorke Lee     * Returns a list of installed and available dialer applications.
145014de02dd2e050c36f7e0d4f57690bd5d023b4f2Yorke Lee     *
146014de02dd2e050c36f7e0d4f57690bd5d023b4f2Yorke Lee     * In order to appear in the list, a dialer application must implement an intent-filter with
147014de02dd2e050c36f7e0d4f57690bd5d023b4f2Yorke Lee     * the DIAL intent for the following schemes:
148014de02dd2e050c36f7e0d4f57690bd5d023b4f2Yorke Lee     *
149014de02dd2e050c36f7e0d4f57690bd5d023b4f2Yorke Lee     * 1) Empty scheme
150014de02dd2e050c36f7e0d4f57690bd5d023b4f2Yorke Lee     * 2) tel Uri scheme
151014de02dd2e050c36f7e0d4f57690bd5d023b4f2Yorke Lee     *
152014de02dd2e050c36f7e0d4f57690bd5d023b4f2Yorke Lee     * @hide
153014de02dd2e050c36f7e0d4f57690bd5d023b4f2Yorke Lee     **/
154b401a94d843bb12660bf4fd1f0d3e4d788e19faaTony Mak    public static List<String> getInstalledDialerApplications(Context context, int userId) {
155014de02dd2e050c36f7e0d4f57690bd5d023b4f2Yorke Lee        PackageManager packageManager = context.getPackageManager();
156014de02dd2e050c36f7e0d4f57690bd5d023b4f2Yorke Lee
157014de02dd2e050c36f7e0d4f57690bd5d023b4f2Yorke Lee        // Get the list of apps registered for the DIAL intent with empty scheme
158014de02dd2e050c36f7e0d4f57690bd5d023b4f2Yorke Lee        Intent intent = new Intent(Intent.ACTION_DIAL);
159b401a94d843bb12660bf4fd1f0d3e4d788e19faaTony Mak        List<ResolveInfo> resolveInfoList =
160b401a94d843bb12660bf4fd1f0d3e4d788e19faaTony Mak                packageManager.queryIntentActivitiesAsUser(intent, 0, userId);
161014de02dd2e050c36f7e0d4f57690bd5d023b4f2Yorke Lee
1628e0207ba5b7ca3bca9d87847eef4d00aa89d7a7aYorke Lee        List<String> packageNames = new ArrayList<>();
163014de02dd2e050c36f7e0d4f57690bd5d023b4f2Yorke Lee
164014de02dd2e050c36f7e0d4f57690bd5d023b4f2Yorke Lee        for (ResolveInfo resolveInfo : resolveInfoList) {
165014de02dd2e050c36f7e0d4f57690bd5d023b4f2Yorke Lee            final ActivityInfo activityInfo = resolveInfo.activityInfo;
166856a5ac70474e9f57f71699ad934c701b01c1c7bYorke Lee            if (activityInfo != null && !packageNames.contains(activityInfo.packageName)) {
167856a5ac70474e9f57f71699ad934c701b01c1c7bYorke Lee                packageNames.add(activityInfo.packageName);
168014de02dd2e050c36f7e0d4f57690bd5d023b4f2Yorke Lee            }
169014de02dd2e050c36f7e0d4f57690bd5d023b4f2Yorke Lee        }
170014de02dd2e050c36f7e0d4f57690bd5d023b4f2Yorke Lee
171856a5ac70474e9f57f71699ad934c701b01c1c7bYorke Lee        final Intent dialIntentWithTelScheme = new Intent(Intent.ACTION_DIAL);
172856a5ac70474e9f57f71699ad934c701b01c1c7bYorke Lee        dialIntentWithTelScheme.setData(Uri.fromParts(PhoneAccount.SCHEME_TEL, "", null));
173856a5ac70474e9f57f71699ad934c701b01c1c7bYorke Lee        return filterByIntent(context, packageNames, dialIntentWithTelScheme);
174014de02dd2e050c36f7e0d4f57690bd5d023b4f2Yorke Lee    }
175014de02dd2e050c36f7e0d4f57690bd5d023b4f2Yorke Lee
176b401a94d843bb12660bf4fd1f0d3e4d788e19faaTony Mak    public static List<String> getInstalledDialerApplications(Context context) {
177b401a94d843bb12660bf4fd1f0d3e4d788e19faaTony Mak        return getInstalledDialerApplications(context, Process.myUserHandle().getIdentifier());
178b401a94d843bb12660bf4fd1f0d3e4d788e19faaTony Mak    }
179b401a94d843bb12660bf4fd1f0d3e4d788e19faaTony Mak
180014de02dd2e050c36f7e0d4f57690bd5d023b4f2Yorke Lee    /**
181610438230b72bc4932e6580230bfa2d5dd4e9913Yorke Lee     * Determines if the package name belongs to the user-selected default dialer or the preloaded
182610438230b72bc4932e6580230bfa2d5dd4e9913Yorke Lee     * system dialer, and thus should be allowed to perform certain privileged operations.
183610438230b72bc4932e6580230bfa2d5dd4e9913Yorke Lee     *
184610438230b72bc4932e6580230bfa2d5dd4e9913Yorke Lee     * @param context A valid context.
185610438230b72bc4932e6580230bfa2d5dd4e9913Yorke Lee     * @param packageName of the package to check for.
186610438230b72bc4932e6580230bfa2d5dd4e9913Yorke Lee     *
187610438230b72bc4932e6580230bfa2d5dd4e9913Yorke Lee     * @return {@code true} if the provided package name corresponds to the user-selected default
188610438230b72bc4932e6580230bfa2d5dd4e9913Yorke Lee     *         dialer or the preloaded system dialer, {@code false} otherwise.
189610438230b72bc4932e6580230bfa2d5dd4e9913Yorke Lee     *
190610438230b72bc4932e6580230bfa2d5dd4e9913Yorke Lee     * @hide
191610438230b72bc4932e6580230bfa2d5dd4e9913Yorke Lee     */
192610438230b72bc4932e6580230bfa2d5dd4e9913Yorke Lee    public static boolean isDefaultOrSystemDialer(Context context, String packageName) {
193610438230b72bc4932e6580230bfa2d5dd4e9913Yorke Lee        if (TextUtils.isEmpty(packageName)) {
194610438230b72bc4932e6580230bfa2d5dd4e9913Yorke Lee            return false;
195610438230b72bc4932e6580230bfa2d5dd4e9913Yorke Lee        }
196610438230b72bc4932e6580230bfa2d5dd4e9913Yorke Lee        final TelecomManager tm = getTelecomManager(context);
197610438230b72bc4932e6580230bfa2d5dd4e9913Yorke Lee        return packageName.equals(tm.getDefaultDialerPackage())
198610438230b72bc4932e6580230bfa2d5dd4e9913Yorke Lee                || packageName.equals(tm.getSystemDialerPackage());
199610438230b72bc4932e6580230bfa2d5dd4e9913Yorke Lee    }
200610438230b72bc4932e6580230bfa2d5dd4e9913Yorke Lee
201856a5ac70474e9f57f71699ad934c701b01c1c7bYorke Lee    /**
202856a5ac70474e9f57f71699ad934c701b01c1c7bYorke Lee     * Filter a given list of package names for those packages that contain an activity that has
203856a5ac70474e9f57f71699ad934c701b01c1c7bYorke Lee     * an intent filter for a given intent.
204856a5ac70474e9f57f71699ad934c701b01c1c7bYorke Lee     *
205856a5ac70474e9f57f71699ad934c701b01c1c7bYorke Lee     * @param context A valid context
206856a5ac70474e9f57f71699ad934c701b01c1c7bYorke Lee     * @param packageNames List of package names to filter.
207856a5ac70474e9f57f71699ad934c701b01c1c7bYorke Lee     * @return The filtered list.
208856a5ac70474e9f57f71699ad934c701b01c1c7bYorke Lee     */
209856a5ac70474e9f57f71699ad934c701b01c1c7bYorke Lee    private static List<String> filterByIntent(Context context, List<String> packageNames,
210856a5ac70474e9f57f71699ad934c701b01c1c7bYorke Lee            Intent intent) {
211856a5ac70474e9f57f71699ad934c701b01c1c7bYorke Lee        if (packageNames == null || packageNames.isEmpty()) {
212856a5ac70474e9f57f71699ad934c701b01c1c7bYorke Lee            return new ArrayList<>();
213856a5ac70474e9f57f71699ad934c701b01c1c7bYorke Lee        }
214856a5ac70474e9f57f71699ad934c701b01c1c7bYorke Lee
215856a5ac70474e9f57f71699ad934c701b01c1c7bYorke Lee        final List<String> result = new ArrayList<>();
2162a9e3f8e6813716ab88ca54fd04ae047dc9aaaebJeff Sharkey        final List<ResolveInfo> resolveInfoList = context.getPackageManager()
2172f3e35376ada0327b34a71d7c45ac6e6d955d7dcJeff Sharkey                .queryIntentActivities(intent, 0);
218856a5ac70474e9f57f71699ad934c701b01c1c7bYorke Lee        final int length = resolveInfoList.size();
219856a5ac70474e9f57f71699ad934c701b01c1c7bYorke Lee        for (int i = 0; i < length; i++) {
220856a5ac70474e9f57f71699ad934c701b01c1c7bYorke Lee            final ActivityInfo info = resolveInfoList.get(i).activityInfo;
221856a5ac70474e9f57f71699ad934c701b01c1c7bYorke Lee            if (info != null && packageNames.contains(info.packageName)
222856a5ac70474e9f57f71699ad934c701b01c1c7bYorke Lee                    && !result.contains(info.packageName)) {
223856a5ac70474e9f57f71699ad934c701b01c1c7bYorke Lee                result.add(info.packageName);
224856a5ac70474e9f57f71699ad934c701b01c1c7bYorke Lee            }
225856a5ac70474e9f57f71699ad934c701b01c1c7bYorke Lee        }
226856a5ac70474e9f57f71699ad934c701b01c1c7bYorke Lee
227856a5ac70474e9f57f71699ad934c701b01c1c7bYorke Lee        return result;
228856a5ac70474e9f57f71699ad934c701b01c1c7bYorke Lee    }
229856a5ac70474e9f57f71699ad934c701b01c1c7bYorke Lee
230856a5ac70474e9f57f71699ad934c701b01c1c7bYorke Lee
231014de02dd2e050c36f7e0d4f57690bd5d023b4f2Yorke Lee    private static TelecomManager getTelecomManager(Context context) {
232014de02dd2e050c36f7e0d4f57690bd5d023b4f2Yorke Lee        return (TelecomManager) context.getSystemService(Context.TELECOM_SERVICE);
233014de02dd2e050c36f7e0d4f57690bd5d023b4f2Yorke Lee    }
234014de02dd2e050c36f7e0d4f57690bd5d023b4f2Yorke Lee}
235