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