TelecomServiceImpl.java revision c07b8e190b04e8b3e504478fa808d646d8c88a52
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.getCallAudioManager().silenceRingers();
572                        mCallsManager.getInCallController().silenceRinger();
573                    } finally {
574                        Binder.restoreCallingIdentity(token);
575                    }
576                }
577            } finally {
578                Log.endSession();
579            }
580        }
581
582        /**
583         * @see android.telecom.TelecomManager#getDefaultPhoneApp
584         * @deprecated - Use {@link android.telecom.TelecomManager#getDefaultDialerPackage()}
585         *         instead.
586         */
587        @Override
588        public ComponentName getDefaultPhoneApp() {
589            try {
590                Log.startSession("TSI.gDPA");
591                // No need to synchronize
592                Resources resources = mContext.getResources();
593                return new ComponentName(
594                        resources.getString(R.string.ui_default_package),
595                        resources.getString(R.string.dialer_default_class));
596            } finally {
597                Log.endSession();
598            }
599        }
600
601        /**
602         * @return the package name of the current user-selected default dialer. If no default
603         *         has been selected, the package name of the system dialer is returned. If
604         *         neither exists, then {@code null} is returned.
605         * @see android.telecom.TelecomManager#getDefaultDialerPackage
606         */
607        @Override
608        public String getDefaultDialerPackage() {
609            try {
610                Log.startSession("TSI.gDDP");
611                final long token = Binder.clearCallingIdentity();
612                try {
613                    return mDefaultDialerManagerAdapter.getDefaultDialerApplication(mContext);
614                } finally {
615                    Binder.restoreCallingIdentity(token);
616                }
617            } finally {
618                Log.endSession();
619            }
620        }
621
622        /**
623         * @see android.telecom.TelecomManager#getSystemDialerPackage
624         */
625        @Override
626        public String getSystemDialerPackage() {
627            try {
628                Log.startSession("TSI.gSDP");
629                return mContext.getResources().getString(R.string.ui_default_package);
630            } finally {
631                Log.endSession();
632            }
633        }
634
635        /**
636         * @see android.telecom.TelecomManager#isInCall
637         */
638        @Override
639        public boolean isInCall(String callingPackage) {
640            try {
641                Log.startSession("TSI.iIC");
642                if (!canReadPhoneState(callingPackage, "isInCall")) {
643                    return false;
644                }
645
646                synchronized (mLock) {
647                    final int callState = mCallsManager.getCallState();
648                    return callState == TelephonyManager.CALL_STATE_OFFHOOK
649                            || callState == TelephonyManager.CALL_STATE_RINGING;
650                }
651            } finally {
652                Log.endSession();
653            }
654        }
655
656        /**
657         * @see android.telecom.TelecomManager#isRinging
658         */
659        @Override
660        public boolean isRinging(String callingPackage) {
661            try {
662                Log.startSession("TSI.iR");
663                if (!canReadPhoneState(callingPackage, "isRinging")) {
664                    return false;
665                }
666
667                synchronized (mLock) {
668                    // Note: We are explicitly checking the calls telecom is tracking rather than
669                    // relying on mCallsManager#getCallState(). Since getCallState() relies on the
670                    // current state as tracked by PhoneStateBroadcaster, any failure to properly
671                    // track the current call state there could result in the wrong ringing state
672                    // being reported by this API.
673                    return mCallsManager.hasRingingCall();
674                }
675            } finally {
676                Log.endSession();
677            }
678        }
679
680        /**
681         * @see TelecomManager#getCallState
682         */
683        @Override
684        public int getCallState() {
685            try {
686                Log.startSession("TSI.getCallState");
687                synchronized (mLock) {
688                    return mCallsManager.getCallState();
689                }
690            } finally {
691                Log.endSession();
692            }
693        }
694
695        /**
696         * @see android.telecom.TelecomManager#endCall
697         */
698        @Override
699        public boolean endCall() {
700            try {
701                Log.startSession("TSI.eC");
702                synchronized (mLock) {
703                    enforceModifyPermission();
704
705                    long token = Binder.clearCallingIdentity();
706                    try {
707                        return endCallInternal();
708                    } finally {
709                        Binder.restoreCallingIdentity(token);
710                    }
711                }
712            } finally {
713                Log.endSession();
714            }
715        }
716
717        /**
718         * @see android.telecom.TelecomManager#acceptRingingCall
719         */
720        @Override
721        public void acceptRingingCall() {
722            try {
723                Log.startSession("TSI.aRC");
724                synchronized (mLock) {
725                    enforceModifyPermission();
726
727                    long token = Binder.clearCallingIdentity();
728                    try {
729                        acceptRingingCallInternal(DEFAULT_VIDEO_STATE);
730                    } finally {
731                        Binder.restoreCallingIdentity(token);
732                    }
733                }
734            } finally {
735                Log.endSession();
736            }
737        }
738
739        /**
740         * @see android.telecom.TelecomManager#acceptRingingCall(int)
741         *
742         */
743        @Override
744        public void acceptRingingCallWithVideoState(int videoState) {
745            try {
746                Log.startSession("TSI.aRCWVS");
747                synchronized (mLock) {
748                    enforceModifyPermission();
749
750                    long token = Binder.clearCallingIdentity();
751                    try {
752                        acceptRingingCallInternal(videoState);
753                    } finally {
754                        Binder.restoreCallingIdentity(token);
755                    }
756                }
757            } finally {
758                Log.endSession();
759            }
760        }
761
762        /**
763         * @see android.telecom.TelecomManager#showInCallScreen
764         */
765        @Override
766        public void showInCallScreen(boolean showDialpad, String callingPackage) {
767            try {
768                Log.startSession("TSI.sICS");
769                if (!canReadPhoneState(callingPackage, "showInCallScreen")) {
770                    return;
771                }
772
773                synchronized (mLock) {
774
775                    long token = Binder.clearCallingIdentity();
776                    try {
777                        mCallsManager.getInCallController().bringToForeground(showDialpad);
778                    } finally {
779                        Binder.restoreCallingIdentity(token);
780                    }
781                }
782            } finally {
783                Log.endSession();
784            }
785        }
786
787        /**
788         * @see android.telecom.TelecomManager#cancelMissedCallsNotification
789         */
790        @Override
791        public void cancelMissedCallsNotification(String callingPackage) {
792            try {
793                Log.startSession("TSI.cMCN");
794                synchronized (mLock) {
795                    enforcePermissionOrPrivilegedDialer(MODIFY_PHONE_STATE, callingPackage);
796                    UserHandle userHandle = Binder.getCallingUserHandle();
797                    long token = Binder.clearCallingIdentity();
798                    try {
799                        mCallsManager.getMissedCallNotifier().clearMissedCalls(userHandle);
800                    } finally {
801                        Binder.restoreCallingIdentity(token);
802                    }
803                }
804            } finally {
805                Log.endSession();
806            }
807        }
808        /**
809         * @see android.telecom.TelecomManager#handleMmi
810         */
811        @Override
812        public boolean handlePinMmi(String dialString, String callingPackage) {
813            try {
814                Log.startSession("TSI.hPM");
815                synchronized (mLock) {
816                    enforcePermissionOrPrivilegedDialer(MODIFY_PHONE_STATE, callingPackage);
817
818                    // Switch identity so that TelephonyManager checks Telecom's permissions
819                    // instead.
820                    long token = Binder.clearCallingIdentity();
821                    boolean retval = false;
822                    try {
823                        retval = getTelephonyManager().handlePinMmi(dialString);
824                    } finally {
825                        Binder.restoreCallingIdentity(token);
826                    }
827
828                    return retval;
829                }
830            }finally {
831                Log.endSession();
832            }
833        }
834
835        /**
836         * @see android.telecom.TelecomManager#handleMmi
837         */
838        @Override
839        public boolean handlePinMmiForPhoneAccount(PhoneAccountHandle accountHandle,
840                String dialString, String callingPackage) {
841            try {
842                Log.startSession("TSI.hPMFPA");
843                synchronized (mLock) {
844                    enforcePermissionOrPrivilegedDialer(MODIFY_PHONE_STATE, callingPackage);
845
846                    UserHandle callingUserHandle = Binder.getCallingUserHandle();
847                    if (!isPhoneAccountHandleVisibleToCallingUser(accountHandle,
848                            callingUserHandle)) {
849                        Log.d(this, "%s is not visible for the calling user [hMMI]", accountHandle);
850                        return false;
851                    }
852
853                    // Switch identity so that TelephonyManager checks Telecom's permissions
854                    // instead.
855                    long token = Binder.clearCallingIdentity();
856                    boolean retval = false;
857                    try {
858                        int subId = mPhoneAccountRegistrar.getSubscriptionIdForPhoneAccount(
859                                accountHandle);
860                        retval = getTelephonyManager().handlePinMmiForSubscriber(subId, dialString);
861                    } finally {
862                        Binder.restoreCallingIdentity(token);
863                    }
864                    return retval;
865                }
866            }finally {
867                Log.endSession();
868            }
869        }
870
871        /**
872         * @see android.telecom.TelecomManager#getAdnUriForPhoneAccount
873         */
874        @Override
875        public Uri getAdnUriForPhoneAccount(PhoneAccountHandle accountHandle,
876                String callingPackage) {
877            try {
878                Log.startSession("TSI.aAUFPA");
879                synchronized (mLock) {
880                    enforcePermissionOrPrivilegedDialer(MODIFY_PHONE_STATE, callingPackage);
881                    if (!isPhoneAccountHandleVisibleToCallingUser(accountHandle,
882                            Binder.getCallingUserHandle())) {
883                        Log.d(this, "%s is not visible for the calling user [gA4PA]",
884                                accountHandle);
885                        return null;
886                    }
887                    // Switch identity so that TelephonyManager checks Telecom's permissions
888                    // instead.
889                    long token = Binder.clearCallingIdentity();
890                    String retval = "content://icc/adn/";
891                    try {
892                        long subId = mPhoneAccountRegistrar
893                                .getSubscriptionIdForPhoneAccount(accountHandle);
894                        retval = retval + "subId/" + subId;
895                    } finally {
896                        Binder.restoreCallingIdentity(token);
897                    }
898
899                    return Uri.parse(retval);
900                }
901            } finally {
902                Log.endSession();
903            }
904        }
905
906        /**
907         * @see android.telecom.TelecomManager#isTtySupported
908         */
909        @Override
910        public boolean isTtySupported(String callingPackage) {
911            try {
912                Log.startSession("TSI.iTS");
913                if (!canReadPhoneState(callingPackage, "hasVoiceMailNumber")) {
914                    return false;
915                }
916
917                synchronized (mLock) {
918                    return mCallsManager.isTtySupported();
919                }
920            } finally {
921                Log.endSession();
922            }
923        }
924
925        /**
926         * @see android.telecom.TelecomManager#getCurrentTtyMode
927         */
928        @Override
929        public int getCurrentTtyMode(String callingPackage) {
930            try {
931                Log.startSession("TSI.gCTM");
932                if (!canReadPhoneState(callingPackage, "getCurrentTtyMode")) {
933                    return TelecomManager.TTY_MODE_OFF;
934                }
935
936                synchronized (mLock) {
937                    return mCallsManager.getCurrentTtyMode();
938                }
939            } finally {
940                Log.endSession();
941            }
942        }
943
944        /**
945         * @see android.telecom.TelecomManager#addNewIncomingCall
946         */
947        @Override
948        public void addNewIncomingCall(PhoneAccountHandle phoneAccountHandle, Bundle extras) {
949            try {
950                Log.startSession("TSI.aNIC");
951                synchronized (mLock) {
952                    Log.i(this, "Adding new incoming call with phoneAccountHandle %s",
953                            phoneAccountHandle);
954                    if (phoneAccountHandle != null &&
955                            phoneAccountHandle.getComponentName() != null) {
956                        // TODO(sail): Add unit tests for adding incoming calls from a SIM call
957                        // manager.
958                        if (isCallerSimCallManager() && TelephonyUtil.isPstnComponentName(
959                                phoneAccountHandle.getComponentName())) {
960                            Log.v(this, "Allowing call manager to add incoming call with PSTN" +
961                                    " handle");
962                        } else {
963                            mAppOpsManager.checkPackage(
964                                    Binder.getCallingUid(),
965                                    phoneAccountHandle.getComponentName().getPackageName());
966                            // Make sure it doesn't cross the UserHandle boundary
967                            enforceUserHandleMatchesCaller(phoneAccountHandle);
968                        }
969
970                        long token = Binder.clearCallingIdentity();
971                        try {
972                            Intent intent = new Intent(TelecomManager.ACTION_INCOMING_CALL);
973                            intent.putExtra(TelecomManager.EXTRA_PHONE_ACCOUNT_HANDLE,
974                                    phoneAccountHandle);
975                            intent.putExtra(CallIntentProcessor.KEY_IS_INCOMING_CALL, true);
976                            if (extras != null) {
977                                intent.putExtra(TelecomManager.EXTRA_INCOMING_CALL_EXTRAS, extras);
978                            }
979                            mCallIntentProcessorAdapter.processIncomingCallIntent(
980                                    mCallsManager, intent);
981                        } finally {
982                            Binder.restoreCallingIdentity(token);
983                        }
984                    } else {
985                        Log.w(this, "Null phoneAccountHandle. Ignoring request to add new" +
986                                " incoming call");
987                    }
988                }
989            } finally {
990                Log.endSession();
991            }
992        }
993
994        /**
995         * @see android.telecom.TelecomManager#addNewUnknownCall
996         */
997        @Override
998        public void addNewUnknownCall(PhoneAccountHandle phoneAccountHandle, Bundle extras) {
999            try {
1000                Log.startSession("TSI.aNUC");
1001                synchronized (mLock) {
1002                    if (phoneAccountHandle != null &&
1003                            phoneAccountHandle.getComponentName() != null) {
1004                        mAppOpsManager.checkPackage(
1005                                Binder.getCallingUid(),
1006                                phoneAccountHandle.getComponentName().getPackageName());
1007
1008                        // Make sure it doesn't cross the UserHandle boundary
1009                        enforceUserHandleMatchesCaller(phoneAccountHandle);
1010                        long token = Binder.clearCallingIdentity();
1011
1012                        try {
1013                            Intent intent = new Intent(TelecomManager.ACTION_NEW_UNKNOWN_CALL);
1014                            intent.putExtras(extras);
1015                            intent.putExtra(CallIntentProcessor.KEY_IS_UNKNOWN_CALL, true);
1016                            intent.putExtra(TelecomManager.EXTRA_PHONE_ACCOUNT_HANDLE,
1017                                    phoneAccountHandle);
1018                            mCallIntentProcessorAdapter.processUnknownCallIntent(mCallsManager, intent);
1019                        } finally {
1020                            Binder.restoreCallingIdentity(token);
1021                        }
1022                    } else {
1023                        Log.i(this,
1024                                "Null phoneAccountHandle or not initiated by Telephony. " +
1025                                        "Ignoring request to add new unknown call.");
1026                    }
1027                }
1028            } finally {
1029                Log.endSession();
1030            }
1031        }
1032
1033        /**
1034         * @see android.telecom.TelecomManager#placeCall
1035         */
1036        @Override
1037        public void placeCall(Uri handle, Bundle extras, String callingPackage) {
1038            try {
1039                Log.startSession("TSI.pC");
1040                enforceCallingPackage(callingPackage);
1041                if (!canCallPhone(callingPackage, "placeCall")) {
1042                    throw new SecurityException("Package " + callingPackage
1043                            + " is not allowed to place phone calls");
1044                }
1045
1046                // Note: we can still get here for the default/system dialer, even if the Phone
1047                // permission is turned off. This is because the default/system dialer is always
1048                // allowed to attempt to place a call (regardless of permission state), in case
1049                // it turns out to be an emergency call. If the permission is denied and the
1050                // call is being made to a non-emergency number, the call will be denied later on
1051                // by {@link UserCallIntentProcessor}.
1052
1053                final boolean hasCallAppOp = mAppOpsManager.noteOp(AppOpsManager.OP_CALL_PHONE,
1054                        Binder.getCallingUid(), callingPackage) == AppOpsManager.MODE_ALLOWED;
1055
1056                final boolean hasCallPermission = mContext.checkCallingPermission(CALL_PHONE) ==
1057                        PackageManager.PERMISSION_GRANTED;
1058
1059                synchronized (mLock) {
1060                    final UserHandle userHandle = Binder.getCallingUserHandle();
1061                    long token = Binder.clearCallingIdentity();
1062                    try {
1063                        final Intent intent = new Intent(Intent.ACTION_CALL, handle);
1064                        intent.putExtras(extras);
1065                        mUserCallIntentProcessorFactory.create(mContext, userHandle)
1066                                .processIntent(
1067                                        intent, callingPackage, hasCallAppOp && hasCallPermission);
1068                    } finally {
1069                        Binder.restoreCallingIdentity(token);
1070                    }
1071                }
1072            } finally {
1073                Log.endSession();
1074            }
1075        }
1076
1077        /**
1078         * @see android.telecom.TelecomManager#enablePhoneAccount
1079         */
1080        @Override
1081        public boolean enablePhoneAccount(PhoneAccountHandle accountHandle, boolean isEnabled) {
1082            try {
1083                Log.startSession("TSI.ePA");
1084                enforceModifyPermission();
1085                synchronized (mLock) {
1086                    long token = Binder.clearCallingIdentity();
1087                    try {
1088                        // enable/disable phone account
1089                        return mPhoneAccountRegistrar.enablePhoneAccount(accountHandle, isEnabled);
1090                    } finally {
1091                        Binder.restoreCallingIdentity(token);
1092                    }
1093                }
1094            } finally {
1095                Log.endSession();
1096            }
1097        }
1098
1099        @Override
1100        public boolean setDefaultDialer(String packageName) {
1101            try {
1102                Log.startSession("TSI.sDD");
1103                enforcePermission(MODIFY_PHONE_STATE);
1104                enforcePermission(WRITE_SECURE_SETTINGS);
1105                synchronized (mLock) {
1106                    long token = Binder.clearCallingIdentity();
1107                    try {
1108                        final boolean result =
1109                                mDefaultDialerManagerAdapter
1110                                        .setDefaultDialerApplication(mContext, packageName);
1111                        if (result) {
1112                            final Intent intent =
1113                                    new Intent(TelecomManager.ACTION_DEFAULT_DIALER_CHANGED);
1114                            intent.putExtra(TelecomManager.EXTRA_CHANGE_DEFAULT_DIALER_PACKAGE_NAME,
1115                                    packageName);
1116                            mContext.sendBroadcastAsUser(intent,
1117                                    new UserHandle(ActivityManager.getCurrentUser()));
1118                        }
1119                        return result;
1120                    } finally {
1121                        Binder.restoreCallingIdentity(token);
1122                    }
1123                }
1124            } finally {
1125                Log.endSession();
1126            }
1127        }
1128
1129        @Override
1130        public List<ParcelableCallAnalytics> dumpCallAnalytics() {
1131            try {
1132                Log.startSession("TSI.dCA");
1133                enforcePermission(DUMP);
1134                return Arrays.asList(Analytics.dumpToParcelableAnalytics());
1135            } finally {
1136                Log.endSession();
1137            }
1138        }
1139
1140        /**
1141         * Dumps the current state of the TelecomService.  Used when generating problem reports.
1142         *
1143         * @param fd The file descriptor.
1144         * @param writer The print writer to dump the state to.
1145         * @param args Optional dump arguments.
1146         */
1147        @Override
1148        protected void dump(FileDescriptor fd, final PrintWriter writer, String[] args) {
1149            if (mContext.checkCallingOrSelfPermission(
1150                    android.Manifest.permission.DUMP)
1151                    != PackageManager.PERMISSION_GRANTED) {
1152                writer.println("Permission Denial: can't dump TelecomService " +
1153                        "from from pid=" + Binder.getCallingPid() + ", uid=" +
1154                        Binder.getCallingUid());
1155                return;
1156            }
1157
1158            final IndentingPrintWriter pw = new IndentingPrintWriter(writer, "  ");
1159            if (mCallsManager != null) {
1160                pw.println("CallsManager: ");
1161                pw.increaseIndent();
1162                mCallsManager.dump(pw);
1163                pw.decreaseIndent();
1164
1165                pw.println("PhoneAccountRegistrar: ");
1166                pw.increaseIndent();
1167                mPhoneAccountRegistrar.dump(pw);
1168                pw.decreaseIndent();
1169
1170                pw.println("Analytics:");
1171                pw.increaseIndent();
1172                Analytics.dump(pw);
1173                pw.decreaseIndent();
1174            }
1175
1176            Log.dumpCallEvents(pw);
1177        }
1178    };
1179
1180    private Context mContext;
1181    private AppOpsManager mAppOpsManager;
1182    private UserManager mUserManager;
1183    private PackageManager mPackageManager;
1184    private CallsManager mCallsManager;
1185    private final PhoneAccountRegistrar mPhoneAccountRegistrar;
1186    private final CallIntentProcessor.Adapter mCallIntentProcessorAdapter;
1187    private final UserCallIntentProcessorFactory mUserCallIntentProcessorFactory;
1188    private final DefaultDialerManagerAdapter mDefaultDialerManagerAdapter;
1189    private final SubscriptionManagerAdapter mSubscriptionManagerAdapter;
1190    private final TelecomSystem.SyncRoot mLock;
1191
1192    public TelecomServiceImpl(
1193            Context context,
1194            CallsManager callsManager,
1195            PhoneAccountRegistrar phoneAccountRegistrar,
1196            CallIntentProcessor.Adapter callIntentProcessorAdapter,
1197            UserCallIntentProcessorFactory userCallIntentProcessorFactory,
1198            DefaultDialerManagerAdapter defaultDialerManagerAdapter,
1199            SubscriptionManagerAdapter subscriptionManagerAdapter,
1200            TelecomSystem.SyncRoot lock) {
1201        mContext = context;
1202        mAppOpsManager = (AppOpsManager) mContext.getSystemService(Context.APP_OPS_SERVICE);
1203
1204        mUserManager = (UserManager) mContext.getSystemService(Context.USER_SERVICE);
1205        mPackageManager = mContext.getPackageManager();
1206
1207        mCallsManager = callsManager;
1208        mLock = lock;
1209        mPhoneAccountRegistrar = phoneAccountRegistrar;
1210        mUserCallIntentProcessorFactory = userCallIntentProcessorFactory;
1211        mDefaultDialerManagerAdapter = defaultDialerManagerAdapter;
1212        mCallIntentProcessorAdapter = callIntentProcessorAdapter;
1213        mSubscriptionManagerAdapter = subscriptionManagerAdapter;
1214    }
1215
1216    public ITelecomService.Stub getBinder() {
1217        return mBinderImpl;
1218    }
1219
1220    //
1221    // Supporting methods for the ITelecomService interface implementation.
1222    //
1223
1224    private boolean isPhoneAccountHandleVisibleToCallingUser(
1225            PhoneAccountHandle phoneAccountUserHandle, UserHandle callingUser) {
1226        return mPhoneAccountRegistrar.getPhoneAccount(phoneAccountUserHandle, callingUser) != null;
1227    }
1228
1229    private boolean isCallerSystemApp() {
1230        int uid = Binder.getCallingUid();
1231        String[] packages = mPackageManager.getPackagesForUid(uid);
1232        for (String packageName : packages) {
1233            if (isPackageSystemApp(packageName)) {
1234                return true;
1235            }
1236        }
1237        return false;
1238    }
1239
1240    private boolean isPackageSystemApp(String packageName) {
1241        try {
1242            ApplicationInfo applicationInfo = mPackageManager.getApplicationInfo(packageName,
1243                    PackageManager.GET_META_DATA);
1244            if ((applicationInfo.flags & ApplicationInfo.FLAG_SYSTEM) != 0) {
1245                return true;
1246            }
1247        } catch (PackageManager.NameNotFoundException e) {
1248        }
1249        return false;
1250    }
1251
1252    private void acceptRingingCallInternal(int videoState) {
1253        Call call = mCallsManager.getFirstCallWithState(CallState.RINGING);
1254        if (call != null) {
1255            if (videoState == DEFAULT_VIDEO_STATE || !isValidAcceptVideoState(videoState)) {
1256                videoState = call.getVideoState();
1257            }
1258            call.answer(videoState);
1259        }
1260    }
1261
1262    private boolean endCallInternal() {
1263        // Always operate on the foreground call if one exists, otherwise get the first call in
1264        // priority order by call-state.
1265        Call call = mCallsManager.getForegroundCall();
1266        if (call == null) {
1267            call = mCallsManager.getFirstCallWithState(
1268                    CallState.ACTIVE,
1269                    CallState.DIALING,
1270                    CallState.RINGING,
1271                    CallState.ON_HOLD);
1272        }
1273
1274        if (call != null) {
1275            if (call.getState() == CallState.RINGING) {
1276                call.reject(false /* rejectWithMessage */, null);
1277            } else {
1278                call.disconnect();
1279            }
1280            return true;
1281        }
1282
1283        return false;
1284    }
1285
1286    private void enforcePhoneAccountModificationForPackage(String packageName) {
1287        // TODO: Use a new telecomm permission for this instead of reusing modify.
1288
1289        int result = mContext.checkCallingOrSelfPermission(MODIFY_PHONE_STATE);
1290
1291        // Callers with MODIFY_PHONE_STATE can use the PhoneAccount mechanism to implement
1292        // built-in behavior even when PhoneAccounts are not exposed as a third-part API. They
1293        // may also modify PhoneAccounts on behalf of any 'packageName'.
1294
1295        if (result != PackageManager.PERMISSION_GRANTED) {
1296            // Other callers are only allowed to modify PhoneAccounts if the relevant system
1297            // feature is enabled ...
1298            enforceConnectionServiceFeature();
1299            // ... and the PhoneAccounts they refer to are for their own package.
1300            enforceCallingPackage(packageName);
1301        }
1302    }
1303
1304    private void enforcePermissionOrPrivilegedDialer(String permission, String packageName) {
1305        if (!isPrivilegedDialerCalling(packageName)) {
1306            try {
1307                enforcePermission(permission);
1308            } catch (SecurityException e) {
1309                Log.e(this, e, "Caller must be the default or system dialer, or have the permission"
1310                        + " %s to perform this operation.", permission);
1311                throw e;
1312            }
1313        }
1314    }
1315
1316    private void enforceCallingPackage(String packageName) {
1317        mAppOpsManager.checkPackage(Binder.getCallingUid(), packageName);
1318    }
1319
1320    private void enforceConnectionServiceFeature() {
1321        enforceFeature(PackageManager.FEATURE_CONNECTION_SERVICE);
1322    }
1323
1324    private void enforceRegisterSimSubscriptionPermission() {
1325        enforcePermission(REGISTER_SIM_SUBSCRIPTION);
1326    }
1327
1328    private void enforceModifyPermission() {
1329        enforcePermission(MODIFY_PHONE_STATE);
1330    }
1331
1332    private void enforcePermission(String permission) {
1333        mContext.enforceCallingOrSelfPermission(permission, null);
1334    }
1335
1336    private void enforceRegisterMultiUser() {
1337        if (!isCallerSystemApp()) {
1338            throw new SecurityException("CAPABILITY_MULTI_USER is only available to system apps.");
1339        }
1340    }
1341
1342    private void enforceUserHandleMatchesCaller(PhoneAccountHandle accountHandle) {
1343        if (!Binder.getCallingUserHandle().equals(accountHandle.getUserHandle())) {
1344            throw new SecurityException("Calling UserHandle does not match PhoneAccountHandle's");
1345        }
1346    }
1347
1348    private void enforceCrossUserPermission(int callingUid) {
1349        if (callingUid != Process.SYSTEM_UID && callingUid != 0) {
1350            mContext.enforceCallingOrSelfPermission(
1351                    android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, "Must be system or have"
1352                            + " INTERACT_ACROSS_USERS_FULL permission");
1353        }
1354    }
1355
1356    private void enforceFeature(String feature) {
1357        PackageManager pm = mContext.getPackageManager();
1358        if (!pm.hasSystemFeature(feature)) {
1359            throw new UnsupportedOperationException(
1360                    "System does not support feature " + feature);
1361        }
1362    }
1363
1364    private boolean canReadPhoneState(String callingPackage, String message) {
1365        // The system/default dialer can always read phone state - so that emergency calls will
1366        // still work.
1367        if (isPrivilegedDialerCalling(callingPackage)) {
1368            return true;
1369        }
1370
1371        try {
1372            mContext.enforceCallingOrSelfPermission(READ_PRIVILEGED_PHONE_STATE, message);
1373            // SKIP checking run-time OP_READ_PHONE_STATE since caller or self has PRIVILEGED
1374            // permission
1375            return true;
1376        } catch (SecurityException e) {
1377            // Accessing phone state is gated by a special permission.
1378            mContext.enforceCallingOrSelfPermission(READ_PHONE_STATE, message);
1379
1380            // Some apps that have the permission can be restricted via app ops.
1381            return mAppOpsManager.noteOp(AppOpsManager.OP_READ_PHONE_STATE,
1382                    Binder.getCallingUid(), callingPackage) == AppOpsManager.MODE_ALLOWED;
1383        }
1384    }
1385
1386    private boolean canCallPhone(String callingPackage, String message) {
1387        // The system/default dialer can always read phone state - so that emergency calls will
1388        // still work.
1389        if (isPrivilegedDialerCalling(callingPackage)) {
1390            return true;
1391        }
1392
1393        // Accessing phone state is gated by a special permission.
1394        mContext.enforceCallingOrSelfPermission(CALL_PHONE, message);
1395
1396        // Some apps that have the permission can be restricted via app ops.
1397        return mAppOpsManager.noteOp(AppOpsManager.OP_CALL_PHONE,
1398                Binder.getCallingUid(), callingPackage) == AppOpsManager.MODE_ALLOWED;
1399    }
1400
1401    private boolean isCallerSimCallManager() {
1402        long token = Binder.clearCallingIdentity();
1403        PhoneAccountHandle accountHandle = null;
1404        try {
1405             accountHandle = mPhoneAccountRegistrar.getSimCallManagerOfCurrentUser();
1406        } finally {
1407            Binder.restoreCallingIdentity(token);
1408        }
1409
1410        if (accountHandle != null) {
1411            try {
1412                mAppOpsManager.checkPackage(
1413                        Binder.getCallingUid(), accountHandle.getComponentName().getPackageName());
1414                return true;
1415            } catch (SecurityException e) {
1416            }
1417        }
1418        return false;
1419    }
1420
1421    private boolean isPrivilegedDialerCalling(String callingPackage) {
1422        mAppOpsManager.checkPackage(Binder.getCallingUid(), callingPackage);
1423        return mDefaultDialerManagerAdapter.isDefaultOrSystemDialer(mContext, callingPackage);
1424    }
1425
1426    private TelephonyManager getTelephonyManager() {
1427        return (TelephonyManager) mContext.getSystemService(Context.TELEPHONY_SERVICE);
1428    }
1429
1430    /**
1431     * Determines if a video state is valid for accepting an incoming call.
1432     * For the purpose of accepting a call, states {@link VideoProfile#STATE_AUDIO_ONLY}, and
1433     * any combination of {@link VideoProfile#STATE_RX_ENABLED} and
1434     * {@link VideoProfile#STATE_TX_ENABLED} are considered valid.
1435     *
1436     * @param videoState The video state.
1437     * @return {@code true} if the video state is valid, {@code false} otherwise.
1438     */
1439    private boolean isValidAcceptVideoState(int videoState) {
1440        // Given a video state input, turn off TX and RX so that we can determine if those were the
1441        // only bits set.
1442        int remainingState = videoState & ~VideoProfile.STATE_TX_ENABLED;
1443        remainingState = remainingState & ~VideoProfile.STATE_RX_ENABLED;
1444
1445        // If only TX or RX were set (or neither), the video state is valid.
1446        return remainingState == 0;
1447    }
1448}
1449