DefaultDialerManager.java revision 8e0207ba5b7ca3bca9d87847eef4d00aa89d7a7a
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.Context;
18014de02dd2e050c36f7e0d4f57690bd5d023b4f2Yorke Leeimport android.content.Intent;
19014de02dd2e050c36f7e0d4f57690bd5d023b4f2Yorke Leeimport android.content.pm.ActivityInfo;
20014de02dd2e050c36f7e0d4f57690bd5d023b4f2Yorke Leeimport android.content.pm.PackageManager;
21014de02dd2e050c36f7e0d4f57690bd5d023b4f2Yorke Leeimport android.content.pm.ResolveInfo;
22014de02dd2e050c36f7e0d4f57690bd5d023b4f2Yorke Leeimport android.provider.Settings;
23014de02dd2e050c36f7e0d4f57690bd5d023b4f2Yorke Leeimport android.text.TextUtils;
24014de02dd2e050c36f7e0d4f57690bd5d023b4f2Yorke Lee
25014de02dd2e050c36f7e0d4f57690bd5d023b4f2Yorke Leeimport java.util.ArrayList;
26014de02dd2e050c36f7e0d4f57690bd5d023b4f2Yorke Leeimport java.util.List;
27014de02dd2e050c36f7e0d4f57690bd5d023b4f2Yorke Lee
28014de02dd2e050c36f7e0d4f57690bd5d023b4f2Yorke Lee/**
29014de02dd2e050c36f7e0d4f57690bd5d023b4f2Yorke Lee * Class for managing the default dialer application that will receive incoming calls, and be
30014de02dd2e050c36f7e0d4f57690bd5d023b4f2Yorke Lee * allowed to make emergency outgoing calls.
31014de02dd2e050c36f7e0d4f57690bd5d023b4f2Yorke Lee *
32014de02dd2e050c36f7e0d4f57690bd5d023b4f2Yorke Lee * @hide
33014de02dd2e050c36f7e0d4f57690bd5d023b4f2Yorke Lee */
34014de02dd2e050c36f7e0d4f57690bd5d023b4f2Yorke Leepublic class DefaultDialerManager {
35014de02dd2e050c36f7e0d4f57690bd5d023b4f2Yorke Lee    private static final String TAG = "DefaultDialerManager";
36014de02dd2e050c36f7e0d4f57690bd5d023b4f2Yorke Lee
37014de02dd2e050c36f7e0d4f57690bd5d023b4f2Yorke Lee    /**
38014de02dd2e050c36f7e0d4f57690bd5d023b4f2Yorke Lee     * Sets the specified package name as the default dialer application. The caller of this method
39014de02dd2e050c36f7e0d4f57690bd5d023b4f2Yorke Lee     * needs to have permission to write to secure settings.
40014de02dd2e050c36f7e0d4f57690bd5d023b4f2Yorke Lee     *
41014de02dd2e050c36f7e0d4f57690bd5d023b4f2Yorke Lee     * @hide
42014de02dd2e050c36f7e0d4f57690bd5d023b4f2Yorke Lee     * */
43014de02dd2e050c36f7e0d4f57690bd5d023b4f2Yorke Lee    public static void setDefaultPhoneApplication(Context context, String packageName) {
44014de02dd2e050c36f7e0d4f57690bd5d023b4f2Yorke Lee        // Get old package name
45014de02dd2e050c36f7e0d4f57690bd5d023b4f2Yorke Lee        String oldPackageName = Settings.Secure.getString(context.getContentResolver(),
46014de02dd2e050c36f7e0d4f57690bd5d023b4f2Yorke Lee                Settings.Secure.DIALER_DEFAULT_APPLICATION);
47014de02dd2e050c36f7e0d4f57690bd5d023b4f2Yorke Lee
48014de02dd2e050c36f7e0d4f57690bd5d023b4f2Yorke Lee        if (packageName != null && oldPackageName != null && packageName.equals(oldPackageName)) {
49014de02dd2e050c36f7e0d4f57690bd5d023b4f2Yorke Lee            // No change
50014de02dd2e050c36f7e0d4f57690bd5d023b4f2Yorke Lee            return;
51014de02dd2e050c36f7e0d4f57690bd5d023b4f2Yorke Lee        }
52014de02dd2e050c36f7e0d4f57690bd5d023b4f2Yorke Lee
53014de02dd2e050c36f7e0d4f57690bd5d023b4f2Yorke Lee        // Only make the change if the new package belongs to a valid phone application
548e0207ba5b7ca3bca9d87847eef4d00aa89d7a7aYorke Lee        List<String> packageNames = getInstalledDialerApplications(context);
55014de02dd2e050c36f7e0d4f57690bd5d023b4f2Yorke Lee
568e0207ba5b7ca3bca9d87847eef4d00aa89d7a7aYorke Lee        if (packageNames.contains(packageName)) {
57014de02dd2e050c36f7e0d4f57690bd5d023b4f2Yorke Lee            // Update the secure setting.
58014de02dd2e050c36f7e0d4f57690bd5d023b4f2Yorke Lee            Settings.Secure.putString(context.getContentResolver(),
598e0207ba5b7ca3bca9d87847eef4d00aa89d7a7aYorke Lee                    Settings.Secure.DIALER_DEFAULT_APPLICATION, packageName);
60014de02dd2e050c36f7e0d4f57690bd5d023b4f2Yorke Lee        }
61014de02dd2e050c36f7e0d4f57690bd5d023b4f2Yorke Lee    }
62014de02dd2e050c36f7e0d4f57690bd5d023b4f2Yorke Lee
63014de02dd2e050c36f7e0d4f57690bd5d023b4f2Yorke Lee    /**
64014de02dd2e050c36f7e0d4f57690bd5d023b4f2Yorke Lee     * Returns the installed dialer application that will be used to receive incoming calls, and is
65014de02dd2e050c36f7e0d4f57690bd5d023b4f2Yorke Lee     * allowed to make emergency calls.
66014de02dd2e050c36f7e0d4f57690bd5d023b4f2Yorke Lee     *
67014de02dd2e050c36f7e0d4f57690bd5d023b4f2Yorke Lee     * The application will be returned in order of preference:
68014de02dd2e050c36f7e0d4f57690bd5d023b4f2Yorke Lee     * 1) User selected phone application (if still installed)
69014de02dd2e050c36f7e0d4f57690bd5d023b4f2Yorke Lee     * 2) Pre-installed system dialer (if not disabled)
70014de02dd2e050c36f7e0d4f57690bd5d023b4f2Yorke Lee     * 3) Null
71014de02dd2e050c36f7e0d4f57690bd5d023b4f2Yorke Lee     *
72014de02dd2e050c36f7e0d4f57690bd5d023b4f2Yorke Lee     * @hide
73014de02dd2e050c36f7e0d4f57690bd5d023b4f2Yorke Lee     * */
748e0207ba5b7ca3bca9d87847eef4d00aa89d7a7aYorke Lee    public static String getDefaultDialerApplication(Context context) {
75014de02dd2e050c36f7e0d4f57690bd5d023b4f2Yorke Lee        String defaultPackageName = Settings.Secure.getString(context.getContentResolver(),
76014de02dd2e050c36f7e0d4f57690bd5d023b4f2Yorke Lee                Settings.Secure.DIALER_DEFAULT_APPLICATION);
77014de02dd2e050c36f7e0d4f57690bd5d023b4f2Yorke Lee
788e0207ba5b7ca3bca9d87847eef4d00aa89d7a7aYorke Lee
798e0207ba5b7ca3bca9d87847eef4d00aa89d7a7aYorke Lee        final List<String> packageNames = getInstalledDialerApplications(context);
808e0207ba5b7ca3bca9d87847eef4d00aa89d7a7aYorke Lee
818e0207ba5b7ca3bca9d87847eef4d00aa89d7a7aYorke Lee        // Verify that the default dialer has not been disabled or uninstalled.
828e0207ba5b7ca3bca9d87847eef4d00aa89d7a7aYorke Lee        if (packageNames.contains(defaultPackageName)) {
838e0207ba5b7ca3bca9d87847eef4d00aa89d7a7aYorke Lee            return defaultPackageName;
84014de02dd2e050c36f7e0d4f57690bd5d023b4f2Yorke Lee        }
85014de02dd2e050c36f7e0d4f57690bd5d023b4f2Yorke Lee
86014de02dd2e050c36f7e0d4f57690bd5d023b4f2Yorke Lee        // No user-set dialer found, fallback to system dialer
878e0207ba5b7ca3bca9d87847eef4d00aa89d7a7aYorke Lee        String systemDialerPackageName = getTelecomManager(context).getSystemDialerPackage();
88014de02dd2e050c36f7e0d4f57690bd5d023b4f2Yorke Lee
898e0207ba5b7ca3bca9d87847eef4d00aa89d7a7aYorke Lee        if (TextUtils.isEmpty(systemDialerPackageName)) {
90014de02dd2e050c36f7e0d4f57690bd5d023b4f2Yorke Lee            // No system dialer configured at build time
91014de02dd2e050c36f7e0d4f57690bd5d023b4f2Yorke Lee            return null;
92014de02dd2e050c36f7e0d4f57690bd5d023b4f2Yorke Lee        }
93014de02dd2e050c36f7e0d4f57690bd5d023b4f2Yorke Lee
948e0207ba5b7ca3bca9d87847eef4d00aa89d7a7aYorke Lee        if (packageNames.contains(systemDialerPackageName)) {
958e0207ba5b7ca3bca9d87847eef4d00aa89d7a7aYorke Lee            return systemDialerPackageName;
968e0207ba5b7ca3bca9d87847eef4d00aa89d7a7aYorke Lee        } else {
978e0207ba5b7ca3bca9d87847eef4d00aa89d7a7aYorke Lee            return null;
988e0207ba5b7ca3bca9d87847eef4d00aa89d7a7aYorke Lee        }
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     **/
1128e0207ba5b7ca3bca9d87847eef4d00aa89d7a7aYorke Lee    public static List<String> 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
1198e0207ba5b7ca3bca9d87847eef4d00aa89d7a7aYorke Lee        List<String> packageNames = new ArrayList<>();
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            }
1268e0207ba5b7ca3bca9d87847eef4d00aa89d7a7aYorke Lee            packageNames.add(activityInfo.packageName);
127014de02dd2e050c36f7e0d4f57690bd5d023b4f2Yorke Lee        }
128014de02dd2e050c36f7e0d4f57690bd5d023b4f2Yorke Lee
129014de02dd2e050c36f7e0d4f57690bd5d023b4f2Yorke Lee        // TODO: Filter for apps that don't handle DIAL intent with tel scheme
1308e0207ba5b7ca3bca9d87847eef4d00aa89d7a7aYorke Lee        return packageNames;
131014de02dd2e050c36f7e0d4f57690bd5d023b4f2Yorke Lee    }
132014de02dd2e050c36f7e0d4f57690bd5d023b4f2Yorke Lee
133014de02dd2e050c36f7e0d4f57690bd5d023b4f2Yorke Lee    /**
134610438230b72bc4932e6580230bfa2d5dd4e9913Yorke Lee     * Determines if the package name belongs to the user-selected default dialer or the preloaded
135610438230b72bc4932e6580230bfa2d5dd4e9913Yorke Lee     * system dialer, and thus should be allowed to perform certain privileged operations.
136610438230b72bc4932e6580230bfa2d5dd4e9913Yorke Lee     *
137610438230b72bc4932e6580230bfa2d5dd4e9913Yorke Lee     * @param context A valid context.
138610438230b72bc4932e6580230bfa2d5dd4e9913Yorke Lee     * @param packageName of the package to check for.
139610438230b72bc4932e6580230bfa2d5dd4e9913Yorke Lee     *
140610438230b72bc4932e6580230bfa2d5dd4e9913Yorke Lee     * @return {@code true} if the provided package name corresponds to the user-selected default
141610438230b72bc4932e6580230bfa2d5dd4e9913Yorke Lee     *         dialer or the preloaded system dialer, {@code false} otherwise.
142610438230b72bc4932e6580230bfa2d5dd4e9913Yorke Lee     *
143610438230b72bc4932e6580230bfa2d5dd4e9913Yorke Lee     * @hide
144610438230b72bc4932e6580230bfa2d5dd4e9913Yorke Lee     */
145610438230b72bc4932e6580230bfa2d5dd4e9913Yorke Lee    public static boolean isDefaultOrSystemDialer(Context context, String packageName) {
146610438230b72bc4932e6580230bfa2d5dd4e9913Yorke Lee        if (TextUtils.isEmpty(packageName)) {
147610438230b72bc4932e6580230bfa2d5dd4e9913Yorke Lee            return false;
148610438230b72bc4932e6580230bfa2d5dd4e9913Yorke Lee        }
149610438230b72bc4932e6580230bfa2d5dd4e9913Yorke Lee        final TelecomManager tm = getTelecomManager(context);
150610438230b72bc4932e6580230bfa2d5dd4e9913Yorke Lee        return packageName.equals(tm.getDefaultDialerPackage())
151610438230b72bc4932e6580230bfa2d5dd4e9913Yorke Lee                || packageName.equals(tm.getSystemDialerPackage());
152610438230b72bc4932e6580230bfa2d5dd4e9913Yorke Lee    }
153610438230b72bc4932e6580230bfa2d5dd4e9913Yorke Lee
154014de02dd2e050c36f7e0d4f57690bd5d023b4f2Yorke Lee    private static TelecomManager getTelecomManager(Context context) {
155014de02dd2e050c36f7e0d4f57690bd5d023b4f2Yorke Lee        return (TelecomManager) context.getSystemService(Context.TELECOM_SERVICE);
156014de02dd2e050c36f7e0d4f57690bd5d023b4f2Yorke Lee    }
157014de02dd2e050c36f7e0d4f57690bd5d023b4f2Yorke Lee}
158