Home | History | Annotate | Download | only in telecom
      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 
     17 package com.android.server.telecom;
     18 
     19 import android.Manifest;
     20 import android.annotation.SdkConstant;
     21 import android.app.AppOpsManager;
     22 import android.app.Service;
     23 import android.content.ComponentName;
     24 import android.content.Context;
     25 import android.content.Intent;
     26 import android.content.pm.ApplicationInfo;
     27 import android.content.pm.PackageManager;
     28 import android.content.res.Resources;
     29 import android.net.Uri;
     30 import android.os.Binder;
     31 import android.os.Bundle;
     32 import android.os.Handler;
     33 import android.os.IBinder;
     34 import android.os.Looper;
     35 import android.os.Message;
     36 import android.os.UserHandle;
     37 import android.os.UserManager;
     38 import android.telecom.CallState;
     39 import android.telecom.PhoneAccount;
     40 import android.telecom.PhoneAccountHandle;
     41 import android.telecom.TelecomManager;
     42 import android.telephony.SubscriptionManager;
     43 import android.telephony.TelephonyManager;
     44 import android.text.TextUtils;
     45 
     46 // TODO: Needed for move to system service: import com.android.internal.R;
     47 import com.android.internal.telecom.ITelecomService;
     48 import com.android.internal.util.IndentingPrintWriter;
     49 
     50 import java.io.FileDescriptor;
     51 import java.io.PrintWriter;
     52 import java.util.ArrayList;
     53 import java.util.List;
     54 
     55 /**
     56  * Implementation of the ITelecom interface.
     57  */
     58 public class TelecomService extends Service {
     59     /**
     60      * The {@link Intent} that must be declared as handled by the service.
     61      */
     62     @SdkConstant(SdkConstant.SdkConstantType.SERVICE_ACTION)
     63     public static final String SERVICE_INTERFACE = "android.telecom.ITelecomService";
     64 
     65     /** The context. */
     66     private Context mContext;
     67 
     68     /**
     69      * A request object for use with {@link MainThreadHandler}. Requesters should wait() on the
     70      * request after sending. The main thread will notify the request when it is complete.
     71      */
     72     private static final class MainThreadRequest {
     73         /** The result of the request that is run on the main thread */
     74         public Object result;
     75         /** Object that can be used to store non-integer arguments */
     76         public Object arg;
     77     }
     78 
     79     /**
     80      * A handler that processes messages on the main thread. Since many of the method calls are not
     81      * thread safe this is needed to shuttle the requests from the inbound binder threads to the
     82      * main thread.
     83      */
     84     private final class MainThreadHandler extends Handler {
     85         @Override
     86         public void handleMessage(Message msg) {
     87             if (msg.obj instanceof MainThreadRequest) {
     88                 MainThreadRequest request = (MainThreadRequest) msg.obj;
     89                 Object result = null;
     90                 switch (msg.what) {
     91                     case MSG_SILENCE_RINGER:
     92                         mCallsManager.getRinger().silence();
     93                         break;
     94                     case MSG_SHOW_CALL_SCREEN:
     95                         mCallsManager.getInCallController().bringToForeground(msg.arg1 == 1);
     96                         break;
     97                     case MSG_END_CALL:
     98                         result = endCallInternal();
     99                         break;
    100                     case MSG_ACCEPT_RINGING_CALL:
    101                         acceptRingingCallInternal();
    102                         break;
    103                     case MSG_CANCEL_MISSED_CALLS_NOTIFICATION:
    104                         mMissedCallNotifier.clearMissedCalls();
    105                         break;
    106                     case MSG_IS_TTY_SUPPORTED:
    107                         result = mCallsManager.isTtySupported();
    108                         break;
    109                     case MSG_GET_CURRENT_TTY_MODE:
    110                         result = mCallsManager.getCurrentTtyMode();
    111                         break;
    112                     case MSG_NEW_INCOMING_CALL:
    113                         if (request.arg == null || !(request.arg instanceof Intent)) {
    114                             Log.w(this, "Invalid new incoming call request");
    115                             break;
    116                         }
    117                         CallReceiver.processIncomingCallIntent((Intent) request.arg);
    118                         break;
    119                 }
    120 
    121                 if (result != null) {
    122                     request.result = result;
    123                     synchronized(request) {
    124                         request.notifyAll();
    125                     }
    126                 }
    127             }
    128         }
    129     }
    130 
    131     private static final String TAG = TelecomService.class.getSimpleName();
    132 
    133     private static final String SERVICE_NAME = "telecom";
    134 
    135     private static final int MSG_SILENCE_RINGER = 1;
    136     private static final int MSG_SHOW_CALL_SCREEN = 2;
    137     private static final int MSG_END_CALL = 3;
    138     private static final int MSG_ACCEPT_RINGING_CALL = 4;
    139     private static final int MSG_CANCEL_MISSED_CALLS_NOTIFICATION = 5;
    140     private static final int MSG_IS_TTY_SUPPORTED = 6;
    141     private static final int MSG_GET_CURRENT_TTY_MODE = 7;
    142     private static final int MSG_NEW_INCOMING_CALL = 8;
    143 
    144     private final MainThreadHandler mMainThreadHandler = new MainThreadHandler();
    145 
    146     private CallsManager mCallsManager;
    147     private MissedCallNotifier mMissedCallNotifier;
    148     private PhoneAccountRegistrar mPhoneAccountRegistrar;
    149     private AppOpsManager mAppOpsManager;
    150     private UserManager mUserManager;
    151     private PackageManager mPackageManager;
    152     private TelecomServiceImpl mServiceImpl;
    153 
    154     @Override
    155     public void onCreate() {
    156         super.onCreate();
    157 
    158         Log.d(this, "onCreate");
    159         mContext = this;
    160         mAppOpsManager = (AppOpsManager) mContext.getSystemService(Context.APP_OPS_SERVICE);
    161         mServiceImpl = new TelecomServiceImpl();
    162 
    163         TelecomGlobals globals = TelecomGlobals.getInstance();
    164         globals.initialize(this);
    165 
    166         mMissedCallNotifier = globals.getMissedCallNotifier();
    167         mPhoneAccountRegistrar = globals.getPhoneAccountRegistrar();
    168         mCallsManager = globals.getCallsManager();
    169         mUserManager = (UserManager) mContext.getSystemService(Context.USER_SERVICE);
    170         mPackageManager = mContext.getPackageManager();
    171     }
    172 
    173     @Override
    174     public IBinder onBind(Intent intent) {
    175         Log.d(this, "onBind");
    176         return mServiceImpl;
    177     }
    178 
    179     /**
    180      * Implementation of the ITelecomService interface.
    181      * TODO: Reorganize this inner class to top of file.
    182      */
    183     class TelecomServiceImpl extends ITelecomService.Stub {
    184         @Override
    185         public PhoneAccountHandle getDefaultOutgoingPhoneAccount(String uriScheme) {
    186             enforceReadPermission();
    187             long token = Binder.clearCallingIdentity();
    188             try {
    189                 PhoneAccountHandle defaultOutgoingPhoneAccount =
    190                         mPhoneAccountRegistrar.getDefaultOutgoingPhoneAccount(uriScheme);
    191                 // Make sure that the calling user can see this phone account.
    192                 if (defaultOutgoingPhoneAccount != null
    193                         && !isVisibleToCaller(defaultOutgoingPhoneAccount)) {
    194                     Log.w(this, "No account found for the calling user");
    195                     return null;
    196                 }
    197                 return defaultOutgoingPhoneAccount;
    198             } catch (Exception e) {
    199                 Log.e(this, e, "getDefaultOutgoingPhoneAccount");
    200                 throw e;
    201             } finally {
    202                 Binder.restoreCallingIdentity(token);
    203             }
    204         }
    205 
    206         @Override
    207         public PhoneAccountHandle getUserSelectedOutgoingPhoneAccount() {
    208             try {
    209                 PhoneAccountHandle userSelectedOutgoingPhoneAccount =
    210                         mPhoneAccountRegistrar.getUserSelectedOutgoingPhoneAccount();
    211                 // Make sure that the calling user can see this phone account.
    212                 if (!isVisibleToCaller(userSelectedOutgoingPhoneAccount)) {
    213                     Log.w(this, "No account found for the calling user");
    214                     return null;
    215                 }
    216                 return userSelectedOutgoingPhoneAccount;
    217             } catch (Exception e) {
    218                 Log.e(this, e, "getUserSelectedOutgoingPhoneAccount");
    219                 throw e;
    220             }
    221         }
    222 
    223         @Override
    224         public void setUserSelectedOutgoingPhoneAccount(PhoneAccountHandle accountHandle) {
    225             enforceModifyPermission();
    226 
    227             try {
    228                 mPhoneAccountRegistrar.setUserSelectedOutgoingPhoneAccount(accountHandle);
    229             } catch (Exception e) {
    230                 Log.e(this, e, "setUserSelectedOutgoingPhoneAccount");
    231                 throw e;
    232             }
    233         }
    234 
    235         @Override
    236         public List<PhoneAccountHandle> getCallCapablePhoneAccounts() {
    237             enforceReadPermission();
    238             long token = Binder.clearCallingIdentity();
    239             try {
    240                 return filterForAccountsVisibleToCaller(
    241                         mPhoneAccountRegistrar.getCallCapablePhoneAccounts());
    242             } catch (Exception e) {
    243                 Log.e(this, e, "getCallCapablePhoneAccounts");
    244                 throw e;
    245             } finally {
    246                 Binder.restoreCallingIdentity(token);
    247             }
    248         }
    249 
    250         @Override
    251         public List<PhoneAccountHandle> getPhoneAccountsSupportingScheme(String uriScheme) {
    252             enforceReadPermission();
    253             long token = Binder.clearCallingIdentity();
    254             try {
    255                 return filterForAccountsVisibleToCaller(
    256                         mPhoneAccountRegistrar.getCallCapablePhoneAccounts(uriScheme));
    257             } catch (Exception e) {
    258                 Log.e(this, e, "getPhoneAccountsSupportingScheme %s", uriScheme);
    259                 throw e;
    260             } finally {
    261                 Binder.restoreCallingIdentity(token);
    262             }
    263         }
    264 
    265         @Override
    266         public List<PhoneAccountHandle> getPhoneAccountsForPackage(String packageName) {
    267             try {
    268                 return filterForAccountsVisibleToCaller(
    269                         mPhoneAccountRegistrar.getPhoneAccountsForPackage(packageName));
    270             } catch (Exception e) {
    271                 Log.e(this, e, "getPhoneAccountsForPackage %s", packageName);
    272                 throw e;
    273             }
    274         }
    275 
    276         @Override
    277         public PhoneAccount getPhoneAccount(PhoneAccountHandle accountHandle) {
    278             try {
    279                 if (!isVisibleToCaller(accountHandle)) {
    280                     Log.w(this, "%s is not visible for the calling user", accountHandle);
    281                     return null;
    282                 }
    283                 return mPhoneAccountRegistrar.getPhoneAccountInternal(accountHandle);
    284             } catch (Exception e) {
    285                 Log.e(this, e, "getPhoneAccount %s", accountHandle);
    286                 throw e;
    287             }
    288         }
    289 
    290         @Override
    291         public int getAllPhoneAccountsCount() {
    292             try {
    293                 // This list is pre-filtered for the calling user.
    294                 return getAllPhoneAccounts().size();
    295             } catch (Exception e) {
    296                 Log.e(this, e, "getAllPhoneAccountsCount");
    297                 throw e;
    298             }
    299         }
    300 
    301         @Override
    302         public List<PhoneAccount> getAllPhoneAccounts() {
    303             try {
    304                 List<PhoneAccount> allPhoneAccounts = mPhoneAccountRegistrar.getAllPhoneAccounts();
    305                 List<PhoneAccount> profilePhoneAccounts = new ArrayList<>(allPhoneAccounts.size());
    306                 for (PhoneAccount phoneAccount : profilePhoneAccounts) {
    307                     if (isVisibleToCaller(phoneAccount)) {
    308                         profilePhoneAccounts.add(phoneAccount);
    309                     }
    310                 }
    311                 return profilePhoneAccounts;
    312             } catch (Exception e) {
    313                 Log.e(this, e, "getAllPhoneAccounts");
    314                 throw e;
    315             }
    316         }
    317 
    318         @Override
    319         public List<PhoneAccountHandle> getAllPhoneAccountHandles() {
    320             try {
    321                 return filterForAccountsVisibleToCaller(
    322                         mPhoneAccountRegistrar.getAllPhoneAccountHandles());
    323             } catch (Exception e) {
    324                 Log.e(this, e, "getAllPhoneAccounts");
    325                 throw e;
    326             }
    327         }
    328 
    329         @Override
    330         public PhoneAccountHandle getSimCallManager() {
    331             try {
    332                 PhoneAccountHandle accountHandle = mPhoneAccountRegistrar.getSimCallManager();
    333                 if (!isVisibleToCaller(accountHandle)) {
    334                     Log.w(this, "%s is not visible for the calling user", accountHandle);
    335                     return null;
    336                 }
    337                 return accountHandle;
    338             } catch (Exception e) {
    339                 Log.e(this, e, "getSimCallManager");
    340                 throw e;
    341             }
    342         }
    343 
    344         @Override
    345         public void setSimCallManager(PhoneAccountHandle accountHandle) {
    346             enforceModifyPermission();
    347 
    348             try {
    349                 mPhoneAccountRegistrar.setSimCallManager(accountHandle);
    350             } catch (Exception e) {
    351                 Log.e(this, e, "setSimCallManager");
    352                 throw e;
    353             }
    354         }
    355 
    356         @Override
    357         public List<PhoneAccountHandle> getSimCallManagers() {
    358             enforceReadPermission();
    359             long token = Binder.clearCallingIdentity();
    360             try {
    361                 return filterForAccountsVisibleToCaller(
    362                         mPhoneAccountRegistrar.getConnectionManagerPhoneAccounts());
    363             } catch (Exception e) {
    364                 Log.e(this, e, "getSimCallManagers");
    365                 throw e;
    366             } finally {
    367                 Binder.restoreCallingIdentity(token);
    368             }
    369         }
    370 
    371         @Override
    372         public void registerPhoneAccount(PhoneAccount account) {
    373             try {
    374                 enforcePhoneAccountModificationForPackage(
    375                         account.getAccountHandle().getComponentName().getPackageName());
    376                 if (account.hasCapabilities(PhoneAccount.CAPABILITY_CALL_PROVIDER)) {
    377                     enforceRegisterCallProviderPermission();
    378                 }
    379                 if (account.hasCapabilities(PhoneAccount.CAPABILITY_SIM_SUBSCRIPTION)) {
    380                     enforceRegisterSimSubscriptionPermission();
    381                 }
    382                 if (account.hasCapabilities(PhoneAccount.CAPABILITY_CONNECTION_MANAGER)) {
    383                     enforceRegisterConnectionManagerPermission();
    384                 }
    385                 if (account.hasCapabilities(PhoneAccount.CAPABILITY_MULTI_USER)) {
    386                     enforceRegisterMultiUser();
    387                 }
    388                 enforceUserHandleMatchesCaller(account.getAccountHandle());
    389 
    390                 mPhoneAccountRegistrar.registerPhoneAccount(account);
    391             } catch (Exception e) {
    392                 Log.e(this, e, "registerPhoneAccount %s", account);
    393                 throw e;
    394             }
    395         }
    396 
    397         @Override
    398         public void unregisterPhoneAccount(PhoneAccountHandle accountHandle) {
    399             try {
    400                 enforcePhoneAccountModificationForPackage(
    401                         accountHandle.getComponentName().getPackageName());
    402                 enforceUserHandleMatchesCaller(accountHandle);
    403                 mPhoneAccountRegistrar.unregisterPhoneAccount(accountHandle);
    404             } catch (Exception e) {
    405                 Log.e(this, e, "unregisterPhoneAccount %s", accountHandle);
    406                 throw e;
    407             }
    408         }
    409 
    410         @Override
    411         public void clearAccounts(String packageName) {
    412             try {
    413                 enforcePhoneAccountModificationForPackage(packageName);
    414                 mPhoneAccountRegistrar.clearAccounts(packageName, Binder.getCallingUserHandle());
    415             } catch (Exception e) {
    416                 Log.e(this, e, "clearAccounts %s", packageName);
    417                 throw e;
    418             }
    419         }
    420 
    421         /**
    422          * @see android.telecom.TelecomManager#isVoiceMailNumber
    423          */
    424         @Override
    425         public boolean isVoiceMailNumber(PhoneAccountHandle accountHandle, String number) {
    426             enforceReadPermissionOrDefaultDialer();
    427             try {
    428                 if (!isVisibleToCaller(accountHandle)) {
    429                     Log.w(this, "%s is not visible for the calling user", accountHandle);
    430                     return false;
    431                 }
    432                 return mPhoneAccountRegistrar.isVoiceMailNumber(accountHandle, number);
    433             } catch (Exception e) {
    434                 Log.e(this, e, "getSubscriptionIdForPhoneAccount");
    435                 throw e;
    436             }
    437         }
    438 
    439         /**
    440          * @see android.telecom.TelecomManager#hasVoiceMailNumber
    441          */
    442         @Override
    443         public boolean hasVoiceMailNumber(PhoneAccountHandle accountHandle) {
    444             enforceReadPermissionOrDefaultDialer();
    445             try {
    446                 if (!isVisibleToCaller(accountHandle)) {
    447                     Log.w(this, "%s is not visible for the calling user", accountHandle);
    448                     return false;
    449                 }
    450 
    451                 int subId = mPhoneAccountRegistrar.getSubscriptionIdForPhoneAccount(accountHandle);
    452                 return !TextUtils.isEmpty(getTelephonyManager().getVoiceMailNumber(subId));
    453             } catch (Exception e) {
    454                 Log.e(this, e, "getSubscriptionIdForPhoneAccount");
    455                 throw e;
    456             }
    457         }
    458 
    459         /**
    460          * @see android.telecom.TelecomManager#getLine1Number
    461          */
    462         @Override
    463         public String getLine1Number(PhoneAccountHandle accountHandle) {
    464             enforceReadPermissionOrDefaultDialer();
    465             try {
    466                 if (!isVisibleToCaller(accountHandle)) {
    467                     Log.w(this, "%s is not visible for the calling user", accountHandle);
    468                     return null;
    469                 }
    470                 int subId = mPhoneAccountRegistrar.getSubscriptionIdForPhoneAccount(accountHandle);
    471                 return getTelephonyManager().getLine1NumberForSubscriber(subId);
    472             } catch (Exception e) {
    473                 Log.e(this, e, "getSubscriptionIdForPhoneAccount");
    474                 throw e;
    475             }
    476         }
    477 
    478         /**
    479          * @see android.telecom.TelecomManager#silenceRinger
    480          */
    481         @Override
    482         public void silenceRinger() {
    483             Log.d(this, "silenceRinger");
    484             enforceModifyPermission();
    485             sendRequestAsync(MSG_SILENCE_RINGER, 0);
    486         }
    487 
    488         /**
    489          * @see android.telecom.TelecomManager#getDefaultPhoneApp
    490          */
    491         @Override
    492         public ComponentName getDefaultPhoneApp() {
    493             Resources resources = mContext.getResources();
    494             return new ComponentName(
    495                     resources.getString(R.string.ui_default_package),
    496                     resources.getString(R.string.dialer_default_class));
    497         }
    498 
    499         /**
    500          * @see android.telecom.TelecomManager#isInCall
    501          */
    502         @Override
    503         public boolean isInCall() {
    504             enforceReadPermission();
    505             // Do not use sendRequest() with this method since it could cause a deadlock with
    506             // audio service, which we call into from the main thread: AudioManager.setMode().
    507             final int callState = mCallsManager.getCallState();
    508             return callState == TelephonyManager.CALL_STATE_OFFHOOK
    509                     || callState == TelephonyManager.CALL_STATE_RINGING;
    510         }
    511 
    512         /**
    513          * @see android.telecom.TelecomManager#isRinging
    514          */
    515         @Override
    516         public boolean isRinging() {
    517             enforceReadPermission();
    518             return mCallsManager.getCallState() == TelephonyManager.CALL_STATE_RINGING;
    519         }
    520 
    521         /**
    522          * @see TelecomManager#getCallState
    523          */
    524         @Override
    525         public int getCallState() {
    526             return mCallsManager.getCallState();
    527         }
    528 
    529         /**
    530          * @see android.telecom.TelecomManager#endCall
    531          */
    532         @Override
    533         public boolean endCall() {
    534             enforceModifyPermission();
    535             return (boolean) sendRequest(MSG_END_CALL);
    536         }
    537 
    538         /**
    539          * @see android.telecom.TelecomManager#acceptRingingCall
    540          */
    541         @Override
    542         public void acceptRingingCall() {
    543             enforceModifyPermission();
    544             sendRequestAsync(MSG_ACCEPT_RINGING_CALL, 0);
    545         }
    546 
    547         /**
    548          * @see android.telecom.TelecomManager#showInCallScreen
    549          */
    550         @Override
    551         public void showInCallScreen(boolean showDialpad) {
    552             enforceReadPermissionOrDefaultDialer();
    553             sendRequestAsync(MSG_SHOW_CALL_SCREEN, showDialpad ? 1 : 0);
    554         }
    555 
    556         /**
    557          * @see android.telecom.TelecomManager#cancelMissedCallsNotification
    558          */
    559         @Override
    560         public void cancelMissedCallsNotification() {
    561             enforceModifyPermissionOrDefaultDialer();
    562             sendRequestAsync(MSG_CANCEL_MISSED_CALLS_NOTIFICATION, 0);
    563         }
    564 
    565         /**
    566          * @see android.telecom.TelecomManager#handleMmi
    567          */
    568         @Override
    569         public boolean handlePinMmi(String dialString) {
    570             enforceModifyPermissionOrDefaultDialer();
    571 
    572             // Switch identity so that TelephonyManager checks Telecom's permissions instead.
    573             long token = Binder.clearCallingIdentity();
    574             boolean retval = false;
    575             try {
    576                 retval = getTelephonyManager().handlePinMmi(dialString);
    577             } finally {
    578                 Binder.restoreCallingIdentity(token);
    579             }
    580 
    581             return retval;
    582         }
    583 
    584         /**
    585          * @see android.telecom.TelecomManager#handleMmi
    586          */
    587         @Override
    588         public boolean handlePinMmiForPhoneAccount(PhoneAccountHandle accountHandle,
    589                 String dialString) {
    590             enforceModifyPermissionOrDefaultDialer();
    591 
    592             if (!isVisibleToCaller(accountHandle)) {
    593                 Log.w(this, "%s is not visible for the calling user", accountHandle);
    594                 return false;
    595             }
    596 
    597             // Switch identity so that TelephonyManager checks Telecom's permissions instead.
    598             long token = Binder.clearCallingIdentity();
    599             boolean retval = false;
    600             try {
    601                 int subId = mPhoneAccountRegistrar.getSubscriptionIdForPhoneAccount(accountHandle);
    602                 retval = getTelephonyManager().handlePinMmiForSubscriber(subId, dialString);
    603             } finally {
    604                 Binder.restoreCallingIdentity(token);
    605             }
    606 
    607             return retval;
    608         }
    609 
    610         /**
    611          * @see android.telecom.TelecomManager#getAdnUriForPhoneAccount
    612          */
    613         @Override
    614         public Uri getAdnUriForPhoneAccount(PhoneAccountHandle accountHandle) {
    615             enforceModifyPermissionOrDefaultDialer();
    616 
    617             if (!isVisibleToCaller(accountHandle)) {
    618                 Log.w(this, "%s is not visible for the calling user", accountHandle);
    619                 return null;
    620             }
    621 
    622             // Switch identity so that TelephonyManager checks Telecom's permissions instead.
    623             long token = Binder.clearCallingIdentity();
    624             String retval = "content://icc/adn/";
    625             try {
    626                 long subId = mPhoneAccountRegistrar.getSubscriptionIdForPhoneAccount(accountHandle);
    627                 retval = retval + "subId/" + subId;
    628             } finally {
    629                 Binder.restoreCallingIdentity(token);
    630             }
    631 
    632             return Uri.parse(retval);
    633         }
    634 
    635         /**
    636          * @see android.telecom.TelecomManager#isTtySupported
    637          */
    638         @Override
    639         public boolean isTtySupported() {
    640             enforceReadPermission();
    641             return (boolean) sendRequest(MSG_IS_TTY_SUPPORTED);
    642         }
    643 
    644         /**
    645          * @see android.telecom.TelecomManager#getCurrentTtyMode
    646          */
    647         @Override
    648         public int getCurrentTtyMode() {
    649             enforceReadPermission();
    650             return (int) sendRequest(MSG_GET_CURRENT_TTY_MODE);
    651         }
    652 
    653         /**
    654          * @see android.telecom.TelecomManager#addNewIncomingCall
    655          */
    656         @Override
    657         public void addNewIncomingCall(PhoneAccountHandle phoneAccountHandle, Bundle extras) {
    658             Log.i(this, "Adding new incoming call with phoneAccountHandle %s", phoneAccountHandle);
    659             if (phoneAccountHandle != null && phoneAccountHandle.getComponentName() != null) {
    660                 mAppOpsManager.checkPackage(
    661                         Binder.getCallingUid(), phoneAccountHandle.getComponentName().getPackageName());
    662 
    663                 // Make sure it doesn't cross the UserHandle boundary
    664                 enforceUserHandleMatchesCaller(phoneAccountHandle);
    665 
    666                 Intent intent = new Intent(TelecomManager.ACTION_INCOMING_CALL);
    667                 intent.putExtra(TelecomManager.EXTRA_PHONE_ACCOUNT_HANDLE, phoneAccountHandle);
    668                 intent.putExtra(CallReceiver.KEY_IS_INCOMING_CALL, true);
    669                 if (extras != null) {
    670                     intent.putExtra(TelecomManager.EXTRA_INCOMING_CALL_EXTRAS, extras);
    671                 }
    672                 sendRequestAsync(MSG_NEW_INCOMING_CALL, 0, intent);
    673             } else {
    674                 Log.w(this, "Null phoneAccountHandle. Ignoring request to add new incoming call");
    675             }
    676         }
    677 
    678         /**
    679          * @see android.telecom.TelecomManager#addNewUnknownCall
    680          */
    681         @Override
    682         public void addNewUnknownCall(PhoneAccountHandle phoneAccountHandle, Bundle extras) {
    683             if (phoneAccountHandle != null && phoneAccountHandle.getComponentName() != null &&
    684                     TelephonyUtil.isPstnComponentName(phoneAccountHandle.getComponentName())) {
    685                 mAppOpsManager.checkPackage(
    686                         Binder.getCallingUid(), phoneAccountHandle.getComponentName().getPackageName());
    687 
    688                 // Make sure it doesn't cross the UserHandle boundary
    689                 enforceUserHandleMatchesCaller(phoneAccountHandle);
    690 
    691                 Intent intent = new Intent(TelecomManager.ACTION_NEW_UNKNOWN_CALL);
    692                 intent.setClass(mContext, CallReceiver.class);
    693                 intent.setFlags(Intent.FLAG_RECEIVER_FOREGROUND);
    694                 intent.putExtras(extras);
    695                 intent.putExtra(CallReceiver.KEY_IS_UNKNOWN_CALL, true);
    696                 intent.putExtra(TelecomManager.EXTRA_PHONE_ACCOUNT_HANDLE, phoneAccountHandle);
    697                 mContext.sendBroadcastAsUser(intent, phoneAccountHandle.getUserHandle());
    698             } else {
    699                 Log.i(this, "Null phoneAccountHandle or not initiated by Telephony. Ignoring request"
    700                         + " to add new unknown call.");
    701             }
    702         }
    703 
    704         /**
    705          * Dumps the current state of the TelecomService.  Used when generating problem reports.
    706          *
    707          * @param fd The file descriptor.
    708          * @param writer The print writer to dump the state to.
    709          * @param args Optional dump arguments.
    710          */
    711         @Override
    712         protected void dump(FileDescriptor fd, final PrintWriter writer, String[] args) {
    713             if (mContext.checkCallingOrSelfPermission(
    714                     android.Manifest.permission.DUMP)
    715                     != PackageManager.PERMISSION_GRANTED) {
    716                 writer.println("Permission Denial: can't dump TelecomService " +
    717                         "from from pid=" + Binder.getCallingPid() + ", uid=" +
    718                         Binder.getCallingUid());
    719                 return;
    720             }
    721 
    722             final IndentingPrintWriter pw = new IndentingPrintWriter(writer, "  ");
    723             if (mCallsManager != null) {
    724                 pw.println("mCallsManager: ");
    725                 pw.increaseIndent();
    726                 mCallsManager.dump(pw);
    727                 pw.decreaseIndent();
    728 
    729                 pw.println("mPhoneAccountRegistrar: ");
    730                 pw.increaseIndent();
    731                 mPhoneAccountRegistrar.dump(pw);
    732                 pw.decreaseIndent();
    733             }
    734         }
    735     }
    736 
    737     //
    738     // Supporting methods for the ITelecomService interface implementation.
    739     //
    740 
    741     private boolean isVisibleToCaller(PhoneAccountHandle accountHandle) {
    742         if (accountHandle == null) {
    743             return false;
    744         }
    745 
    746         return isVisibleToCaller(mPhoneAccountRegistrar.getPhoneAccountInternal(accountHandle));
    747     }
    748 
    749     private boolean isVisibleToCaller(PhoneAccount account) {
    750         if (account == null) {
    751             return false;
    752         }
    753 
    754         // If this PhoneAccount has CAPABILITY_MULTI_USER, it should be visible to all users and
    755         // all profiles. Only Telephony and SIP accounts should have this capability.
    756         if (account.hasCapabilities(PhoneAccount.CAPABILITY_MULTI_USER)) {
    757             return true;
    758         }
    759 
    760         UserHandle phoneAccountUserHandle = account.getAccountHandle().getUserHandle();
    761         if (phoneAccountUserHandle == null) {
    762             return false;
    763         }
    764 
    765         List<UserHandle> profileUserHandles;
    766         if (isCallerSystemApp()) {
    767             // If the caller lives in /system/priv-app, it can see PhoneAccounts for all of the
    768             // *profiles* that the calling user owns, but not for any other *users*.
    769             profileUserHandles = mUserManager.getUserProfiles();
    770         } else {
    771             // Otherwise, it has to be owned by the current caller's profile.
    772             profileUserHandles = new ArrayList<>(1);
    773             profileUserHandles.add(Binder.getCallingUserHandle());
    774         }
    775 
    776         return profileUserHandles.contains(phoneAccountUserHandle);
    777     }
    778 
    779     /**
    780      * Given a list of {@link PhoneAccountHandle}s, filter them to the ones that the calling
    781      * user can see.
    782      *
    783      * @param phoneAccountHandles Unfiltered list of account handles.
    784      *
    785      * @return {@link PhoneAccountHandle}s visible to the calling user and its profiles.
    786      */
    787     private List<PhoneAccountHandle> filterForAccountsVisibleToCaller(
    788             List<PhoneAccountHandle> phoneAccountHandles) {
    789         List<PhoneAccountHandle> profilePhoneAccountHandles =
    790                 new ArrayList<>(phoneAccountHandles.size());
    791         for (PhoneAccountHandle phoneAccountHandle : phoneAccountHandles) {
    792             if (isVisibleToCaller(phoneAccountHandle)) {
    793                 profilePhoneAccountHandles.add(phoneAccountHandle);
    794             }
    795         }
    796         return profilePhoneAccountHandles;
    797     }
    798 
    799     private boolean isCallerSystemApp() {
    800         int uid = Binder.getCallingUid();
    801         String[] packages = mPackageManager.getPackagesForUid(uid);
    802         for (String packageName : packages) {
    803             if (isPackageSystemApp(packageName)) {
    804                 return true;
    805             }
    806         }
    807         return false;
    808     }
    809 
    810     private boolean isPackageSystemApp(String packageName) {
    811         try {
    812             ApplicationInfo applicationInfo = mPackageManager.getApplicationInfo(packageName,
    813                     PackageManager.GET_META_DATA);
    814             if ((applicationInfo.flags & ApplicationInfo.FLAG_SYSTEM) != 0) {
    815                 return true;
    816             }
    817         } catch (PackageManager.NameNotFoundException e) {
    818         }
    819         return false;
    820     }
    821 
    822     private void acceptRingingCallInternal() {
    823         Call call = mCallsManager.getFirstCallWithState(CallState.RINGING);
    824         if (call != null) {
    825             call.answer(call.getVideoState());
    826         }
    827     }
    828 
    829     private boolean endCallInternal() {
    830         // Always operate on the foreground call if one exists, otherwise get the first call in
    831         // priority order by call-state.
    832         Call call = mCallsManager.getForegroundCall();
    833         if (call == null) {
    834             call = mCallsManager.getFirstCallWithState(
    835                     CallState.ACTIVE,
    836                     CallState.DIALING,
    837                     CallState.RINGING,
    838                     CallState.ON_HOLD);
    839         }
    840 
    841         if (call != null) {
    842             if (call.getState() == CallState.RINGING) {
    843                 call.reject(false /* rejectWithMessage */, null);
    844             } else {
    845                 call.disconnect();
    846             }
    847             return true;
    848         }
    849 
    850         return false;
    851     }
    852 
    853     private void enforcePhoneAccountModificationForPackage(String packageName) {
    854         // TODO: Use a new telecomm permission for this instead of reusing modify.
    855 
    856         int result = mContext.checkCallingOrSelfPermission(Manifest.permission.MODIFY_PHONE_STATE);
    857 
    858         // Callers with MODIFY_PHONE_STATE can use the PhoneAccount mechanism to implement
    859         // built-in behavior even when PhoneAccounts are not exposed as a third-part API. They
    860         // may also modify PhoneAccounts on behalf of any 'packageName'.
    861 
    862         if (result != PackageManager.PERMISSION_GRANTED) {
    863             // Other callers are only allowed to modify PhoneAccounts if the relevant system
    864             // feature is enabled ...
    865             enforceConnectionServiceFeature();
    866             // ... and the PhoneAccounts they refer to are for their own package.
    867             enforceCallingPackage(packageName);
    868         }
    869     }
    870 
    871     private void enforceReadPermissionOrDefaultDialer() {
    872         if (!isDefaultDialerCalling()) {
    873             enforceReadPermission();
    874         }
    875     }
    876 
    877     private void enforceModifyPermissionOrDefaultDialer() {
    878         if (!isDefaultDialerCalling()) {
    879             enforceModifyPermission();
    880         }
    881     }
    882 
    883     private void enforceCallingPackage(String packageName) {
    884         mAppOpsManager.checkPackage(Binder.getCallingUid(), packageName);
    885     }
    886 
    887     private void enforceConnectionServiceFeature() {
    888         enforceFeature(PackageManager.FEATURE_CONNECTION_SERVICE);
    889     }
    890 
    891     private void enforceRegisterCallProviderPermission() {
    892         enforcePermission(android.Manifest.permission.REGISTER_CALL_PROVIDER);
    893     }
    894 
    895     private void enforceRegisterSimSubscriptionPermission() {
    896         enforcePermission(android.Manifest.permission.REGISTER_SIM_SUBSCRIPTION);
    897     }
    898 
    899     private void enforceRegisterConnectionManagerPermission() {
    900         enforcePermission(android.Manifest.permission.REGISTER_CONNECTION_MANAGER);
    901     }
    902 
    903     private void enforceReadPermission() {
    904         enforcePermission(Manifest.permission.READ_PHONE_STATE);
    905     }
    906 
    907     private void enforceModifyPermission() {
    908         enforcePermission(Manifest.permission.MODIFY_PHONE_STATE);
    909     }
    910 
    911     private void enforcePermission(String permission) {
    912         mContext.enforceCallingOrSelfPermission(permission, null);
    913     }
    914 
    915     private void enforceRegisterMultiUser() {
    916         if (!isCallerSystemApp()) {
    917             throw new SecurityException("CAPABILITY_MULTI_USER is only available to system apps.");
    918         }
    919     }
    920 
    921     private void enforceUserHandleMatchesCaller(PhoneAccountHandle accountHandle) {
    922         if (!Binder.getCallingUserHandle().equals(accountHandle.getUserHandle())) {
    923             throw new SecurityException("Calling UserHandle does not match PhoneAccountHandle's");
    924         }
    925     }
    926 
    927     private void enforceFeature(String feature) {
    928         PackageManager pm = mContext.getPackageManager();
    929         if (!pm.hasSystemFeature(feature)) {
    930             throw new UnsupportedOperationException(
    931                     "System does not support feature " + feature);
    932         }
    933     }
    934 
    935     private boolean isDefaultDialerCalling() {
    936         ComponentName defaultDialerComponent = getDefaultPhoneAppInternal();
    937         if (defaultDialerComponent != null) {
    938             try {
    939                 mAppOpsManager.checkPackage(
    940                         Binder.getCallingUid(), defaultDialerComponent.getPackageName());
    941                 return true;
    942             } catch (SecurityException e) {
    943                 Log.e(TAG, e, "Could not get default dialer.");
    944             }
    945         }
    946         return false;
    947     }
    948 
    949     private ComponentName getDefaultPhoneAppInternal() {
    950         Resources resources = mContext.getResources();
    951         return new ComponentName(
    952                 resources.getString(R.string.ui_default_package),
    953                 resources.getString(R.string.dialer_default_class));
    954     }
    955 
    956     private TelephonyManager getTelephonyManager() {
    957         return (TelephonyManager)mContext.getSystemService(Context.TELEPHONY_SERVICE);
    958     }
    959 
    960     private MainThreadRequest sendRequestAsync(int command, int arg1) {
    961         return sendRequestAsync(command, arg1, null);
    962     }
    963 
    964     private MainThreadRequest sendRequestAsync(int command, int arg1, Object arg) {
    965         MainThreadRequest request = new MainThreadRequest();
    966         request.arg = arg;
    967         mMainThreadHandler.obtainMessage(command, arg1, 0, request).sendToTarget();
    968         return request;
    969     }
    970 
    971     /**
    972      * Posts the specified command to be executed on the main thread, waits for the request to
    973      * complete, and returns the result.
    974      */
    975     private Object sendRequest(int command) {
    976         if (Looper.myLooper() == mMainThreadHandler.getLooper()) {
    977             MainThreadRequest request = new MainThreadRequest();
    978             mMainThreadHandler.handleMessage(mMainThreadHandler.obtainMessage(command, request));
    979             return request.result;
    980         } else {
    981             MainThreadRequest request = sendRequestAsync(command, 0);
    982 
    983             // Wait for the request to complete
    984             synchronized (request) {
    985                 while (request.result == null) {
    986                     try {
    987                         request.wait();
    988                     } catch (InterruptedException e) {
    989                         // Do nothing, go back and wait until the request is complete
    990                     }
    991                 }
    992             }
    993             return request.result;
    994         }
    995     }
    996 }
    997