TelecomServiceImpl.java revision 71734c2db8a4e412d833b267777dd011e04cc942
1a1ce1fef2d49d1d537776a5308ace7102a815fe5Brian Carlstrom/*
2a1ce1fef2d49d1d537776a5308ace7102a815fe5Brian Carlstrom * Copyright (C) 2014 The Android Open Source Project
3a1ce1fef2d49d1d537776a5308ace7102a815fe5Brian Carlstrom *
4a1ce1fef2d49d1d537776a5308ace7102a815fe5Brian Carlstrom * Licensed under the Apache License, Version 2.0 (the "License");
5a1ce1fef2d49d1d537776a5308ace7102a815fe5Brian Carlstrom * you may not use this file except in compliance with the License.
6a1ce1fef2d49d1d537776a5308ace7102a815fe5Brian Carlstrom * You may obtain a copy of the License at
7a1ce1fef2d49d1d537776a5308ace7102a815fe5Brian Carlstrom *
8a1ce1fef2d49d1d537776a5308ace7102a815fe5Brian Carlstrom *      http://www.apache.org/licenses/LICENSE-2.0
9a1ce1fef2d49d1d537776a5308ace7102a815fe5Brian Carlstrom *
10a1ce1fef2d49d1d537776a5308ace7102a815fe5Brian Carlstrom * Unless required by applicable law or agreed to in writing, software
11a1ce1fef2d49d1d537776a5308ace7102a815fe5Brian Carlstrom * distributed under the License is distributed on an "AS IS" BASIS,
12a1ce1fef2d49d1d537776a5308ace7102a815fe5Brian Carlstrom * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13a1ce1fef2d49d1d537776a5308ace7102a815fe5Brian Carlstrom * See the License for the specific language governing permissions and
14a1ce1fef2d49d1d537776a5308ace7102a815fe5Brian Carlstrom * limitations under the License.
15a1ce1fef2d49d1d537776a5308ace7102a815fe5Brian Carlstrom */
16a1ce1fef2d49d1d537776a5308ace7102a815fe5Brian Carlstrom
17a1ce1fef2d49d1d537776a5308ace7102a815fe5Brian Carlstrompackage com.android.server.telecom;
18a1ce1fef2d49d1d537776a5308ace7102a815fe5Brian Carlstrom
19a1ce1fef2d49d1d537776a5308ace7102a815fe5Brian Carlstromimport static android.Manifest.permission.CALL_PHONE;
20e63db27db913f1a88e2095a1ee8239b2bb9124e8Ian Rogersimport static android.Manifest.permission.MODIFY_PHONE_STATE;
2170bef0d8f6aa30b0da5c6ca56e1bc5729f74654bAndreas Gampeimport static android.Manifest.permission.READ_PHONE_STATE;
22e63db27db913f1a88e2095a1ee8239b2bb9124e8Ian Rogersimport static android.Manifest.permission.REGISTER_CALL_PROVIDER;
23e63db27db913f1a88e2095a1ee8239b2bb9124e8Ian Rogersimport static android.Manifest.permission.REGISTER_CONNECTION_MANAGER;
24a1ce1fef2d49d1d537776a5308ace7102a815fe5Brian Carlstromimport static android.Manifest.permission.REGISTER_SIM_SUBSCRIPTION;
25bbcc01a5a38d28c221c05788e56473a287f57589Roland Levillainimport static android.Manifest.permission.WRITE_SECURE_SETTINGS;
26e63db27db913f1a88e2095a1ee8239b2bb9124e8Ian Rogers
27a1ce1fef2d49d1d537776a5308ace7102a815fe5Brian Carlstromimport android.app.AppOpsManager;
28a1ce1fef2d49d1d537776a5308ace7102a815fe5Brian Carlstromimport android.content.ComponentName;
29e63db27db913f1a88e2095a1ee8239b2bb9124e8Ian Rogersimport android.content.Context;
302ffb703bf431d74326c88266b4ddaf225eb3c6adIgor Murashkinimport android.content.Intent;
31e63db27db913f1a88e2095a1ee8239b2bb9124e8Ian Rogersimport android.content.pm.ApplicationInfo;
32a1ce1fef2d49d1d537776a5308ace7102a815fe5Brian Carlstromimport android.content.pm.PackageManager;
33e63db27db913f1a88e2095a1ee8239b2bb9124e8Ian Rogersimport android.content.res.Resources;
34e63db27db913f1a88e2095a1ee8239b2bb9124e8Ian Rogersimport android.net.Uri;
35e63db27db913f1a88e2095a1ee8239b2bb9124e8Ian Rogersimport android.os.Binder;
363913e488afb884ccee76d620d4357b6308e55010Andreas Gampeimport android.os.Bundle;
37e63db27db913f1a88e2095a1ee8239b2bb9124e8Ian Rogersimport android.os.IBinder;
38a1ce1fef2d49d1d537776a5308ace7102a815fe5Brian Carlstromimport android.os.UserHandle;
39e63db27db913f1a88e2095a1ee8239b2bb9124e8Ian Rogersimport android.os.UserManager;
40f0972a410a0665dbe32bd96df09a572d69f9f3a3Dmitry Petrochenkoimport android.telecom.DefaultDialerManager;
41a1ce1fef2d49d1d537776a5308ace7102a815fe5Brian Carlstromimport android.telecom.PhoneAccount;
42a1ce1fef2d49d1d537776a5308ace7102a815fe5Brian Carlstromimport android.telecom.PhoneAccountHandle;
43e63db27db913f1a88e2095a1ee8239b2bb9124e8Ian Rogersimport android.telecom.TelecomManager;
44e63db27db913f1a88e2095a1ee8239b2bb9124e8Ian Rogersimport android.telephony.SubscriptionManager;
4536fea8dd490ab6439f391b8cd7f366c59f026fd2Andreas Gampeimport android.telephony.TelephonyManager;
46e63db27db913f1a88e2095a1ee8239b2bb9124e8Ian Rogersimport android.text.TextUtils;
47957ca1cd025104fccb0b08928f955f9bdb4ab91cMathieu Chartier
48a1ce1fef2d49d1d537776a5308ace7102a815fe5Brian Carlstrom// TODO: Needed for move to system service: import com.android.internal.R;
49bdf7f1c3ab65ccb70f62db5ab31dba060632d458Andreas Gampeimport com.android.internal.telecom.ITelecomService;
50a1ce1fef2d49d1d537776a5308ace7102a815fe5Brian Carlstromimport com.android.internal.util.IndentingPrintWriter;
51e63db27db913f1a88e2095a1ee8239b2bb9124e8Ian Rogersimport com.android.server.telecom.components.UserCallIntentProcessor;
52a1ce1fef2d49d1d537776a5308ace7102a815fe5Brian Carlstrom
530795f23920ee9aabf28e45c63cd592dcccf00216Mathieu Chartierimport java.io.FileDescriptor;
54bdf7f1c3ab65ccb70f62db5ab31dba060632d458Andreas Gampeimport java.io.PrintWriter;
55a1ce1fef2d49d1d537776a5308ace7102a815fe5Brian Carlstromimport java.util.ArrayList;
56a1ce1fef2d49d1d537776a5308ace7102a815fe5Brian Carlstromimport java.util.Collections;
57e63db27db913f1a88e2095a1ee8239b2bb9124e8Ian Rogersimport java.util.List;
58a1ce1fef2d49d1d537776a5308ace7102a815fe5Brian Carlstrom
59bbcc01a5a38d28c221c05788e56473a287f57589Roland Levillain/**
60bbcc01a5a38d28c221c05788e56473a287f57589Roland Levillain * Implementation of the ITelecom interface.
61bbcc01a5a38d28c221c05788e56473a287f57589Roland Levillain */
62bbcc01a5a38d28c221c05788e56473a287f57589Roland Levillainpublic class TelecomServiceImpl {
63a1ce1fef2d49d1d537776a5308ace7102a815fe5Brian Carlstrom    private static final String PERMISSION_PROCESS_PHONE_ACCOUNT_REGISTRATION =
640d5a281c671444bfa75d63caf1427a8c0e6e1177Roland Levillain            "android.permission.PROCESS_PHONE_ACCOUNT_REGISTRATION";
650d5a281c671444bfa75d63caf1427a8c0e6e1177Roland Levillain
6670bef0d8f6aa30b0da5c6ca56e1bc5729f74654bAndreas Gampe    private final ITelecomService.Stub mBinderImpl = new ITelecomService.Stub() {
6770bef0d8f6aa30b0da5c6ca56e1bc5729f74654bAndreas Gampe        @Override
6870bef0d8f6aa30b0da5c6ca56e1bc5729f74654bAndreas Gampe        public PhoneAccountHandle getDefaultOutgoingPhoneAccount(String uriScheme,
6970bef0d8f6aa30b0da5c6ca56e1bc5729f74654bAndreas Gampe                String callingPackage) {
7070bef0d8f6aa30b0da5c6ca56e1bc5729f74654bAndreas Gampe            synchronized (mLock) {
7170bef0d8f6aa30b0da5c6ca56e1bc5729f74654bAndreas Gampe                if (!canReadPhoneState(callingPackage, "getDefaultOutgoingPhoneAccount")) {
7270bef0d8f6aa30b0da5c6ca56e1bc5729f74654bAndreas Gampe                    return null;
7370bef0d8f6aa30b0da5c6ca56e1bc5729f74654bAndreas Gampe                }
7470bef0d8f6aa30b0da5c6ca56e1bc5729f74654bAndreas Gampe
7570bef0d8f6aa30b0da5c6ca56e1bc5729f74654bAndreas Gampe                long token = Binder.clearCallingIdentity();
7670bef0d8f6aa30b0da5c6ca56e1bc5729f74654bAndreas Gampe                try {
7770bef0d8f6aa30b0da5c6ca56e1bc5729f74654bAndreas Gampe                    PhoneAccountHandle defaultOutgoingPhoneAccount =
78877fd963548a3175665bfef25b0d24bc0e5a0135Calin Juravle                            mPhoneAccountRegistrar.getOutgoingPhoneAccountForScheme(uriScheme);
79877fd963548a3175665bfef25b0d24bc0e5a0135Calin Juravle                    // Make sure that the calling user can see this phone account.
80d0af56cdb1eaebea403e382257bdc14d7b7fdaa4Mathieu Chartier                    // TODO: Does this isVisible check actually work considering we are clearing
81d0af56cdb1eaebea403e382257bdc14d7b7fdaa4Mathieu Chartier                    // the calling identity?
82d0af56cdb1eaebea403e382257bdc14d7b7fdaa4Mathieu Chartier                    if (defaultOutgoingPhoneAccount != null
83d0af56cdb1eaebea403e382257bdc14d7b7fdaa4Mathieu Chartier                            && !isVisibleToCaller(defaultOutgoingPhoneAccount)) {
84e63db27db913f1a88e2095a1ee8239b2bb9124e8Ian Rogers                        Log.w(this, "No account found for the calling user");
85a1ce1fef2d49d1d537776a5308ace7102a815fe5Brian Carlstrom                        return null;
86a1ce1fef2d49d1d537776a5308ace7102a815fe5Brian Carlstrom                    }
87bdf7f1c3ab65ccb70f62db5ab31dba060632d458Andreas Gampe                    return defaultOutgoingPhoneAccount;
88a1ce1fef2d49d1d537776a5308ace7102a815fe5Brian Carlstrom                } catch (Exception e) {
89bdf7f1c3ab65ccb70f62db5ab31dba060632d458Andreas Gampe                    Log.e(this, e, "getDefaultOutgoingPhoneAccount");
90a1ce1fef2d49d1d537776a5308ace7102a815fe5Brian Carlstrom                    throw e;
915a4b8a236030460651a3136397d23ca6744e7eb7Andreas Gampe                } finally {
92a1ce1fef2d49d1d537776a5308ace7102a815fe5Brian Carlstrom                    Binder.restoreCallingIdentity(token);
93bdf7f1c3ab65ccb70f62db5ab31dba060632d458Andreas Gampe                }
94a1ce1fef2d49d1d537776a5308ace7102a815fe5Brian Carlstrom            }
955a4b8a236030460651a3136397d23ca6744e7eb7Andreas Gampe        }
96a1ce1fef2d49d1d537776a5308ace7102a815fe5Brian Carlstrom
97bdf7f1c3ab65ccb70f62db5ab31dba060632d458Andreas Gampe        @Override
98a1ce1fef2d49d1d537776a5308ace7102a815fe5Brian Carlstrom        public PhoneAccountHandle getUserSelectedOutgoingPhoneAccount() {
993f41a0193eadf037b4003c1996151f386ca07b13Andreas Gampe            synchronized (mLock) {
100ceb07b3285eaab350a8cd12f7d74be3e40a255ddMathieu Chartier                try {
101e63db27db913f1a88e2095a1ee8239b2bb9124e8Ian Rogers                    PhoneAccountHandle userSelectedOutgoingPhoneAccount =
102a1ce1fef2d49d1d537776a5308ace7102a815fe5Brian Carlstrom                            mPhoneAccountRegistrar.getUserSelectedOutgoingPhoneAccount();
103e63db27db913f1a88e2095a1ee8239b2bb9124e8Ian Rogers                    // Make sure that the calling user can see this phone account.
104a1ce1fef2d49d1d537776a5308ace7102a815fe5Brian Carlstrom                    if (!isVisibleToCaller(userSelectedOutgoingPhoneAccount)) {
105409e80901468f6c746eeae5c6e93ceedf1d8c711Nicolas Geoffray                        Log.w(this, "No account found for the calling user");
106700a402244a1a423da4f3ba8032459f4b65fa18fIan Rogers                        return null;
107700a402244a1a423da4f3ba8032459f4b65fa18fIan Rogers                    }
108700a402244a1a423da4f3ba8032459f4b65fa18fIan Rogers                    return userSelectedOutgoingPhoneAccount;
1096f3dbbadf4ce66982eb3d400e0a74cb73eb034f3Ian Rogers                } catch (Exception e) {
1106f3dbbadf4ce66982eb3d400e0a74cb73eb034f3Ian Rogers                    Log.e(this, e, "getUserSelectedOutgoingPhoneAccount");
111a1ce1fef2d49d1d537776a5308ace7102a815fe5Brian Carlstrom                    throw e;
112a1ce1fef2d49d1d537776a5308ace7102a815fe5Brian Carlstrom                }
113700a402244a1a423da4f3ba8032459f4b65fa18fIan Rogers            }
1148a630577ed2d9e9571c3434c505e5de223b23c07Vladimir Marko        }
1158a630577ed2d9e9571c3434c505e5de223b23c07Vladimir Marko
116700a402244a1a423da4f3ba8032459f4b65fa18fIan Rogers        @Override
117a1ce1fef2d49d1d537776a5308ace7102a815fe5Brian Carlstrom        public void setUserSelectedOutgoingPhoneAccount(PhoneAccountHandle accountHandle) {
118a1ce1fef2d49d1d537776a5308ace7102a815fe5Brian Carlstrom            synchronized (mLock) {
119a1ce1fef2d49d1d537776a5308ace7102a815fe5Brian Carlstrom                enforceModifyPermission();
120a1ce1fef2d49d1d537776a5308ace7102a815fe5Brian Carlstrom
121a1ce1fef2d49d1d537776a5308ace7102a815fe5Brian Carlstrom                long token = Binder.clearCallingIdentity();
122                try {
123                    mPhoneAccountRegistrar.setUserSelectedOutgoingPhoneAccount(accountHandle);
124                } catch (Exception e) {
125                    Log.e(this, e, "setUserSelectedOutgoingPhoneAccount");
126                    throw e;
127                } finally {
128                    Binder.restoreCallingIdentity(token);
129                }
130            }
131        }
132
133        @Override
134        public List<PhoneAccountHandle> getCallCapablePhoneAccounts(
135                boolean includeDisabledAccounts, String callingPackage) {
136            if (!canReadPhoneState(callingPackage, "getDefaultOutgoingPhoneAccount")) {
137                return Collections.emptyList();
138            }
139
140            synchronized (mLock) {
141                long token = Binder.clearCallingIdentity();
142                try {
143                    // TODO: Does this isVisible check actually work considering we are clearing
144                    // the calling identity?
145                    return filterForAccountsVisibleToCaller(
146                            mPhoneAccountRegistrar.getCallCapablePhoneAccounts(
147                                    null, includeDisabledAccounts));
148                } catch (Exception e) {
149                    Log.e(this, e, "getCallCapablePhoneAccounts");
150                    throw e;
151                } finally {
152                    Binder.restoreCallingIdentity(token);
153                }
154            }
155        }
156
157        @Override
158        public List<PhoneAccountHandle> getPhoneAccountsSupportingScheme(String uriScheme,
159                String callingPackage) {
160            synchronized (mLock) {
161                if (!canReadPhoneState(callingPackage, "getPhoneAccountsSupportingScheme")) {
162                    return Collections.emptyList();
163                }
164
165                long token = Binder.clearCallingIdentity();
166                try {
167                    // TODO: Does this isVisible check actually work considering we are clearing
168                    // the calling identity?
169                    return filterForAccountsVisibleToCaller(
170                            mPhoneAccountRegistrar.getCallCapablePhoneAccounts(uriScheme, false));
171                } catch (Exception e) {
172                    Log.e(this, e, "getPhoneAccountsSupportingScheme %s", uriScheme);
173                    throw e;
174                } finally {
175                    Binder.restoreCallingIdentity(token);
176                }
177            }
178        }
179
180        @Override
181        public List<PhoneAccountHandle> getPhoneAccountsForPackage(String packageName) {
182            synchronized (mLock) {
183                try {
184                    return filterForAccountsVisibleToCaller(
185                            mPhoneAccountRegistrar.getPhoneAccountsForPackage(packageName));
186                } catch (Exception e) {
187                    Log.e(this, e, "getPhoneAccountsForPackage %s", packageName);
188                    throw e;
189                }
190            }
191        }
192
193        @Override
194        public PhoneAccount getPhoneAccount(PhoneAccountHandle accountHandle) {
195            synchronized (mLock) {
196                try {
197                    if (!isVisibleToCaller(accountHandle)) {
198                        Log.w(this, "%s is not visible for the calling user [gPA]", accountHandle);
199                        return null;
200                    }
201                    // TODO: Do we really want to return for *any* user?
202                    return mPhoneAccountRegistrar.getPhoneAccount(accountHandle);
203                } catch (Exception e) {
204                    Log.e(this, e, "getPhoneAccount %s", accountHandle);
205                    throw e;
206                }
207            }
208        }
209
210        @Override
211        public int getAllPhoneAccountsCount() {
212            synchronized (mLock) {
213                try {
214                    // This list is pre-filtered for the calling user.
215                    return getAllPhoneAccounts().size();
216                } catch (Exception e) {
217                    Log.e(this, e, "getAllPhoneAccountsCount");
218                    throw e;
219                }
220            }
221        }
222
223        @Override
224        public List<PhoneAccount> getAllPhoneAccounts() {
225            synchronized (mLock) {
226                try {
227                    List<PhoneAccount> allPhoneAccounts = mPhoneAccountRegistrar
228                            .getAllPhoneAccounts();
229                    List<PhoneAccount> profilePhoneAccounts = new ArrayList<>(
230                            allPhoneAccounts.size());
231                    for (PhoneAccount phoneAccount : profilePhoneAccounts) {
232                        if (isVisibleToCaller(phoneAccount)) {
233                            profilePhoneAccounts.add(phoneAccount);
234                        }
235                    }
236                    return profilePhoneAccounts;
237                } catch (Exception e) {
238                    Log.e(this, e, "getAllPhoneAccounts");
239                    throw e;
240                }
241            }
242        }
243
244        @Override
245        public List<PhoneAccountHandle> getAllPhoneAccountHandles() {
246            synchronized (mLock) {
247                try {
248                    return filterForAccountsVisibleToCaller(
249                            mPhoneAccountRegistrar.getAllPhoneAccountHandles());
250                } catch (Exception e) {
251                    Log.e(this, e, "getAllPhoneAccounts");
252                    throw e;
253                }
254            }
255        }
256
257        @Override
258        public PhoneAccountHandle getSimCallManager() {
259            synchronized (mLock) {
260                try {
261                    PhoneAccountHandle accountHandle = mPhoneAccountRegistrar.getSimCallManager();
262                    if (!isVisibleToCaller(accountHandle)) {
263                        Log.w(this, "%s is not visible for the calling user [gsCM]", accountHandle);
264                        return null;
265                    }
266                    return accountHandle;
267                } catch (Exception e) {
268                    Log.e(this, e, "getSimCallManager");
269                    throw e;
270                }
271            }
272        }
273
274        @Override
275        public void setSimCallManager(PhoneAccountHandle accountHandle) {
276            synchronized (mLock) {
277                enforceModifyPermission();
278                try {
279                    mPhoneAccountRegistrar.setSimCallManager(accountHandle);
280                } catch (Exception e) {
281                    Log.e(this, e, "setSimCallManager");
282                    throw e;
283                }
284            }
285        }
286
287        @Override
288        public List<PhoneAccountHandle> getSimCallManagers(String callingPackage) {
289            synchronized (mLock) {
290                if (!canReadPhoneState(callingPackage, "getSimCallManagers")) {
291                    return Collections.emptyList();
292                }
293
294                long token = Binder.clearCallingIdentity();
295                try {
296                    // TODO: Does this isVisible check actually work considering we are clearing
297                    // the calling identity?
298                    return filterForAccountsVisibleToCaller(
299                            mPhoneAccountRegistrar.getConnectionManagerPhoneAccounts());
300                } catch (Exception e) {
301                    Log.e(this, e, "getSimCallManagers");
302                    throw e;
303                } finally {
304                    Binder.restoreCallingIdentity(token);
305                }
306            }
307        }
308
309        @Override
310        public void registerPhoneAccount(PhoneAccount account) {
311            synchronized (mLock) {
312                try {
313                    enforcePhoneAccountModificationForPackage(
314                            account.getAccountHandle().getComponentName().getPackageName());
315                    if (account.hasCapabilities(PhoneAccount.CAPABILITY_CALL_PROVIDER)) {
316                        enforceRegisterCallProviderPermission();
317                    }
318                    if (account.hasCapabilities(PhoneAccount.CAPABILITY_SIM_SUBSCRIPTION)) {
319                        enforceRegisterSimSubscriptionPermission();
320                    }
321                    if (account.hasCapabilities(PhoneAccount.CAPABILITY_CONNECTION_MANAGER)) {
322                        enforceRegisterConnectionManagerPermission();
323                    }
324                    if (account.hasCapabilities(PhoneAccount.CAPABILITY_MULTI_USER)) {
325                        enforceRegisterMultiUser();
326                    }
327                    enforceUserHandleMatchesCaller(account.getAccountHandle());
328
329                    mPhoneAccountRegistrar.registerPhoneAccount(account);
330
331                    // Broadcast an intent indicating the phone account which was registered.
332                    long token = Binder.clearCallingIdentity();
333                    try {
334                        Intent intent = new Intent(TelecomManager.ACTION_PHONE_ACCOUNT_REGISTERED);
335                        intent.putExtra(TelecomManager.EXTRA_PHONE_ACCOUNT_HANDLE,
336                                account.getAccountHandle());
337                        Log.i(this, "Sending phone-account intent as user");
338                        mContext.sendBroadcastAsUser(intent, UserHandle.ALL,
339                                PERMISSION_PROCESS_PHONE_ACCOUNT_REGISTRATION);
340                    } finally {
341                        Binder.restoreCallingIdentity(token);
342                    }
343                } catch (Exception e) {
344                    Log.e(this, e, "registerPhoneAccount %s", account);
345                    throw e;
346                }
347            }
348        }
349
350        @Override
351        public void unregisterPhoneAccount(PhoneAccountHandle accountHandle) {
352            synchronized (mLock) {
353                try {
354                    enforcePhoneAccountModificationForPackage(
355                            accountHandle.getComponentName().getPackageName());
356                    enforceUserHandleMatchesCaller(accountHandle);
357                    mPhoneAccountRegistrar.unregisterPhoneAccount(accountHandle);
358                } catch (Exception e) {
359                    Log.e(this, e, "unregisterPhoneAccount %s", accountHandle);
360                    throw e;
361                }
362            }
363        }
364
365        @Override
366        public void clearAccounts(String packageName) {
367            synchronized (mLock) {
368                try {
369                    enforcePhoneAccountModificationForPackage(packageName);
370                    mPhoneAccountRegistrar
371                            .clearAccounts(packageName, Binder.getCallingUserHandle());
372                } catch (Exception e) {
373                    Log.e(this, e, "clearAccounts %s", packageName);
374                    throw e;
375                }
376            }
377        }
378
379        /**
380         * @see android.telecom.TelecomManager#isVoiceMailNumber
381         */
382        @Override
383        public boolean isVoiceMailNumber(PhoneAccountHandle accountHandle, String number,
384                String callingPackage) {
385            synchronized (mLock) {
386                if (!canReadPhoneState(callingPackage, "isVoiceMailNumber")) {
387                    return false;
388                }
389
390                if (!isVisibleToCaller(accountHandle)) {
391                    Log.w(this, "%s is not visible for the calling user [iVMN]", accountHandle);
392                    return false;
393                }
394
395                long token = Binder.clearCallingIdentity();
396                try {
397                    return mPhoneAccountRegistrar.isVoiceMailNumber(accountHandle, number);
398                } catch (Exception e) {
399                    Log.e(this, e, "getSubscriptionIdForPhoneAccount");
400                    throw e;
401                } finally {
402                    Binder.restoreCallingIdentity(token);
403                }
404            }
405        }
406
407        /**
408         * @see android.telecom.TelecomManager#getVoiceMailNumber
409         */
410        @Override
411        public String getVoiceMailNumber(PhoneAccountHandle accountHandle, String callingPackage) {
412            synchronized (mLock) {
413                if (!canReadPhoneState(callingPackage, "getVoiceMailNumber")) {
414                    return null;
415                }
416
417                try {
418                    if (!isVisibleToCaller(accountHandle)) {
419                        Log.w(this, "%s is not visible for the calling user [gVMN]", accountHandle);
420                        return null;
421                    }
422
423                    int subId = SubscriptionManager.getDefaultVoiceSubId();
424                    if (accountHandle != null) {
425                        subId = mPhoneAccountRegistrar
426                                .getSubscriptionIdForPhoneAccount(accountHandle);
427                    }
428                    return getTelephonyManager().getVoiceMailNumber(subId);
429                } catch (Exception e) {
430                    Log.e(this, e, "getSubscriptionIdForPhoneAccount");
431                    throw e;
432                }
433            }
434        }
435
436        /**
437         * @see android.telecom.TelecomManager#getLine1Number
438         */
439        @Override
440        public String getLine1Number(PhoneAccountHandle accountHandle, String callingPackage) {
441            if (!canReadPhoneState(callingPackage, "getLine1Number")) {
442                return null;
443            }
444
445            synchronized (mLock) {
446                if (!isVisibleToCaller(accountHandle)) {
447                    Log.w(this, "%s is not visible for the calling user [gL1N]", accountHandle);
448                    return null;
449                }
450
451                long token = Binder.clearCallingIdentity();
452                try {
453                    int subId =
454                            mPhoneAccountRegistrar.getSubscriptionIdForPhoneAccount(accountHandle);
455                    return getTelephonyManager().getLine1NumberForSubscriber(subId);
456                } catch (Exception e) {
457                    Log.e(this, e, "getSubscriptionIdForPhoneAccount");
458                    throw e;
459                } finally {
460                    Binder.restoreCallingIdentity(token);
461                }
462            }
463        }
464
465        /**
466         * @see android.telecom.TelecomManager#silenceRinger
467         */
468        @Override
469        public void silenceRinger(String callingPackage) {
470            synchronized (mLock) {
471                enforcePermissionOrPrivilegedDialer(MODIFY_PHONE_STATE, callingPackage);
472
473                long token = Binder.clearCallingIdentity();
474                try {
475                    mCallsManager.getRinger().silence();
476                } finally {
477                    Binder.restoreCallingIdentity(token);
478                }
479            }
480        }
481
482        /**
483         * @see android.telecom.TelecomManager#getDefaultPhoneApp
484         * @deprecated - Use {@link android.telecom.TelecomManager#getDefaultDialerPackage()}
485         *         instead.
486         */
487        @Override
488        public ComponentName getDefaultPhoneApp() {
489            // No need to synchronize
490            Resources resources = mContext.getResources();
491            return new ComponentName(
492                    resources.getString(R.string.ui_default_package),
493                    resources.getString(R.string.dialer_default_class));
494        }
495
496        /**
497         * @return the package name of the current user-selected default dialer. If no default
498         *         has been selected, the package name of the system dialer is returned. If
499         *         neither exists, then {@code null} is returned.
500         * @see android.telecom.TelecomManager#getDefaultDialerPackage
501         */
502        @Override
503        public String getDefaultDialerPackage() {
504            final long token = Binder.clearCallingIdentity();
505            try {
506                return DefaultDialerManager.getDefaultDialerApplication(mContext);
507            } finally {
508                Binder.restoreCallingIdentity(token);
509            }
510        }
511
512        /**
513         * @see android.telecom.TelecomManager#getSystemDialerPackage
514         */
515        @Override
516        public String getSystemDialerPackage() {
517            return mContext.getResources().getString(R.string.ui_default_package);
518        }
519
520        /**
521         * @see android.telecom.TelecomManager#isInCall
522         */
523        @Override
524        public boolean isInCall(String callingPackage) {
525            if (!canReadPhoneState(callingPackage, "isInCall")) {
526                return false;
527            }
528
529            synchronized (mLock) {
530                final int callState = mCallsManager.getCallState();
531                return callState == TelephonyManager.CALL_STATE_OFFHOOK
532                        || callState == TelephonyManager.CALL_STATE_RINGING;
533            }
534        }
535
536        /**
537         * @see android.telecom.TelecomManager#isRinging
538         */
539        @Override
540        public boolean isRinging(String callingPackage) {
541            if (!canReadPhoneState(callingPackage, "isRinging")) {
542                return false;
543            }
544
545            synchronized (mLock) {
546                return mCallsManager.getCallState() == TelephonyManager.CALL_STATE_RINGING;
547            }
548        }
549
550        /**
551         * @see TelecomManager#getCallState
552         */
553        @Override
554        public int getCallState() {
555            synchronized (mLock) {
556                return mCallsManager.getCallState();
557            }
558        }
559
560        /**
561         * @see android.telecom.TelecomManager#endCall
562         */
563        @Override
564        public boolean endCall() {
565            synchronized (mLock) {
566                enforceModifyPermission();
567
568                long token = Binder.clearCallingIdentity();
569                try {
570                    return endCallInternal();
571                } finally {
572                    Binder.restoreCallingIdentity(token);
573                }
574            }
575        }
576
577        /**
578         * @see android.telecom.TelecomManager#acceptRingingCall
579         */
580        @Override
581        public void acceptRingingCall() {
582            synchronized (mLock) {
583                enforceModifyPermission();
584
585                long token = Binder.clearCallingIdentity();
586                try {
587                    acceptRingingCallInternal();
588                } finally {
589                    Binder.restoreCallingIdentity(token);
590                }
591            }
592        }
593
594        /**
595         * @see android.telecom.TelecomManager#showInCallScreen
596         */
597        @Override
598        public void showInCallScreen(boolean showDialpad, String callingPackage) {
599            if (!canReadPhoneState(callingPackage, "showInCallScreen")) {
600                return;
601            }
602
603            synchronized (mLock) {
604
605                long token = Binder.clearCallingIdentity();
606                try {
607                    mCallsManager.getInCallController().bringToForeground(showDialpad);
608                } finally {
609                    Binder.restoreCallingIdentity(token);
610                }
611            }
612        }
613
614        /**
615         * @see android.telecom.TelecomManager#cancelMissedCallsNotification
616         */
617        @Override
618        public void cancelMissedCallsNotification(String callingPackage) {
619            synchronized (mLock) {
620                enforcePermissionOrPrivilegedDialer(MODIFY_PHONE_STATE, callingPackage);
621                long token = Binder.clearCallingIdentity();
622                try {
623                    mCallsManager.getMissedCallNotifier().clearMissedCalls();
624                } finally {
625                    Binder.restoreCallingIdentity(token);
626                }
627            }
628        }
629
630        /**
631         * @see android.telecom.TelecomManager#handleMmi
632         */
633        @Override
634        public boolean handlePinMmi(String dialString, String callingPackage) {
635            synchronized (mLock) {
636                enforcePermissionOrPrivilegedDialer(MODIFY_PHONE_STATE, callingPackage);
637
638                // Switch identity so that TelephonyManager checks Telecom's permissions instead.
639                long token = Binder.clearCallingIdentity();
640                boolean retval = false;
641                try {
642                    retval = getTelephonyManager().handlePinMmi(dialString);
643                } finally {
644                    Binder.restoreCallingIdentity(token);
645                }
646
647                return retval;
648            }
649        }
650
651        /**
652         * @see android.telecom.TelecomManager#handleMmi
653         */
654        @Override
655        public boolean handlePinMmiForPhoneAccount(
656                PhoneAccountHandle accountHandle,
657                String dialString,
658                String callingPackage) {
659            synchronized (mLock) {
660                enforcePermissionOrPrivilegedDialer(MODIFY_PHONE_STATE, callingPackage);
661
662                if (!isVisibleToCaller(accountHandle)) {
663                    Log.w(this, "%s is not visible for the calling user [hMMI]", accountHandle);
664                    return false;
665                }
666
667                // Switch identity so that TelephonyManager checks Telecom's permissions instead.
668                long token = Binder.clearCallingIdentity();
669                boolean retval = false;
670                try {
671                    int subId = mPhoneAccountRegistrar
672                            .getSubscriptionIdForPhoneAccount(accountHandle);
673                    retval = getTelephonyManager().handlePinMmiForSubscriber(subId, dialString);
674                } finally {
675                    Binder.restoreCallingIdentity(token);
676                }
677
678                return retval;
679            }
680        }
681
682        /**
683         * @see android.telecom.TelecomManager#getAdnUriForPhoneAccount
684         */
685        @Override
686        public Uri getAdnUriForPhoneAccount(PhoneAccountHandle accountHandle,
687                String callingPackage) {
688            synchronized (mLock) {
689                enforcePermissionOrPrivilegedDialer(MODIFY_PHONE_STATE, callingPackage);
690
691                if (!isVisibleToCaller(accountHandle)) {
692                    Log.w(this, "%s is not visible for the calling user [gA4PA]", accountHandle);
693                    return null;
694                }
695
696                // Switch identity so that TelephonyManager checks Telecom's permissions instead.
697                long token = Binder.clearCallingIdentity();
698                String retval = "content://icc/adn/";
699                try {
700                    long subId = mPhoneAccountRegistrar
701                            .getSubscriptionIdForPhoneAccount(accountHandle);
702                    retval = retval + "subId/" + subId;
703                } finally {
704                    Binder.restoreCallingIdentity(token);
705                }
706
707                return Uri.parse(retval);
708            }
709        }
710
711        /**
712         * @see android.telecom.TelecomManager#isTtySupported
713         */
714        @Override
715        public boolean isTtySupported(String callingPackage) {
716            if (!canReadPhoneState(callingPackage, "hasVoiceMailNumber")) {
717                return false;
718            }
719
720            synchronized (mLock) {
721                return mCallsManager.isTtySupported();
722            }
723        }
724
725        /**
726         * @see android.telecom.TelecomManager#getCurrentTtyMode
727         */
728        @Override
729        public int getCurrentTtyMode(String callingPackage) {
730            if (!canReadPhoneState(callingPackage, "getCurrentTtyMode")) {
731                return TelecomManager.TTY_MODE_OFF;
732            }
733
734            synchronized (mLock) {
735                return mCallsManager.getCurrentTtyMode();
736            }
737        }
738
739        /**
740         * @see android.telecom.TelecomManager#addNewIncomingCall
741         */
742        @Override
743        public void addNewIncomingCall(PhoneAccountHandle phoneAccountHandle, Bundle extras) {
744            synchronized (mLock) {
745                Log.i(this, "Adding new incoming call with phoneAccountHandle %s",
746                        phoneAccountHandle);
747                if (phoneAccountHandle != null && phoneAccountHandle.getComponentName() != null) {
748                    mAppOpsManager.checkPackage(
749                            Binder.getCallingUid(),
750                            phoneAccountHandle.getComponentName().getPackageName());
751
752                    // Make sure it doesn't cross the UserHandle boundary
753                    enforceUserHandleMatchesCaller(phoneAccountHandle);
754                    long token = Binder.clearCallingIdentity();
755
756                    try {
757                        Intent intent = new Intent(TelecomManager.ACTION_INCOMING_CALL);
758                        intent.putExtra(TelecomManager.EXTRA_PHONE_ACCOUNT_HANDLE,
759                            phoneAccountHandle);
760                        intent.putExtra(CallIntentProcessor.KEY_IS_INCOMING_CALL, true);
761                        if (extras != null) {
762                            intent.putExtra(TelecomManager.EXTRA_INCOMING_CALL_EXTRAS, extras);
763                        }
764                        CallIntentProcessor.processIncomingCallIntent(mCallsManager, intent);
765                    } finally {
766                        Binder.restoreCallingIdentity(token);
767                    }
768                } else {
769                    Log.w(this,
770                            "Null phoneAccountHandle. Ignoring request to add new incoming call");
771                }
772            }
773        }
774
775        /**
776         * @see android.telecom.TelecomManager#addNewUnknownCall
777         */
778        @Override
779        public void addNewUnknownCall(PhoneAccountHandle phoneAccountHandle, Bundle extras) {
780            synchronized (mLock) {
781                if (phoneAccountHandle != null && phoneAccountHandle.getComponentName() != null) {
782                    mAppOpsManager.checkPackage(
783                            Binder.getCallingUid(),
784                            phoneAccountHandle.getComponentName().getPackageName());
785
786                    // Make sure it doesn't cross the UserHandle boundary
787                    enforceUserHandleMatchesCaller(phoneAccountHandle);
788                    long token = Binder.clearCallingIdentity();
789
790                    try {
791                        Intent intent = new Intent(TelecomManager.ACTION_NEW_UNKNOWN_CALL);
792                        intent.putExtras(extras);
793                        intent.putExtra(CallIntentProcessor.KEY_IS_UNKNOWN_CALL, true);
794                        intent.putExtra(TelecomManager.EXTRA_PHONE_ACCOUNT_HANDLE,
795                            phoneAccountHandle);
796                        CallIntentProcessor.processUnknownCallIntent(mCallsManager, intent);
797                    } finally {
798                        Binder.restoreCallingIdentity(token);
799                    }
800                } else {
801                    Log.i(this,
802                            "Null phoneAccountHandle or not initiated by Telephony. " +
803                            "Ignoring request to add new unknown call.");
804                }
805            }
806        }
807
808        /**
809         * @see android.telecom.TelecomManager#placeCall
810         */
811        @Override
812        public void placeCall(Uri handle, Bundle extras, String callingPackage) {
813            enforceCallingPackage(callingPackage);
814            if (!canCallPhone(callingPackage, "placeCall")) {
815                throw new SecurityException("Package " + callingPackage
816                        + " is not allowed to place phone calls");
817            }
818
819            synchronized (mLock) {
820                final UserHandle userHandle = Binder.getCallingUserHandle();
821                long token = Binder.clearCallingIdentity();
822                try {
823                    final Intent intent = new Intent(Intent.ACTION_CALL, handle);
824                    intent.putExtras(extras);
825                    new UserCallIntentProcessor(mContext, userHandle).processIntent(intent,
826                            callingPackage);
827                } finally {
828                    Binder.restoreCallingIdentity(token);
829                }
830            }
831        }
832
833        /**
834         * @see android.telecom.TelecomManager#enablePhoneAccount
835         */
836        @Override
837        public boolean enablePhoneAccount(PhoneAccountHandle accountHandle, boolean isEnabled) {
838            enforceModifyPermission();
839            synchronized (mLock) {
840                long token  = Binder.clearCallingIdentity();
841                try {
842                    // enable/disable phone account
843                    return mPhoneAccountRegistrar.enablePhoneAccount(accountHandle, isEnabled);
844                } finally {
845                    Binder.restoreCallingIdentity(token);
846                }
847            }
848        }
849
850        @Override
851        public boolean setDefaultDialer(String packageName) {
852            enforcePermission(MODIFY_PHONE_STATE);
853            enforcePermission(WRITE_SECURE_SETTINGS);
854            synchronized (mLock) {
855                long token  = Binder.clearCallingIdentity();
856                try {
857                    return DefaultDialerManager.setDefaultDialerApplication(mContext, packageName);
858                } finally {
859                    Binder.restoreCallingIdentity(token);
860                }
861            }
862        }
863
864        /**
865         * Dumps the current state of the TelecomService.  Used when generating problem reports.
866         *
867         * @param fd The file descriptor.
868         * @param writer The print writer to dump the state to.
869         * @param args Optional dump arguments.
870         */
871        @Override
872        protected void dump(FileDescriptor fd, final PrintWriter writer, String[] args) {
873            if (mContext.checkCallingOrSelfPermission(
874                    android.Manifest.permission.DUMP)
875                    != PackageManager.PERMISSION_GRANTED) {
876                writer.println("Permission Denial: can't dump TelecomService " +
877                        "from from pid=" + Binder.getCallingPid() + ", uid=" +
878                        Binder.getCallingUid());
879                return;
880            }
881
882            final IndentingPrintWriter pw = new IndentingPrintWriter(writer, "  ");
883            if (mCallsManager != null) {
884                pw.println("CallsManager: ");
885                pw.increaseIndent();
886                mCallsManager.dump(pw);
887                pw.decreaseIndent();
888
889                pw.println("PhoneAccountRegistrar: ");
890                pw.increaseIndent();
891                mPhoneAccountRegistrar.dump(pw);
892                pw.decreaseIndent();
893            }
894
895            Log.dumpCallEvents(pw);
896        }
897    };
898
899    private Context mContext;
900    private AppOpsManager mAppOpsManager;
901    private UserManager mUserManager;
902    private PackageManager mPackageManager;
903    private CallsManager mCallsManager;
904    private final PhoneAccountRegistrar mPhoneAccountRegistrar;
905    private final TelecomSystem.SyncRoot mLock;
906
907    public TelecomServiceImpl(
908            Context context,
909            CallsManager callsManager,
910            PhoneAccountRegistrar phoneAccountRegistrar,
911            TelecomSystem.SyncRoot lock) {
912        mContext = context;
913        mAppOpsManager = (AppOpsManager) mContext.getSystemService(Context.APP_OPS_SERVICE);
914
915        mUserManager = (UserManager) mContext.getSystemService(Context.USER_SERVICE);
916        mPackageManager = mContext.getPackageManager();
917
918        mCallsManager = callsManager;
919        mLock = lock;
920        mPhoneAccountRegistrar = phoneAccountRegistrar;
921    }
922
923    public ITelecomService.Stub getBinder() {
924        return mBinderImpl;
925    }
926
927    //
928    // Supporting methods for the ITelecomService interface implementation.
929    //
930
931    private boolean isVisibleToCaller(PhoneAccountHandle accountHandle) {
932        if (accountHandle == null) {
933            return false;
934        }
935        return isVisibleToCaller(mPhoneAccountRegistrar.getPhoneAccount(accountHandle));
936    }
937
938    private boolean isVisibleToCaller(PhoneAccount account) {
939        if (account == null) {
940            return false;
941        }
942
943        // If this PhoneAccount has CAPABILITY_MULTI_USER, it should be visible to all users and
944        // all profiles. Only Telephony and SIP accounts should have this capability.
945        if (account.hasCapabilities(PhoneAccount.CAPABILITY_MULTI_USER)) {
946            return true;
947        }
948
949        UserHandle phoneAccountUserHandle = account.getAccountHandle().getUserHandle();
950        if (phoneAccountUserHandle == null) {
951            return false;
952        }
953
954        if (phoneAccountUserHandle.equals(Binder.getCallingUserHandle())) {
955            return true;
956        }
957
958        List<UserHandle> profileUserHandles;
959        if (UserHandle.getCallingUserId() == UserHandle.USER_OWNER) {
960            profileUserHandles = mUserManager.getUserProfiles();
961        } else {
962            // Otherwise, it has to be owned by the current caller's profile.
963            profileUserHandles = new ArrayList<>(1);
964            profileUserHandles.add(Binder.getCallingUserHandle());
965        }
966
967        return profileUserHandles.contains(phoneAccountUserHandle);
968    }
969
970    /**
971     * Given a list of {@link PhoneAccountHandle}s, filter them to the ones that the calling
972     * user can see.
973     *
974     * @param phoneAccountHandles Unfiltered list of account handles.
975     *
976     * @return {@link PhoneAccountHandle}s visible to the calling user and its profiles.
977     */
978    private List<PhoneAccountHandle> filterForAccountsVisibleToCaller(
979            List<PhoneAccountHandle> phoneAccountHandles) {
980        List<PhoneAccountHandle> profilePhoneAccountHandles =
981                new ArrayList<>(phoneAccountHandles.size());
982        for (PhoneAccountHandle phoneAccountHandle : phoneAccountHandles) {
983            if (isVisibleToCaller(phoneAccountHandle)) {
984                profilePhoneAccountHandles.add(phoneAccountHandle);
985            }
986        }
987        return profilePhoneAccountHandles;
988    }
989
990    private boolean isCallerSystemApp() {
991        int uid = Binder.getCallingUid();
992        String[] packages = mPackageManager.getPackagesForUid(uid);
993        for (String packageName : packages) {
994            if (isPackageSystemApp(packageName)) {
995                return true;
996            }
997        }
998        return false;
999    }
1000
1001    private boolean isPackageSystemApp(String packageName) {
1002        try {
1003            ApplicationInfo applicationInfo = mPackageManager.getApplicationInfo(packageName,
1004                    PackageManager.GET_META_DATA);
1005            if ((applicationInfo.flags & ApplicationInfo.FLAG_SYSTEM) != 0) {
1006                return true;
1007            }
1008        } catch (PackageManager.NameNotFoundException e) {
1009        }
1010        return false;
1011    }
1012
1013    private void acceptRingingCallInternal() {
1014        Call call = mCallsManager.getFirstCallWithState(CallState.RINGING);
1015        if (call != null) {
1016            call.answer(call.getVideoState());
1017        }
1018    }
1019
1020    private boolean endCallInternal() {
1021        // Always operate on the foreground call if one exists, otherwise get the first call in
1022        // priority order by call-state.
1023        Call call = mCallsManager.getForegroundCall();
1024        if (call == null) {
1025            call = mCallsManager.getFirstCallWithState(
1026                    CallState.ACTIVE,
1027                    CallState.DIALING,
1028                    CallState.RINGING,
1029                    CallState.ON_HOLD);
1030        }
1031
1032        if (call != null) {
1033            if (call.getState() == CallState.RINGING) {
1034                call.reject(false /* rejectWithMessage */, null);
1035            } else {
1036                call.disconnect();
1037            }
1038            return true;
1039        }
1040
1041        return false;
1042    }
1043
1044    private void enforcePhoneAccountModificationForPackage(String packageName) {
1045        // TODO: Use a new telecomm permission for this instead of reusing modify.
1046
1047        int result = mContext.checkCallingOrSelfPermission(MODIFY_PHONE_STATE);
1048
1049        // Callers with MODIFY_PHONE_STATE can use the PhoneAccount mechanism to implement
1050        // built-in behavior even when PhoneAccounts are not exposed as a third-part API. They
1051        // may also modify PhoneAccounts on behalf of any 'packageName'.
1052
1053        if (result != PackageManager.PERMISSION_GRANTED) {
1054            // Other callers are only allowed to modify PhoneAccounts if the relevant system
1055            // feature is enabled ...
1056            enforceConnectionServiceFeature();
1057            // ... and the PhoneAccounts they refer to are for their own package.
1058            enforceCallingPackage(packageName);
1059        }
1060    }
1061
1062    private void enforcePermissionOrPrivilegedDialer(String permission, String packageName) {
1063        if (!isPrivilegedDialerCalling(packageName)) {
1064            try {
1065                enforcePermission(permission);
1066            } catch (SecurityException e) {
1067                Log.e(this, e, "Caller must be the default or system dialer, or have the permission"
1068                        + " %s to perform this operation.", permission);
1069                throw e;
1070            }
1071        }
1072    }
1073
1074    private void enforceCallingPackage(String packageName) {
1075        mAppOpsManager.checkPackage(Binder.getCallingUid(), packageName);
1076    }
1077
1078    private void enforceConnectionServiceFeature() {
1079        enforceFeature(PackageManager.FEATURE_CONNECTION_SERVICE);
1080    }
1081
1082    private void enforceRegisterCallProviderPermission() {
1083        enforcePermission(REGISTER_CALL_PROVIDER);
1084    }
1085
1086    private void enforceRegisterSimSubscriptionPermission() {
1087        enforcePermission(REGISTER_SIM_SUBSCRIPTION);
1088    }
1089
1090    private void enforceRegisterConnectionManagerPermission() {
1091        enforcePermission(REGISTER_CONNECTION_MANAGER);
1092    }
1093
1094    private void enforceModifyPermission() {
1095        enforcePermission(MODIFY_PHONE_STATE);
1096    }
1097
1098    private void enforcePermission(String permission) {
1099        mContext.enforceCallingOrSelfPermission(permission, null);
1100    }
1101
1102    private void enforceRegisterMultiUser() {
1103        if (!isCallerSystemApp()) {
1104            throw new SecurityException("CAPABILITY_MULTI_USER is only available to system apps.");
1105        }
1106    }
1107
1108    private void enforceUserHandleMatchesCaller(PhoneAccountHandle accountHandle) {
1109        if (!Binder.getCallingUserHandle().equals(accountHandle.getUserHandle())) {
1110            throw new SecurityException("Calling UserHandle does not match PhoneAccountHandle's");
1111        }
1112    }
1113
1114    private void enforceFeature(String feature) {
1115        PackageManager pm = mContext.getPackageManager();
1116        if (!pm.hasSystemFeature(feature)) {
1117            throw new UnsupportedOperationException(
1118                    "System does not support feature " + feature);
1119        }
1120    }
1121
1122    private boolean canReadPhoneState(String callingPackage, String message) {
1123        // The system/default dialer can always read phone state - so that emergency calls will
1124        // still work.
1125        if (isPrivilegedDialerCalling(callingPackage)) {
1126            return true;
1127        }
1128
1129        // Accessing phone state is gated by a special permission.
1130        mContext.enforceCallingOrSelfPermission(READ_PHONE_STATE, message);
1131
1132        // Some apps that have the permission can be restricted via app ops.
1133        return mAppOpsManager.noteOp(AppOpsManager.OP_READ_PHONE_STATE,
1134                Binder.getCallingUid(), callingPackage) == AppOpsManager.MODE_ALLOWED;
1135    }
1136
1137    private boolean canCallPhone(String callingPackage, String message) {
1138        // The system/default dialer can always read phone state - so that emergency calls will
1139        // still work.
1140        if (isPrivilegedDialerCalling(callingPackage)) {
1141            return true;
1142        }
1143
1144        // Accessing phone state is gated by a special permission.
1145        mContext.enforceCallingOrSelfPermission(CALL_PHONE, message);
1146
1147        // Some apps that have the permission can be restricted via app ops.
1148        return mAppOpsManager.noteOp(AppOpsManager.OP_CALL_PHONE,
1149                Binder.getCallingUid(), callingPackage) == AppOpsManager.MODE_ALLOWED;
1150    }
1151
1152    private boolean isCallerSimCallManager() {
1153        PhoneAccountHandle accountHandle = TelecomSystem.getInstance().getPhoneAccountRegistrar()
1154                .getSimCallManager();
1155        if (accountHandle != null) {
1156            try {
1157                mAppOpsManager.checkPackage(
1158                        Binder.getCallingUid(), accountHandle.getComponentName().getPackageName());
1159                return true;
1160            } catch (SecurityException e) {
1161            }
1162        }
1163        return false;
1164    }
1165
1166    private boolean isPrivilegedDialerCalling(String callingPackage) {
1167        mAppOpsManager.checkPackage(Binder.getCallingUid(), callingPackage);
1168        return DefaultDialerManager.isDefaultOrSystemDialer(mContext, callingPackage);
1169    }
1170
1171    private TelephonyManager getTelephonyManager() {
1172        return (TelephonyManager)mContext.getSystemService(Context.TELEPHONY_SERVICE);
1173    }
1174}
1175