Loading flags/telecom_api_flags.aconfig +12 −0 Original line number Diff line number Diff line Loading @@ -82,3 +82,15 @@ flag { description: "Allow system apps such as accessibility to accept and end VOIP calls." bug: "353579043" } # OWNER=grantmenke TARGET=25Q4 flag { name: "reuse_original_conn_remote_conf_api" is_exported: true namespace: "telecom" description: "Allow reusing the telephony connection when creating a new conference call." bug: "391889544" metadata { purpose: PURPOSE_FEATURE } } src/com/android/server/telecom/ConnectionServiceWrapper.java +127 −0 Original line number Diff line number Diff line Loading @@ -679,6 +679,133 @@ public class ConnectionServiceWrapper extends ServiceBinder implements } } @Override public void addConferenceCallFromConnection(String callId, ParcelableConference parcelableConference, Session.Info sessionInfo) { Log.startSession(sessionInfo, LogUtils.Sessions.CSW_ADD_CONFERENCE_CALL_FROM_CONN, mPackageAbbreviation); Log.i(this, "addConferenceCallFromConnection: callId = " + callId); UserHandle callingUserHandle = Binder.getCallingUserHandle(); // Check status hints image for cross user access if (parcelableConference.getStatusHints() != null) { Icon icon = parcelableConference.getStatusHints().getIcon(); parcelableConference.getStatusHints().setIcon(StatusHints .validateAccountIconUserBoundary(icon, callingUserHandle)); } if (parcelableConference.getConnectElapsedTimeMillis() != 0 && mContext.checkCallingOrSelfPermission(MODIFY_PHONE_STATE) != PackageManager.PERMISSION_GRANTED) { Log.w(this, "addConferenceCall from caller without permission!"); parcelableConference = new ParcelableConference.Builder( parcelableConference.getPhoneAccount(), parcelableConference.getState()) .setConnectionCapabilities(parcelableConference.getConnectionCapabilities()) .setConnectionProperties(parcelableConference.getConnectionProperties()) .setConnectionIds(parcelableConference.getConnectionIds()) .setVideoAttributes(parcelableConference.getVideoProvider(), parcelableConference.getVideoState()) .setStatusHints(parcelableConference.getStatusHints()) .setExtras(parcelableConference.getExtras()) .setAddress(parcelableConference.getHandle(), parcelableConference.getHandlePresentation()) // no caller display name set. .setDisconnectCause(parcelableConference.getDisconnectCause()) .setRingbackRequested(parcelableConference.isRingbackRequested()) .build(); } long token = Binder.clearCallingIdentity(); try { synchronized (mLock) { Call existingTelecomCall = mCallIdMapper.getCall(callId); if (existingTelecomCall == null) { Log.e(this, new Exception(), "Attempting to create a " + "conference call using an existing call id that cannot be found " + "in telecom. Call ID = " + callId); return; } logIncoming("addConferenceCallFromConnection %s %s [%s]", callId, parcelableConference, parcelableConference.getConnectionIds()); // Make sure that there's at least one valid call. For remote connections // we'll get a add conference msg from both the remote connection service // and from the real connection service. boolean hasValidCalls = false; for (String connId : parcelableConference.getConnectionIds()) { if (mCallIdMapper.getCall(connId) != null) { hasValidCalls = true; } } // But don't bail out if the connection count is 0, because that is a valid // IMS conference state. if (!hasValidCalls && parcelableConference.getConnectionIds().size() > 0) { Log.i(this, "Attempting to add a conference with no valid calls"); return; } Bundle connectionExtras = parcelableConference.getExtras(); String connectIdToCheck = null; if (connectionExtras != null && connectionExtras .containsKey(Connection.EXTRA_ORIGINAL_CONNECTION_ID)) { // Conference was added via a connection manager, see if its original id is // known. connectIdToCheck = connectionExtras .getString(Connection.EXTRA_ORIGINAL_CONNECTION_ID); } else { connectIdToCheck = callId; } // Check to see if this conference has already been added. Call alreadyAddedConnection = mCallsManager .getAlreadyAddedConnection(connectIdToCheck); if (alreadyAddedConnection != null && mCallIdMapper.getCall(callId) == null) { Log.i(this, "addConferenceCallFromConnection: attempting to " + "add the conference via a connection mgr"); // We are currently attempting to add the conference via a connection mgr, // and the originating ConnectionService has already added it. Instead of // making a new Telecom call, we will simply add it to the ID mapper here, // and replace the ConnectionService on the call. mCallIdMapper.addCall(alreadyAddedConnection, callId); alreadyAddedConnection.replaceConnectionService( ConnectionServiceWrapper.this); } else { // Convert the existing Telecom call into a conference: existingTelecomCall.setConferenceState(true); // Set the attributes of the parcelableConference for the Telecom call: existingTelecomCall.setTargetPhoneAccount( parcelableConference.getPhoneAccount()); existingTelecomCall.setConnectionProperties( parcelableConference.getConnectionProperties()); existingTelecomCall.setConnectionCapabilities( parcelableConference.getConnectionCapabilities()); existingTelecomCall.setCallDirection( parcelableConference.getCallDirection()); existingTelecomCall.setVideoProvider( parcelableConference.getVideoProvider()); existingTelecomCall.setVideoState(parcelableConference.getVideoState()); existingTelecomCall.setStatusHints(parcelableConference.getStatusHints()); existingTelecomCall.setHandle(parcelableConference.getHandle(), parcelableConference.getHandlePresentation()); existingTelecomCall.setDisconnectCause( parcelableConference.getDisconnectCause()); existingTelecomCall.setRingbackRequested( parcelableConference.isRingbackRequested()); } } } catch (Throwable t) { Log.e(ConnectionServiceWrapper.this, t, ""); throw t; } finally { Binder.restoreCallingIdentity(token); Log.endSession(); } } @Override public void onPostDialWait(String callId, String remaining, Session.Info sessionInfo) throws RemoteException { Loading src/com/android/server/telecom/LogUtils.java +1 −0 Original line number Diff line number Diff line Loading @@ -88,6 +88,7 @@ public class LogUtils { public static final String CSW_REMOVE_CALL = "CSW.rC"; public static final String CSW_SET_IS_CONFERENCED = "CSW.sIC"; public static final String CSW_ADD_CONFERENCE_CALL = "CSW.aCC"; public static final String CSW_ADD_CONFERENCE_CALL_FROM_CONN = "CSW.aCCFC"; public static final String CSA_SET_STATE = "CSA.sSS"; } Loading Loading
flags/telecom_api_flags.aconfig +12 −0 Original line number Diff line number Diff line Loading @@ -82,3 +82,15 @@ flag { description: "Allow system apps such as accessibility to accept and end VOIP calls." bug: "353579043" } # OWNER=grantmenke TARGET=25Q4 flag { name: "reuse_original_conn_remote_conf_api" is_exported: true namespace: "telecom" description: "Allow reusing the telephony connection when creating a new conference call." bug: "391889544" metadata { purpose: PURPOSE_FEATURE } }
src/com/android/server/telecom/ConnectionServiceWrapper.java +127 −0 Original line number Diff line number Diff line Loading @@ -679,6 +679,133 @@ public class ConnectionServiceWrapper extends ServiceBinder implements } } @Override public void addConferenceCallFromConnection(String callId, ParcelableConference parcelableConference, Session.Info sessionInfo) { Log.startSession(sessionInfo, LogUtils.Sessions.CSW_ADD_CONFERENCE_CALL_FROM_CONN, mPackageAbbreviation); Log.i(this, "addConferenceCallFromConnection: callId = " + callId); UserHandle callingUserHandle = Binder.getCallingUserHandle(); // Check status hints image for cross user access if (parcelableConference.getStatusHints() != null) { Icon icon = parcelableConference.getStatusHints().getIcon(); parcelableConference.getStatusHints().setIcon(StatusHints .validateAccountIconUserBoundary(icon, callingUserHandle)); } if (parcelableConference.getConnectElapsedTimeMillis() != 0 && mContext.checkCallingOrSelfPermission(MODIFY_PHONE_STATE) != PackageManager.PERMISSION_GRANTED) { Log.w(this, "addConferenceCall from caller without permission!"); parcelableConference = new ParcelableConference.Builder( parcelableConference.getPhoneAccount(), parcelableConference.getState()) .setConnectionCapabilities(parcelableConference.getConnectionCapabilities()) .setConnectionProperties(parcelableConference.getConnectionProperties()) .setConnectionIds(parcelableConference.getConnectionIds()) .setVideoAttributes(parcelableConference.getVideoProvider(), parcelableConference.getVideoState()) .setStatusHints(parcelableConference.getStatusHints()) .setExtras(parcelableConference.getExtras()) .setAddress(parcelableConference.getHandle(), parcelableConference.getHandlePresentation()) // no caller display name set. .setDisconnectCause(parcelableConference.getDisconnectCause()) .setRingbackRequested(parcelableConference.isRingbackRequested()) .build(); } long token = Binder.clearCallingIdentity(); try { synchronized (mLock) { Call existingTelecomCall = mCallIdMapper.getCall(callId); if (existingTelecomCall == null) { Log.e(this, new Exception(), "Attempting to create a " + "conference call using an existing call id that cannot be found " + "in telecom. Call ID = " + callId); return; } logIncoming("addConferenceCallFromConnection %s %s [%s]", callId, parcelableConference, parcelableConference.getConnectionIds()); // Make sure that there's at least one valid call. For remote connections // we'll get a add conference msg from both the remote connection service // and from the real connection service. boolean hasValidCalls = false; for (String connId : parcelableConference.getConnectionIds()) { if (mCallIdMapper.getCall(connId) != null) { hasValidCalls = true; } } // But don't bail out if the connection count is 0, because that is a valid // IMS conference state. if (!hasValidCalls && parcelableConference.getConnectionIds().size() > 0) { Log.i(this, "Attempting to add a conference with no valid calls"); return; } Bundle connectionExtras = parcelableConference.getExtras(); String connectIdToCheck = null; if (connectionExtras != null && connectionExtras .containsKey(Connection.EXTRA_ORIGINAL_CONNECTION_ID)) { // Conference was added via a connection manager, see if its original id is // known. connectIdToCheck = connectionExtras .getString(Connection.EXTRA_ORIGINAL_CONNECTION_ID); } else { connectIdToCheck = callId; } // Check to see if this conference has already been added. Call alreadyAddedConnection = mCallsManager .getAlreadyAddedConnection(connectIdToCheck); if (alreadyAddedConnection != null && mCallIdMapper.getCall(callId) == null) { Log.i(this, "addConferenceCallFromConnection: attempting to " + "add the conference via a connection mgr"); // We are currently attempting to add the conference via a connection mgr, // and the originating ConnectionService has already added it. Instead of // making a new Telecom call, we will simply add it to the ID mapper here, // and replace the ConnectionService on the call. mCallIdMapper.addCall(alreadyAddedConnection, callId); alreadyAddedConnection.replaceConnectionService( ConnectionServiceWrapper.this); } else { // Convert the existing Telecom call into a conference: existingTelecomCall.setConferenceState(true); // Set the attributes of the parcelableConference for the Telecom call: existingTelecomCall.setTargetPhoneAccount( parcelableConference.getPhoneAccount()); existingTelecomCall.setConnectionProperties( parcelableConference.getConnectionProperties()); existingTelecomCall.setConnectionCapabilities( parcelableConference.getConnectionCapabilities()); existingTelecomCall.setCallDirection( parcelableConference.getCallDirection()); existingTelecomCall.setVideoProvider( parcelableConference.getVideoProvider()); existingTelecomCall.setVideoState(parcelableConference.getVideoState()); existingTelecomCall.setStatusHints(parcelableConference.getStatusHints()); existingTelecomCall.setHandle(parcelableConference.getHandle(), parcelableConference.getHandlePresentation()); existingTelecomCall.setDisconnectCause( parcelableConference.getDisconnectCause()); existingTelecomCall.setRingbackRequested( parcelableConference.isRingbackRequested()); } } } catch (Throwable t) { Log.e(ConnectionServiceWrapper.this, t, ""); throw t; } finally { Binder.restoreCallingIdentity(token); Log.endSession(); } } @Override public void onPostDialWait(String callId, String remaining, Session.Info sessionInfo) throws RemoteException { Loading
src/com/android/server/telecom/LogUtils.java +1 −0 Original line number Diff line number Diff line Loading @@ -88,6 +88,7 @@ public class LogUtils { public static final String CSW_REMOVE_CALL = "CSW.rC"; public static final String CSW_SET_IS_CONFERENCED = "CSW.sIC"; public static final String CSW_ADD_CONFERENCE_CALL = "CSW.aCC"; public static final String CSW_ADD_CONFERENCE_CALL_FROM_CONN = "CSW.aCCFC"; public static final String CSA_SET_STATE = "CSA.sSS"; } Loading