1 /* 2 * Copyright (C) 2013 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.components; 18 19 import android.app.admin.DevicePolicyManager; 20 import android.content.Context; 21 import android.content.Intent; 22 import android.net.Uri; 23 import android.os.UserHandle; 24 import android.os.UserManager; 25 import android.telecom.Log; 26 import android.telecom.PhoneAccount; 27 import android.telecom.TelecomManager; 28 import android.telecom.VideoProfile; 29 import android.telephony.PhoneNumberUtils; 30 import android.telephony.TelephonyManager; 31 32 import com.android.server.telecom.CallIntentProcessor; 33 import com.android.server.telecom.R; 34 import com.android.server.telecom.TelecomSystem; 35 import com.android.server.telecom.TelephonyUtil; 36 import com.android.server.telecom.UserUtil; 37 import com.android.server.telecom.flags.FeatureFlags; 38 39 // TODO: Needed for move to system service: import com.android.internal.R; 40 41 /** 42 * Handles system CALL actions and forwards them to {@link CallIntentProcessor}. 43 * Handles all three CALL action types: CALL, CALL_PRIVILEGED, and CALL_EMERGENCY. 44 * 45 * Pre-L, the only way apps were were allowed to make outgoing emergency calls was the 46 * ACTION_CALL_PRIVILEGED action (which requires the system only CALL_PRIVILEGED permission). 47 * 48 * In L, any app that has the CALL_PRIVILEGED permission can continue to make outgoing emergency 49 * calls via ACTION_CALL_PRIVILEGED. 50 * 51 * In addition, the default dialer (identified via 52 * {@link android.telecom.TelecomManager#getDefaultDialerPackage()} will also be granted the 53 * ability to make emergency outgoing calls using the CALL action. In order to do this, it must 54 * use the {@link TelecomManager#placeCall(Uri, android.os.Bundle)} method to allow its package 55 * name to be passed to {@link UserCallIntentProcessor}. Calling startActivity will continue to 56 * work on all non-emergency numbers just like it did pre-L. 57 */ 58 public class UserCallIntentProcessor { 59 60 private final Context mContext; 61 private final UserHandle mUserHandle; 62 private FeatureFlags mFeatureFlags; 63 UserCallIntentProcessor(Context context, UserHandle userHandle, FeatureFlags featureFlags)64 public UserCallIntentProcessor(Context context, UserHandle userHandle, 65 FeatureFlags featureFlags) { 66 mContext = context; 67 mUserHandle = userHandle; 68 mFeatureFlags = featureFlags; 69 } 70 71 /** 72 * Processes intents sent to the activity. 73 * 74 * @param intent The intent. 75 * @param callingPackageName The package name of the calling app. 76 * @param isSelfManaged {@code true} if SelfManaged profile enabled. 77 * @param canCallNonEmergency {@code true} if the caller is permitted to call non-emergency 78 * numbers. 79 * @param isLocalInvocation {@code true} if the caller is within the system service (i.e. the 80 * caller is {@link com.android.server.telecom.TelecomServiceImpl}) 81 * and we can skip the re-broadcast of the intent to Telecom. 82 * When {@code false}, we need to re-broadcast the intent to Telcom 83 * to trampoline it to the system service where the Telecom 84 * service resides. 85 */ processIntent(Intent intent, String callingPackageName, boolean isSelfManaged, boolean canCallNonEmergency, boolean isLocalInvocation)86 public void processIntent(Intent intent, String callingPackageName, 87 boolean isSelfManaged, boolean canCallNonEmergency, 88 boolean isLocalInvocation) { 89 String action = intent.getAction(); 90 91 if (Intent.ACTION_CALL.equals(action) || 92 Intent.ACTION_CALL_PRIVILEGED.equals(action) || 93 Intent.ACTION_CALL_EMERGENCY.equals(action)) { 94 processOutgoingCallIntent(intent, callingPackageName, isSelfManaged, 95 canCallNonEmergency, isLocalInvocation); 96 } 97 } 98 processOutgoingCallIntent(Intent intent, String callingPackageName, boolean isSelfManaged, boolean canCallNonEmergency, boolean isLocalInvocation)99 private void processOutgoingCallIntent(Intent intent, String callingPackageName, 100 boolean isSelfManaged, boolean canCallNonEmergency, 101 boolean isLocalInvocation) { 102 Uri handle = intent.getData(); 103 if (handle == null) return; 104 String scheme = handle.getScheme(); 105 String uriString = handle.getSchemeSpecificPart(); 106 107 // Ensure sip URIs dialed using TEL scheme get converted to SIP scheme. 108 if (PhoneAccount.SCHEME_TEL.equals(scheme) && PhoneNumberUtils.isUriNumber(uriString)) { 109 handle = Uri.fromParts(PhoneAccount.SCHEME_SIP, uriString, null); 110 } 111 112 if (UserUtil.hasOutgoingCallsUserRestriction(mContext, mUserHandle, handle, isSelfManaged, 113 UserCallIntentProcessor.class.getCanonicalName(), mFeatureFlags)) { 114 return; 115 } 116 117 if (!isSelfManaged && !canCallNonEmergency && 118 !TelephonyUtil.shouldProcessAsEmergency(mContext, handle)) { 119 String reason = android.Manifest.permission.CALL_PHONE + " permission is not granted."; 120 UserUtil.showErrorDialogForRestrictedOutgoingCall(mContext, 121 R.string.outgoing_call_not_allowed_no_permission, 122 this.getClass().getCanonicalName(), reason); 123 return; 124 } 125 126 int videoState = intent.getIntExtra( 127 TelecomManager.EXTRA_START_CALL_WITH_VIDEO_STATE, 128 VideoProfile.STATE_AUDIO_ONLY); 129 Log.d(this, "processOutgoingCallIntent videoState = " + videoState); 130 131 // Save the user handle of current user before forwarding the intent to primary user. 132 intent.putExtra(CallIntentProcessor.KEY_INITIATING_USER, mUserHandle); 133 134 sendIntentToDestination(intent, isLocalInvocation, callingPackageName); 135 } 136 137 /** 138 * Potentially trampolines the intent to Telecom via TelecomServiceImpl. 139 * If the caller is local to the Telecom service, we send the intent to Telecom without 140 * sending it through TelecomServiceImpl. 141 */ sendIntentToDestination(Intent intent, boolean isLocalInvocation, String callingPackage)142 private boolean sendIntentToDestination(Intent intent, boolean isLocalInvocation, 143 String callingPackage) { 144 intent.putExtra(CallIntentProcessor.KEY_IS_INCOMING_CALL, false); 145 intent.setFlags(Intent.FLAG_RECEIVER_FOREGROUND); 146 if (isLocalInvocation) { 147 // We are invoking this from TelecomServiceImpl, so TelecomSystem is available. Don't 148 // bother trampolining the intent, just sent it directly to the call intent processor. 149 // TODO: We should not be using an intent here; this whole flows needs cleanup. 150 Log.i(this, "sendIntentToDestination: send intent to Telecom directly."); 151 synchronized (TelecomSystem.getInstance().getLock()) { 152 TelecomSystem.getInstance().getCallIntentProcessor().processIntent(intent, 153 callingPackage); 154 } 155 } else { 156 // We're calling from the UserCallActivity, so the TelecomSystem is not in the same 157 // process; we need to trampoline to TelecomSystem in the system server process. 158 Log.i(this, "sendIntentToDestination: trampoline to Telecom."); 159 TelecomManager tm = (TelecomManager) mContext.getSystemService(Context.TELECOM_SERVICE); 160 tm.handleCallIntent(intent, callingPackage); 161 } 162 return true; 163 } 164 } 165