Support for override active D2D transport.
Adding support for overriding the active D2D transport.
Also adding more log messages.
And wire in received DTMF messages into TelephonyConnection.
Prevent D2D for emergency calls.
Test: Manual testing with two devices.
Test: Manual test with test emergency numbers.
Test: Run D2D unit tests.
Bug: 163085177
Change-Id: I5f971fcfc49a86388ed17e1774baf44d920de9b7
diff --git a/src/com/android/phone/PhoneInterfaceManager.java b/src/com/android/phone/PhoneInterfaceManager.java
index 722f97b..3bad155 100755
--- a/src/com/android/phone/PhoneInterfaceManager.java
+++ b/src/com/android/phone/PhoneInterfaceManager.java
@@ -9933,7 +9933,7 @@
@Override
public void sendDeviceToDeviceMessage(int message, int value) {
TelephonyPermissions.enforceShellOnly(Binder.getCallingUid(),
- "setCarrierSingleRegistrationEnabledOverride");
+ "sendDeviceToDeviceMessage");
enforceModifyPermission();
final long identity = Binder.clearCallingIdentity();
@@ -9950,6 +9950,29 @@
}
}
+ /**
+ * Sets the specified device to device transport active.
+ * @param transport The transport to set active.
+ */
+ @Override
+ public void setActiveDeviceToDeviceTransport(@NonNull String transport) {
+ TelephonyPermissions.enforceShellOnly(Binder.getCallingUid(),
+ "setActiveDeviceToDeviceTransport");
+ enforceModifyPermission();
+
+ final long identity = Binder.clearCallingIdentity();
+ try {
+ TelephonyConnectionService service =
+ TelecomAccountRegistry.getInstance(null).getTelephonyConnectionService();
+ if (service == null) {
+ Rlog.e(LOG_TAG, "setActiveDeviceToDeviceTransport: not in a call.");
+ return;
+ }
+ service.setActiveDeviceToDeviceTransport(transport);
+ } finally {
+ Binder.restoreCallingIdentity(identity);
+ }
+ }
/**
* Gets the config of RCS VoLTE single registration enabled for the device.
diff --git a/src/com/android/phone/TelephonyShellCommand.java b/src/com/android/phone/TelephonyShellCommand.java
index 79dfbcf..ea12984 100644
--- a/src/com/android/phone/TelephonyShellCommand.java
+++ b/src/com/android/phone/TelephonyShellCommand.java
@@ -113,6 +113,7 @@
private static final String D2D_SUBCOMMAND = "d2d";
private static final String D2D_SEND = "send";
+ private static final String D2D_TRANSPORT = "transport";
private static final String RCS_UCE_COMMAND = "uce";
private static final String UCE_GET_EAB_CONTACT = "get-eab-contact";
@@ -271,6 +272,9 @@
MESSAGE_DEVICE_BATTERY_STATE));
pw.println(" Type: " + MESSAGE_DEVICE_NETWORK_COVERAGE + " - "
+ Communicator.messageToString(MESSAGE_DEVICE_NETWORK_COVERAGE));
+ pw.println(" d2d transport TYPE");
+ pw.println(" Forces the specified D2D transport TYPE to be active. Use the");
+ pw.println(" short class name of the transport; i.e. DtmfTransport or RtpTransport.");
}
private void onHelpIms() {
@@ -634,6 +638,9 @@
case D2D_SEND: {
return handleD2dSendCommand();
}
+ case D2D_TRANSPORT: {
+ return handleD2dTransportCommand();
+ }
}
return -1;
@@ -641,11 +648,9 @@
private int handleD2dSendCommand() {
PrintWriter errPw = getErrPrintWriter();
- String opt;
int messageType = -1;
int messageValue = -1;
-
String arg = getNextArg();
if (arg == null) {
onHelpD2D();
@@ -681,6 +686,25 @@
return 0;
}
+ private int handleD2dTransportCommand() {
+ PrintWriter errPw = getErrPrintWriter();
+
+ String arg = getNextArg();
+ if (arg == null) {
+ onHelpD2D();
+ return 0;
+ }
+
+ try {
+ mInterface.setActiveDeviceToDeviceTransport(arg);
+ } catch (RemoteException e) {
+ Log.w(LOG_TAG, "d2d transport error: " + e.getMessage());
+ errPw.println("Exception: " + e.getMessage());
+ return -1;
+ }
+ return 0;
+ }
+
// ims set-ims-service
private int handleImsSetServiceCommand() {
PrintWriter errPw = getErrPrintWriter();
diff --git a/src/com/android/services/telephony/TelephonyConnection.java b/src/com/android/services/telephony/TelephonyConnection.java
index 7a59908..da41077 100755
--- a/src/com/android/services/telephony/TelephonyConnection.java
+++ b/src/com/android/services/telephony/TelephonyConnection.java
@@ -28,6 +28,7 @@
import android.os.Handler;
import android.os.Looper;
import android.os.Message;
+import android.os.Messenger;
import android.os.PersistableBundle;
import android.telecom.BluetoothCallQualityReport;
import android.telecom.CallAudioState;
@@ -95,6 +96,7 @@
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.Executors;
+import java.util.stream.Collectors;
/**
* Base class for CDMA and GSM connections.
@@ -133,6 +135,7 @@
private static final int MSG_ON_CONNECTION_EVENT = 19;
private static final int MSG_REDIAL_CONNECTION_CHANGED = 20;
private static final int MSG_REJECT = 21;
+ private static final int MSG_DTMF_DONE = 22;
private static final String JAPAN_COUNTRY_CODE_WITH_PLUS_SIGN = "+81";
private static final String JAPAN_ISO_COUNTRY_CODE = "JP";
@@ -303,6 +306,9 @@
int rejectReason = (int) msg.obj;
reject(rejectReason);
break;
+ case MSG_DTMF_DONE:
+ Log.i(this, "MSG_DTMF_DONE");
+ break;
case MSG_SET_CALL_RADIO_TECH:
int vrat = (int) msg.obj;
@@ -341,6 +347,8 @@
}
};
+ private final Messenger mHandlerMessenger = new Messenger(mHandler);
+
/**
* Handles {@link SuppServiceNotification}s pertinent to Telephony.
* @param ssn the notification.
@@ -510,7 +518,7 @@
@Override
public void onStateChanged(android.telecom.Connection c, int state) {
- mCommunicator.onStateChanged(c, state);
+ mCommunicator.onStateChanged(c.getTelecomCallId(), state);
}
}
@@ -742,6 +750,15 @@
extensionData.size());
mRtpTransport.onRtpHeaderExtensionsReceived(extensionData);
}
+
+ @Override
+ public void onReceivedDtmfDigit(char digit) {
+ if (mDtmfTransport == null) {
+ return;
+ }
+ Log.i(this, "onReceivedDtmfDigit: digit=%c", digit);
+ mDtmfTransport.onDtmfReceived(digit);
+ }
};
private TelephonyConnectionService mTelephonyConnectionService;
@@ -2351,7 +2368,7 @@
}
if (mCommunicator != null) {
- mCommunicator.onStateChanged(this, getState());
+ mCommunicator.onStateChanged(getTelecomCallId(), getState());
}
}
}
@@ -3284,13 +3301,18 @@
private void maybeConfigureDeviceToDeviceCommunication() {
if (!getPhone().getContext().getResources().getBoolean(
R.bool.config_use_device_to_device_communication)) {
- Log.d(this, "maybeConfigureDeviceToDeviceCommunication: not using D2D.");
+ Log.i(this, "maybeConfigureDeviceToDeviceCommunication: not using D2D.");
return;
}
if (!isImsConnection()) {
- Log.d(this, "maybeConfigureDeviceToDeviceCommunication: not an IMS connection.");
+ Log.i(this, "maybeConfigureDeviceToDeviceCommunication: not an IMS connection.");
return;
}
+ if (mTreatAsEmergencyCall || mIsNetworkIdentifiedEmergencyCall) {
+ Log.i(this, "maybeConfigureDeviceToDeviceCommunication: emergency call; no D2D");
+ return;
+ }
+
// Implement abstracted out RTP functionality the RTP transport depends on.
RtpAdapter rtpAdapter = new RtpAdapter() {
@Override
@@ -3309,8 +3331,11 @@
if (!isImsConnection()) {
Log.w(TelephonyConnection.this, "sendRtpHeaderExtensions: not an ims conn.");
}
- Log.d(TelephonyConnection.this, "sendRtpHeaderExtensions: sending %d messages",
- rtpHeaderExtensions.size());
+
+ Log.i(TelephonyConnection.this, "sendRtpHeaderExtensions: sending: %s",
+ rtpHeaderExtensions.stream()
+ .map(r -> r.toString())
+ .collect(Collectors.joining(",")));
ImsPhoneConnection originalConnection =
(ImsPhoneConnection) mOriginalConnection;
originalConnection.sendRtpHeaderExtensions(rtpHeaderExtensions);
@@ -3322,10 +3347,12 @@
if (!isImsConnection()) {
Log.w(TelephonyConnection.this, "sendDtmf: not an ims conn.");
}
- Log.d(TelephonyConnection.this, "sendDtmf: send digit %c", digit);
+ Log.i(TelephonyConnection.this, "sendDtmf: send digit %c", digit);
ImsPhoneConnection originalConnection =
(ImsPhoneConnection) mOriginalConnection;
- originalConnection.getImsCall().sendDtmf(digit, null /* result msg not needed */);
+ Message dtmfComplete = mHandler.obtainMessage(MSG_DTMF_DONE);
+ dtmfComplete.replyTo = mHandlerMessenger;
+ originalConnection.getImsCall().sendDtmf(digit, dtmfComplete);
};
ContentResolver cr = getPhone().getContext().getContentResolver();
mDtmfTransport = new DtmfTransport(dtmfAdapter, new Timeouts.Adapter(cr),
diff --git a/src/com/android/services/telephony/TelephonyConnectionService.java b/src/com/android/services/telephony/TelephonyConnectionService.java
index 219c782..0803178 100644
--- a/src/com/android/services/telephony/TelephonyConnectionService.java
+++ b/src/com/android/services/telephony/TelephonyConnectionService.java
@@ -2538,6 +2538,26 @@
});
}
+ /**
+ * Overrides the current D2D transport, forcing the specified one to be active. Used for test.
+ * @param transport The class simple name of the transport to make active.
+ */
+ public void setActiveDeviceToDeviceTransport(@NonNull String transport) {
+ getAllConnections().stream()
+ .filter(f -> f instanceof TelephonyConnection)
+ .forEach(t -> {
+ TelephonyConnection tc = (TelephonyConnection) t;
+ Communicator c = tc.getCommunicator();
+ if (c == null) {
+ Log.w(this, "setActiveDeviceToDeviceTransport: D2D not enabled");
+ return;
+ }
+ Log.i(this, "setActiveDeviceToDeviceTransport: callId=%s, set to: %s",
+ tc.getTelecomCallId(), transport);
+ c.setTransportActive(transport);
+ });
+ }
+
private PhoneAccountHandle adjustAccountHandle(Phone phone,
PhoneAccountHandle origAccountHandle) {
int origSubId = PhoneUtils.getSubIdForPhoneAccountHandle(origAccountHandle);