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