Loading src/com/android/server/telecom/Call.java +8 −0 Original line number Diff line number Diff line Loading @@ -85,6 +85,7 @@ import java.util.Set; import java.util.concurrent.CompletableFuture; import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.TimeUnit; import java.util.stream.Collectors; /** * Encapsulates all aspects of a given phone call throughout its lifecycle, starting Loading Loading @@ -3160,6 +3161,13 @@ public class Call implements CreateConnectionResponse, EventManager.Loggable, void setConferenceableCalls(List<Call> conferenceableCalls) { mConferenceableCalls.clear(); mConferenceableCalls.addAll(conferenceableCalls); String confCallIds = ""; if (!conferenceableCalls.isEmpty()) { confCallIds = conferenceableCalls.stream() .map(c -> c.getId()) .collect(Collectors.joining(",")); } Log.addEvent(this, LogUtils.Events.CONF_CALLS_CHANGED, confCallIds); for (Listener l : mListeners) { l.onConferenceableCallsChanged(this); Loading src/com/android/server/telecom/ConnectionServiceWrapper.java +39 −0 Original line number Diff line number Diff line Loading @@ -920,6 +920,45 @@ public class ConnectionServiceWrapper extends ServiceBinder implements } else { connectIdToCheck = callId; } // Handle the case where an existing connection was added by Telephony via // a connection manager. The remote connection service API does not include // the ability to specify a parent connection when adding an existing // connection, so we stash the desired parent in the connection extras. if (connectionExtras != null && connectionExtras.containsKey( Connection.EXTRA_ADD_TO_CONFERENCE_ID) && connection.getParentCallId() == null) { String parentId = connectionExtras.getString( Connection.EXTRA_ADD_TO_CONFERENCE_ID); Log.i(ConnectionServiceWrapper.this, "addExistingConnection: remote " + "connection will auto-add to parent %s", parentId); // Replace parcelable connection instance, swapping the new desired // parent in. connection = new ParcelableConnection( connection.getPhoneAccount(), connection.getState(), connection.getConnectionCapabilities(), connection.getConnectionProperties(), connection.getSupportedAudioRoutes(), connection.getHandle(), connection.getHandlePresentation(), connection.getCallerDisplayName(), connection.getCallerDisplayNamePresentation(), connection.getVideoProvider(), connection.getVideoState(), connection.isRingbackRequested(), connection.getIsVoipAudioMode(), connection.getConnectTimeMillis(), connection.getConnectElapsedTimeMillis(), connection.getStatusHints(), connection.getDisconnectCause(), connection.getConferenceableConnectionIds(), connection.getExtras(), parentId, connection.getCallDirection(), connection.getCallerNumberVerificationStatus()); } // Check to see if this Connection has already been added. Call alreadyAddedConnection = mCallsManager .getAlreadyAddedConnection(connectIdToCheck); Loading src/com/android/server/telecom/LogUtils.java +1 −0 Original line number Diff line number Diff line Loading @@ -138,6 +138,7 @@ public class LogUtils { public static final String REMOVE_CHILD = "REMOVE_CHILD"; public static final String SET_PARENT = "SET_PARENT"; public static final String CONF_STATE_CHANGED = "CONF_STATE_CHANGED"; public static final String CONF_CALLS_CHANGED = "CONF_CALLS_CHANGED"; public static final String CALL_DIRECTION_CHANGED = "CALL_DIRECTION_CHANGED"; public static final String MUTE = "MUTE"; public static final String UNMUTE = "UNMUTE"; Loading src/com/android/server/telecom/TelecomServiceImpl.java +19 −7 Original line number Diff line number Diff line Loading @@ -852,6 +852,7 @@ public class TelecomServiceImpl { public boolean hasManageOngoingCallsPermission(String callingPackage) { try { Log.startSession("TSI.hMOCP"); enforceCallingPackage(callingPackage); return PermissionChecker.checkPermissionForDataDeliveryFromDataSource( mContext, Manifest.permission.MANAGE_ONGOING_CALLS, Binder.getCallingPid(), Loading Loading @@ -1466,6 +1467,7 @@ public class TelecomServiceImpl { enforceCallingPackage(callingPackage); PhoneAccountHandle phoneAccountHandle = null; boolean clearPhoneAccountHandleExtra = false; if (extras != null) { phoneAccountHandle = extras.getParcelable( TelecomManager.EXTRA_PHONE_ACCOUNT_HANDLE); Loading @@ -1477,17 +1479,24 @@ public class TelecomServiceImpl { boolean isSelfManaged = phoneAccountHandle != null && isSelfManagedConnectionService(phoneAccountHandle); if (isSelfManaged) { mContext.enforceCallingOrSelfPermission(Manifest.permission.MANAGE_OWN_CALLS, "Self-managed ConnectionServices require MANAGE_OWN_CALLS permission."); try { mContext.enforceCallingOrSelfPermission( Manifest.permission.MANAGE_OWN_CALLS, "Self-managed ConnectionServices require " + "MANAGE_OWN_CALLS permission."); } catch (SecurityException e) { // Fallback to use mobile network to avoid disclosing phone account handle // package information clearPhoneAccountHandleExtra = true; } if (!callingPackage.equals( if (!clearPhoneAccountHandleExtra && !callingPackage.equals( phoneAccountHandle.getComponentName().getPackageName()) && !canCallPhone(callingPackage, callingFeatureId, "CALL_PHONE permission required to place calls.")) { // The caller is not allowed to place calls, so we want to ensure that it // can only place calls through itself. throw new SecurityException("Self-managed ConnectionServices can only " + "place calls through their own ConnectionService."); // The caller is not allowed to place calls, so fallback to use mobile // network. clearPhoneAccountHandleExtra = true; } } else if (!canCallPhone(callingPackage, callingFeatureId, "placeCall")) { throw new SecurityException("Package " + callingPackage Loading Loading @@ -1522,6 +1531,9 @@ public class TelecomServiceImpl { final Intent intent = new Intent(hasCallPrivilegedPermission ? Intent.ACTION_CALL_PRIVILEGED : Intent.ACTION_CALL, handle); if (extras != null) { if (clearPhoneAccountHandleExtra) { extras.remove(TelecomManager.EXTRA_PHONE_ACCOUNT_HANDLE); } extras.setDefusable(true); intent.putExtras(extras); } Loading Loading
src/com/android/server/telecom/Call.java +8 −0 Original line number Diff line number Diff line Loading @@ -85,6 +85,7 @@ import java.util.Set; import java.util.concurrent.CompletableFuture; import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.TimeUnit; import java.util.stream.Collectors; /** * Encapsulates all aspects of a given phone call throughout its lifecycle, starting Loading Loading @@ -3160,6 +3161,13 @@ public class Call implements CreateConnectionResponse, EventManager.Loggable, void setConferenceableCalls(List<Call> conferenceableCalls) { mConferenceableCalls.clear(); mConferenceableCalls.addAll(conferenceableCalls); String confCallIds = ""; if (!conferenceableCalls.isEmpty()) { confCallIds = conferenceableCalls.stream() .map(c -> c.getId()) .collect(Collectors.joining(",")); } Log.addEvent(this, LogUtils.Events.CONF_CALLS_CHANGED, confCallIds); for (Listener l : mListeners) { l.onConferenceableCallsChanged(this); Loading
src/com/android/server/telecom/ConnectionServiceWrapper.java +39 −0 Original line number Diff line number Diff line Loading @@ -920,6 +920,45 @@ public class ConnectionServiceWrapper extends ServiceBinder implements } else { connectIdToCheck = callId; } // Handle the case where an existing connection was added by Telephony via // a connection manager. The remote connection service API does not include // the ability to specify a parent connection when adding an existing // connection, so we stash the desired parent in the connection extras. if (connectionExtras != null && connectionExtras.containsKey( Connection.EXTRA_ADD_TO_CONFERENCE_ID) && connection.getParentCallId() == null) { String parentId = connectionExtras.getString( Connection.EXTRA_ADD_TO_CONFERENCE_ID); Log.i(ConnectionServiceWrapper.this, "addExistingConnection: remote " + "connection will auto-add to parent %s", parentId); // Replace parcelable connection instance, swapping the new desired // parent in. connection = new ParcelableConnection( connection.getPhoneAccount(), connection.getState(), connection.getConnectionCapabilities(), connection.getConnectionProperties(), connection.getSupportedAudioRoutes(), connection.getHandle(), connection.getHandlePresentation(), connection.getCallerDisplayName(), connection.getCallerDisplayNamePresentation(), connection.getVideoProvider(), connection.getVideoState(), connection.isRingbackRequested(), connection.getIsVoipAudioMode(), connection.getConnectTimeMillis(), connection.getConnectElapsedTimeMillis(), connection.getStatusHints(), connection.getDisconnectCause(), connection.getConferenceableConnectionIds(), connection.getExtras(), parentId, connection.getCallDirection(), connection.getCallerNumberVerificationStatus()); } // Check to see if this Connection has already been added. Call alreadyAddedConnection = mCallsManager .getAlreadyAddedConnection(connectIdToCheck); Loading
src/com/android/server/telecom/LogUtils.java +1 −0 Original line number Diff line number Diff line Loading @@ -138,6 +138,7 @@ public class LogUtils { public static final String REMOVE_CHILD = "REMOVE_CHILD"; public static final String SET_PARENT = "SET_PARENT"; public static final String CONF_STATE_CHANGED = "CONF_STATE_CHANGED"; public static final String CONF_CALLS_CHANGED = "CONF_CALLS_CHANGED"; public static final String CALL_DIRECTION_CHANGED = "CALL_DIRECTION_CHANGED"; public static final String MUTE = "MUTE"; public static final String UNMUTE = "UNMUTE"; Loading
src/com/android/server/telecom/TelecomServiceImpl.java +19 −7 Original line number Diff line number Diff line Loading @@ -852,6 +852,7 @@ public class TelecomServiceImpl { public boolean hasManageOngoingCallsPermission(String callingPackage) { try { Log.startSession("TSI.hMOCP"); enforceCallingPackage(callingPackage); return PermissionChecker.checkPermissionForDataDeliveryFromDataSource( mContext, Manifest.permission.MANAGE_ONGOING_CALLS, Binder.getCallingPid(), Loading Loading @@ -1466,6 +1467,7 @@ public class TelecomServiceImpl { enforceCallingPackage(callingPackage); PhoneAccountHandle phoneAccountHandle = null; boolean clearPhoneAccountHandleExtra = false; if (extras != null) { phoneAccountHandle = extras.getParcelable( TelecomManager.EXTRA_PHONE_ACCOUNT_HANDLE); Loading @@ -1477,17 +1479,24 @@ public class TelecomServiceImpl { boolean isSelfManaged = phoneAccountHandle != null && isSelfManagedConnectionService(phoneAccountHandle); if (isSelfManaged) { mContext.enforceCallingOrSelfPermission(Manifest.permission.MANAGE_OWN_CALLS, "Self-managed ConnectionServices require MANAGE_OWN_CALLS permission."); try { mContext.enforceCallingOrSelfPermission( Manifest.permission.MANAGE_OWN_CALLS, "Self-managed ConnectionServices require " + "MANAGE_OWN_CALLS permission."); } catch (SecurityException e) { // Fallback to use mobile network to avoid disclosing phone account handle // package information clearPhoneAccountHandleExtra = true; } if (!callingPackage.equals( if (!clearPhoneAccountHandleExtra && !callingPackage.equals( phoneAccountHandle.getComponentName().getPackageName()) && !canCallPhone(callingPackage, callingFeatureId, "CALL_PHONE permission required to place calls.")) { // The caller is not allowed to place calls, so we want to ensure that it // can only place calls through itself. throw new SecurityException("Self-managed ConnectionServices can only " + "place calls through their own ConnectionService."); // The caller is not allowed to place calls, so fallback to use mobile // network. clearPhoneAccountHandleExtra = true; } } else if (!canCallPhone(callingPackage, callingFeatureId, "placeCall")) { throw new SecurityException("Package " + callingPackage Loading Loading @@ -1522,6 +1531,9 @@ public class TelecomServiceImpl { final Intent intent = new Intent(hasCallPrivilegedPermission ? Intent.ACTION_CALL_PRIVILEGED : Intent.ACTION_CALL, handle); if (extras != null) { if (clearPhoneAccountHandleExtra) { extras.remove(TelecomManager.EXTRA_PHONE_ACCOUNT_HANDLE); } extras.setDefusable(true); intent.putExtras(extras); } Loading