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