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