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