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
handleMessage(Message msg)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
onCreate()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
onBind(Intent intent)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
getDefaultOutgoingPhoneAccount(String uriScheme)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
getUserSelectedOutgoingPhoneAccount()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
setUserSelectedOutgoingPhoneAccount(PhoneAccountHandle accountHandle)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
getCallCapablePhoneAccounts()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
getPhoneAccountsSupportingScheme(String uriScheme)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
getPhoneAccountsForPackage(String packageName)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
getPhoneAccount(PhoneAccountHandle accountHandle)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
getAllPhoneAccountsCount()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
getAllPhoneAccounts()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
getAllPhoneAccountHandles()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
getSimCallManager()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
setSimCallManager(PhoneAccountHandle accountHandle)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
getSimCallManagers()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
registerPhoneAccount(PhoneAccount account)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
unregisterPhoneAccount(PhoneAccountHandle accountHandle)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
clearAccounts(String packageName)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
isVoiceMailNumber(PhoneAccountHandle accountHandle, String number)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
hasVoiceMailNumber(PhoneAccountHandle accountHandle)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
getLine1Number(PhoneAccountHandle accountHandle)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
silenceRinger()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
getDefaultPhoneApp()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
isInCall()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
isRinging()516         public boolean isRinging() {
517             enforceReadPermission();
518             return mCallsManager.getCallState() == TelephonyManager.CALL_STATE_RINGING;
519         }
520 
521         /**
522          * @see TelecomManager#getCallState
523          */
524         @Override
getCallState()525         public int getCallState() {
526             return mCallsManager.getCallState();
527         }
528 
529         /**
530          * @see android.telecom.TelecomManager#endCall
531          */
532         @Override
endCall()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
acceptRingingCall()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
showInCallScreen(boolean showDialpad)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
cancelMissedCallsNotification()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
handlePinMmi(String dialString)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
handlePinMmiForPhoneAccount(PhoneAccountHandle accountHandle, String dialString)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
getAdnUriForPhoneAccount(PhoneAccountHandle accountHandle)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
isTtySupported()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
getCurrentTtyMode()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
addNewIncomingCall(PhoneAccountHandle phoneAccountHandle, Bundle extras)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
addNewUnknownCall(PhoneAccountHandle phoneAccountHandle, Bundle extras)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
dump(FileDescriptor fd, final PrintWriter writer, String[] args)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 
isVisibleToCaller(PhoneAccountHandle accountHandle)741     private boolean isVisibleToCaller(PhoneAccountHandle accountHandle) {
742         if (accountHandle == null) {
743             return false;
744         }
745 
746         return isVisibleToCaller(mPhoneAccountRegistrar.getPhoneAccountInternal(accountHandle));
747     }
748 
isVisibleToCaller(PhoneAccount account)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      */
filterForAccountsVisibleToCaller( List<PhoneAccountHandle> phoneAccountHandles)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 
isCallerSystemApp()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 
isPackageSystemApp(String packageName)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 
acceptRingingCallInternal()822     private void acceptRingingCallInternal() {
823         Call call = mCallsManager.getFirstCallWithState(CallState.RINGING);
824         if (call != null) {
825             call.answer(call.getVideoState());
826         }
827     }
828 
endCallInternal()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 
enforcePhoneAccountModificationForPackage(String packageName)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 
enforceReadPermissionOrDefaultDialer()871     private void enforceReadPermissionOrDefaultDialer() {
872         if (!isDefaultDialerCalling()) {
873             enforceReadPermission();
874         }
875     }
876 
enforceModifyPermissionOrDefaultDialer()877     private void enforceModifyPermissionOrDefaultDialer() {
878         if (!isDefaultDialerCalling()) {
879             enforceModifyPermission();
880         }
881     }
882 
enforceCallingPackage(String packageName)883     private void enforceCallingPackage(String packageName) {
884         mAppOpsManager.checkPackage(Binder.getCallingUid(), packageName);
885     }
886 
enforceConnectionServiceFeature()887     private void enforceConnectionServiceFeature() {
888         enforceFeature(PackageManager.FEATURE_CONNECTION_SERVICE);
889     }
890 
enforceRegisterCallProviderPermission()891     private void enforceRegisterCallProviderPermission() {
892         enforcePermission(android.Manifest.permission.REGISTER_CALL_PROVIDER);
893     }
894 
enforceRegisterSimSubscriptionPermission()895     private void enforceRegisterSimSubscriptionPermission() {
896         enforcePermission(android.Manifest.permission.REGISTER_SIM_SUBSCRIPTION);
897     }
898 
enforceRegisterConnectionManagerPermission()899     private void enforceRegisterConnectionManagerPermission() {
900         enforcePermission(android.Manifest.permission.REGISTER_CONNECTION_MANAGER);
901     }
902 
enforceReadPermission()903     private void enforceReadPermission() {
904         enforcePermission(Manifest.permission.READ_PHONE_STATE);
905     }
906 
enforceModifyPermission()907     private void enforceModifyPermission() {
908         enforcePermission(Manifest.permission.MODIFY_PHONE_STATE);
909     }
910 
enforcePermission(String permission)911     private void enforcePermission(String permission) {
912         mContext.enforceCallingOrSelfPermission(permission, null);
913     }
914 
enforceRegisterMultiUser()915     private void enforceRegisterMultiUser() {
916         if (!isCallerSystemApp()) {
917             throw new SecurityException("CAPABILITY_MULTI_USER is only available to system apps.");
918         }
919     }
920 
enforceUserHandleMatchesCaller(PhoneAccountHandle accountHandle)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 
enforceFeature(String feature)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 
isDefaultDialerCalling()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 
getDefaultPhoneAppInternal()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 
getTelephonyManager()956     private TelephonyManager getTelephonyManager() {
957         return (TelephonyManager)mContext.getSystemService(Context.TELEPHONY_SERVICE);
958     }
959 
sendRequestAsync(int command, int arg1)960     private MainThreadRequest sendRequestAsync(int command, int arg1) {
961         return sendRequestAsync(command, arg1, null);
962     }
963 
sendRequestAsync(int command, int arg1, Object arg)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      */
sendRequest(int command)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