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