Added support for FDN Check in
Supplementary Services(SS).

If FDN is available and enabled, then only SS whose control strings are
present in FDN list are allowed.

Bug: 218262162
Test: Manual
      atest com.android.internal.telephony.GsmCdmaPhoneTest
      atest com.android.internal.telephony.gsm.GsmMmiCodeTest
      atest com.android.internal.telephony.FdnUtilsTest
Change-Id: Ifde290a188e002b5d05e210c34a50a6bf2551863
diff --git a/src/java/com/android/internal/telephony/FdnUtils.java b/src/java/com/android/internal/telephony/FdnUtils.java
index 5ad6ce4..aa2bcfd 100644
--- a/src/java/com/android/internal/telephony/FdnUtils.java
+++ b/src/java/com/android/internal/telephony/FdnUtils.java
@@ -75,6 +75,29 @@
     }
 
     /**
+     * If FDN is enabled, check to see if the given supplementary service control strings are
+     * blocked due to FDN.
+     * @param phoneId The phone object id for which the FDN check is performed
+     * @param controlStrings control strings associated with the supplementary service request
+     * @param defaultCountryIso country ISO for the subscription associated with this phone
+     * @return {@code true} if the FDN list does not contain any of the control strings.
+     */
+    public static boolean isSuppServiceRequestBlockedByFdn(int phoneId,
+            ArrayList<String> controlStrings, String defaultCountryIso) {
+        if (!isFdnEnabled(phoneId)) {
+            return false;
+        }
+
+        ArrayList<AdnRecord> fdnList = getFdnList(phoneId);
+        for(String controlString : controlStrings) {
+            if(isFDN(controlString, defaultCountryIso, fdnList)) {
+                return false;
+            }
+        }
+        return true;
+    }
+
+    /**
      * Checks if dialStr is part of FDN list.
      *
      * @param fdnList List of all FDN records associated with a sim card
diff --git a/src/java/com/android/internal/telephony/GsmCdmaPhone.java b/src/java/com/android/internal/telephony/GsmCdmaPhone.java
index 1d3c3e5..892f336 100644
--- a/src/java/com/android/internal/telephony/GsmCdmaPhone.java
+++ b/src/java/com/android/internal/telephony/GsmCdmaPhone.java
@@ -99,6 +99,7 @@
 import com.android.internal.telephony.dataconnection.TransportManager;
 import com.android.internal.telephony.emergency.EmergencyNumberTracker;
 import com.android.internal.telephony.gsm.GsmMmiCode;
+import com.android.internal.telephony.gsm.SsData;
 import com.android.internal.telephony.gsm.SuppServiceNotification;
 import com.android.internal.telephony.imsphone.ImsPhone;
 import com.android.internal.telephony.imsphone.ImsPhoneCallTracker;
@@ -1697,6 +1698,13 @@
             return true;
         }
 
+        // Perform FDN check
+        if(FdnUtils.isNumberBlockedByFDN(mPhoneId, ussdRequest, getCountryIso())) {
+            sendUssdResponse(ussdRequest, null, TelephonyManager.USSD_RETURN_FAILURE,
+                    wrappedCallback );
+            return true;
+        }
+
         // Try over IMS if possible.
         Phone imsPhone = mImsPhone;
         if ((imsPhone != null)
@@ -2340,6 +2348,15 @@
     @Override
     public void getCallForwardingOption(int commandInterfaceCFReason, int serviceClass,
             Message onComplete) {
+        // Perform FDN check
+        SsData.ServiceType serviceType = GsmMmiCode.cfReasonToServiceType(commandInterfaceCFReason);
+        if(isRequestBlockedByFDN(SsData.RequestType.SS_INTERROGATION, serviceType)) {
+            AsyncResult.forMessage(onComplete, null,
+                    new CommandException(CommandException.Error.FDN_CHECK_FAILURE));
+            onComplete.sendToTarget();
+            return;
+        }
+
         Phone imsPhone = mImsPhone;
         if (useSsOverIms(onComplete)) {
             imsPhone.getCallForwardingOption(commandInterfaceCFReason, serviceClass, onComplete);
@@ -2389,6 +2406,16 @@
             int serviceClass,
             int timerSeconds,
             Message onComplete) {
+        // Perform FDN check
+        SsData.RequestType requestType = GsmMmiCode.cfActionToRequestType(commandInterfaceCFAction);
+        SsData.ServiceType serviceType = GsmMmiCode.cfReasonToServiceType(commandInterfaceCFReason);
+        if(isRequestBlockedByFDN(requestType, serviceType)) {
+            AsyncResult.forMessage(onComplete, null,
+                    new CommandException(CommandException.Error.FDN_CHECK_FAILURE));
+            onComplete.sendToTarget();
+            return;
+        }
+
         Phone imsPhone = mImsPhone;
         if (useSsOverIms(onComplete)) {
             imsPhone.setCallForwardingOption(commandInterfaceCFAction, commandInterfaceCFReason,
@@ -2442,6 +2469,15 @@
     @Override
     public void getCallBarring(String facility, String password, Message onComplete,
             int serviceClass) {
+        // Perform FDN check
+        SsData.ServiceType serviceType = GsmMmiCode.cbFacilityToServiceType(facility);
+        if (isRequestBlockedByFDN(SsData.RequestType.SS_INTERROGATION, serviceType)) {
+            AsyncResult.forMessage(onComplete, null,
+                    new CommandException(CommandException.Error.FDN_CHECK_FAILURE));
+            onComplete.sendToTarget();
+            return;
+        }
+
         Phone imsPhone = mImsPhone;
         if (useSsOverIms(onComplete)) {
             imsPhone.getCallBarring(facility, password, onComplete, serviceClass);
@@ -2458,6 +2494,17 @@
     @Override
     public void setCallBarring(String facility, boolean lockState, String password,
             Message onComplete, int serviceClass) {
+        // Perform FDN check
+        SsData.RequestType requestType = lockState ? SsData.RequestType.SS_ACTIVATION :
+                SsData.RequestType.SS_DEACTIVATION;
+        SsData.ServiceType serviceType = GsmMmiCode.cbFacilityToServiceType(facility);
+        if (isRequestBlockedByFDN(requestType, serviceType)) {
+            AsyncResult.forMessage(onComplete, null,
+                    new CommandException(CommandException.Error.FDN_CHECK_FAILURE));
+            onComplete.sendToTarget();
+            return;
+        }
+
         Phone imsPhone = mImsPhone;
         if (useSsOverIms(onComplete)) {
             imsPhone.setCallBarring(facility, lockState, password, onComplete, serviceClass);
@@ -2481,6 +2528,18 @@
      */
     public void changeCallBarringPassword(String facility, String oldPwd, String newPwd,
             Message onComplete) {
+        // Perform FDN check
+        SsData.ServiceType serviceType = GsmMmiCode.cbFacilityToServiceType(facility);
+        ArrayList<String> controlStrings = GsmMmiCode.getControlStringsForPwd(
+                SsData.RequestType.SS_REGISTRATION,
+                serviceType);
+        if(FdnUtils.isSuppServiceRequestBlockedByFdn(mPhoneId, controlStrings, getCountryIso())) {
+            AsyncResult.forMessage(onComplete, null,
+                    new CommandException(CommandException.Error.FDN_CHECK_FAILURE));
+            onComplete.sendToTarget();
+            return;
+        }
+
         if (isPhoneTypeGsm()) {
             mCi.changeBarringPassword(facility, oldPwd, newPwd, onComplete);
         } else {
@@ -2490,6 +2549,14 @@
 
     @Override
     public void getOutgoingCallerIdDisplay(Message onComplete) {
+        // Perform FDN check
+        if(isRequestBlockedByFDN(SsData.RequestType.SS_INTERROGATION, SsData.ServiceType.SS_CLIR)){
+            AsyncResult.forMessage(onComplete, null,
+                    new CommandException(CommandException.Error.FDN_CHECK_FAILURE));
+            onComplete.sendToTarget();
+            return;
+        }
+
         Phone imsPhone = mImsPhone;
         if (useSsOverIms(onComplete)) {
             imsPhone.getOutgoingCallerIdDisplay(onComplete);
@@ -2508,6 +2575,15 @@
 
     @Override
     public void setOutgoingCallerIdDisplay(int commandInterfaceCLIRMode, Message onComplete) {
+        // Perform FDN check
+        SsData.RequestType requestType = GsmMmiCode.clirModeToRequestType(commandInterfaceCLIRMode);
+        if (isRequestBlockedByFDN(requestType, SsData.ServiceType.SS_CLIR)) {
+            AsyncResult.forMessage(onComplete, null,
+                    new CommandException(CommandException.Error.FDN_CHECK_FAILURE));
+            onComplete.sendToTarget();
+            return;
+        }
+
         Phone imsPhone = mImsPhone;
         if (useSsOverIms(onComplete)) {
             imsPhone.setOutgoingCallerIdDisplay(commandInterfaceCLIRMode, onComplete);
@@ -2530,6 +2606,14 @@
 
     @Override
     public void queryCLIP(Message onComplete) {
+        // Perform FDN check
+        if(isRequestBlockedByFDN(SsData.RequestType.SS_INTERROGATION, SsData.ServiceType.SS_CLIP)){
+            AsyncResult.forMessage(onComplete, null,
+                    new CommandException(CommandException.Error.FDN_CHECK_FAILURE));
+            onComplete.sendToTarget();
+            return;
+        }
+
         Phone imsPhone = mImsPhone;
         if (useSsOverIms(onComplete)) {
             imsPhone.queryCLIP(onComplete);
@@ -2548,6 +2632,14 @@
 
     @Override
     public void getCallWaiting(Message onComplete) {
+        // Perform FDN check
+        if(isRequestBlockedByFDN(SsData.RequestType.SS_INTERROGATION, SsData.ServiceType.SS_WAIT)){
+            AsyncResult.forMessage(onComplete, null,
+                    new CommandException(CommandException.Error.FDN_CHECK_FAILURE));
+            onComplete.sendToTarget();
+            return;
+        }
+
         Phone imsPhone = mImsPhone;
         if (useSsOverIms(onComplete)) {
             imsPhone.getCallWaiting(onComplete);
@@ -2589,6 +2681,16 @@
 
     @Override
     public void setCallWaiting(boolean enable, int serviceClass, Message onComplete) {
+        // Perform FDN check
+        SsData.RequestType requestType = enable ? SsData.RequestType.SS_ACTIVATION :
+                SsData.RequestType.SS_DEACTIVATION;
+        if (isRequestBlockedByFDN(requestType, SsData.ServiceType.SS_WAIT)) {
+            AsyncResult.forMessage(onComplete, null,
+                    new CommandException(CommandException.Error.FDN_CHECK_FAILURE));
+            onComplete.sendToTarget();
+            return;
+        }
+
         Phone imsPhone = mImsPhone;
         if (useSsOverIms(onComplete)) {
             imsPhone.setCallWaiting(enable, onComplete);
@@ -4921,4 +5023,16 @@
     public InboundSmsHandler getInboundSmsHandler(boolean is3gpp2) {
         return mIccSmsInterfaceManager.getInboundSmsHandler(is3gpp2);
     }
-}
+
+    /**
+     * The following function checks if supplementary service request is blocked due to FDN.
+     * @param requestType request type associated with the supplementary service
+     * @param serviceType supplementary service type
+     * @return {@code true} if request is blocked due to FDN.
+     */
+    private boolean isRequestBlockedByFDN(SsData.RequestType requestType,
+            SsData.ServiceType serviceType) {
+        ArrayList<String> controlStrings = GsmMmiCode.getControlStrings(requestType, serviceType);
+        return FdnUtils.isSuppServiceRequestBlockedByFdn(mPhoneId, controlStrings, getCountryIso());
+    }
+}
\ No newline at end of file
diff --git a/src/java/com/android/internal/telephony/SmsController.java b/src/java/com/android/internal/telephony/SmsController.java
index 0cd7d29..589a0d7 100644
--- a/src/java/com/android/internal/telephony/SmsController.java
+++ b/src/java/com/android/internal/telephony/SmsController.java
@@ -902,7 +902,7 @@
      */
     private boolean isNumberBlockedByFDN(int subId, String destAddr, String callingPackage) {
         int phoneId = SubscriptionManager.getPhoneId(subId);
-        if (!FdnUtils.isFdnEnabled(subId)) {
+        if (!FdnUtils.isFdnEnabled(phoneId)) {
             return false;
         }
 
diff --git a/src/java/com/android/internal/telephony/gsm/GsmMmiCode.java b/src/java/com/android/internal/telephony/gsm/GsmMmiCode.java
index dec2468..1353511 100644
--- a/src/java/com/android/internal/telephony/gsm/GsmMmiCode.java
+++ b/src/java/com/android/internal/telephony/gsm/GsmMmiCode.java
@@ -61,6 +61,7 @@
 import com.android.internal.telephony.util.ArrayUtils;
 import com.android.telephony.Rlog;
 
+import java.util.ArrayList;
 import java.util.regex.Matcher;
 import java.util.regex.Pattern;
 
@@ -455,7 +456,7 @@
         return "";
     }
 
-    private String getActionStringFromReqType(SsData.RequestType rType) {
+    private static String getActionStringFromReqType(SsData.RequestType rType) {
         switch (rType) {
             case SS_ACTIVATION:
                 return ACTION_ACTIVATE;
@@ -520,6 +521,40 @@
         }
     }
 
+    public static SsData.ServiceType cfReasonToServiceType(int commandInterfaceCFReason) {
+        switch (commandInterfaceCFReason) {
+            case CommandsInterface.CF_REASON_UNCONDITIONAL:
+                return  SsData.ServiceType.SS_CFU;
+            case CommandsInterface.CF_REASON_BUSY:
+                return SsData.ServiceType.SS_CF_BUSY;
+            case CommandsInterface.CF_REASON_NO_REPLY:
+                return SsData.ServiceType.SS_CF_NO_REPLY;
+            case CommandsInterface.CF_REASON_NOT_REACHABLE:
+                return SsData.ServiceType.SS_CF_NOT_REACHABLE;
+            case CommandsInterface.CF_REASON_ALL:
+                return SsData.ServiceType.SS_CF_ALL;
+            case CommandsInterface.CF_REASON_ALL_CONDITIONAL:
+                return SsData.ServiceType.SS_CF_ALL_CONDITIONAL;
+            default:
+                return null;
+        }
+    }
+
+    public static SsData.RequestType cfActionToRequestType(int commandInterfaceCFAction) {
+        switch (commandInterfaceCFAction) {
+            case CommandsInterface.CF_ACTION_DISABLE:
+                return SsData.RequestType.SS_DEACTIVATION;
+            case CommandsInterface.CF_ACTION_ENABLE:
+                return SsData.RequestType.SS_ACTIVATION;
+            case CommandsInterface.CF_ACTION_REGISTRATION:
+                return SsData.RequestType.SS_REGISTRATION;
+            case CommandsInterface.CF_ACTION_ERASURE:
+                return SsData.RequestType.SS_ERASURE;
+            default:
+                return null;
+        }
+    }
+
     @UnsupportedAppUsage
     private static int
     siToServiceClass(String si) {
@@ -623,6 +658,29 @@
         }
     }
 
+    public static SsData.ServiceType cbFacilityToServiceType(String commandInterfaceCBFacility) {
+        switch(commandInterfaceCBFacility) {
+            case CommandsInterface.CB_FACILITY_BAOC:
+                return SsData.ServiceType.SS_BAOC;
+            case CommandsInterface.CB_FACILITY_BAOIC:
+                return SsData.ServiceType.SS_BAOIC;
+            case CommandsInterface.CB_FACILITY_BAOICxH:
+                return SsData.ServiceType.SS_BAOIC_EXC_HOME;
+            case CommandsInterface.CB_FACILITY_BAIC:
+                return SsData.ServiceType.SS_BAIC;
+            case CommandsInterface.CB_FACILITY_BAICr:
+                return SsData.ServiceType.SS_BAIC_ROAMING;
+            case CommandsInterface.CB_FACILITY_BA_ALL:
+                return SsData.ServiceType.SS_ALL_BARRING;
+            case CommandsInterface.CB_FACILITY_BA_MO:
+                return SsData.ServiceType.SS_OUTGOING_BARRING;
+            case CommandsInterface.CB_FACILITY_BA_MT:
+                return SsData.ServiceType.SS_INCOMING_BARRING;
+            default:
+                return null;
+        }
+    }
+
     //***** Constructor
 
     @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
@@ -892,6 +950,17 @@
         return CommandsInterface.CLIR_DEFAULT;
     }
 
+    public static SsData.RequestType clirModeToRequestType(int commandInterfaceCLIRMode) {
+        switch (commandInterfaceCLIRMode) {
+            case CommandsInterface.CLIR_SUPPRESSION:
+                return SsData.RequestType.SS_ACTIVATION;
+            case CommandsInterface.CLIR_INVOCATION:
+                return SsData.RequestType.SS_DEACTIVATION;
+            default:
+                return null;
+        }
+    }
+
     /**
      * Returns true if the Service Code is FAC to dial as a normal call.
      *
@@ -1827,6 +1896,120 @@
         return this.mCallbackReceiver;
     }
 
+    /**
+     * Returns list of control strings for a supplementary service request
+     * as defined in TS 22.030 6.5
+     * @param requestType request type associated with the supplementary service
+     * @param serviceType supplementary service type
+     * @return list of control strings associated with the supplementary service.
+     */
+    public static ArrayList<String> getControlStrings(SsData.RequestType requestType,
+            SsData.ServiceType serviceType) {
+        ArrayList<String> controlStrings = new ArrayList<>();
+        if (requestType == null || serviceType == null) {
+            return controlStrings;
+        }
+
+        String actionStr = getActionStringFromReqType(requestType);
+        switch (serviceType) {
+            case SS_CFU:
+                controlStrings.add(actionStr + SC_CFU);
+                controlStrings.add(actionStr + SC_CF_All);
+                break;
+            case SS_CF_BUSY:
+                controlStrings.add(actionStr + SC_CFB);
+                controlStrings.add(actionStr + SC_CF_All_Conditional);
+                controlStrings.add(actionStr + SC_CF_All);
+                break;
+            case SS_CF_NO_REPLY:
+                controlStrings.add(actionStr + SC_CFNRy);
+                controlStrings.add(actionStr + SC_CF_All_Conditional);
+                controlStrings.add(actionStr + SC_CF_All);
+                break;
+            case SS_CF_NOT_REACHABLE:
+                controlStrings.add(actionStr + SC_CFNR);
+                controlStrings.add(actionStr + SC_CF_All_Conditional);
+                controlStrings.add(actionStr + SC_CF_All);
+                break;
+            case SS_CF_ALL:
+                controlStrings.add(actionStr + SC_CF_All);
+                break;
+            case SS_CF_ALL_CONDITIONAL:
+                controlStrings.add(actionStr + SC_CF_All_Conditional);
+                controlStrings.add(actionStr + SC_CF_All);
+                break;
+            case SS_CLIP:
+                controlStrings.add(actionStr + SC_CLIP);
+                break;
+            case SS_CLIR:
+                controlStrings.add(actionStr + SC_CLIR);
+                break;
+            case SS_WAIT:
+                controlStrings.add(actionStr + SC_WAIT);
+                break;
+            case SS_BAOC:
+                controlStrings.add(actionStr + SC_BAOC);
+                controlStrings.add(actionStr + SC_BA_MO);
+                controlStrings.add(actionStr + SC_BA_ALL);
+                break;
+            case SS_BAOIC:
+                controlStrings.add(actionStr + SC_BAOIC);
+                controlStrings.add(actionStr + SC_BA_MO);
+                controlStrings.add(actionStr + SC_BA_ALL);
+                break;
+            case SS_BAOIC_EXC_HOME:
+                controlStrings.add(actionStr + SC_BAOICxH);
+                controlStrings.add(actionStr + SC_BA_MO);
+                controlStrings.add(actionStr + SC_BA_ALL);
+                break;
+            case SS_BAIC:
+                controlStrings.add(actionStr + SC_BAIC);
+                controlStrings.add(actionStr + SC_BA_MT);
+                controlStrings.add(actionStr + SC_BA_ALL);
+                break;
+            case SS_BAIC_ROAMING:
+                controlStrings.add(actionStr + SC_BAICr);
+                controlStrings.add(actionStr + SC_BA_MT);
+                controlStrings.add(actionStr + SC_BA_ALL);
+                break;
+            case SS_ALL_BARRING:
+                controlStrings.add(actionStr + SC_BA_ALL);
+                break;
+            case SS_OUTGOING_BARRING:
+                controlStrings.add(actionStr + SC_BA_MO);
+                controlStrings.add(actionStr + SC_BA_ALL);
+                break;
+            case SS_INCOMING_BARRING:
+                controlStrings.add(actionStr + SC_BA_MT);
+                controlStrings.add(actionStr + SC_BA_ALL);
+                break;
+        }
+       return controlStrings;
+    }
+
+    /**
+     * Returns control strings for registration of new password as per TS 22.030 6.5.4
+     * @param requestType request type associated with the supplementary service
+     * @param serviceType supplementary service type
+     * @return list of control strings for new password registration.
+     */
+    public static ArrayList<String> getControlStringsForPwd(SsData.RequestType requestType,
+            SsData.ServiceType serviceType) {
+        ArrayList<String> controlStrings = new ArrayList<>();
+        if (requestType == null || serviceType == null) {
+            return controlStrings;
+        }
+
+        controlStrings = getControlStrings(SsData.RequestType.SS_ACTIVATION, serviceType);
+        String actionStr = getActionStringFromReqType(requestType);
+        ArrayList<String> controlStringsPwd = new ArrayList<>();
+        for(String controlString : controlStrings) {
+            // Prepend each control string with **SC_PWD
+            controlStringsPwd.add(actionStr + SC_PWD + controlString);
+        }
+        return controlStringsPwd;
+    }
+
     /***
      * TODO: It would be nice to have a method here that can take in a dialstring and
      * figure out if there is an MMI code embedded within it.  This code would replace
diff --git a/tests/telephonytests/src/com/android/internal/telephony/GsmCdmaPhoneTest.java b/tests/telephonytests/src/com/android/internal/telephony/GsmCdmaPhoneTest.java
index 54b9a1d..e5a1fe1 100644
--- a/tests/telephonytests/src/com/android/internal/telephony/GsmCdmaPhoneTest.java
+++ b/tests/telephonytests/src/com/android/internal/telephony/GsmCdmaPhoneTest.java
@@ -78,8 +78,11 @@
 import com.android.internal.telephony.imsphone.ImsPhone;
 import com.android.internal.telephony.test.SimulatedCommands;
 import com.android.internal.telephony.test.SimulatedCommandsVerifier;
+import com.android.internal.telephony.uicc.AdnRecord;
+import com.android.internal.telephony.uicc.AdnRecordCache;
 import com.android.internal.telephony.uicc.IccCardApplicationStatus;
 import com.android.internal.telephony.uicc.IccCardStatus;
+import com.android.internal.telephony.uicc.IccConstants;
 import com.android.internal.telephony.uicc.IccRecords;
 import com.android.internal.telephony.uicc.IccVmNotSupportedException;
 import com.android.internal.telephony.uicc.UiccController;
@@ -109,6 +112,7 @@
     private UiccSlot mUiccSlot;
     private UiccPort mUiccPort;
     private CommandsInterface mMockCi;
+    private AdnRecordCache adnRecordCache;
 
     //mPhoneUnderTest
     private GsmCdmaPhone mPhoneUT;
@@ -140,6 +144,7 @@
         mUiccSlot = Mockito.mock(UiccSlot.class);
         mUiccPort = Mockito.mock(UiccPort.class);
         mMockCi = Mockito.mock(CommandsInterface.class);
+        adnRecordCache = Mockito.mock(AdnRecordCache.class);
         doReturn(false).when(mSST).isDeviceShuttingDown();
         doReturn(true).when(mImsManager).isVolteEnabledByPlatform();
 
@@ -1875,4 +1880,304 @@
         processAllMessages();
         verify(mMockCi, never()).setUsageSetting(any(), anyInt());
     }
+
+    public void fdnCheckSetup() {
+        // FDN check setup
+        mPhoneUT.mCi = mMockCi;
+        doReturn(adnRecordCache).when(mSimRecords).getAdnCache();
+        doReturn(mUiccProfile).when(mUiccController).getUiccProfileForPhone(anyInt());
+        doReturn(true).when(mUiccCardApplication3gpp).getIccFdnAvailable();
+        doReturn(true).when(mUiccCardApplication3gpp).getIccFdnEnabled();
+    }
+
+    @Test
+    public void testGetCallForwardingOption_FdnCheck() {
+        // FDN check setup
+        fdnCheckSetup();
+        ArrayList<AdnRecord> fdnList = new ArrayList<>();
+        doReturn(fdnList).when(adnRecordCache).getRecordsIfLoaded(IccConstants.EF_FDN);
+        Message message = Message.obtain(mTestHandler);
+
+        // FDN check success - no exception is returned
+        AdnRecord adnRecord = new AdnRecord(null, "*#21");
+        fdnList.add(0, adnRecord);
+        mPhoneUT.getCallForwardingOption(CommandsInterface.CF_REASON_UNCONDITIONAL, message);
+        processAllMessages();
+        verify(mMockCi).queryCallForwardStatus(eq(CommandsInterface.CF_REASON_UNCONDITIONAL),
+                eq(CommandsInterface.SERVICE_CLASS_VOICE), any(), any());
+        // FDN check failure - returns CommandException in onComplete
+        fdnList.remove(0);
+        mPhoneUT.getCallForwardingOption(CommandsInterface.CF_REASON_UNCONDITIONAL, message);
+        processAllMessages();
+        AsyncResult ar = (AsyncResult) message.obj;
+        assertTrue(ar.exception instanceof CommandException);
+        assertEquals(((CommandException) ar.exception).getCommandError(),
+                CommandException.Error.FDN_CHECK_FAILURE);
+
+        // clean up
+        fdnCheckCleanup();
+    }
+
+    @Test
+    public void testSetCallForwardingOption_FdnCheck() {
+        // FDN check setup
+        fdnCheckSetup();
+        ArrayList<AdnRecord> fdnList = new ArrayList<>();
+        doReturn(fdnList).when(adnRecordCache).getRecordsIfLoaded(IccConstants.EF_FDN);
+        Message message = Message.obtain(mTestHandler);
+
+        // FDN check success - no exception is returned
+        AdnRecord adnRecord = new AdnRecord(null, "**21");
+        fdnList.add(0, adnRecord);
+        mPhoneUT.setCallForwardingOption(CommandsInterface.CF_ACTION_REGISTRATION,
+                CommandsInterface.CF_REASON_UNCONDITIONAL, "123", 0,
+                message);
+        processAllMessages();
+        verify(mMockCi).setCallForward(eq(CommandsInterface.CF_ACTION_REGISTRATION),
+                eq(CommandsInterface.CF_REASON_UNCONDITIONAL),
+                eq(CommandsInterface.SERVICE_CLASS_VOICE), eq("123"), eq(0), any());
+        // FDN check failure - returns CommandException in onComplete
+        fdnList.remove(0);
+        mPhoneUT.setCallForwardingOption(CommandsInterface.CF_ACTION_REGISTRATION,
+                CommandsInterface.CF_REASON_UNCONDITIONAL, "", 0, message);
+        processAllMessages();
+        AsyncResult ar = (AsyncResult) message.obj;
+        assertTrue(ar.exception instanceof CommandException);
+        assertEquals(((CommandException) ar.exception).getCommandError(),
+                CommandException.Error.FDN_CHECK_FAILURE);
+
+        // clean up
+        fdnCheckCleanup();
+    }
+
+    @Test
+    public void testGetCallBarring_FdnCheck() {
+        // FDN check setup
+        fdnCheckSetup();
+        ArrayList<AdnRecord> fdnList = new ArrayList<>();
+        doReturn(fdnList).when(adnRecordCache).getRecordsIfLoaded(IccConstants.EF_FDN);
+        Message message = Message.obtain(mTestHandler);
+
+        // FDN check success - no exception is returned
+        AdnRecord adnRecord = new AdnRecord(null, "*#330");
+        fdnList.add(0, adnRecord);
+        mPhoneUT.getCallBarring(CommandsInterface.CB_FACILITY_BA_ALL, "", message,
+                CommandsInterface.SERVICE_CLASS_VOICE);
+        processAllMessages();
+        verify(mMockCi).queryFacilityLock(eq(CommandsInterface.CB_FACILITY_BA_ALL), any(),
+                eq(CommandsInterface.SERVICE_CLASS_VOICE), any());
+        // FDN check failure - returns CommandException in onComplete
+        fdnList.remove(0);
+        mPhoneUT.getCallBarring(CommandsInterface.CB_FACILITY_BA_ALL, "", message,
+                CommandsInterface.SERVICE_CLASS_VOICE);
+        processAllMessages();
+        AsyncResult ar = (AsyncResult) message.obj;
+        assertTrue(ar.exception instanceof CommandException);
+        assertEquals(((CommandException) ar.exception).getCommandError(),
+                CommandException.Error.FDN_CHECK_FAILURE);
+
+        // clean up
+        fdnCheckCleanup();
+    }
+
+    @Test
+    public void testSetCallBarring_FdnCheck() {
+        // FDN check setup
+        fdnCheckSetup();
+        ArrayList<AdnRecord> fdnList = new ArrayList<>();
+        doReturn(fdnList).when(adnRecordCache).getRecordsIfLoaded(IccConstants.EF_FDN);
+        Message message = Message.obtain(mTestHandler);
+
+        // FDN check success - no exception is returned
+        AdnRecord adnRecord = new AdnRecord(null, "*330");
+        fdnList.add(0, adnRecord);
+        mPhoneUT.setCallBarring(CommandsInterface.CB_FACILITY_BA_ALL, true, "",
+                message, CommandsInterface.SERVICE_CLASS_VOICE);
+        processAllMessages();
+        verify(mMockCi).setFacilityLock(eq(CommandsInterface.CB_FACILITY_BA_ALL),
+                eq(true), any(), eq(CommandsInterface.SERVICE_CLASS_VOICE), any());
+        // FDN check failure - returns CommandException in onComplete
+        fdnList.remove(0);
+        mPhoneUT.setCallBarring(CommandsInterface.CB_FACILITY_BA_ALL, true, "",
+                message, CommandsInterface.SERVICE_CLASS_VOICE);
+        processAllMessages();
+        AsyncResult ar = (AsyncResult) message.obj;
+        assertTrue(ar.exception instanceof CommandException);
+        assertEquals(((CommandException) ar.exception).getCommandError(),
+                CommandException.Error.FDN_CHECK_FAILURE);
+
+        // clean up
+        fdnCheckCleanup();
+    }
+
+    @Test
+    public void testChangeCallBarringPassword_FdnCheck() {
+        // FDN check setup
+        fdnCheckSetup();
+        ArrayList<AdnRecord> fdnList = new ArrayList<>();
+        doReturn(fdnList).when(adnRecordCache).getRecordsIfLoaded(IccConstants.EF_FDN);
+        Message message = Message.obtain(mTestHandler);
+
+        // FDN check success - no exception is returned
+        AdnRecord adnRecord = new AdnRecord(null, "**03*330");
+        fdnList.add(0, adnRecord);
+        mPhoneUT.changeCallBarringPassword(CommandsInterface.CB_FACILITY_BA_ALL, "",
+                "", message);
+        processAllMessages();
+        verify(mMockCi).changeBarringPassword(eq(CommandsInterface.CB_FACILITY_BA_ALL), any(),
+                any(), any());
+        // FDN check failure - returns CommandException in onComplete
+        fdnList.remove(0);
+        mPhoneUT.changeCallBarringPassword(CommandsInterface.CB_FACILITY_BA_ALL, "",
+                "", message);
+        processAllMessages();
+        AsyncResult ar = (AsyncResult) message.obj;
+        assertTrue(ar.exception instanceof CommandException);
+        assertEquals(((CommandException) ar.exception).getCommandError(),
+                CommandException.Error.FDN_CHECK_FAILURE);
+
+        // clean up
+        fdnCheckCleanup();
+    }
+
+    @Test
+    public void testGetOutgoingCallerIdDisplay_FdnCheck() {
+        // FDN check setup
+        fdnCheckSetup();
+        ArrayList<AdnRecord> fdnList = new ArrayList<>();
+        doReturn(fdnList).when(adnRecordCache).getRecordsIfLoaded(IccConstants.EF_FDN);
+        Message message = Message.obtain(mTestHandler);
+
+        // FDN check success - no exception is returned
+        AdnRecord adnRecord = new AdnRecord(null, "*#31");
+        fdnList.add(0, adnRecord);
+        mPhoneUT.getOutgoingCallerIdDisplay(message);
+        processAllMessages();
+        verify(mMockCi).getCLIR(any());
+        // FDN check failure - returns CommandException in onComplete
+        fdnList.remove(0);
+        mPhoneUT.getOutgoingCallerIdDisplay(message);
+        processAllMessages();
+        AsyncResult ar = (AsyncResult) message.obj;
+        assertTrue(ar.exception instanceof CommandException);
+        assertEquals(((CommandException) ar.exception).getCommandError(),
+                CommandException.Error.FDN_CHECK_FAILURE);
+
+        // clean up
+        fdnCheckCleanup();
+    }
+
+    @Test
+    public void testSetOutgoingCallerIdDisplay_FdnCheck() {
+        // FDN check setup
+        fdnCheckSetup();
+        ArrayList<AdnRecord> fdnList = new ArrayList<>();
+        doReturn(fdnList).when(adnRecordCache).getRecordsIfLoaded(IccConstants.EF_FDN);
+        Message message = Message.obtain(mTestHandler);
+
+        // FDN check success - no exception is returned
+        AdnRecord adnRecord = new AdnRecord(null, "*31");
+        fdnList.add(0, adnRecord);
+        mPhoneUT.setOutgoingCallerIdDisplay(CommandsInterface.CLIR_SUPPRESSION, message);
+        processAllMessages();
+        verify(mMockCi).setCLIR(eq(CommandsInterface.CLIR_SUPPRESSION), any());
+        // FDN check failure - returns CommandException in onComplete
+        fdnList.remove(0);
+        mPhoneUT.setOutgoingCallerIdDisplay(CommandsInterface.CLIR_SUPPRESSION, message);
+        processAllMessages();
+        AsyncResult ar = (AsyncResult) message.obj;
+        assertTrue(ar.exception instanceof CommandException);
+        assertEquals(((CommandException) ar.exception).getCommandError(),
+                CommandException.Error.FDN_CHECK_FAILURE);
+
+        // clean up
+        fdnCheckCleanup();
+    }
+
+    @Test
+    public void testQueryCLIP_FdnCheck() {
+        // FDN check setup
+        fdnCheckSetup();
+        ArrayList<AdnRecord> fdnList = new ArrayList<>();
+        doReturn(fdnList).when(adnRecordCache).getRecordsIfLoaded(IccConstants.EF_FDN);
+        Message message = Message.obtain(mTestHandler);
+
+        // FDN check success - no exception is returned
+        AdnRecord adnRecord = new AdnRecord(null, "*#30");
+        fdnList.add(0, adnRecord);
+        mPhoneUT.queryCLIP(message);
+        processAllMessages();
+        verify(mMockCi).queryCLIP(any());
+        // FDN check failure - returns CommandException in onComplete
+        fdnList.remove(0);
+        mPhoneUT.queryCLIP(message);
+        processAllMessages();
+        AsyncResult ar = (AsyncResult) message.obj;
+        assertTrue(ar.exception instanceof CommandException);
+        assertEquals(((CommandException) ar.exception).getCommandError(),
+                CommandException.Error.FDN_CHECK_FAILURE);
+
+        // clean up
+        fdnCheckCleanup();
+    }
+
+    @Test
+    public void testGetCallWaiting_FdnCheck() {
+        // FDN check setup
+        fdnCheckSetup();
+        ArrayList<AdnRecord> fdnList = new ArrayList<>();
+        doReturn(fdnList).when(adnRecordCache).getRecordsIfLoaded(IccConstants.EF_FDN);
+        Message message = Message.obtain(mTestHandler);
+
+        // FDN check success - no exception is returned
+        AdnRecord adnRecord = new AdnRecord(null, "*#43");
+        fdnList.add(0, adnRecord);
+        mPhoneUT.getCallWaiting(message);
+        processAllMessages();
+        verify(mMockCi).queryCallWaiting(eq(CommandsInterface.SERVICE_CLASS_NONE), any());
+        // FDN check failure - returns CommandException in onComplete
+        fdnList.remove(0);
+        mPhoneUT.getCallWaiting(message);
+        processAllMessages();
+        AsyncResult ar = (AsyncResult) message.obj;
+        assertTrue(ar.exception instanceof CommandException);
+        assertEquals(((CommandException) ar.exception).getCommandError(),
+                CommandException.Error.FDN_CHECK_FAILURE);
+
+        // clean up
+        fdnCheckCleanup();
+    }
+
+    @Test
+    public void testSetCallWaiting_FdnCheck() {
+        // FDN check setup
+        fdnCheckSetup();
+        ArrayList<AdnRecord> fdnList = new ArrayList<>();
+        doReturn(fdnList).when(adnRecordCache).getRecordsIfLoaded(IccConstants.EF_FDN);
+        Message message = Message.obtain(mTestHandler);
+
+        // FDN check success - no exception is returned
+        AdnRecord adnRecord = new AdnRecord(null, "*43");
+        fdnList.add(0, adnRecord);
+        mPhoneUT.setCallWaiting(true, CommandsInterface.SERVICE_CLASS_VOICE, message);
+        processAllMessages();
+        verify(mMockCi).setCallWaiting(eq(true), eq(CommandsInterface.SERVICE_CLASS_VOICE),
+                any());
+        // FDN check failure - returns CommandException in onComplete
+        fdnList.remove(0);
+        mPhoneUT.setCallWaiting(true, CommandsInterface.SERVICE_CLASS_VOICE, message);
+        processAllMessages();
+        AsyncResult ar = (AsyncResult) message.obj;
+        assertTrue(ar.exception instanceof CommandException);
+        assertEquals(((CommandException) ar.exception).getCommandError(),
+                CommandException.Error.FDN_CHECK_FAILURE);
+
+        // clean up
+        fdnCheckCleanup();
+    }
+
+    public void fdnCheckCleanup() {
+        doReturn(false).when(mUiccCardApplication3gpp).getIccFdnAvailable();
+        doReturn(false).when(mUiccCardApplication3gpp).getIccFdnEnabled();
+    }
 }
diff --git a/tests/telephonytests/src/com/android/internal/telephony/gsm/GsmMmiCodeTest.java b/tests/telephonytests/src/com/android/internal/telephony/gsm/GsmMmiCodeTest.java
index 8c1caa5..70df8aa 100644
--- a/tests/telephonytests/src/com/android/internal/telephony/gsm/GsmMmiCodeTest.java
+++ b/tests/telephonytests/src/com/android/internal/telephony/gsm/GsmMmiCodeTest.java
@@ -16,6 +16,8 @@
 
 package com.android.internal.telephony.gsm;
 
+import static com.google.common.truth.Truth.assertThat;
+
 import static junit.framework.Assert.fail;
 
 import static org.junit.Assert.assertTrue;
@@ -36,6 +38,7 @@
 import org.junit.Test;
 import org.junit.runner.RunWith;
 
+import java.util.ArrayList;
 import java.util.concurrent.Executor;
 
 /**
@@ -102,6 +105,209 @@
         }
     }
 
+    // The main purpose of this test is to list all the valid use cases of getControlStrings().
+    @Test
+    public void testGetControlStrings() {
+        // Test if controlStrings list is empty when inputs are null
+        ArrayList<String> controlStrings = GsmMmiCode.getControlStrings(null,
+                null);
+        assertThat(controlStrings).isEmpty();
+
+        // Test control strings of Call Forwarding Unconditional
+        controlStrings = GsmMmiCode.getControlStrings(SsData.RequestType.SS_INTERROGATION,
+                SsData.ServiceType.SS_CFU);
+        assertThat(controlStrings).containsExactly("*#21", "*#002");
+        controlStrings = GsmMmiCode.getControlStrings(SsData.RequestType.SS_REGISTRATION,
+                SsData.ServiceType.SS_CFU);
+        assertThat(controlStrings).containsExactly("**21", "**002");
+        controlStrings = GsmMmiCode.getControlStrings(SsData.RequestType.SS_DEACTIVATION,
+                SsData.ServiceType.SS_CFU);
+        assertThat(controlStrings).containsExactly("#21", "#002");
+
+        // Test control strings of Call Forwarding Busy
+        controlStrings = GsmMmiCode.getControlStrings(SsData.RequestType.SS_INTERROGATION,
+                SsData.ServiceType.SS_CF_BUSY);
+        assertThat(controlStrings).containsExactly("*#67", "*#004", "*#002");
+        controlStrings = GsmMmiCode.getControlStrings(SsData.RequestType.SS_REGISTRATION,
+                SsData.ServiceType.SS_CF_BUSY);
+        assertThat(controlStrings).containsExactly("**67", "**004", "**002");
+        controlStrings = GsmMmiCode.getControlStrings(SsData.RequestType.SS_DEACTIVATION,
+                SsData.ServiceType.SS_CF_BUSY);
+        assertThat(controlStrings).containsExactly("#67", "#004", "#002");
+
+        // Test control strings of Call Forwarding No Reply
+        controlStrings = GsmMmiCode.getControlStrings(SsData.RequestType.SS_INTERROGATION,
+                SsData.ServiceType.SS_CF_NO_REPLY);
+        assertThat(controlStrings).containsExactly("*#61", "*#004", "*#002");
+        controlStrings = GsmMmiCode.getControlStrings(SsData.RequestType.SS_REGISTRATION,
+                SsData.ServiceType.SS_CF_NO_REPLY);
+        assertThat(controlStrings).containsExactly("**61", "**004", "**002");
+        controlStrings = GsmMmiCode.getControlStrings(SsData.RequestType.SS_DEACTIVATION,
+                SsData.ServiceType.SS_CF_NO_REPLY);
+        assertThat(controlStrings).containsExactly("#61", "#004", "#002");
+
+        // Test control strings of Call Forwarding Not Reachable
+        controlStrings = GsmMmiCode.getControlStrings(SsData.RequestType.SS_INTERROGATION,
+                SsData.ServiceType.SS_CF_NOT_REACHABLE);
+        assertThat(controlStrings).containsExactly("*#62", "*#004", "*#002");
+        controlStrings = GsmMmiCode.getControlStrings(SsData.RequestType.SS_REGISTRATION,
+                SsData.ServiceType.SS_CF_NOT_REACHABLE);
+        assertThat(controlStrings).containsExactly("**62", "**004", "**002");
+        controlStrings = GsmMmiCode.getControlStrings(SsData.RequestType.SS_DEACTIVATION,
+                SsData.ServiceType.SS_CF_NOT_REACHABLE);
+        assertThat(controlStrings).containsExactly("#62", "#004", "#002");
+
+        // Test control strings of Call Forwarding All
+        controlStrings = GsmMmiCode.getControlStrings(SsData.RequestType.SS_INTERROGATION,
+                SsData.ServiceType.SS_CF_ALL);
+        assertThat(controlStrings).containsExactly("*#002");
+        controlStrings = GsmMmiCode.getControlStrings(SsData.RequestType.SS_REGISTRATION,
+                SsData.ServiceType.SS_CF_ALL);
+        assertThat(controlStrings).containsExactly("**002");
+        controlStrings = GsmMmiCode.getControlStrings(SsData.RequestType.SS_DEACTIVATION,
+                SsData.ServiceType.SS_CF_ALL);
+        assertThat(controlStrings).containsExactly("#002");
+
+        // Test control strings of Call Forwarding ALl Conditional
+        controlStrings = GsmMmiCode.getControlStrings(SsData.RequestType.SS_INTERROGATION,
+                SsData.ServiceType.SS_CF_ALL_CONDITIONAL);
+        assertThat(controlStrings).containsExactly("*#004", "*#002");
+        controlStrings = GsmMmiCode.getControlStrings(SsData.RequestType.SS_REGISTRATION,
+                SsData.ServiceType.SS_CF_ALL_CONDITIONAL);
+        assertThat(controlStrings).containsExactly("**004", "**002");
+        controlStrings = GsmMmiCode.getControlStrings(SsData.RequestType.SS_DEACTIVATION,
+                SsData.ServiceType.SS_CF_ALL_CONDITIONAL);
+        assertThat(controlStrings).containsExactly("#004", "#002");
+
+        // Test control strings of CLIP
+        controlStrings = GsmMmiCode.getControlStrings(SsData.RequestType.SS_INTERROGATION,
+                SsData.ServiceType.SS_CLIP);
+        assertThat(controlStrings).containsExactly("*#30");
+
+        // Test control strings of CLIR
+        controlStrings = GsmMmiCode.getControlStrings(SsData.RequestType.SS_INTERROGATION,
+                SsData.ServiceType.SS_CLIR);
+        assertThat(controlStrings).containsExactly("*#31");
+        controlStrings = GsmMmiCode.getControlStrings(SsData.RequestType.SS_ACTIVATION,
+                SsData.ServiceType.SS_CLIR);
+        assertThat(controlStrings).containsExactly("*31");
+        controlStrings = GsmMmiCode.getControlStrings(SsData.RequestType.SS_DEACTIVATION,
+                SsData.ServiceType.SS_CLIR);
+        assertThat(controlStrings).containsExactly("#31");
+
+        // Test control strings of Call Waiting
+        controlStrings = GsmMmiCode.getControlStrings(SsData.RequestType.SS_INTERROGATION,
+                SsData.ServiceType.SS_WAIT);
+        assertThat(controlStrings).containsExactly("*#43");
+        controlStrings = GsmMmiCode.getControlStrings(SsData.RequestType.SS_ACTIVATION,
+                SsData.ServiceType.SS_WAIT);
+        assertThat(controlStrings).containsExactly("*43");
+        controlStrings = GsmMmiCode.getControlStrings(SsData.RequestType.SS_DEACTIVATION,
+                SsData.ServiceType.SS_WAIT);
+        assertThat(controlStrings).containsExactly("#43");
+
+        // Test control strings of BAOC
+        controlStrings = GsmMmiCode.getControlStrings(SsData.RequestType.SS_INTERROGATION,
+                SsData.ServiceType.SS_BAOC);
+        assertThat(controlStrings).containsExactly("*#33", "*#330", "*#333");
+        controlStrings = GsmMmiCode.getControlStrings(SsData.RequestType.SS_ACTIVATION,
+                SsData.ServiceType.SS_BAOC);
+        assertThat(controlStrings).containsExactly("*33", "*330", "*333");
+        controlStrings = GsmMmiCode.getControlStrings(SsData.RequestType.SS_DEACTIVATION,
+                SsData.ServiceType.SS_BAOC);
+        assertThat(controlStrings).containsExactly("#33", "#330", "#333");
+
+        // Test control strings of BAOIC
+        controlStrings = GsmMmiCode.getControlStrings(SsData.RequestType.SS_INTERROGATION,
+                SsData.ServiceType.SS_BAOIC);
+        assertThat(controlStrings).containsExactly("*#331", "*#330", "*#333");
+        controlStrings = GsmMmiCode.getControlStrings(SsData.RequestType.SS_ACTIVATION,
+                SsData.ServiceType.SS_BAOIC);
+        assertThat(controlStrings).containsExactly("*331", "*330", "*333");
+        controlStrings = GsmMmiCode.getControlStrings(SsData.RequestType.SS_DEACTIVATION,
+                SsData.ServiceType.SS_BAOIC);
+        assertThat(controlStrings).containsExactly("#331", "#330", "#333");
+
+        // Test control strings of BAOICxH
+        controlStrings = GsmMmiCode.getControlStrings(SsData.RequestType.SS_INTERROGATION,
+                SsData.ServiceType.SS_BAOIC_EXC_HOME);
+        assertThat(controlStrings).containsExactly("*#332", "*#330", "*#333");
+        controlStrings = GsmMmiCode.getControlStrings(SsData.RequestType.SS_ACTIVATION,
+                SsData.ServiceType.SS_BAOIC_EXC_HOME);
+        assertThat(controlStrings).containsExactly("*332", "*330", "*333");
+        controlStrings = GsmMmiCode.getControlStrings(SsData.RequestType.SS_DEACTIVATION,
+                SsData.ServiceType.SS_BAOIC_EXC_HOME);
+        assertThat(controlStrings).containsExactly("#332", "#330", "#333");
+
+        // Test control strings of BAIC
+        controlStrings = GsmMmiCode.getControlStrings(SsData.RequestType.SS_INTERROGATION,
+                SsData.ServiceType.SS_BAIC);
+        assertThat(controlStrings).containsExactly("*#35", "*#330", "*#353");
+        controlStrings = GsmMmiCode.getControlStrings(SsData.RequestType.SS_ACTIVATION,
+                SsData.ServiceType.SS_BAIC);
+        assertThat(controlStrings).containsExactly("*35", "*330", "*353");
+        controlStrings = GsmMmiCode.getControlStrings(SsData.RequestType.SS_DEACTIVATION,
+                SsData.ServiceType.SS_BAIC);
+        assertThat(controlStrings).containsExactly("#35", "#330", "#353");
+
+        // Test control strings of BAICr
+        controlStrings = GsmMmiCode.getControlStrings(SsData.RequestType.SS_INTERROGATION,
+                SsData.ServiceType.SS_BAIC_ROAMING);
+        assertThat(controlStrings).containsExactly("*#351", "*#330", "*#353");
+        controlStrings = GsmMmiCode.getControlStrings(SsData.RequestType.SS_ACTIVATION,
+                SsData.ServiceType.SS_BAIC_ROAMING);
+        assertThat(controlStrings).containsExactly("*351", "*330", "*353");
+        controlStrings = GsmMmiCode.getControlStrings(SsData.RequestType.SS_DEACTIVATION,
+                SsData.ServiceType.SS_BAIC_ROAMING);
+        assertThat(controlStrings).containsExactly("#351", "#330", "#353");
+
+        // Test control strings of BA_ALL
+        controlStrings = GsmMmiCode.getControlStrings(SsData.RequestType.SS_INTERROGATION,
+                SsData.ServiceType.SS_ALL_BARRING);
+        assertThat(controlStrings).containsExactly("*#330");
+        controlStrings = GsmMmiCode.getControlStrings(SsData.RequestType.SS_ACTIVATION,
+                SsData.ServiceType.SS_ALL_BARRING);
+        assertThat(controlStrings).containsExactly("*330");
+        controlStrings = GsmMmiCode.getControlStrings(SsData.RequestType.SS_DEACTIVATION,
+                SsData.ServiceType.SS_ALL_BARRING);
+        assertThat(controlStrings).containsExactly( "#330");
+
+        // Test control strings of BA_MO
+        controlStrings = GsmMmiCode.getControlStrings(SsData.RequestType.SS_INTERROGATION,
+                SsData.ServiceType.SS_OUTGOING_BARRING);
+        assertThat(controlStrings).containsExactly("*#333", "*#330");
+        controlStrings = GsmMmiCode.getControlStrings(SsData.RequestType.SS_ACTIVATION,
+                SsData.ServiceType.SS_OUTGOING_BARRING);
+        assertThat(controlStrings).containsExactly("*333", "*330");
+        controlStrings = GsmMmiCode.getControlStrings(SsData.RequestType.SS_DEACTIVATION,
+                SsData.ServiceType.SS_OUTGOING_BARRING);
+        assertThat(controlStrings).containsExactly( "#333", "#330");
+
+        // Test control strings of BA_MT
+        controlStrings = GsmMmiCode.getControlStrings(SsData.RequestType.SS_INTERROGATION,
+                SsData.ServiceType.SS_INCOMING_BARRING);
+        assertThat(controlStrings).containsExactly("*#353", "*#330");
+        controlStrings = GsmMmiCode.getControlStrings(SsData.RequestType.SS_ACTIVATION,
+                SsData.ServiceType.SS_INCOMING_BARRING);
+        assertThat(controlStrings).containsExactly("*353", "*330");
+        controlStrings = GsmMmiCode.getControlStrings(SsData.RequestType.SS_DEACTIVATION,
+                SsData.ServiceType.SS_INCOMING_BARRING);
+        assertThat(controlStrings).containsExactly( "#353", "#330");
+    }
+
+    @Test
+    public void testGetControlStringsForPwd() {
+        // Test if controlStrings list is empty when inputs are null
+        ArrayList<String> controlStrings = GsmMmiCode.getControlStringsForPwd(null,
+                null);
+        assertThat(controlStrings).isEmpty();
+
+        // Test control strings of Call Barring Change Password
+        controlStrings = GsmMmiCode.getControlStringsForPwd(
+                SsData.RequestType.SS_REGISTRATION, SsData.ServiceType.SS_ALL_BARRING);
+        assertThat(controlStrings).containsExactly("**03*330");
+    }
+
     private void setCarrierSupportsCallerIdVerticalServiceCodesCarrierConfig() {
         final PersistableBundle bundle = new PersistableBundle();
         bundle.putBoolean(CarrierConfigManager