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