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