blob: bf8fac621081bd6c61a0dd44dac1dda1b6ea4fa9 [file] [log] [blame]
Yorke Lee014de022015-04-21 17:15:47 -07001/*
2 * Copyright (C) 2015 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
5 * in compliance with the License. You may obtain a copy of the License at
6 *
7 * http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software distributed under the License
10 * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
11 * or implied. See the License for the specific language governing permissions and limitations under
12 * the License.
13 */
14
15package android.telecom;
16
17import android.content.ComponentName;
18import android.content.Context;
19import android.content.Intent;
20import android.content.pm.ActivityInfo;
21import android.content.pm.PackageManager;
22import android.content.pm.ResolveInfo;
23import android.provider.Settings;
24import android.text.TextUtils;
25
26import java.util.ArrayList;
27import java.util.List;
28
29/**
30 * Class for managing the default dialer application that will receive incoming calls, and be
31 * allowed to make emergency outgoing calls.
32 *
33 * @hide
34 */
35public class DefaultDialerManager {
36 private static final String TAG = "DefaultDialerManager";
37
38 /**
39 * Sets the specified package name as the default dialer application. The caller of this method
40 * needs to have permission to write to secure settings.
41 *
42 * @hide
43 * */
44 public static void setDefaultPhoneApplication(Context context, String packageName) {
45 // Get old package name
46 String oldPackageName = Settings.Secure.getString(context.getContentResolver(),
47 Settings.Secure.DIALER_DEFAULT_APPLICATION);
48
49 if (packageName != null && oldPackageName != null && packageName.equals(oldPackageName)) {
50 // No change
51 return;
52 }
53
54 // Only make the change if the new package belongs to a valid phone application
55 List<ComponentName> componentNames = getInstalledDialerApplications(context);
56 final ComponentName foundComponent = getComponentName(componentNames, packageName);
57
58 if (foundComponent != null) {
59 // Update the secure setting.
60 Settings.Secure.putString(context.getContentResolver(),
61 Settings.Secure.DIALER_DEFAULT_APPLICATION, foundComponent.getPackageName());
62 }
63 }
64
65 /**
66 * Returns the installed dialer application that will be used to receive incoming calls, and is
67 * allowed to make emergency calls.
68 *
69 * The application will be returned in order of preference:
70 * 1) User selected phone application (if still installed)
71 * 2) Pre-installed system dialer (if not disabled)
72 * 3) Null
73 *
74 * @hide
75 * */
76 public static ComponentName getDefaultDialerApplication(Context context) {
77 String defaultPackageName = Settings.Secure.getString(context.getContentResolver(),
78 Settings.Secure.DIALER_DEFAULT_APPLICATION);
79
80 final List<ComponentName> componentNames = getInstalledDialerApplications(context);
81 if (!TextUtils.isEmpty(defaultPackageName)) {
82 final ComponentName defaultDialer =
83 getComponentName(componentNames, defaultPackageName);
84 if (defaultDialer != null) {
85 return defaultDialer;
86 }
87 }
88
89 // No user-set dialer found, fallback to system dialer
Yorke Lee1011f482015-04-23 15:58:27 -070090 String systemDialer = getTelecomManager(context).getSystemDialerPackage();
Yorke Lee014de022015-04-21 17:15:47 -070091
Yorke Lee1011f482015-04-23 15:58:27 -070092 if (TextUtils.isEmpty(systemDialer)) {
Yorke Lee014de022015-04-21 17:15:47 -070093 // No system dialer configured at build time
94 return null;
95 }
96
97 // Verify that the system dialer has not been disabled.
Yorke Lee1011f482015-04-23 15:58:27 -070098 return getComponentName(componentNames, systemDialer);
Yorke Lee014de022015-04-21 17:15:47 -070099 }
100
101 /**
102 * Returns a list of installed and available dialer applications.
103 *
104 * In order to appear in the list, a dialer application must implement an intent-filter with
105 * the DIAL intent for the following schemes:
106 *
107 * 1) Empty scheme
108 * 2) tel Uri scheme
109 *
110 * @hide
111 **/
112 public static List<ComponentName> getInstalledDialerApplications(Context context) {
113 PackageManager packageManager = context.getPackageManager();
114
115 // Get the list of apps registered for the DIAL intent with empty scheme
116 Intent intent = new Intent(Intent.ACTION_DIAL);
117 List<ResolveInfo> resolveInfoList = packageManager.queryIntentActivities(intent, 0);
118
119 List<ComponentName> componentNames = new ArrayList<ComponentName> ();
120
121 for (ResolveInfo resolveInfo : resolveInfoList) {
122 final ActivityInfo activityInfo = resolveInfo.activityInfo;
123 if (activityInfo == null) {
124 continue;
125 }
126 final ComponentName componentName =
127 new ComponentName(activityInfo.packageName, activityInfo.name);
128 componentNames.add(componentName);
129 }
130
131 // TODO: Filter for apps that don't handle DIAL intent with tel scheme
132 return componentNames;
133 }
134
135 /**
136 * Returns the {@link ComponentName} for the installed dialer application for a given package
137 * name.
138 *
139 * @param context A valid context.
140 * @param packageName to retrieve the {@link ComponentName} for.
141 *
142 * @return The {@link ComponentName} for the installed dialer application corresponding to the
143 * package name, or null if none is found.
144 *
145 * @hide
146 */
147 public static ComponentName getDialerApplicationForPackageName(Context context,
148 String packageName) {
149 return getComponentName(getInstalledDialerApplications(context), packageName);
150 }
151
152 /**
153 * Returns the component from a list of application components that corresponds to the package
154 * name.
155 *
156 * @param componentNames A list of component names
157 * @param packageName The package name to look for
158 * @return The {@link ComponentName} that matches the provided packageName, or null if not
159 * found.
160 */
161 private static ComponentName getComponentName(List<ComponentName> componentNames,
162 String packageName) {
163 for (ComponentName componentName : componentNames) {
164 if (TextUtils.equals(packageName, componentName.getPackageName())) {
165 return componentName;
166 }
167 }
168 return null;
169 }
170
171 private static TelecomManager getTelecomManager(Context context) {
172 return (TelecomManager) context.getSystemService(Context.TELECOM_SERVICE);
173 }
174}