Add telephony shell command to force D2D communications enabled.

This command is used for CTS testing to force override D2D on.

Test: Added CTS test leveraging the new command.
Test: Manual test to verify command operation.
Bug: 183239479
Change-Id: Iad10239ca6621710b11208fe05216a86120ab976
diff --git a/src/com/android/phone/PhoneInterfaceManager.java b/src/com/android/phone/PhoneInterfaceManager.java
index b355e9b..58d0218 100755
--- a/src/com/android/phone/PhoneInterfaceManager.java
+++ b/src/com/android/phone/PhoneInterfaceManager.java
@@ -140,6 +140,7 @@
 import com.android.internal.telephony.CallForwardInfo;
 import com.android.internal.telephony.CallManager;
 import com.android.internal.telephony.CallStateException;
+import com.android.internal.telephony.CallTracker;
 import com.android.internal.telephony.CarrierResolver;
 import com.android.internal.telephony.CellNetworkScanResult;
 import com.android.internal.telephony.CommandException;
@@ -10244,6 +10245,32 @@
         }
     }
 
+    @Override
+    public void setDeviceToDeviceForceEnabled(boolean isForceEnabled) {
+        TelephonyPermissions.enforceShellOnly(Binder.getCallingUid(),
+                "setDeviceToDeviceForceEnabled");
+
+        final long identity = Binder.clearCallingIdentity();
+        try {
+            Arrays.stream(PhoneFactory.getPhones()).forEach(
+                    p -> {
+                        Phone thePhone = p.getImsPhone();
+                        if (thePhone != null && thePhone instanceof ImsPhone) {
+                            ImsPhone imsPhone = (ImsPhone) thePhone;
+                            CallTracker tracker = imsPhone.getCallTracker();
+                            if (tracker != null && tracker instanceof ImsPhoneCallTracker) {
+                                ImsPhoneCallTracker imsPhoneCallTracker =
+                                        (ImsPhoneCallTracker) tracker;
+                                imsPhoneCallTracker.setDeviceToDeviceForceEnabled(isForceEnabled);
+                            }
+                        }
+                    }
+            );
+        } 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 d2a3c40..c83ea64 100644
--- a/src/com/android/phone/TelephonyShellCommand.java
+++ b/src/com/android/phone/TelephonyShellCommand.java
@@ -133,6 +133,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 D2D_SET_DEVICE_SUPPORT = "set-device-support";
 
     private static final String BARRING_SUBCOMMAND = "barring";
     private static final String BARRING_SEND_INFO = "send";
@@ -383,6 +384,10 @@
         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.");
+        pw.println("  d2d set-device-support true/default");
+        pw.println("    true - forces device support to be enabled for D2D.");
+        pw.println("    default - clear any previously set force-enable of D2D, reverting to ");
+        pw.println("    the current device's configuration.");
     }
 
     private void onHelpBarring() {
@@ -916,6 +921,9 @@
             case D2D_TRANSPORT: {
                 return handleD2dTransportCommand();
             }
+            case D2D_SET_DEVICE_SUPPORT: {
+                return handleD2dDeviceSupportedCommand();
+            }
         }
 
         return -1;
@@ -1067,6 +1075,26 @@
         return 0;
     }
 
+    private int handleD2dDeviceSupportedCommand() {
+        PrintWriter errPw = getErrPrintWriter();
+
+        String arg = getNextArg();
+        if (arg == null) {
+            onHelpD2D();
+            return 0;
+        }
+
+        boolean isEnabled = "true".equals(arg.toLowerCase());
+        try {
+            mInterface.setDeviceToDeviceForceEnabled(isEnabled);
+        } catch (RemoteException e) {
+            Log.w(LOG_TAG, "Error forcing D2D enabled: " + e.getMessage());
+            errPw.println("Exception: " + e.getMessage());
+            return -1;
+        }
+        return 0;
+    }
+
     // ims set-ims-service
     private int handleImsSetServiceCommand() {
         PrintWriter errPw = getErrPrintWriter();