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