TelecomServiceImpl.java revision ecd74a56dbce2d15ff46ad3e64a16dfe8b6c734f
1/*
2 * Copyright (C) 2014 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 *      http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17package com.android.server.telecom;
18
19import static android.Manifest.permission.CALL_PHONE;
20import static android.Manifest.permission.DUMP;
21import static android.Manifest.permission.MODIFY_PHONE_STATE;
22import static android.Manifest.permission.READ_PHONE_STATE;
23import static android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE;
24import static android.Manifest.permission.REGISTER_SIM_SUBSCRIPTION;
25import static android.Manifest.permission.WRITE_SECURE_SETTINGS;
26
27import android.app.ActivityManager;
28import android.app.AppOpsManager;
29import android.content.ComponentName;
30import android.content.Context;
31import android.content.Intent;
32import android.content.pm.ApplicationInfo;
33import android.content.pm.PackageManager;
34import android.content.res.Resources;
35import android.net.Uri;
36import android.os.Binder;
37import android.os.Bundle;
38import android.os.Process;
39import android.os.UserHandle;
40import android.os.UserManager;
41import android.telecom.DefaultDialerManager;
42import android.telecom.ParcelableCallAnalytics;
43import android.telecom.PhoneAccount;
44import android.telecom.PhoneAccountHandle;
45import android.telecom.TelecomManager;
46import android.telecom.VideoProfile;
47import android.telephony.SubscriptionManager;
48import android.telephony.TelephonyManager;
49
50// TODO: Needed for move to system service: import com.android.internal.R;
51import com.android.internal.telecom.ITelecomService;
52import com.android.internal.util.IndentingPrintWriter;
53import com.android.server.telecom.components.UserCallIntentProcessorFactory;
54
55import java.io.FileDescriptor;
56import java.io.PrintWriter;
57import java.util.ArrayList;
58import java.util.Arrays;
59import java.util.Collections;
60import java.util.List;
61
62/**
63 * Implementation of the ITelecom interface.
64 */
65public class TelecomServiceImpl {
66    public interface DefaultDialerManagerAdapter {
67        String getDefaultDialerApplication(Context context);
68        boolean setDefaultDialerApplication(Context context, String packageName);
69        boolean isDefaultOrSystemDialer(Context context, String packageName);
70    }
71
72    static class DefaultDialerManagerAdapterImpl implements DefaultDialerManagerAdapter {
73        @Override
74        public String getDefaultDialerApplication(Context context) {
75            return DefaultDialerManager.getDefaultDialerApplication(context);
76        }
77
78        @Override
79        public boolean setDefaultDialerApplication(Context context, String packageName) {
80            return DefaultDialerManager.setDefaultDialerApplication(context, packageName);
81        }
82
83        @Override
84        public boolean isDefaultOrSystemDialer(Context context, String packageName) {
85            return DefaultDialerManager.isDefaultOrSystemDialer(context, packageName);
86        }
87    }
88
89    public interface SubscriptionManagerAdapter {
90        int getDefaultVoiceSubId();
91    }
92
93    static class SubscriptionManagerAdapterImpl implements SubscriptionManagerAdapter {
94        @Override
95        public int getDefaultVoiceSubId() {
96            return SubscriptionManager.getDefaultVoiceSubId();
97        }
98    }
99
100    private static final String PERMISSION_PROCESS_PHONE_ACCOUNT_REGISTRATION =
101            "android.permission.PROCESS_PHONE_ACCOUNT_REGISTRATION";
102    private static final int DEFAULT_VIDEO_STATE = -1;
103
104    private final ITelecomService.Stub mBinderImpl = new ITelecomService.Stub() {
105        @Override
106        public PhoneAccountHandle getDefaultOutgoingPhoneAccount(String uriScheme,
107                String callingPackage) {
108            try {
109                Log.startSession("TSI.gDOPA");
110                synchronized (mLock) {
111                    if (!canReadPhoneState(callingPackage, "getDefaultOutgoingPhoneAccount")) {
112                        return null;
113                    }
114
115                    final UserHandle callingUserHandle = Binder.getCallingUserHandle();
116                    long token = Binder.clearCallingIdentity();
117                    try {
118                        return mPhoneAccountRegistrar
119                                .getOutgoingPhoneAccountForScheme(uriScheme, callingUserHandle);
120                    } catch (Exception e) {
121                        Log.e(this, e, "getDefaultOutgoingPhoneAccount");
122                        throw e;
123                    } finally {
124                        Binder.restoreCallingIdentity(token);
125                    }
126                }
127            } finally {
128                Log.endSession();
129            }
130        }
131
132        @Override
133        public PhoneAccountHandle getUserSelectedOutgoingPhoneAccount() {
134            synchronized (mLock) {
135                try {
136                    Log.startSession("TSI.gUSOPA");
137                    final UserHandle callingUserHandle = Binder.getCallingUserHandle();
138                    return mPhoneAccountRegistrar.getUserSelectedOutgoingPhoneAccount(
139                            callingUserHandle);
140                } catch (Exception e) {
141                    Log.e(this, e, "getUserSelectedOutgoingPhoneAccount");
142                    throw e;
143                } finally {
144                    Log.endSession();
145                }
146            }
147        }
148
149        @Override
150        public void setUserSelectedOutgoingPhoneAccount(PhoneAccountHandle accountHandle) {
151            try {
152                Log.startSession("TSI.sUSOPA");
153                synchronized (mLock) {
154                    enforceModifyPermission();
155                    UserHandle callingUserHandle = Binder.getCallingUserHandle();
156                    long token = Binder.clearCallingIdentity();
157                    try {
158                        mPhoneAccountRegistrar.setUserSelectedOutgoingPhoneAccount(
159                                accountHandle, callingUserHandle);
160                    } catch (Exception e) {
161                        Log.e(this, e, "setUserSelectedOutgoingPhoneAccount");
162                        throw e;
163                    } finally {
164                        Binder.restoreCallingIdentity(token);
165                    }
166                }
167            } finally {
168                Log.endSession();
169            }
170        }
171
172        @Override
173        public List<PhoneAccountHandle> getCallCapablePhoneAccounts(
174                boolean includeDisabledAccounts, String callingPackage) {
175            try {
176                Log.startSession("TSI.gCCPA");
177                if (!canReadPhoneState(callingPackage, "getDefaultOutgoingPhoneAccount")) {
178                    return Collections.emptyList();
179                }
180                synchronized (mLock) {
181                    final UserHandle callingUserHandle = Binder.getCallingUserHandle();
182                    long token = Binder.clearCallingIdentity();
183                    try {
184                        return mPhoneAccountRegistrar.getCallCapablePhoneAccounts(null,
185                                includeDisabledAccounts, callingUserHandle);
186                    } catch (Exception e) {
187                        Log.e(this, e, "getCallCapablePhoneAccounts");
188                        throw e;
189                    } finally {
190                        Binder.restoreCallingIdentity(token);
191                    }
192                }
193            } finally {
194                Log.endSession();
195            }
196        }
197
198        @Override
199        public List<PhoneAccountHandle> getPhoneAccountsSupportingScheme(String uriScheme,
200                String callingPackage) {
201            try {
202                Log.startSession("TSI.gPASS");
203                synchronized (mLock) {
204                    if (!canReadPhoneState(callingPackage, "getPhoneAccountsSupportingScheme")) {
205                        return Collections.emptyList();
206                    }
207                    final UserHandle callingUserHandle = Binder.getCallingUserHandle();
208                    long token = Binder.clearCallingIdentity();
209                    try {
210                        return mPhoneAccountRegistrar.getCallCapablePhoneAccounts(uriScheme, false,
211                                callingUserHandle);
212                    } catch (Exception e) {
213                        Log.e(this, e, "getPhoneAccountsSupportingScheme %s", uriScheme);
214                        throw e;
215                    } finally {
216                        Binder.restoreCallingIdentity(token);
217                    }
218                }
219            } finally {
220                Log.endSession();
221            }
222        }
223
224        @Override
225        public List<PhoneAccountHandle> getPhoneAccountsForPackage(String packageName) {
226            synchronized (mLock) {
227                final UserHandle callingUserHandle = Binder.getCallingUserHandle();
228                long token = Binder.clearCallingIdentity();
229                try {
230                    Log.startSession("TSI.gPAFP");
231                    return mPhoneAccountRegistrar.getPhoneAccountsForPackage(packageName,
232                            callingUserHandle);
233                } catch (Exception e) {
234                    Log.e(this, e, "getPhoneAccountsForPackage %s", packageName);
235                    throw e;
236                } finally {
237                    Binder.restoreCallingIdentity(token);
238                    Log.endSession();
239                }
240            }
241        }
242
243        @Override
244        public PhoneAccount getPhoneAccount(PhoneAccountHandle accountHandle) {
245            synchronized (mLock) {
246                final UserHandle callingUserHandle = Binder.getCallingUserHandle();
247                long token = Binder.clearCallingIdentity();
248                try {
249                    Log.startSession("TSI.gPA");
250                    // In ideal case, we should not resolve the handle across profiles. But given
251                    // the fact that profile's call is handled by its parent user's in-call UI,
252                    // parent user's in call UI need to be able to get phone account from the
253                    // profile's phone account handle.
254                    return mPhoneAccountRegistrar
255                            .getPhoneAccount(accountHandle, callingUserHandle,
256                            /* acrossProfiles */ true);
257                } catch (Exception e) {
258                    Log.e(this, e, "getPhoneAccount %s", accountHandle);
259                    throw e;
260                } finally {
261                    Binder.restoreCallingIdentity(token);
262                    Log.endSession();
263                }
264            }
265        }
266
267        @Override
268        public int getAllPhoneAccountsCount() {
269            synchronized (mLock) {
270                try {
271                    Log.startSession("TSI.gAPAC");
272                    // This list is pre-filtered for the calling user.
273                    return getAllPhoneAccounts().size();
274                } catch (Exception e) {
275                    Log.e(this, e, "getAllPhoneAccountsCount");
276                    throw e;
277                } finally {
278                    Log.endSession();
279                }
280            }
281        }
282
283        @Override
284        public List<PhoneAccount> getAllPhoneAccounts() {
285            synchronized (mLock) {
286                final UserHandle callingUserHandle = Binder.getCallingUserHandle();
287                long token = Binder.clearCallingIdentity();
288                try {
289                    Log.startSession("TSI.gAPA");
290                    return mPhoneAccountRegistrar.getAllPhoneAccounts(callingUserHandle);
291                } catch (Exception e) {
292                    Log.e(this, e, "getAllPhoneAccounts");
293                    throw e;
294                } finally {
295                    Binder.restoreCallingIdentity(token);
296                    Log.endSession();
297                }
298            }
299        }
300
301        @Override
302        public List<PhoneAccountHandle> getAllPhoneAccountHandles() {
303            synchronized (mLock) {
304                final UserHandle callingUserHandle = Binder.getCallingUserHandle();
305                long token = Binder.clearCallingIdentity();
306                try {
307                    Log.startSession("TSI.gAPAH");
308                    return mPhoneAccountRegistrar.getAllPhoneAccountHandles(callingUserHandle);
309                } catch (Exception e) {
310                    Log.e(this, e, "getAllPhoneAccounts");
311                    throw e;
312                } finally {
313                    Binder.restoreCallingIdentity(token);
314                    Log.endSession();
315                }
316            }
317        }
318
319        @Override
320        public PhoneAccountHandle getSimCallManager() {
321            try {
322                Log.startSession("TSI.gSCM");
323                long token = Binder.clearCallingIdentity();
324                int user;
325                try {
326                    user = ActivityManager.getCurrentUser();
327                    return getSimCallManagerForUser(user);
328                } finally {
329                    Binder.restoreCallingIdentity(token);
330                }
331            } finally {
332                Log.endSession();
333            }
334        }
335
336        @Override
337        public PhoneAccountHandle getSimCallManagerForUser(int user) {
338            synchronized (mLock) {
339                try {
340                    Log.startSession("TSI.gSCMFU");
341                    final int callingUid = Binder.getCallingUid();
342                    long token = Binder.clearCallingIdentity();
343                    try {
344                        if (user != ActivityManager.getCurrentUser()) {
345                            enforceCrossUserPermission(callingUid);
346                        }
347                        return mPhoneAccountRegistrar.getSimCallManager(UserHandle.of(user));
348                    } finally {
349                        Binder.restoreCallingIdentity(token);
350                    }
351                } catch (Exception e) {
352                    Log.e(this, e, "getSimCallManager");
353                    throw e;
354                } finally {
355                    Log.endSession();
356                }
357            }
358        }
359
360        @Override
361        public void registerPhoneAccount(PhoneAccount account) {
362            try {
363                Log.startSession("TSI.rPA");
364                synchronized (mLock) {
365                    if (!mContext.getApplicationContext().getResources().getBoolean(
366                            com.android.internal.R.bool.config_voice_capable)) {
367                        Log.w(this,
368                                "registerPhoneAccount not allowed on non-voice capable device.");
369                        return;
370                    }
371                    try {
372                        enforcePhoneAccountModificationForPackage(
373                                account.getAccountHandle().getComponentName().getPackageName());
374                        if (account.hasCapabilities(PhoneAccount.CAPABILITY_SIM_SUBSCRIPTION)) {
375                            enforceRegisterSimSubscriptionPermission();
376                        }
377                        if (account.hasCapabilities(PhoneAccount.CAPABILITY_MULTI_USER)) {
378                            enforceRegisterMultiUser();
379                        }
380                        enforceUserHandleMatchesCaller(account.getAccountHandle());
381                        mPhoneAccountRegistrar.registerPhoneAccount(account);
382                        // Broadcast an intent indicating the phone account which was registered.
383                        long token = Binder.clearCallingIdentity();
384                        try {
385                            Intent intent = new Intent(
386                                    TelecomManager.ACTION_PHONE_ACCOUNT_REGISTERED);
387                            intent.putExtra(TelecomManager.EXTRA_PHONE_ACCOUNT_HANDLE,
388                                    account.getAccountHandle());
389                            Log.i(this, "Sending phone-account registered intent as user");
390                            mContext.sendBroadcastAsUser(intent, UserHandle.ALL,
391                                    PERMISSION_PROCESS_PHONE_ACCOUNT_REGISTRATION);
392                        } finally {
393                            Binder.restoreCallingIdentity(token);
394                        }
395                    } catch (Exception e) {
396                        Log.e(this, e, "registerPhoneAccount %s", account);
397                        throw e;
398                    }
399                }
400            } finally {
401                Log.endSession();
402            }
403        }
404
405        @Override
406        public void unregisterPhoneAccount(PhoneAccountHandle accountHandle) {
407            synchronized (mLock) {
408                try {
409                    Log.startSession("TSI.uPA");
410                    enforcePhoneAccountModificationForPackage(
411                            accountHandle.getComponentName().getPackageName());
412                    enforceUserHandleMatchesCaller(accountHandle);
413                    mPhoneAccountRegistrar.unregisterPhoneAccount(accountHandle);
414
415                    // Broadcast an intent indicating the phone account which was unregistered.
416                    long token = Binder.clearCallingIdentity();
417                    try {
418                        Intent intent =
419                                new Intent(TelecomManager.ACTION_PHONE_ACCOUNT_UNREGISTERED);
420                        intent.putExtra(
421                                TelecomManager.EXTRA_PHONE_ACCOUNT_HANDLE, accountHandle);
422                        Log.i(this, "Sending phone-account unregistered intent as user");
423                        mContext.sendBroadcastAsUser(intent, UserHandle.ALL,
424                                PERMISSION_PROCESS_PHONE_ACCOUNT_REGISTRATION);
425                    } finally {
426                        Binder.restoreCallingIdentity(token);
427                    }
428                } catch (Exception e) {
429                    Log.e(this, e, "unregisterPhoneAccount %s", accountHandle);
430                    throw e;
431                } finally {
432                    Log.endSession();
433                }
434            }
435        }
436
437        @Override
438        public void clearAccounts(String packageName) {
439            synchronized (mLock) {
440                try {
441                    Log.startSession("TSI.cA");
442                    enforcePhoneAccountModificationForPackage(packageName);
443                    mPhoneAccountRegistrar
444                            .clearAccounts(packageName, Binder.getCallingUserHandle());
445                } catch (Exception e) {
446                    Log.e(this, e, "clearAccounts %s", packageName);
447                    throw e;
448                } finally {
449                    Log.endSession();
450                }
451            }
452        }
453
454        /**
455         * @see android.telecom.TelecomManager#isVoiceMailNumber
456         */
457        @Override
458        public boolean isVoiceMailNumber(PhoneAccountHandle accountHandle, String number,
459                String callingPackage) {
460            try {
461                Log.startSession("TSI.iVMN");
462                synchronized (mLock) {
463                    if (!canReadPhoneState(callingPackage, "isVoiceMailNumber")) {
464                        return false;
465                    }
466                    final UserHandle callingUserHandle = Binder.getCallingUserHandle();
467                    if (!isPhoneAccountHandleVisibleToCallingUser(accountHandle,
468                            callingUserHandle)) {
469                        Log.d(this, "%s is not visible for the calling user [iVMN]", accountHandle);
470                        return false;
471                    }
472                    long token = Binder.clearCallingIdentity();
473                    try {
474                        return mPhoneAccountRegistrar.isVoiceMailNumber(accountHandle, number);
475                    } catch (Exception e) {
476                        Log.e(this, e, "getSubscriptionIdForPhoneAccount");
477                        throw e;
478                    } finally {
479                        Binder.restoreCallingIdentity(token);
480                    }
481                }
482            } finally {
483                Log.endSession();
484            }
485        }
486
487        /**
488         * @see android.telecom.TelecomManager#getVoiceMailNumber
489         */
490        @Override
491        public String getVoiceMailNumber(PhoneAccountHandle accountHandle, String callingPackage) {
492            try {
493                Log.startSession("TSI.gVMN");
494                synchronized (mLock) {
495                    if (!canReadPhoneState(callingPackage, "getVoiceMailNumber")) {
496                        return null;
497                    }
498                    try {
499                        final UserHandle callingUserHandle = Binder.getCallingUserHandle();
500                        if (!isPhoneAccountHandleVisibleToCallingUser(accountHandle,
501                                callingUserHandle)) {
502                            Log.d(this, "%s is not visible for the calling user [gVMN]",
503                                    accountHandle);
504                            return null;
505                        }
506                        int subId = mSubscriptionManagerAdapter.getDefaultVoiceSubId();
507                        if (accountHandle != null) {
508                            subId = mPhoneAccountRegistrar
509                                    .getSubscriptionIdForPhoneAccount(accountHandle);
510                        }
511                        return getTelephonyManager().getVoiceMailNumber(subId);
512                    } catch (Exception e) {
513                        Log.e(this, e, "getSubscriptionIdForPhoneAccount");
514                        throw e;
515                    }
516                }
517            } finally {
518                Log.endSession();
519            }
520        }
521
522        /**
523         * @see android.telecom.TelecomManager#getLine1Number
524         */
525        @Override
526        public String getLine1Number(PhoneAccountHandle accountHandle, String callingPackage) {
527            try {
528                Log.startSession("getL1N");
529                if (!canReadPhoneState(callingPackage, "getLine1Number")) {
530                    return null;
531                }
532
533                synchronized (mLock) {
534                    final UserHandle callingUserHandle = Binder.getCallingUserHandle();
535                    if (!isPhoneAccountHandleVisibleToCallingUser(accountHandle,
536                            callingUserHandle)) {
537                        Log.d(this, "%s is not visible for the calling user [gL1N]", accountHandle);
538                        return null;
539                    }
540
541                    long token = Binder.clearCallingIdentity();
542                    try {
543                        int subId = mPhoneAccountRegistrar.getSubscriptionIdForPhoneAccount(
544                                accountHandle);
545                        return getTelephonyManager().getLine1NumberForSubscriber(subId);
546                    } catch (Exception e) {
547                        Log.e(this, e, "getSubscriptionIdForPhoneAccount");
548                        throw e;
549                    } finally {
550                        Binder.restoreCallingIdentity(token);
551                    }
552                }
553            } finally {
554                Log.endSession();
555            }
556        }
557
558        /**
559         * @see android.telecom.TelecomManager#silenceRinger
560         */
561        @Override
562        public void silenceRinger(String callingPackage) {
563            try {
564                Log.startSession("TSI.sR");
565                synchronized (mLock) {
566                    enforcePermissionOrPrivilegedDialer(MODIFY_PHONE_STATE, callingPackage);
567
568                    long token = Binder.clearCallingIdentity();
569                    try {
570                        Log.i(this, "Silence Ringer requested by %s", callingPackage);
571                        mCallsManager.getRinger().silence();
572                    } finally {
573                        Binder.restoreCallingIdentity(token);
574                    }
575                }
576            } finally {
577                Log.endSession();
578            }
579        }
580
581        /**
582         * @see android.telecom.TelecomManager#getDefaultPhoneApp
583         * @deprecated - Use {@link android.telecom.TelecomManager#getDefaultDialerPackage()}
584         *         instead.
585         */
586        @Override
587        public ComponentName getDefaultPhoneApp() {
588            try {
589                Log.startSession("TSI.gDPA");
590                // No need to synchronize
591                Resources resources = mContext.getResources();
592                return new ComponentName(
593                        resources.getString(R.string.ui_default_package),
594                        resources.getString(R.string.dialer_default_class));
595            } finally {
596                Log.endSession();
597            }
598        }
599
600        /**
601         * @return the package name of the current user-selected default dialer. If no default
602         *         has been selected, the package name of the system dialer is returned. If
603         *         neither exists, then {@code null} is returned.
604         * @see android.telecom.TelecomManager#getDefaultDialerPackage
605         */
606        @Override
607        public String getDefaultDialerPackage() {
608            try {
609                Log.startSession("TSI.gDDP");
610                final long token = Binder.clearCallingIdentity();
611                try {
612                    return mDefaultDialerManagerAdapter.getDefaultDialerApplication(mContext);
613                } finally {
614                    Binder.restoreCallingIdentity(token);
615                }
616            } finally {
617                Log.endSession();
618            }
619        }
620
621        /**
622         * @see android.telecom.TelecomManager#getSystemDialerPackage
623         */
624        @Override
625        public String getSystemDialerPackage() {
626            try {
627                Log.startSession("TSI.gSDP");
628                return mContext.getResources().getString(R.string.ui_default_package);
629            } finally {
630                Log.endSession();
631            }
632        }
633
634        /**
635         * @see android.telecom.TelecomManager#isInCall
636         */
637        @Override
638        public boolean isInCall(String callingPackage) {
639            try {
640                Log.startSession("TSI.iIC");
641                if (!canReadPhoneState(callingPackage, "isInCall")) {
642                    return false;
643                }
644
645                synchronized (mLock) {
646                    final int callState = mCallsManager.getCallState();
647                    return callState == TelephonyManager.CALL_STATE_OFFHOOK
648                            || callState == TelephonyManager.CALL_STATE_RINGING;
649                }
650            } finally {
651                Log.endSession();
652            }
653        }
654
655        /**
656         * @see android.telecom.TelecomManager#isRinging
657         */
658        @Override
659        public boolean isRinging(String callingPackage) {
660            try {
661                Log.startSession("TSI.iR");
662                if (!canReadPhoneState(callingPackage, "isRinging")) {
663                    return false;
664                }
665
666                synchronized (mLock) {
667                    // Note: We are explicitly checking the calls telecom is tracking rather than
668                    // relying on mCallsManager#getCallState(). Since getCallState() relies on the
669                    // current state as tracked by PhoneStateBroadcaster, any failure to properly
670                    // track the current call state there could result in the wrong ringing state
671                    // being reported by this API.
672                    return mCallsManager.hasRingingCall();
673                }
674            } finally {
675                Log.endSession();
676            }
677        }
678
679        /**
680         * @see TelecomManager#getCallState
681         */
682        @Override
683        public int getCallState() {
684            try {
685                Log.startSession("TSI.getCallState");
686                synchronized (mLock) {
687                    return mCallsManager.getCallState();
688                }
689            } finally {
690                Log.endSession();
691            }
692        }
693
694        /**
695         * @see android.telecom.TelecomManager#endCall
696         */
697        @Override
698        public boolean endCall() {
699            try {
700                Log.startSession("TSI.eC");
701                synchronized (mLock) {
702                    enforceModifyPermission();
703
704                    long token = Binder.clearCallingIdentity();
705                    try {
706                        return endCallInternal();
707                    } finally {
708                        Binder.restoreCallingIdentity(token);
709                    }
710                }
711            } finally {
712                Log.endSession();
713            }
714        }
715
716        /**
717         * @see android.telecom.TelecomManager#acceptRingingCall
718         */
719        @Override
720        public void acceptRingingCall() {
721            try {
722                Log.startSession("TSI.aRC");
723                synchronized (mLock) {
724                    enforceModifyPermission();
725
726                    long token = Binder.clearCallingIdentity();
727                    try {
728                        acceptRingingCallInternal(DEFAULT_VIDEO_STATE);
729                    } finally {
730                        Binder.restoreCallingIdentity(token);
731                    }
732                }
733            } finally {
734                Log.endSession();
735            }
736        }
737
738        /**
739         * @see android.telecom.TelecomManager#acceptRingingCall(int)
740         *
741         */
742        @Override
743        public void acceptRingingCallWithVideoState(int videoState) {
744            try {
745                Log.startSession("TSI.aRCWVS");
746                synchronized (mLock) {
747                    enforceModifyPermission();
748
749                    long token = Binder.clearCallingIdentity();
750                    try {
751                        acceptRingingCallInternal(videoState);
752                    } finally {
753                        Binder.restoreCallingIdentity(token);
754                    }
755                }
756            } finally {
757                Log.endSession();
758            }
759        }
760
761        /**
762         * @see android.telecom.TelecomManager#showInCallScreen
763         */
764        @Override
765        public void showInCallScreen(boolean showDialpad, String callingPackage) {
766            try {
767                Log.startSession("TSI.sICS");
768                if (!canReadPhoneState(callingPackage, "showInCallScreen")) {
769                    return;
770                }
771
772                synchronized (mLock) {
773
774                    long token = Binder.clearCallingIdentity();
775                    try {
776                        mCallsManager.getInCallController().bringToForeground(showDialpad);
777                    } finally {
778                        Binder.restoreCallingIdentity(token);
779                    }
780                }
781            } finally {
782                Log.endSession();
783            }
784        }
785
786        /**
787         * @see android.telecom.TelecomManager#cancelMissedCallsNotification
788         */
789        @Override
790        public void cancelMissedCallsNotification(String callingPackage) {
791            try {
792                Log.startSession("TSI.cMCN");
793                synchronized (mLock) {
794                    enforcePermissionOrPrivilegedDialer(MODIFY_PHONE_STATE, callingPackage);
795                    long token = Binder.clearCallingIdentity();
796                    try {
797                        mCallsManager.getMissedCallNotifier().clearMissedCalls();
798                    } finally {
799                        Binder.restoreCallingIdentity(token);
800                    }
801                }
802            } finally {
803                Log.endSession();
804            }
805        }
806        /**
807         * @see android.telecom.TelecomManager#handleMmi
808         */
809        @Override
810        public boolean handlePinMmi(String dialString, String callingPackage) {
811            try {
812                Log.startSession("TSI.hPM");
813                synchronized (mLock) {
814                    enforcePermissionOrPrivilegedDialer(MODIFY_PHONE_STATE, callingPackage);
815
816                    // Switch identity so that TelephonyManager checks Telecom's permissions
817                    // instead.
818                    long token = Binder.clearCallingIdentity();
819                    boolean retval = false;
820                    try {
821                        retval = getTelephonyManager().handlePinMmi(dialString);
822                    } finally {
823                        Binder.restoreCallingIdentity(token);
824                    }
825
826                    return retval;
827                }
828            }finally {
829                Log.endSession();
830            }
831        }
832
833        /**
834         * @see android.telecom.TelecomManager#handleMmi
835         */
836        @Override
837        public boolean handlePinMmiForPhoneAccount(PhoneAccountHandle accountHandle,
838                String dialString, String callingPackage) {
839            try {
840                Log.startSession("TSI.hPMFPA");
841                synchronized (mLock) {
842                    enforcePermissionOrPrivilegedDialer(MODIFY_PHONE_STATE, callingPackage);
843
844                    UserHandle callingUserHandle = Binder.getCallingUserHandle();
845                    if (!isPhoneAccountHandleVisibleToCallingUser(accountHandle,
846                            callingUserHandle)) {
847                        Log.d(this, "%s is not visible for the calling user [hMMI]", accountHandle);
848                        return false;
849                    }
850
851                    // Switch identity so that TelephonyManager checks Telecom's permissions
852                    // instead.
853                    long token = Binder.clearCallingIdentity();
854                    boolean retval = false;
855                    try {
856                        int subId = mPhoneAccountRegistrar.getSubscriptionIdForPhoneAccount(
857                                accountHandle);
858                        retval = getTelephonyManager().handlePinMmiForSubscriber(subId, dialString);
859                    } finally {
860                        Binder.restoreCallingIdentity(token);
861                    }
862                    return retval;
863                }
864            }finally {
865                Log.endSession();
866            }
867        }
868
869        /**
870         * @see android.telecom.TelecomManager#getAdnUriForPhoneAccount
871         */
872        @Override
873        public Uri getAdnUriForPhoneAccount(PhoneAccountHandle accountHandle,
874                String callingPackage) {
875            try {
876                Log.startSession("TSI.aAUFPA");
877                synchronized (mLock) {
878                    enforcePermissionOrPrivilegedDialer(MODIFY_PHONE_STATE, callingPackage);
879                    if (!isPhoneAccountHandleVisibleToCallingUser(accountHandle,
880                            Binder.getCallingUserHandle())) {
881                        Log.d(this, "%s is not visible for the calling user [gA4PA]",
882                                accountHandle);
883                        return null;
884                    }
885                    // Switch identity so that TelephonyManager checks Telecom's permissions
886                    // instead.
887                    long token = Binder.clearCallingIdentity();
888                    String retval = "content://icc/adn/";
889                    try {
890                        long subId = mPhoneAccountRegistrar
891                                .getSubscriptionIdForPhoneAccount(accountHandle);
892                        retval = retval + "subId/" + subId;
893                    } finally {
894                        Binder.restoreCallingIdentity(token);
895                    }
896
897                    return Uri.parse(retval);
898                }
899            } finally {
900                Log.endSession();
901            }
902        }
903
904        /**
905         * @see android.telecom.TelecomManager#isTtySupported
906         */
907        @Override
908        public boolean isTtySupported(String callingPackage) {
909            try {
910                Log.startSession("TSI.iTS");
911                if (!canReadPhoneState(callingPackage, "hasVoiceMailNumber")) {
912                    return false;
913                }
914
915                synchronized (mLock) {
916                    return mCallsManager.isTtySupported();
917                }
918            } finally {
919                Log.endSession();
920            }
921        }
922
923        /**
924         * @see android.telecom.TelecomManager#getCurrentTtyMode
925         */
926        @Override
927        public int getCurrentTtyMode(String callingPackage) {
928            try {
929                Log.startSession("TSI.gCTM");
930                if (!canReadPhoneState(callingPackage, "getCurrentTtyMode")) {
931                    return TelecomManager.TTY_MODE_OFF;
932                }
933
934                synchronized (mLock) {
935                    return mCallsManager.getCurrentTtyMode();
936                }
937            } finally {
938                Log.endSession();
939            }
940        }
941
942        /**
943         * @see android.telecom.TelecomManager#addNewIncomingCall
944         */
945        @Override
946        public void addNewIncomingCall(PhoneAccountHandle phoneAccountHandle, Bundle extras) {
947            try {
948                Log.startSession("TSI.aNIC");
949                synchronized (mLock) {
950                    Log.i(this, "Adding new incoming call with phoneAccountHandle %s",
951                            phoneAccountHandle);
952                    if (phoneAccountHandle != null &&
953                            phoneAccountHandle.getComponentName() != null) {
954                        // TODO(sail): Add unit tests for adding incoming calls from a SIM call
955                        // manager.
956                        if (isCallerSimCallManager() && TelephonyUtil.isPstnComponentName(
957                                phoneAccountHandle.getComponentName())) {
958                            Log.v(this, "Allowing call manager to add incoming call with PSTN" +
959                                    " handle");
960                        } else {
961                            mAppOpsManager.checkPackage(
962                                    Binder.getCallingUid(),
963                                    phoneAccountHandle.getComponentName().getPackageName());
964                            // Make sure it doesn't cross the UserHandle boundary
965                            enforceUserHandleMatchesCaller(phoneAccountHandle);
966                        }
967
968                        long token = Binder.clearCallingIdentity();
969                        try {
970                            Intent intent = new Intent(TelecomManager.ACTION_INCOMING_CALL);
971                            intent.putExtra(TelecomManager.EXTRA_PHONE_ACCOUNT_HANDLE,
972                                    phoneAccountHandle);
973                            intent.putExtra(CallIntentProcessor.KEY_IS_INCOMING_CALL, true);
974                            if (extras != null) {
975                                intent.putExtra(TelecomManager.EXTRA_INCOMING_CALL_EXTRAS, extras);
976                            }
977                            mCallIntentProcessorAdapter.processIncomingCallIntent(
978                                    mCallsManager, intent);
979                        } finally {
980                            Binder.restoreCallingIdentity(token);
981                        }
982                    } else {
983                        Log.w(this, "Null phoneAccountHandle. Ignoring request to add new" +
984                                " incoming call");
985                    }
986                }
987            } finally {
988                Log.endSession();
989            }
990        }
991
992        /**
993         * @see android.telecom.TelecomManager#addNewUnknownCall
994         */
995        @Override
996        public void addNewUnknownCall(PhoneAccountHandle phoneAccountHandle, Bundle extras) {
997            try {
998                Log.startSession("TSI.aNUC");
999                synchronized (mLock) {
1000                    if (phoneAccountHandle != null &&
1001                            phoneAccountHandle.getComponentName() != null) {
1002                        mAppOpsManager.checkPackage(
1003                                Binder.getCallingUid(),
1004                                phoneAccountHandle.getComponentName().getPackageName());
1005
1006                        // Make sure it doesn't cross the UserHandle boundary
1007                        enforceUserHandleMatchesCaller(phoneAccountHandle);
1008                        long token = Binder.clearCallingIdentity();
1009
1010                        try {
1011                            Intent intent = new Intent(TelecomManager.ACTION_NEW_UNKNOWN_CALL);
1012                            intent.putExtras(extras);
1013                            intent.putExtra(CallIntentProcessor.KEY_IS_UNKNOWN_CALL, true);
1014                            intent.putExtra(TelecomManager.EXTRA_PHONE_ACCOUNT_HANDLE,
1015                                    phoneAccountHandle);
1016                            mCallIntentProcessorAdapter.processUnknownCallIntent(mCallsManager, intent);
1017                        } finally {
1018                            Binder.restoreCallingIdentity(token);
1019                        }
1020                    } else {
1021                        Log.i(this,
1022                                "Null phoneAccountHandle or not initiated by Telephony. " +
1023                                        "Ignoring request to add new unknown call.");
1024                    }
1025                }
1026            } finally {
1027                Log.endSession();
1028            }
1029        }
1030
1031        /**
1032         * @see android.telecom.TelecomManager#placeCall
1033         */
1034        @Override
1035        public void placeCall(Uri handle, Bundle extras, String callingPackage) {
1036            try {
1037                Log.startSession("TSI.pC");
1038                enforceCallingPackage(callingPackage);
1039                if (!canCallPhone(callingPackage, "placeCall")) {
1040                    throw new SecurityException("Package " + callingPackage
1041                            + " is not allowed to place phone calls");
1042                }
1043
1044                // Note: we can still get here for the default/system dialer, even if the Phone
1045                // permission is turned off. This is because the default/system dialer is always
1046                // allowed to attempt to place a call (regardless of permission state), in case
1047                // it turns out to be an emergency call. If the permission is denied and the
1048                // call is being made to a non-emergency number, the call will be denied later on
1049                // by {@link UserCallIntentProcessor}.
1050
1051                final boolean hasCallAppOp = mAppOpsManager.noteOp(AppOpsManager.OP_CALL_PHONE,
1052                        Binder.getCallingUid(), callingPackage) == AppOpsManager.MODE_ALLOWED;
1053
1054                final boolean hasCallPermission = mContext.checkCallingPermission(CALL_PHONE) ==
1055                        PackageManager.PERMISSION_GRANTED;
1056
1057                synchronized (mLock) {
1058                    final UserHandle userHandle = Binder.getCallingUserHandle();
1059                    long token = Binder.clearCallingIdentity();
1060                    try {
1061                        final Intent intent = new Intent(Intent.ACTION_CALL, handle);
1062                        intent.putExtras(extras);
1063                        mUserCallIntentProcessorFactory.create(mContext, userHandle)
1064                                .processIntent(
1065                                        intent, callingPackage, hasCallAppOp && hasCallPermission);
1066                    } finally {
1067                        Binder.restoreCallingIdentity(token);
1068                    }
1069                }
1070            } finally {
1071                Log.endSession();
1072            }
1073        }
1074
1075        /**
1076         * @see android.telecom.TelecomManager#enablePhoneAccount
1077         */
1078        @Override
1079        public boolean enablePhoneAccount(PhoneAccountHandle accountHandle, boolean isEnabled) {
1080            try {
1081                Log.startSession("TSI.ePA");
1082                enforceModifyPermission();
1083                synchronized (mLock) {
1084                    long token = Binder.clearCallingIdentity();
1085                    try {
1086                        // enable/disable phone account
1087                        return mPhoneAccountRegistrar.enablePhoneAccount(accountHandle, isEnabled);
1088                    } finally {
1089                        Binder.restoreCallingIdentity(token);
1090                    }
1091                }
1092            } finally {
1093                Log.endSession();
1094            }
1095        }
1096
1097        @Override
1098        public boolean setDefaultDialer(String packageName) {
1099            try {
1100                Log.startSession("TSI.sDD");
1101                enforcePermission(MODIFY_PHONE_STATE);
1102                enforcePermission(WRITE_SECURE_SETTINGS);
1103                synchronized (mLock) {
1104                    long token = Binder.clearCallingIdentity();
1105                    try {
1106                        final boolean result =
1107                                mDefaultDialerManagerAdapter
1108                                        .setDefaultDialerApplication(mContext, packageName);
1109                        if (result) {
1110                            final Intent intent =
1111                                    new Intent(TelecomManager.ACTION_DEFAULT_DIALER_CHANGED);
1112                            intent.putExtra(TelecomManager.EXTRA_CHANGE_DEFAULT_DIALER_PACKAGE_NAME,
1113                                    packageName);
1114                            mContext.sendBroadcastAsUser(intent,
1115                                    new UserHandle(ActivityManager.getCurrentUser()));
1116                        }
1117                        return result;
1118                    } finally {
1119                        Binder.restoreCallingIdentity(token);
1120                    }
1121                }
1122            } finally {
1123                Log.endSession();
1124            }
1125        }
1126
1127        @Override
1128        public List<ParcelableCallAnalytics> dumpCallAnalytics() {
1129            try {
1130                Log.startSession("TSI.dCA");
1131                enforcePermission(DUMP);
1132                return Arrays.asList(Analytics.dumpToParcelableAnalytics());
1133            } finally {
1134                Log.endSession();
1135            }
1136        }
1137
1138        /**
1139         * Dumps the current state of the TelecomService.  Used when generating problem reports.
1140         *
1141         * @param fd The file descriptor.
1142         * @param writer The print writer to dump the state to.
1143         * @param args Optional dump arguments.
1144         */
1145        @Override
1146        protected void dump(FileDescriptor fd, final PrintWriter writer, String[] args) {
1147            if (mContext.checkCallingOrSelfPermission(
1148                    android.Manifest.permission.DUMP)
1149                    != PackageManager.PERMISSION_GRANTED) {
1150                writer.println("Permission Denial: can't dump TelecomService " +
1151                        "from from pid=" + Binder.getCallingPid() + ", uid=" +
1152                        Binder.getCallingUid());
1153                return;
1154            }
1155
1156            final IndentingPrintWriter pw = new IndentingPrintWriter(writer, "  ");
1157            if (mCallsManager != null) {
1158                pw.println("CallsManager: ");
1159                pw.increaseIndent();
1160                mCallsManager.dump(pw);
1161                pw.decreaseIndent();
1162
1163                pw.println("PhoneAccountRegistrar: ");
1164                pw.increaseIndent();
1165                mPhoneAccountRegistrar.dump(pw);
1166                pw.decreaseIndent();
1167
1168                pw.println("Analytics:");
1169                pw.increaseIndent();
1170                Analytics.dump(pw);
1171                pw.decreaseIndent();
1172            }
1173
1174            Log.dumpCallEvents(pw);
1175        }
1176    };
1177
1178    private Context mContext;
1179    private AppOpsManager mAppOpsManager;
1180    private UserManager mUserManager;
1181    private PackageManager mPackageManager;
1182    private CallsManager mCallsManager;
1183    private final PhoneAccountRegistrar mPhoneAccountRegistrar;
1184    private final CallIntentProcessor.Adapter mCallIntentProcessorAdapter;
1185    private final UserCallIntentProcessorFactory mUserCallIntentProcessorFactory;
1186    private final DefaultDialerManagerAdapter mDefaultDialerManagerAdapter;
1187    private final SubscriptionManagerAdapter mSubscriptionManagerAdapter;
1188    private final TelecomSystem.SyncRoot mLock;
1189
1190    public TelecomServiceImpl(
1191            Context context,
1192            CallsManager callsManager,
1193            PhoneAccountRegistrar phoneAccountRegistrar,
1194            CallIntentProcessor.Adapter callIntentProcessorAdapter,
1195            UserCallIntentProcessorFactory userCallIntentProcessorFactory,
1196            DefaultDialerManagerAdapter defaultDialerManagerAdapter,
1197            SubscriptionManagerAdapter subscriptionManagerAdapter,
1198            TelecomSystem.SyncRoot lock) {
1199        mContext = context;
1200        mAppOpsManager = (AppOpsManager) mContext.getSystemService(Context.APP_OPS_SERVICE);
1201
1202        mUserManager = (UserManager) mContext.getSystemService(Context.USER_SERVICE);
1203        mPackageManager = mContext.getPackageManager();
1204
1205        mCallsManager = callsManager;
1206        mLock = lock;
1207        mPhoneAccountRegistrar = phoneAccountRegistrar;
1208        mUserCallIntentProcessorFactory = userCallIntentProcessorFactory;
1209        mDefaultDialerManagerAdapter = defaultDialerManagerAdapter;
1210        mCallIntentProcessorAdapter = callIntentProcessorAdapter;
1211        mSubscriptionManagerAdapter = subscriptionManagerAdapter;
1212    }
1213
1214    public ITelecomService.Stub getBinder() {
1215        return mBinderImpl;
1216    }
1217
1218    //
1219    // Supporting methods for the ITelecomService interface implementation.
1220    //
1221
1222    private boolean isPhoneAccountHandleVisibleToCallingUser(
1223            PhoneAccountHandle phoneAccountUserHandle, UserHandle callingUser) {
1224        return mPhoneAccountRegistrar.getPhoneAccount(phoneAccountUserHandle, callingUser) != null;
1225    }
1226
1227    private boolean isCallerSystemApp() {
1228        int uid = Binder.getCallingUid();
1229        String[] packages = mPackageManager.getPackagesForUid(uid);
1230        for (String packageName : packages) {
1231            if (isPackageSystemApp(packageName)) {
1232                return true;
1233            }
1234        }
1235        return false;
1236    }
1237
1238    private boolean isPackageSystemApp(String packageName) {
1239        try {
1240            ApplicationInfo applicationInfo = mPackageManager.getApplicationInfo(packageName,
1241                    PackageManager.GET_META_DATA);
1242            if ((applicationInfo.flags & ApplicationInfo.FLAG_SYSTEM) != 0) {
1243                return true;
1244            }
1245        } catch (PackageManager.NameNotFoundException e) {
1246        }
1247        return false;
1248    }
1249
1250    private void acceptRingingCallInternal(int videoState) {
1251        Call call = mCallsManager.getFirstCallWithState(CallState.RINGING);
1252        if (call != null) {
1253            if (videoState == DEFAULT_VIDEO_STATE || !isValidAcceptVideoState(videoState)) {
1254                videoState = call.getVideoState();
1255            }
1256            call.answer(videoState);
1257        }
1258    }
1259
1260    private boolean endCallInternal() {
1261        // Always operate on the foreground call if one exists, otherwise get the first call in
1262        // priority order by call-state.
1263        Call call = mCallsManager.getForegroundCall();
1264        if (call == null) {
1265            call = mCallsManager.getFirstCallWithState(
1266                    CallState.ACTIVE,
1267                    CallState.DIALING,
1268                    CallState.RINGING,
1269                    CallState.ON_HOLD);
1270        }
1271
1272        if (call != null) {
1273            if (call.getState() == CallState.RINGING) {
1274                call.reject(false /* rejectWithMessage */, null);
1275            } else {
1276                call.disconnect();
1277            }
1278            return true;
1279        }
1280
1281        return false;
1282    }
1283
1284    private void enforcePhoneAccountModificationForPackage(String packageName) {
1285        // TODO: Use a new telecomm permission for this instead of reusing modify.
1286
1287        int result = mContext.checkCallingOrSelfPermission(MODIFY_PHONE_STATE);
1288
1289        // Callers with MODIFY_PHONE_STATE can use the PhoneAccount mechanism to implement
1290        // built-in behavior even when PhoneAccounts are not exposed as a third-part API. They
1291        // may also modify PhoneAccounts on behalf of any 'packageName'.
1292
1293        if (result != PackageManager.PERMISSION_GRANTED) {
1294            // Other callers are only allowed to modify PhoneAccounts if the relevant system
1295            // feature is enabled ...
1296            enforceConnectionServiceFeature();
1297            // ... and the PhoneAccounts they refer to are for their own package.
1298            enforceCallingPackage(packageName);
1299        }
1300    }
1301
1302    private void enforcePermissionOrPrivilegedDialer(String permission, String packageName) {
1303        if (!isPrivilegedDialerCalling(packageName)) {
1304            try {
1305                enforcePermission(permission);
1306            } catch (SecurityException e) {
1307                Log.e(this, e, "Caller must be the default or system dialer, or have the permission"
1308                        + " %s to perform this operation.", permission);
1309                throw e;
1310            }
1311        }
1312    }
1313
1314    private void enforceCallingPackage(String packageName) {
1315        mAppOpsManager.checkPackage(Binder.getCallingUid(), packageName);
1316    }
1317
1318    private void enforceConnectionServiceFeature() {
1319        enforceFeature(PackageManager.FEATURE_CONNECTION_SERVICE);
1320    }
1321
1322    private void enforceRegisterSimSubscriptionPermission() {
1323        enforcePermission(REGISTER_SIM_SUBSCRIPTION);
1324    }
1325
1326    private void enforceModifyPermission() {
1327        enforcePermission(MODIFY_PHONE_STATE);
1328    }
1329
1330    private void enforcePermission(String permission) {
1331        mContext.enforceCallingOrSelfPermission(permission, null);
1332    }
1333
1334    private void enforceRegisterMultiUser() {
1335        if (!isCallerSystemApp()) {
1336            throw new SecurityException("CAPABILITY_MULTI_USER is only available to system apps.");
1337        }
1338    }
1339
1340    private void enforceUserHandleMatchesCaller(PhoneAccountHandle accountHandle) {
1341        if (!Binder.getCallingUserHandle().equals(accountHandle.getUserHandle())) {
1342            throw new SecurityException("Calling UserHandle does not match PhoneAccountHandle's");
1343        }
1344    }
1345
1346    private void enforceCrossUserPermission(int callingUid) {
1347        if (callingUid != Process.SYSTEM_UID && callingUid != 0) {
1348            mContext.enforceCallingOrSelfPermission(
1349                    android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, "Must be system or have"
1350                            + " INTERACT_ACROSS_USERS_FULL permission");
1351        }
1352    }
1353
1354    private void enforceFeature(String feature) {
1355        PackageManager pm = mContext.getPackageManager();
1356        if (!pm.hasSystemFeature(feature)) {
1357            throw new UnsupportedOperationException(
1358                    "System does not support feature " + feature);
1359        }
1360    }
1361
1362    private boolean canReadPhoneState(String callingPackage, String message) {
1363        // The system/default dialer can always read phone state - so that emergency calls will
1364        // still work.
1365        if (isPrivilegedDialerCalling(callingPackage)) {
1366            return true;
1367        }
1368
1369        try {
1370            mContext.enforceCallingOrSelfPermission(READ_PRIVILEGED_PHONE_STATE, message);
1371            // SKIP checking run-time OP_READ_PHONE_STATE since caller or self has PRIVILEGED
1372            // permission
1373            return true;
1374        } catch (SecurityException e) {
1375            // Accessing phone state is gated by a special permission.
1376            mContext.enforceCallingOrSelfPermission(READ_PHONE_STATE, message);
1377
1378            // Some apps that have the permission can be restricted via app ops.
1379            return mAppOpsManager.noteOp(AppOpsManager.OP_READ_PHONE_STATE,
1380                    Binder.getCallingUid(), callingPackage) == AppOpsManager.MODE_ALLOWED;
1381        }
1382    }
1383
1384    private boolean canCallPhone(String callingPackage, String message) {
1385        // The system/default dialer can always read phone state - so that emergency calls will
1386        // still work.
1387        if (isPrivilegedDialerCalling(callingPackage)) {
1388            return true;
1389        }
1390
1391        // Accessing phone state is gated by a special permission.
1392        mContext.enforceCallingOrSelfPermission(CALL_PHONE, message);
1393
1394        // Some apps that have the permission can be restricted via app ops.
1395        return mAppOpsManager.noteOp(AppOpsManager.OP_CALL_PHONE,
1396                Binder.getCallingUid(), callingPackage) == AppOpsManager.MODE_ALLOWED;
1397    }
1398
1399    private boolean isCallerSimCallManager() {
1400        long token = Binder.clearCallingIdentity();
1401        PhoneAccountHandle accountHandle = null;
1402        try {
1403             accountHandle = mPhoneAccountRegistrar.getSimCallManagerOfCurrentUser();
1404        } finally {
1405            Binder.restoreCallingIdentity(token);
1406        }
1407
1408        if (accountHandle != null) {
1409            try {
1410                mAppOpsManager.checkPackage(
1411                        Binder.getCallingUid(), accountHandle.getComponentName().getPackageName());
1412                return true;
1413            } catch (SecurityException e) {
1414            }
1415        }
1416        return false;
1417    }
1418
1419    private boolean isPrivilegedDialerCalling(String callingPackage) {
1420        mAppOpsManager.checkPackage(Binder.getCallingUid(), callingPackage);
1421        return mDefaultDialerManagerAdapter.isDefaultOrSystemDialer(mContext, callingPackage);
1422    }
1423
1424    private TelephonyManager getTelephonyManager() {
1425        return (TelephonyManager) mContext.getSystemService(Context.TELEPHONY_SERVICE);
1426    }
1427
1428    /**
1429     * Determines if a video state is valid for accepting an incoming call.
1430     * For the purpose of accepting a call, states {@link VideoProfile#STATE_AUDIO_ONLY}, and
1431     * any combination of {@link VideoProfile#STATE_RX_ENABLED} and
1432     * {@link VideoProfile#STATE_TX_ENABLED} are considered valid.
1433     *
1434     * @param videoState The video state.
1435     * @return {@code true} if the video state is valid, {@code false} otherwise.
1436     */
1437    private boolean isValidAcceptVideoState(int videoState) {
1438        // Given a video state input, turn off TX and RX so that we can determine if those were the
1439        // only bits set.
1440        int remainingState = videoState & ~VideoProfile.STATE_TX_ENABLED;
1441        remainingState = remainingState & ~VideoProfile.STATE_RX_ENABLED;
1442
1443        // If only TX or RX were set (or neither), the video state is valid.
1444        return remainingState == 0;
1445    }
1446}
1447