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