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