DefaultDialerManager.java revision 014de02dd2e050c36f7e0d4f57690bd5d023b4f2
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 17014de02dd2e050c36f7e0d4f57690bd5d023b4f2Yorke Leeimport android.content.ComponentName; 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; 23014de02dd2e050c36f7e0d4f57690bd5d023b4f2Yorke Leeimport android.provider.Settings; 24014de02dd2e050c36f7e0d4f57690bd5d023b4f2Yorke Leeimport android.text.TextUtils; 25014de02dd2e050c36f7e0d4f57690bd5d023b4f2Yorke Lee 26014de02dd2e050c36f7e0d4f57690bd5d023b4f2Yorke Leeimport java.util.ArrayList; 27014de02dd2e050c36f7e0d4f57690bd5d023b4f2Yorke Leeimport java.util.List; 28014de02dd2e050c36f7e0d4f57690bd5d023b4f2Yorke Lee 29014de02dd2e050c36f7e0d4f57690bd5d023b4f2Yorke Lee/** 30014de02dd2e050c36f7e0d4f57690bd5d023b4f2Yorke Lee * Class for managing the default dialer application that will receive incoming calls, and be 31014de02dd2e050c36f7e0d4f57690bd5d023b4f2Yorke Lee * allowed to make emergency outgoing calls. 32014de02dd2e050c36f7e0d4f57690bd5d023b4f2Yorke Lee * 33014de02dd2e050c36f7e0d4f57690bd5d023b4f2Yorke Lee * @hide 34014de02dd2e050c36f7e0d4f57690bd5d023b4f2Yorke Lee */ 35014de02dd2e050c36f7e0d4f57690bd5d023b4f2Yorke Leepublic class DefaultDialerManager { 36014de02dd2e050c36f7e0d4f57690bd5d023b4f2Yorke Lee private static final String TAG = "DefaultDialerManager"; 37014de02dd2e050c36f7e0d4f57690bd5d023b4f2Yorke Lee 38014de02dd2e050c36f7e0d4f57690bd5d023b4f2Yorke Lee /** 39014de02dd2e050c36f7e0d4f57690bd5d023b4f2Yorke Lee * Sets the specified package name as the default dialer application. The caller of this method 40014de02dd2e050c36f7e0d4f57690bd5d023b4f2Yorke Lee * needs to have permission to write to secure settings. 41014de02dd2e050c36f7e0d4f57690bd5d023b4f2Yorke Lee * 42014de02dd2e050c36f7e0d4f57690bd5d023b4f2Yorke Lee * @hide 43014de02dd2e050c36f7e0d4f57690bd5d023b4f2Yorke Lee * */ 44014de02dd2e050c36f7e0d4f57690bd5d023b4f2Yorke Lee public static void setDefaultPhoneApplication(Context context, String packageName) { 45014de02dd2e050c36f7e0d4f57690bd5d023b4f2Yorke Lee // Get old package name 46014de02dd2e050c36f7e0d4f57690bd5d023b4f2Yorke Lee String oldPackageName = Settings.Secure.getString(context.getContentResolver(), 47014de02dd2e050c36f7e0d4f57690bd5d023b4f2Yorke Lee Settings.Secure.DIALER_DEFAULT_APPLICATION); 48014de02dd2e050c36f7e0d4f57690bd5d023b4f2Yorke Lee 49014de02dd2e050c36f7e0d4f57690bd5d023b4f2Yorke Lee if (packageName != null && oldPackageName != null && packageName.equals(oldPackageName)) { 50014de02dd2e050c36f7e0d4f57690bd5d023b4f2Yorke Lee // No change 51014de02dd2e050c36f7e0d4f57690bd5d023b4f2Yorke Lee return; 52014de02dd2e050c36f7e0d4f57690bd5d023b4f2Yorke Lee } 53014de02dd2e050c36f7e0d4f57690bd5d023b4f2Yorke Lee 54014de02dd2e050c36f7e0d4f57690bd5d023b4f2Yorke Lee // Only make the change if the new package belongs to a valid phone application 55014de02dd2e050c36f7e0d4f57690bd5d023b4f2Yorke Lee List<ComponentName> componentNames = getInstalledDialerApplications(context); 56014de02dd2e050c36f7e0d4f57690bd5d023b4f2Yorke Lee final ComponentName foundComponent = getComponentName(componentNames, packageName); 57014de02dd2e050c36f7e0d4f57690bd5d023b4f2Yorke Lee 58014de02dd2e050c36f7e0d4f57690bd5d023b4f2Yorke Lee if (foundComponent != null) { 59014de02dd2e050c36f7e0d4f57690bd5d023b4f2Yorke Lee // Update the secure setting. 60014de02dd2e050c36f7e0d4f57690bd5d023b4f2Yorke Lee Settings.Secure.putString(context.getContentResolver(), 61014de02dd2e050c36f7e0d4f57690bd5d023b4f2Yorke Lee Settings.Secure.DIALER_DEFAULT_APPLICATION, foundComponent.getPackageName()); 62014de02dd2e050c36f7e0d4f57690bd5d023b4f2Yorke Lee } 63014de02dd2e050c36f7e0d4f57690bd5d023b4f2Yorke Lee } 64014de02dd2e050c36f7e0d4f57690bd5d023b4f2Yorke Lee 65014de02dd2e050c36f7e0d4f57690bd5d023b4f2Yorke Lee /** 66014de02dd2e050c36f7e0d4f57690bd5d023b4f2Yorke Lee * Returns the installed dialer application that will be used to receive incoming calls, and is 67014de02dd2e050c36f7e0d4f57690bd5d023b4f2Yorke Lee * allowed to make emergency calls. 68014de02dd2e050c36f7e0d4f57690bd5d023b4f2Yorke Lee * 69014de02dd2e050c36f7e0d4f57690bd5d023b4f2Yorke Lee * The application will be returned in order of preference: 70014de02dd2e050c36f7e0d4f57690bd5d023b4f2Yorke Lee * 1) User selected phone application (if still installed) 71014de02dd2e050c36f7e0d4f57690bd5d023b4f2Yorke Lee * 2) Pre-installed system dialer (if not disabled) 72014de02dd2e050c36f7e0d4f57690bd5d023b4f2Yorke Lee * 3) Null 73014de02dd2e050c36f7e0d4f57690bd5d023b4f2Yorke Lee * 74014de02dd2e050c36f7e0d4f57690bd5d023b4f2Yorke Lee * @hide 75014de02dd2e050c36f7e0d4f57690bd5d023b4f2Yorke Lee * */ 76014de02dd2e050c36f7e0d4f57690bd5d023b4f2Yorke Lee public static ComponentName getDefaultDialerApplication(Context context) { 77014de02dd2e050c36f7e0d4f57690bd5d023b4f2Yorke Lee String defaultPackageName = Settings.Secure.getString(context.getContentResolver(), 78014de02dd2e050c36f7e0d4f57690bd5d023b4f2Yorke Lee Settings.Secure.DIALER_DEFAULT_APPLICATION); 79014de02dd2e050c36f7e0d4f57690bd5d023b4f2Yorke Lee 80014de02dd2e050c36f7e0d4f57690bd5d023b4f2Yorke Lee final List<ComponentName> componentNames = getInstalledDialerApplications(context); 81014de02dd2e050c36f7e0d4f57690bd5d023b4f2Yorke Lee if (!TextUtils.isEmpty(defaultPackageName)) { 82014de02dd2e050c36f7e0d4f57690bd5d023b4f2Yorke Lee final ComponentName defaultDialer = 83014de02dd2e050c36f7e0d4f57690bd5d023b4f2Yorke Lee getComponentName(componentNames, defaultPackageName); 84014de02dd2e050c36f7e0d4f57690bd5d023b4f2Yorke Lee if (defaultDialer != null) { 85014de02dd2e050c36f7e0d4f57690bd5d023b4f2Yorke Lee return defaultDialer; 86014de02dd2e050c36f7e0d4f57690bd5d023b4f2Yorke Lee } 87014de02dd2e050c36f7e0d4f57690bd5d023b4f2Yorke Lee } 88014de02dd2e050c36f7e0d4f57690bd5d023b4f2Yorke Lee 89014de02dd2e050c36f7e0d4f57690bd5d023b4f2Yorke Lee // No user-set dialer found, fallback to system dialer 90014de02dd2e050c36f7e0d4f57690bd5d023b4f2Yorke Lee ComponentName systemDialer = getTelecomManager(context).getDefaultPhoneApp(); 91014de02dd2e050c36f7e0d4f57690bd5d023b4f2Yorke Lee 92014de02dd2e050c36f7e0d4f57690bd5d023b4f2Yorke Lee if (systemDialer == null) { 93014de02dd2e050c36f7e0d4f57690bd5d023b4f2Yorke Lee // No system dialer configured at build time 94014de02dd2e050c36f7e0d4f57690bd5d023b4f2Yorke Lee return null; 95014de02dd2e050c36f7e0d4f57690bd5d023b4f2Yorke Lee } 96014de02dd2e050c36f7e0d4f57690bd5d023b4f2Yorke Lee 97014de02dd2e050c36f7e0d4f57690bd5d023b4f2Yorke Lee // Verify that the system dialer has not been disabled. 98014de02dd2e050c36f7e0d4f57690bd5d023b4f2Yorke Lee return getComponentName(componentNames, systemDialer.getPackageName()); 99014de02dd2e050c36f7e0d4f57690bd5d023b4f2Yorke Lee } 100014de02dd2e050c36f7e0d4f57690bd5d023b4f2Yorke Lee 101014de02dd2e050c36f7e0d4f57690bd5d023b4f2Yorke Lee /** 102014de02dd2e050c36f7e0d4f57690bd5d023b4f2Yorke Lee * Returns a list of installed and available dialer applications. 103014de02dd2e050c36f7e0d4f57690bd5d023b4f2Yorke Lee * 104014de02dd2e050c36f7e0d4f57690bd5d023b4f2Yorke Lee * In order to appear in the list, a dialer application must implement an intent-filter with 105014de02dd2e050c36f7e0d4f57690bd5d023b4f2Yorke Lee * the DIAL intent for the following schemes: 106014de02dd2e050c36f7e0d4f57690bd5d023b4f2Yorke Lee * 107014de02dd2e050c36f7e0d4f57690bd5d023b4f2Yorke Lee * 1) Empty scheme 108014de02dd2e050c36f7e0d4f57690bd5d023b4f2Yorke Lee * 2) tel Uri scheme 109014de02dd2e050c36f7e0d4f57690bd5d023b4f2Yorke Lee * 110014de02dd2e050c36f7e0d4f57690bd5d023b4f2Yorke Lee * @hide 111014de02dd2e050c36f7e0d4f57690bd5d023b4f2Yorke Lee **/ 112014de02dd2e050c36f7e0d4f57690bd5d023b4f2Yorke Lee public static List<ComponentName> getInstalledDialerApplications(Context context) { 113014de02dd2e050c36f7e0d4f57690bd5d023b4f2Yorke Lee PackageManager packageManager = context.getPackageManager(); 114014de02dd2e050c36f7e0d4f57690bd5d023b4f2Yorke Lee 115014de02dd2e050c36f7e0d4f57690bd5d023b4f2Yorke Lee // Get the list of apps registered for the DIAL intent with empty scheme 116014de02dd2e050c36f7e0d4f57690bd5d023b4f2Yorke Lee Intent intent = new Intent(Intent.ACTION_DIAL); 117014de02dd2e050c36f7e0d4f57690bd5d023b4f2Yorke Lee List<ResolveInfo> resolveInfoList = packageManager.queryIntentActivities(intent, 0); 118014de02dd2e050c36f7e0d4f57690bd5d023b4f2Yorke Lee 119014de02dd2e050c36f7e0d4f57690bd5d023b4f2Yorke Lee List<ComponentName> componentNames = new ArrayList<ComponentName> (); 120014de02dd2e050c36f7e0d4f57690bd5d023b4f2Yorke Lee 121014de02dd2e050c36f7e0d4f57690bd5d023b4f2Yorke Lee for (ResolveInfo resolveInfo : resolveInfoList) { 122014de02dd2e050c36f7e0d4f57690bd5d023b4f2Yorke Lee final ActivityInfo activityInfo = resolveInfo.activityInfo; 123014de02dd2e050c36f7e0d4f57690bd5d023b4f2Yorke Lee if (activityInfo == null) { 124014de02dd2e050c36f7e0d4f57690bd5d023b4f2Yorke Lee continue; 125014de02dd2e050c36f7e0d4f57690bd5d023b4f2Yorke Lee } 126014de02dd2e050c36f7e0d4f57690bd5d023b4f2Yorke Lee final ComponentName componentName = 127014de02dd2e050c36f7e0d4f57690bd5d023b4f2Yorke Lee new ComponentName(activityInfo.packageName, activityInfo.name); 128014de02dd2e050c36f7e0d4f57690bd5d023b4f2Yorke Lee componentNames.add(componentName); 129014de02dd2e050c36f7e0d4f57690bd5d023b4f2Yorke Lee } 130014de02dd2e050c36f7e0d4f57690bd5d023b4f2Yorke Lee 131014de02dd2e050c36f7e0d4f57690bd5d023b4f2Yorke Lee // TODO: Filter for apps that don't handle DIAL intent with tel scheme 132014de02dd2e050c36f7e0d4f57690bd5d023b4f2Yorke Lee return componentNames; 133014de02dd2e050c36f7e0d4f57690bd5d023b4f2Yorke Lee } 134014de02dd2e050c36f7e0d4f57690bd5d023b4f2Yorke Lee 135014de02dd2e050c36f7e0d4f57690bd5d023b4f2Yorke Lee /** 136014de02dd2e050c36f7e0d4f57690bd5d023b4f2Yorke Lee * Returns the {@link ComponentName} for the installed dialer application for a given package 137014de02dd2e050c36f7e0d4f57690bd5d023b4f2Yorke Lee * name. 138014de02dd2e050c36f7e0d4f57690bd5d023b4f2Yorke Lee * 139014de02dd2e050c36f7e0d4f57690bd5d023b4f2Yorke Lee * @param context A valid context. 140014de02dd2e050c36f7e0d4f57690bd5d023b4f2Yorke Lee * @param packageName to retrieve the {@link ComponentName} for. 141014de02dd2e050c36f7e0d4f57690bd5d023b4f2Yorke Lee * 142014de02dd2e050c36f7e0d4f57690bd5d023b4f2Yorke Lee * @return The {@link ComponentName} for the installed dialer application corresponding to the 143014de02dd2e050c36f7e0d4f57690bd5d023b4f2Yorke Lee * package name, or null if none is found. 144014de02dd2e050c36f7e0d4f57690bd5d023b4f2Yorke Lee * 145014de02dd2e050c36f7e0d4f57690bd5d023b4f2Yorke Lee * @hide 146014de02dd2e050c36f7e0d4f57690bd5d023b4f2Yorke Lee */ 147014de02dd2e050c36f7e0d4f57690bd5d023b4f2Yorke Lee public static ComponentName getDialerApplicationForPackageName(Context context, 148014de02dd2e050c36f7e0d4f57690bd5d023b4f2Yorke Lee String packageName) { 149014de02dd2e050c36f7e0d4f57690bd5d023b4f2Yorke Lee return getComponentName(getInstalledDialerApplications(context), packageName); 150014de02dd2e050c36f7e0d4f57690bd5d023b4f2Yorke Lee } 151014de02dd2e050c36f7e0d4f57690bd5d023b4f2Yorke Lee 152014de02dd2e050c36f7e0d4f57690bd5d023b4f2Yorke Lee /** 153014de02dd2e050c36f7e0d4f57690bd5d023b4f2Yorke Lee * Returns the component from a list of application components that corresponds to the package 154014de02dd2e050c36f7e0d4f57690bd5d023b4f2Yorke Lee * name. 155014de02dd2e050c36f7e0d4f57690bd5d023b4f2Yorke Lee * 156014de02dd2e050c36f7e0d4f57690bd5d023b4f2Yorke Lee * @param componentNames A list of component names 157014de02dd2e050c36f7e0d4f57690bd5d023b4f2Yorke Lee * @param packageName The package name to look for 158014de02dd2e050c36f7e0d4f57690bd5d023b4f2Yorke Lee * @return The {@link ComponentName} that matches the provided packageName, or null if not 159014de02dd2e050c36f7e0d4f57690bd5d023b4f2Yorke Lee * found. 160014de02dd2e050c36f7e0d4f57690bd5d023b4f2Yorke Lee */ 161014de02dd2e050c36f7e0d4f57690bd5d023b4f2Yorke Lee private static ComponentName getComponentName(List<ComponentName> componentNames, 162014de02dd2e050c36f7e0d4f57690bd5d023b4f2Yorke Lee String packageName) { 163014de02dd2e050c36f7e0d4f57690bd5d023b4f2Yorke Lee for (ComponentName componentName : componentNames) { 164014de02dd2e050c36f7e0d4f57690bd5d023b4f2Yorke Lee if (TextUtils.equals(packageName, componentName.getPackageName())) { 165014de02dd2e050c36f7e0d4f57690bd5d023b4f2Yorke Lee return componentName; 166014de02dd2e050c36f7e0d4f57690bd5d023b4f2Yorke Lee } 167014de02dd2e050c36f7e0d4f57690bd5d023b4f2Yorke Lee } 168014de02dd2e050c36f7e0d4f57690bd5d023b4f2Yorke Lee return null; 169014de02dd2e050c36f7e0d4f57690bd5d023b4f2Yorke Lee } 170014de02dd2e050c36f7e0d4f57690bd5d023b4f2Yorke Lee 171014de02dd2e050c36f7e0d4f57690bd5d023b4f2Yorke Lee private static TelecomManager getTelecomManager(Context context) { 172014de02dd2e050c36f7e0d4f57690bd5d023b4f2Yorke Lee return (TelecomManager) context.getSystemService(Context.TELECOM_SERVICE); 173014de02dd2e050c36f7e0d4f57690bd5d023b4f2Yorke Lee } 174014de02dd2e050c36f7e0d4f57690bd5d023b4f2Yorke Lee} 175