Integrate IRadioModem into telephony

Test: atest RILTest
Bug: 198331673
Change-Id: If93b80b42bf04452301bd9550c69cefca36d38f7
Merged-In: If93b80b42bf04452301bd9550c69cefca36d38f7
diff --git a/src/java/com/android/internal/telephony/RIL.java b/src/java/com/android/internal/telephony/RIL.java
index ddf8c4c..6916f17 100644
--- a/src/java/com/android/internal/telephony/RIL.java
+++ b/src/java/com/android/internal/telephony/RIL.java
@@ -28,7 +28,6 @@
 import android.hardware.radio.V1_0.IRadio;
 import android.hardware.radio.V1_0.IccIo;
 import android.hardware.radio.V1_0.ImsSmsMessage;
-import android.hardware.radio.V1_0.NvWriteItem;
 import android.hardware.radio.V1_0.RadioError;
 import android.hardware.radio.V1_0.RadioIndicationType;
 import android.hardware.radio.V1_0.RadioResponseInfo;
@@ -231,7 +230,7 @@
     static final int VOICE_SERVICE = 6;
     static final int MIN_SERVICE_IDX = RADIO_SERVICE;
     // TODO: update as new services are implemented
-    static final int MAX_SERVICE_IDX = MESSAGING_SERVICE;
+    static final int MAX_SERVICE_IDX = MODEM_SERVICE;
 
     /**
      * An array of sets that records if services are disabled in the HAL for a specific phone ID
@@ -358,17 +357,17 @@
                     break;
 
                 case EVENT_BLOCKING_RESPONSE_TIMEOUT:
-                    int serial = msg.arg1;
+                    int serial = (int) msg.obj;
                     rr = findAndRemoveRequestFromList(serial);
                     // If the request has already been processed, do nothing
-                    if(rr == null) {
+                    if (rr == null) {
                         break;
                     }
 
-                    //build a response if expected
+                    // Build a response if expected
                     if (rr.mResult != null) {
                         Object timeoutResponse = getResponseForTimedOutRILRequest(rr);
-                        AsyncResult.forMessage( rr.mResult, timeoutResponse, null);
+                        AsyncResult.forMessage(rr.mResult, timeoutResponse, null);
                         rr.mResult.sendToTarget();
                         mMetrics.writeOnRilTimeoutResponse(mPhoneId, rr.mSerial, rr.mRequest);
                     }
@@ -621,8 +620,8 @@
     }
 
     /**
-     * Returns a {@link RadioDataProxy}, {@link RadioMessagingProxy} or null if the service is not
-     * available.
+     * Returns a {@link RadioDataProxy}, {@link RadioMessagingProxy}, {@link RadioModemProxy} or
+     * null if the service is not available.
      */
     public <T extends RadioServiceProxy> T getRadioServiceProxy(Class<T> serviceClass,
             Message result) {
@@ -633,6 +632,9 @@
         if (serviceClass == RadioMessagingProxy.class) {
             return (T) getRadioServiceProxy(MESSAGING_SERVICE, result);
         }
+        if (serviceClass == RadioModemProxy.class) {
+            return (T) getRadioServiceProxy(MODEM_SERVICE, result);
+        }
         return null;
     }
 
@@ -693,7 +695,12 @@
                                 android.hardware.radio.modem.IRadioModem.DESCRIPTOR + "/"
                                         + HIDL_SERVICE_NAME[mPhoneId]);
                         mRadioVersion = RADIO_HAL_VERSION_2_0;
-                        // TODO: implement
+                        if (binder != null) {
+                            mRadioVersion = RADIO_HAL_VERSION_2_0;
+                            ((RadioModemProxy) serviceProxy).setAidl(mRadioVersion,
+                                    android.hardware.radio.modem.IRadioModem.Stub
+                                            .asInterface(binder));
+                        }
                         break;
                     case NETWORK_SERVICE:
                         binder = ServiceManager.waitForDeclaredService(
@@ -804,6 +811,11 @@
                                         mMessagingResponse, mMessagingIndication);
                                 break;
                             case MODEM_SERVICE:
+                                mDeathRecipients.get(service).linkToDeath(
+                                        ((RadioModemProxy) serviceProxy).getAidl().asBinder());
+                                ((RadioModemProxy) serviceProxy).getAidl().setResponseFunctions(
+                                        mModemResponse, mModemIndication);
+                                break;
                             case NETWORK_SERVICE:
                             case SIM_SERVICE:
                             case VOICE_SERVICE:
@@ -916,7 +928,7 @@
             mServiceProxies.put(DATA_SERVICE, new RadioDataProxy());
             // TODO: implement
             mServiceProxies.put(MESSAGING_SERVICE, new RadioMessagingProxy());
-            mServiceProxies.put(MODEM_SERVICE, null);
+            mServiceProxies.put(MODEM_SERVICE, new RadioModemProxy());
             mServiceProxies.put(NETWORK_SERVICE, null);
             mServiceProxies.put(SIM_SERVICE, null);
             mServiceProxies.put(VOICE_SERVICE, null);
@@ -939,9 +951,13 @@
         mActiveWakelockWorkSource = new WorkSource();
 
         TelephonyDevController tdc = TelephonyDevController.getInstance();
-        tdc.registerRIL(this);
+        if (proxies == null) {
+            // TelephonyDevController#registerRIL will call getHardwareConfig.
+            // To prevent extra requests when running tests, only registerRIL when proxies is null
+            tdc.registerRIL(this);
+        }
 
-        // set radio callback; needed to set RadioIndication callback (should be done after
+        // Set radio callback; needed to set RadioIndication callback (should be done after
         // wakelock stuff is initialized above as callbacks are received on separate binder threads)
         for (int service = MIN_SERVICE_IDX; service <= MAX_SERVICE_IDX; service++) {
             if (service == RADIO_SERVICE) {
@@ -1297,9 +1313,37 @@
 
     @Override
     public void enableModem(boolean enable, Message result) {
+        RadioModemProxy modemProxy = getRadioServiceProxy(RadioModemProxy.class, result);
+        if (modemProxy.isEmpty()) return;
+        if (mRadioVersion.greaterOrEqual(RADIO_HAL_VERSION_1_3)) {
+            RILRequest rr = obtainRequest(RIL_REQUEST_ENABLE_MODEM, result, mRILDefaultWorkSource);
+
+            if (RILJ_LOGD) {
+                riljLog(rr.serialString() + "> " + RILUtils.requestToString(rr.mRequest)
+                        + " enable = " + enable);
+            }
+
+            try {
+                modemProxy.enableModem(rr.mSerial, enable);
+            } catch (RemoteException | RuntimeException e) {
+                handleRadioProxyExceptionForRR(MODEM_SERVICE, "enableModem", e);
+            }
+        } else {
+            if (RILJ_LOGV) riljLog("enableModem: not supported.");
+            if (result != null) {
+                AsyncResult.forMessage(result, null,
+                        CommandException.fromRilErrno(REQUEST_NOT_SUPPORTED));
+                result.sendToTarget();
+            }
+        }
+    }
+
+    @Override
+    public void setSystemSelectionChannels(@NonNull List<RadioAccessSpecifier> specifiers,
+            Message result) {
         IRadio radioProxy = getRadioProxy(result);
         if (mRadioVersion.less(RADIO_HAL_VERSION_1_3)) {
-            if (RILJ_LOGV) riljLog("enableModem: not supported.");
+            if (RILJ_LOGV) riljLog("setSystemSelectionChannels: not supported.");
             if (result != null) {
                 AsyncResult.forMessage(result, null,
                         CommandException.fromRilErrno(REQUEST_NOT_SUPPORTED));
@@ -1308,40 +1352,7 @@
             return;
         }
 
-        android.hardware.radio.V1_3.IRadio radioProxy13 =
-                (android.hardware.radio.V1_3.IRadio) radioProxy;
-        if (radioProxy13 != null) {
-            RILRequest rr = obtainRequest(RIL_REQUEST_ENABLE_MODEM, result,
-                    mRILDefaultWorkSource);
-
-            if (RILJ_LOGD) {
-                riljLog(rr.serialString() + "> " + RILUtils.requestToString(rr.mRequest)
-                        + " enable = " + enable);
-            }
-
-            try {
-                radioProxy13.enableModem(rr.mSerial, enable);
-            } catch (RemoteException | RuntimeException e) {
-                handleRadioProxyExceptionForRR(rr, "enableModem", e);
-            }
-        }
-    }
-
-    @Override
-    public void setSystemSelectionChannels(@NonNull List<RadioAccessSpecifier> specifiers,
-            Message onComplete) {
-        IRadio radioProxy = getRadioProxy(onComplete);
-        if (mRadioVersion.less(RADIO_HAL_VERSION_1_3)) {
-            if (RILJ_LOGV) riljLog("setSystemSelectionChannels: not supported.");
-            if (onComplete != null) {
-                AsyncResult.forMessage(onComplete, null,
-                        CommandException.fromRilErrno(REQUEST_NOT_SUPPORTED));
-                onComplete.sendToTarget();
-            }
-            return;
-        }
-
-        RILRequest rr = obtainRequest(RIL_REQUEST_SET_SYSTEM_SELECTION_CHANNELS, onComplete,
+        RILRequest rr = obtainRequest(RIL_REQUEST_SET_SYSTEM_SELECTION_CHANNELS, result,
                 mRILDefaultWorkSource);
 
         if (mRadioVersion.less(RADIO_HAL_VERSION_1_5)) {
@@ -1395,19 +1406,19 @@
     }
 
     @Override
-    public void getSystemSelectionChannels(Message onComplete) {
-        IRadio radioProxy = getRadioProxy(onComplete);
+    public void getSystemSelectionChannels(Message result) {
+        IRadio radioProxy = getRadioProxy(result);
         if (mRadioVersion.less(RADIO_HAL_VERSION_1_6)) {
             if (RILJ_LOGV) riljLog("getSystemSelectionChannels: not supported.");
-            if (onComplete != null) {
-                AsyncResult.forMessage(onComplete, null,
+            if (result != null) {
+                AsyncResult.forMessage(result, null,
                         CommandException.fromRilErrno(REQUEST_NOT_SUPPORTED));
-                onComplete.sendToTarget();
+                result.sendToTarget();
             }
             return;
         }
 
-        RILRequest rr = obtainRequest(RIL_REQUEST_GET_SYSTEM_SELECTION_CHANNELS, onComplete,
+        RILRequest rr = obtainRequest(RIL_REQUEST_GET_SYSTEM_SELECTION_CHANNELS, result,
                 mRILDefaultWorkSource);
 
         android.hardware.radio.V1_6.IRadio radioProxy16 =
@@ -1429,20 +1440,9 @@
 
     @Override
     public void getModemStatus(Message result) {
-        IRadio radioProxy = getRadioProxy(result);
-        if (mRadioVersion.less(RADIO_HAL_VERSION_1_3)) {
-            if (RILJ_LOGV) riljLog("getModemStatus: not supported.");
-            if (result != null) {
-                AsyncResult.forMessage(result, null,
-                        CommandException.fromRilErrno(REQUEST_NOT_SUPPORTED));
-                result.sendToTarget();
-            }
-            return;
-        }
-
-        android.hardware.radio.V1_3.IRadio radioProxy13 =
-                (android.hardware.radio.V1_3.IRadio) radioProxy;
-        if (radioProxy13 != null) {
+        RadioModemProxy modemProxy = getRadioServiceProxy(RadioModemProxy.class, result);
+        if (modemProxy.isEmpty()) return;
+        if (mRadioVersion.greaterOrEqual(RADIO_HAL_VERSION_1_3)) {
             RILRequest rr = obtainRequest(RIL_REQUEST_GET_MODEM_STATUS, result,
                     mRILDefaultWorkSource);
 
@@ -1451,9 +1451,16 @@
             }
 
             try {
-                radioProxy13.getModemStackStatus(rr.mSerial);
+                modemProxy.getModemStackStatus(rr.mSerial);
             } catch (RemoteException | RuntimeException e) {
-                handleRadioProxyExceptionForRR(rr, "getModemStatus", e);
+                handleRadioProxyExceptionForRR(MODEM_SERVICE, "getModemStatus", e);
+            }
+        } else {
+            if (RILJ_LOGV) riljLog("getModemStatus: not supported.");
+            if (result != null) {
+                AsyncResult.forMessage(result, null,
+                        CommandException.fromRilErrno(REQUEST_NOT_SUPPORTED));
+                result.sendToTarget();
             }
         }
     }
@@ -1869,10 +1876,9 @@
     @Override
     public void setRadioPower(boolean on, boolean forEmergencyCall,
             boolean preferredForEmergencyCall, Message result) {
-        IRadio radioProxy = getRadioProxy(result);
-        if (radioProxy != null) {
-            RILRequest rr = obtainRequest(RIL_REQUEST_RADIO_POWER, result,
-                    mRILDefaultWorkSource);
+        RadioModemProxy modemProxy = getRadioServiceProxy(RadioModemProxy.class, result);
+        if (!modemProxy.isEmpty()) {
+            RILRequest rr = obtainRequest(RIL_REQUEST_RADIO_POWER, result, mRILDefaultWorkSource);
 
             if (RILJ_LOGD) {
                 riljLog(rr.serialString() + "> " + RILUtils.requestToString(rr.mRequest)
@@ -1880,30 +1886,11 @@
                         + " preferredForEmergencyCall="  + preferredForEmergencyCall);
             }
 
-            if (mRadioVersion.greaterOrEqual(RADIO_HAL_VERSION_1_6)) {
-                android.hardware.radio.V1_6.IRadio radioProxy16 =
-                        (android.hardware.radio.V1_6.IRadio) radioProxy;
-                try {
-                    radioProxy16.setRadioPower_1_6(rr.mSerial, on, forEmergencyCall,
-                            preferredForEmergencyCall);
-                } catch (RemoteException | RuntimeException e) {
-                    handleRadioProxyExceptionForRR(rr, "setRadioPower_1_6", e);
-                }
-            } else if (mRadioVersion.greaterOrEqual(RADIO_HAL_VERSION_1_5)) {
-                android.hardware.radio.V1_5.IRadio radioProxy15 =
-                        (android.hardware.radio.V1_5.IRadio) radioProxy;
-                try {
-                    radioProxy15.setRadioPower_1_5(rr.mSerial, on, forEmergencyCall,
-                            preferredForEmergencyCall);
-                } catch (RemoteException | RuntimeException e) {
-                    handleRadioProxyExceptionForRR(rr, "setRadioPower_1_5", e);
-                }
-            } else {
-                try {
-                    radioProxy.setRadioPower(rr.mSerial, on);
-                } catch (RemoteException | RuntimeException e) {
-                    handleRadioProxyExceptionForRR(rr, "setRadioPower", e);
-                }
+            try {
+                modemProxy.setRadioPower(rr.mSerial, on, forEmergencyCall,
+                        preferredForEmergencyCall);
+            } catch (RemoteException | RuntimeException e) {
+                handleRadioProxyExceptionForRR(MODEM_SERVICE, "setRadioPower", e);
             }
         }
     }
@@ -2718,8 +2705,8 @@
 
     @Override
     public void getBasebandVersion(Message result) {
-        IRadio radioProxy = getRadioProxy(result);
-        if (radioProxy != null) {
+        RadioModemProxy modemProxy = getRadioServiceProxy(RadioModemProxy.class, result);
+        if (!modemProxy.isEmpty()) {
             RILRequest rr = obtainRequest(RIL_REQUEST_BASEBAND_VERSION, result,
                     mRILDefaultWorkSource);
 
@@ -2728,9 +2715,9 @@
             }
 
             try {
-                radioProxy.getBasebandVersion(rr.mSerial);
+                modemProxy.getBasebandVersion(rr.mSerial);
             } catch (RemoteException | RuntimeException e) {
-                handleRadioProxyExceptionForRR(rr, "getBasebandVersion", e);
+                handleRadioProxyExceptionForRR(MODEM_SERVICE, "getBasebandVersion", e);
             }
         }
     }
@@ -3713,8 +3700,8 @@
 
     @Override
     public void getDeviceIdentity(Message result) {
-        IRadio radioProxy = getRadioProxy(result);
-        if (radioProxy != null) {
+        RadioModemProxy modemProxy = getRadioServiceProxy(RadioModemProxy.class, result);
+        if (!modemProxy.isEmpty()) {
             RILRequest rr = obtainRequest(RIL_REQUEST_DEVICE_IDENTITY, result,
                     mRILDefaultWorkSource);
 
@@ -3723,9 +3710,9 @@
             }
 
             try {
-                radioProxy.getDeviceIdentity(rr.mSerial);
+                modemProxy.getDeviceIdentity(rr.mSerial);
             } catch (RemoteException | RuntimeException e) {
-                handleRadioProxyExceptionForRR(rr, "getDeviceIdentity", e);
+                handleRadioProxyExceptionForRR(MODEM_SERVICE, "getDeviceIdentity", e);
             }
         }
     }
@@ -4143,10 +4130,9 @@
     @Override
     public void nvReadItem(int itemID, Message result, WorkSource workSource) {
         workSource = getDefaultWorkSourceIfInvalid(workSource);
-        IRadio radioProxy = getRadioProxy(result);
-        if (radioProxy != null) {
-            RILRequest rr = obtainRequest(RIL_REQUEST_NV_READ_ITEM, result,
-                    workSource);
+        RadioModemProxy modemProxy = getRadioServiceProxy(RadioModemProxy.class, result);
+        if (!modemProxy.isEmpty()) {
+            RILRequest rr = obtainRequest(RIL_REQUEST_NV_READ_ITEM, result, workSource);
 
             if (RILJ_LOGD) {
                 riljLog(rr.serialString() + "> " + RILUtils.requestToString(rr.mRequest)
@@ -4154,9 +4140,9 @@
             }
 
             try {
-                radioProxy.nvReadItem(rr.mSerial, itemID);
+                modemProxy.nvReadItem(rr.mSerial, itemID);
             } catch (RemoteException | RuntimeException e) {
-                handleRadioProxyExceptionForRR(rr, "nvReadItem", e);
+                handleRadioProxyExceptionForRR(MODEM_SERVICE, "nvReadItem", e);
             }
         }
     }
@@ -4164,32 +4150,27 @@
     @Override
     public void nvWriteItem(int itemId, String itemValue, Message result, WorkSource workSource) {
         workSource = getDefaultWorkSourceIfInvalid(workSource);
-        IRadio radioProxy = getRadioProxy(result);
-        if (radioProxy != null) {
-            RILRequest rr = obtainRequest(RIL_REQUEST_NV_WRITE_ITEM, result,
-                    workSource);
+        RadioModemProxy modemProxy = getRadioServiceProxy(RadioModemProxy.class, result);
+        if (!modemProxy.isEmpty()) {
+            RILRequest rr = obtainRequest(RIL_REQUEST_NV_WRITE_ITEM, result, workSource);
 
             if (RILJ_LOGD) {
                 riljLog(rr.serialString() + "> " + RILUtils.requestToString(rr.mRequest)
                         + " itemId = " + itemId + " itemValue = " + itemValue);
             }
 
-            NvWriteItem item = new NvWriteItem();
-            item.itemId = itemId;
-            item.value = RILUtils.convertNullToEmptyString(itemValue);
-
             try {
-                radioProxy.nvWriteItem(rr.mSerial, item);
+                modemProxy.nvWriteItem(rr.mSerial, itemId, itemValue);
             } catch (RemoteException | RuntimeException e) {
-                handleRadioProxyExceptionForRR(rr, "nvWriteItem", e);
+                handleRadioProxyExceptionForRR(MODEM_SERVICE, "nvWriteItem", e);
             }
         }
     }
 
     @Override
     public void nvWriteCdmaPrl(byte[] preferredRoamingList, Message result) {
-        IRadio radioProxy = getRadioProxy(result);
-        if (radioProxy != null) {
+        RadioModemProxy modemProxy = getRadioServiceProxy(RadioModemProxy.class, result);
+        if (!modemProxy.isEmpty()) {
             RILRequest rr = obtainRequest(RIL_REQUEST_NV_WRITE_CDMA_PRL, result,
                     mRILDefaultWorkSource);
 
@@ -4199,23 +4180,18 @@
                         + IccUtils.bytesToHexString(preferredRoamingList));
             }
 
-            ArrayList<Byte> arrList = new ArrayList<>();
-            for (int i = 0; i < preferredRoamingList.length; i++) {
-                arrList.add(preferredRoamingList[i]);
-            }
-
             try {
-                radioProxy.nvWriteCdmaPrl(rr.mSerial, arrList);
+                modemProxy.nvWriteCdmaPrl(rr.mSerial, preferredRoamingList);
             } catch (RemoteException | RuntimeException e) {
-                handleRadioProxyExceptionForRR(rr, "nvWriteCdmaPrl", e);
+                handleRadioProxyExceptionForRR(MODEM_SERVICE, "nvWriteCdmaPrl", e);
             }
         }
     }
 
     @Override
     public void nvResetConfig(int resetType, Message result) {
-        IRadio radioProxy = getRadioProxy(result);
-        if (radioProxy != null) {
+        RadioModemProxy modemProxy = getRadioServiceProxy(RadioModemProxy.class, result);
+        if (!modemProxy.isEmpty()) {
             RILRequest rr = obtainRequest(RIL_REQUEST_NV_RESET_CONFIG, result,
                     mRILDefaultWorkSource);
 
@@ -4225,9 +4201,9 @@
             }
 
             try {
-                radioProxy.nvResetConfig(rr.mSerial, RILUtils.convertToHalResetNvType(resetType));
+                modemProxy.nvResetConfig(rr.mSerial, resetType);
             } catch (RemoteException | RuntimeException e) {
-                handleRadioProxyExceptionForRR(rr, "nvResetConfig", e);
+                handleRadioProxyExceptionForRR(MODEM_SERVICE, "nvResetConfig", e);
             }
         }
     }
@@ -4282,8 +4258,8 @@
 
     @Override
     public void getHardwareConfig(Message result) {
-        IRadio radioProxy = getRadioProxy(result);
-        if (radioProxy != null) {
+        RadioModemProxy modemProxy = getRadioServiceProxy(RadioModemProxy.class, result);
+        if (!modemProxy.isEmpty()) {
             RILRequest rr = obtainRequest(RIL_REQUEST_GET_HARDWARE_CONFIG, result,
                     mRILDefaultWorkSource);
 
@@ -4293,9 +4269,9 @@
             }
 
             try {
-                radioProxy.getHardwareConfig(rr.mSerial);
+                modemProxy.getHardwareConfig(rr.mSerial);
             } catch (RemoteException | RuntimeException e) {
-                handleRadioProxyExceptionForRR(rr, "getHardwareConfig", e);
+                handleRadioProxyExceptionForRR(MODEM_SERVICE, "getHardwareConfig", e);
             }
         }
     }
@@ -4349,9 +4325,27 @@
 
     @Override
     public void requestShutdown(Message result) {
-        IRadio radioProxy = getRadioProxy(result);
-        if (radioProxy != null) {
-            RILRequest rr = obtainRequest(RIL_REQUEST_SHUTDOWN, result,
+        RadioModemProxy modemProxy = getRadioServiceProxy(RadioModemProxy.class, result);
+        if (!modemProxy.isEmpty()) {
+            RILRequest rr = obtainRequest(RIL_REQUEST_SHUTDOWN, result, mRILDefaultWorkSource);
+
+            if (RILJ_LOGD) {
+                riljLog(rr.serialString() + "> " + RILUtils.requestToString(rr.mRequest));
+            }
+
+            try {
+                modemProxy.requestShutdown(rr.mSerial);
+            } catch (RemoteException | RuntimeException e) {
+                handleRadioProxyExceptionForRR(MODEM_SERVICE, "requestShutdown", e);
+            }
+        }
+    }
+
+    @Override
+    public void getRadioCapability(Message result) {
+        RadioModemProxy modemProxy = getRadioServiceProxy(RadioModemProxy.class, result);
+        if (!modemProxy.isEmpty()) {
+            RILRequest rr = obtainRequest(RIL_REQUEST_GET_RADIO_CAPABILITY, result,
                     mRILDefaultWorkSource);
 
             if (RILJ_LOGD) {
@@ -4359,37 +4353,18 @@
             }
 
             try {
-                radioProxy.requestShutdown(rr.mSerial);
+                modemProxy.getRadioCapability(rr.mSerial);
             } catch (RemoteException | RuntimeException e) {
-                handleRadioProxyExceptionForRR(rr, "requestShutdown", e);
+                handleRadioProxyExceptionForRR(MODEM_SERVICE, "getRadioCapability", e);
             }
         }
     }
 
     @Override
-    public void getRadioCapability(Message response) {
-        IRadio radioProxy = getRadioProxy(response);
-        if (radioProxy != null) {
-            RILRequest rr = obtainRequest(RIL_REQUEST_GET_RADIO_CAPABILITY, response,
-                    mRILDefaultWorkSource);
-
-            if (RILJ_LOGD) {
-                riljLog(rr.serialString() + "> " + RILUtils.requestToString(rr.mRequest));
-            }
-
-            try {
-                radioProxy.getRadioCapability(rr.mSerial);
-            } catch (RemoteException | RuntimeException e) {
-                handleRadioProxyExceptionForRR(rr, "getRadioCapability", e);
-            }
-        }
-    }
-
-    @Override
-    public void setRadioCapability(RadioCapability rc, Message response) {
-        IRadio radioProxy = getRadioProxy(response);
-        if (radioProxy != null) {
-            RILRequest rr = obtainRequest(RIL_REQUEST_SET_RADIO_CAPABILITY, response,
+    public void setRadioCapability(RadioCapability rc, Message result) {
+        RadioModemProxy modemProxy = getRadioServiceProxy(RadioModemProxy.class, result);
+        if (!modemProxy.isEmpty()) {
+            RILRequest rr = obtainRequest(RIL_REQUEST_SET_RADIO_CAPABILITY, result,
                     mRILDefaultWorkSource);
 
             if (RILJ_LOGD) {
@@ -4397,19 +4372,10 @@
                         + " RadioCapability = " + rc.toString());
             }
 
-            android.hardware.radio.V1_0.RadioCapability halRc =
-                    new android.hardware.radio.V1_0.RadioCapability();
-
-            halRc.session = rc.getSession();
-            halRc.phase = rc.getPhase();
-            halRc.raf = rc.getRadioAccessFamily();
-            halRc.logicalModemUuid = RILUtils.convertNullToEmptyString(rc.getLogicalModemUuid());
-            halRc.status = rc.getStatus();
-
             try {
-                radioProxy.setRadioCapability(rr.mSerial, halRc);
+                modemProxy.setRadioCapability(rr.mSerial, rc);
             } catch (Exception e) {
-                handleRadioProxyExceptionForRR(rr, "setRadioCapability", e);
+                handleRadioProxyExceptionForRR(MODEM_SERVICE, "setRadioCapability", e);
             }
         }
     }
@@ -4518,10 +4484,10 @@
      */
     @Deprecated
     @Override
-    public void pullLceData(Message response) {
-        IRadio radioProxy = getRadioProxy(response);
+    public void pullLceData(Message result) {
+        IRadio radioProxy = getRadioProxy(result);
         if (radioProxy != null) {
-            RILRequest rr = obtainRequest(RIL_REQUEST_PULL_LCEDATA, response,
+            RILRequest rr = obtainRequest(RIL_REQUEST_PULL_LCEDATA, result,
                     mRILDefaultWorkSource);
 
             if (RILJ_LOGD) {
@@ -4539,28 +4505,23 @@
     @Override
     public void getModemActivityInfo(Message result, WorkSource workSource) {
         workSource = getDefaultWorkSourceIfInvalid(workSource);
-        IRadio radioProxy = getRadioProxy(result);
-        if (radioProxy != null) {
-            RILRequest rr = obtainRequest(RIL_REQUEST_GET_ACTIVITY_INFO, result,
-                    workSource);
+        RadioModemProxy modemProxy = getRadioServiceProxy(RadioModemProxy.class, result);
+        if (!modemProxy.isEmpty()) {
+            RILRequest rr = obtainRequest(RIL_REQUEST_GET_ACTIVITY_INFO, result, workSource);
 
             if (RILJ_LOGD) {
                 riljLog(rr.serialString() + "> " + RILUtils.requestToString(rr.mRequest));
             }
 
             try {
-                radioProxy.getModemActivityInfo(rr.mSerial);
-
-                Message msg = mRilHandler.obtainMessage(EVENT_BLOCKING_RESPONSE_TIMEOUT);
-                msg.obj = null;
-                msg.arg1 = rr.mSerial;
+                modemProxy.getModemActivityInfo(rr.mSerial);
+                Message msg =
+                        mRilHandler.obtainMessage(EVENT_BLOCKING_RESPONSE_TIMEOUT, rr.mSerial);
                 mRilHandler.sendMessageDelayed(msg, DEFAULT_BLOCKING_MESSAGE_RESPONSE_TIMEOUT_MS);
             } catch (RemoteException | RuntimeException e) {
-                handleRadioProxyExceptionForRR(rr, "getModemActivityInfo", e);
+                handleRadioProxyExceptionForRR(MODEM_SERVICE, "getModemActivityInfo", e);
             }
         }
-
-
     }
 
     @Override
@@ -4684,10 +4645,9 @@
     }
 
     @Override
-    public void sendDeviceState(int stateType, boolean state,
-                                Message result) {
-        IRadio radioProxy = getRadioProxy(result);
-        if (radioProxy != null) {
+    public void sendDeviceState(int stateType, boolean state, Message result) {
+        RadioModemProxy modemProxy = getRadioServiceProxy(RadioModemProxy.class, result);
+        if (!modemProxy.isEmpty()) {
             RILRequest rr = obtainRequest(RIL_REQUEST_SEND_DEVICE_STATE, result,
                     mRILDefaultWorkSource);
 
@@ -4697,9 +4657,9 @@
             }
 
             try {
-                radioProxy.sendDeviceState(rr.mSerial, stateType, state);
+                modemProxy.sendDeviceState(rr.mSerial, stateType, state);
             } catch (RemoteException | RuntimeException e) {
-                handleRadioProxyExceptionForRR(rr, "sendDeviceState", e);
+                handleRadioProxyExceptionForRR(MODEM_SERVICE, "sendDeviceState", e);
             }
         }
     }
@@ -5050,18 +5010,18 @@
      * Enable or disable uicc applications on the SIM.
      *
      * @param enable whether to enable or disable uicc applications.
-     * @param onCompleteMessage a Message to return to the requester
+     * @param result a Message to return to the requester
      */
     @Override
-    public void enableUiccApplications(boolean enable, Message onCompleteMessage) {
-        IRadio radioProxy = getRadioProxy(onCompleteMessage);
+    public void enableUiccApplications(boolean enable, Message result) {
+        IRadio radioProxy = getRadioProxy(result);
         if (radioProxy == null) return;
 
         if (mRadioVersion.less(RADIO_HAL_VERSION_1_5)) {
-            if (onCompleteMessage != null) {
-                AsyncResult.forMessage(onCompleteMessage, null,
+            if (result != null) {
+                AsyncResult.forMessage(result, null,
                         CommandException.fromRilErrno(REQUEST_NOT_SUPPORTED));
-                onCompleteMessage.sendToTarget();
+                result.sendToTarget();
             }
             return;
         }
@@ -5070,7 +5030,7 @@
                 (android.hardware.radio.V1_5.IRadio) radioProxy;
 
         RILRequest rr = obtainRequest(RIL_REQUEST_ENABLE_UICC_APPLICATIONS,
-                onCompleteMessage, mRILDefaultWorkSource);
+                result, mRILDefaultWorkSource);
 
         if (RILJ_LOGD) riljLog(rr.serialString() + "> " + RILUtils.requestToString(rr.mRequest));
 
@@ -5084,18 +5044,18 @@
     /**
      * Whether uicc applications are enabled or not.
      *
-     * @param onCompleteMessage a Message to return to the requester
+     * @param result a Message to return to the requester
      */
     @Override
-    public void areUiccApplicationsEnabled(Message onCompleteMessage) {
-        IRadio radioProxy = getRadioProxy(onCompleteMessage);
+    public void areUiccApplicationsEnabled(Message result) {
+        IRadio radioProxy = getRadioProxy(result);
         if (radioProxy == null) return;
 
         if (mRadioVersion.less(RADIO_HAL_VERSION_1_5)) {
-            if (onCompleteMessage != null) {
-                AsyncResult.forMessage(onCompleteMessage, null,
+            if (result != null) {
+                AsyncResult.forMessage(result, null,
                         CommandException.fromRilErrno(REQUEST_NOT_SUPPORTED));
-                onCompleteMessage.sendToTarget();
+                result.sendToTarget();
             }
             return;
         }
@@ -5104,7 +5064,7 @@
                 (android.hardware.radio.V1_5.IRadio) radioProxy;
 
         RILRequest rr = obtainRequest(RIL_REQUEST_GET_UICC_APPLICATIONS_ENABLEMENT,
-                onCompleteMessage, mRILDefaultWorkSource);
+                result, mRILDefaultWorkSource);
 
         if (RILJ_LOGD) riljLog(rr.serialString() + "> " + RILUtils.requestToString(rr.mRequest));
 
diff --git a/src/java/com/android/internal/telephony/RILUtils.java b/src/java/com/android/internal/telephony/RILUtils.java
index dd60c91..8b48588 100644
--- a/src/java/com/android/internal/telephony/RILUtils.java
+++ b/src/java/com/android/internal/telephony/RILUtils.java
@@ -1013,6 +1013,26 @@
     }
 
     /**
+     * Convert to ResetNvType defined in ResetNvType.aidl
+     * @param resetType NV reset type
+     * @return The converted reset type in integer or -1 if param is invalid
+     */
+    public static int convertToHalResetNvTypeAidl(int resetType) {
+        /**
+         * resetType values
+         * 1 - reload all NV items
+         * 2 - erase NV reset (SCRTN)
+         * 3 - factory reset (RTN)
+         */
+        switch (resetType) {
+            case 1: return android.hardware.radio.modem.ResetNvType.RELOAD;
+            case 2: return android.hardware.radio.modem.ResetNvType.ERASE;
+            case 3: return android.hardware.radio.modem.ResetNvType.FACTORY_RESET;
+        }
+        return -1;
+    }
+
+    /**
      * Convert to a list of LinkAddress defined in radio/1.5/types.hal
      * @param linkProperties Link properties
      * @return The converted list of LinkAddresses
diff --git a/src/java/com/android/internal/telephony/RadioModemProxy.java b/src/java/com/android/internal/telephony/RadioModemProxy.java
new file mode 100644
index 0000000..83703b5
--- /dev/null
+++ b/src/java/com/android/internal/telephony/RadioModemProxy.java
@@ -0,0 +1,336 @@
+/*
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.internal.telephony;
+
+import android.os.RemoteException;
+
+/**
+ * A holder for IRadioModem. Use getHidl to get IRadio 1.0 and call the HIDL implementations or
+ * getAidl to get IRadioModem and call the AIDL implementations of the HAL APIs.
+ */
+public class RadioModemProxy extends RadioServiceProxy {
+    private volatile android.hardware.radio.modem.IRadioModem mModemProxy = null;
+
+    /**
+     * Set IRadioModem as the AIDL implementation for RadioServiceProxy
+     * @param halVersion Radio HAL version
+     * @param modem IRadioModem implementation
+     */
+    public void setAidl(HalVersion halVersion,
+            android.hardware.radio.modem.IRadioModem modem) {
+        mHalVersion = halVersion;
+        mModemProxy = modem;
+        mIsAidl = true;
+    }
+
+    /**
+     * Get the AIDL implementation of RadioModemProxy
+     * @return IRadioModem implementation
+     */
+    public android.hardware.radio.modem.IRadioModem getAidl() {
+        return mModemProxy;
+    }
+
+    /**
+     * Reset RadioModemProxy
+     */
+    @Override
+    public void clear() {
+        mHalVersion = RIL.RADIO_HAL_VERSION_UNKNOWN;
+        mRadioProxy = null;
+        mModemProxy = null;
+    }
+
+    /**
+     * Check whether a RadioModem implementation exists
+     * @return false if there is neither a HIDL nor AIDL implementation
+     */
+    @Override
+    public boolean isEmpty() {
+        return mRadioProxy == null && mModemProxy == null;
+    }
+
+    /**
+     * Call IRadioModem#enableModem
+     * @param serial Serial number of request
+     * @param on Whether to enable or disable the modem
+     * @throws RemoteException
+     */
+    public void enableModem(int serial, boolean on) throws RemoteException {
+        if (isEmpty() || mHalVersion.less(RIL.RADIO_HAL_VERSION_1_3)) return;
+        if (isAidl()) {
+            mModemProxy.enableModem(serial, on);
+        } else {
+            ((android.hardware.radio.V1_3.IRadio) mRadioProxy).enableModem(serial, on);
+        }
+    }
+
+    /**
+     * Call IRadioModem#getBasebandVersion
+     * @param serial Serial number of request
+     * @throws RemoteException
+     */
+    public void getBasebandVersion(int serial) throws RemoteException {
+        if (isEmpty()) return;
+        if (isAidl()) {
+            mModemProxy.getBasebandVersion(serial);
+        } else {
+            mRadioProxy.getBasebandVersion(serial);
+        }
+    }
+
+    /**
+     * Call IRadioModem#getDeviceIdentity
+     * @param serial Serial number of request
+     * @throws RemoteException
+     */
+    public void getDeviceIdentity(int serial) throws RemoteException {
+        if (isEmpty()) return;
+        if (isAidl()) {
+            mModemProxy.getDeviceIdentity(serial);
+        } else {
+            mRadioProxy.getDeviceIdentity(serial);
+        }
+    }
+
+    /**
+     * Call IRadioModem#getHardwareConfig
+     * @param serial Serial number of request
+     * @throws RemoteException
+     */
+    public void getHardwareConfig(int serial) throws RemoteException {
+        if (isEmpty()) return;
+        if (isAidl()) {
+            mModemProxy.getHardwareConfig(serial);
+        } else {
+            mRadioProxy.getHardwareConfig(serial);
+        }
+    }
+
+    /**
+     * Call IRadioModem#getModemActivityInfo
+     * @param serial Serial number of request
+     * @throws RemoteException
+     */
+    public void getModemActivityInfo(int serial) throws RemoteException {
+        if (isEmpty()) return;
+        if (isAidl()) {
+            mModemProxy.getModemActivityInfo(serial);
+        } else {
+            mRadioProxy.getModemActivityInfo(serial);
+        }
+    }
+
+    /**
+     * Call IRadioModem#getModemStackStatus
+     * @param serial Serial number of request
+     * @throws RemoteException
+     */
+    public void getModemStackStatus(int serial) throws RemoteException {
+        if (isEmpty() || mHalVersion.less(RIL.RADIO_HAL_VERSION_1_3)) return;
+        if (isAidl()) {
+            mModemProxy.getModemStackStatus(serial);
+        } else {
+            ((android.hardware.radio.V1_3.IRadio) mRadioProxy).getModemStackStatus(serial);
+        }
+    }
+
+    /**
+     * Call IRadioModem#getRadioCapability
+     * @param serial Serial number of request
+     * @throws RemoteException
+     */
+    public void getRadioCapability(int serial) throws RemoteException {
+        if (isEmpty()) return;
+        if (isAidl()) {
+            mModemProxy.getRadioCapability(serial);
+        } else {
+            mRadioProxy.getRadioCapability(serial);
+        }
+    }
+
+    /**
+     * Call IRadioModem#nvReadItem
+     * @param serial Serial number of request
+     * @param itemId ID of the item to read
+     * @throws RemoteException
+     */
+    public void nvReadItem(int serial, int itemId) throws RemoteException {
+        if (isEmpty()) return;
+        if (isAidl()) {
+            mModemProxy.nvReadItem(serial, itemId);
+        } else {
+            mRadioProxy.nvReadItem(serial, itemId);
+        }
+    }
+
+    /**
+     * Call IRadioModem#nvResetConfig
+     * @param serial Serial number of request
+     * @param resetType Reset type; 1: reload NV reset, 2: erase NV reset, 3: factory NV reset
+     * @throws RemoteException
+     */
+    public void nvResetConfig(int serial, int resetType) throws RemoteException {
+        if (isEmpty()) return;
+        if (isAidl()) {
+            mModemProxy.nvResetConfig(serial, RILUtils.convertToHalResetNvTypeAidl(resetType));
+        } else {
+            mRadioProxy.nvResetConfig(serial, RILUtils.convertToHalResetNvType(resetType));
+        }
+    }
+
+    /**
+     * Call IRadioModem#nvWriteCdmaPrl
+     * @param serial Serial number of request
+     * @param prl Preferred roaming list as a byte array
+     * @throws RemoteException
+     */
+    public void nvWriteCdmaPrl(int serial, byte[] prl) throws RemoteException {
+        if (isEmpty()) return;
+        if (isAidl()) {
+            mModemProxy.nvWriteCdmaPrl(serial, prl);
+        } else {
+            mRadioProxy.nvWriteCdmaPrl(serial, RILUtils.primitiveArrayToArrayList(prl));
+        }
+    }
+
+    /**
+     * Call IRadioModem#nvWriteItem
+     * @param serial Serial number of request
+     * @param itemId ID of the item to write
+     * @param itemValue Value to write as a String
+     * @throws RemoteException
+     */
+    public void nvWriteItem(int serial, int itemId, String itemValue) throws RemoteException {
+        if (isEmpty()) return;
+        if (isAidl()) {
+            android.hardware.radio.modem.NvWriteItem item =
+                    new android.hardware.radio.modem.NvWriteItem();
+            item.itemId = itemId;
+            item.value = RILUtils.convertNullToEmptyString(itemValue);
+            mModemProxy.nvWriteItem(serial, item);
+        } else {
+            android.hardware.radio.V1_0.NvWriteItem item =
+                    new android.hardware.radio.V1_0.NvWriteItem();
+            item.itemId = itemId;
+            item.value = RILUtils.convertNullToEmptyString(itemValue);
+            mRadioProxy.nvWriteItem(serial, item);
+        }
+    }
+
+    /**
+     * Call IRadioModem#requestShutdown
+     * @param serial Serial number of request
+     * @throws RemoteException
+     */
+    public void requestShutdown(int serial) throws RemoteException {
+        if (isEmpty()) return;
+        if (isAidl()) {
+            mModemProxy.requestShutdown(serial);
+        } else {
+            mRadioProxy.requestShutdown(serial);
+        }
+    }
+
+    /**
+     * Call IRadioModem#responseAcknowledgement
+     * @throws RemoteException
+     */
+    @Override
+    public void responseAcknowledgement() throws RemoteException {
+        if (isEmpty()) return;
+        if (isAidl()) {
+            mModemProxy.responseAcknowledgement();
+        } else {
+            mRadioProxy.responseAcknowledgement();
+        }
+    }
+
+    /**
+     * Call IRadioModem#sendDeviceState
+     * @param serial Serial number of request
+     * @param deviceStateType Device state type
+     * @param state True if enabled and false if disabled
+     * @throws RemoteException
+     */
+    public void sendDeviceState(int serial, int deviceStateType, boolean state)
+            throws RemoteException {
+        if (isEmpty()) return;
+        if (isAidl()) {
+            mModemProxy.sendDeviceState(serial, deviceStateType, state);
+        } else {
+            mRadioProxy.sendDeviceState(serial, deviceStateType, state);
+        }
+    }
+
+    /**
+     * Call IRadioModem#setRadioCapability
+     * @param serial Serial number of request
+     * @param rc The phone radio capability defined in RadioCapability
+     *           It's a input object used to transfer parameter to logic modem
+     * @throws RemoteException
+     */
+    public void setRadioCapability(int serial, RadioCapability rc) throws RemoteException {
+        if (isEmpty()) return;
+        if (isAidl()) {
+            android.hardware.radio.modem.RadioCapability halRc =
+                    new android.hardware.radio.modem.RadioCapability();
+            halRc.session = rc.getSession();
+            halRc.phase = rc.getPhase();
+            halRc.raf = rc.getRadioAccessFamily();
+            halRc.logicalModemUuid = RILUtils.convertNullToEmptyString(rc.getLogicalModemUuid());
+            halRc.status = rc.getStatus();
+            mModemProxy.setRadioCapability(serial, halRc);
+        } else {
+            android.hardware.radio.V1_0.RadioCapability halRc =
+                    new android.hardware.radio.V1_0.RadioCapability();
+            halRc.session = rc.getSession();
+            halRc.phase = rc.getPhase();
+            halRc.raf = rc.getRadioAccessFamily();
+            halRc.logicalModemUuid = RILUtils.convertNullToEmptyString(rc.getLogicalModemUuid());
+            halRc.status = rc.getStatus();
+            mRadioProxy.setRadioCapability(serial, halRc);
+        }
+    }
+
+    /**
+     * Call IRadioModem#setRadioPower
+     * @param serial Serial number of request
+     * @param powerOn True to turn on radio and false to turn off
+     * @param forEmergencyCall Indicates that this request is due to emergency call
+     *                         No effect if powerOn is false
+     * @param preferredForEmergencyCall Whether or not the following emergency call will be sent
+     *                                  on this modem
+     *                                  No effect if powerOn or forEmergencyCall is false
+     * @throws RemoteException
+     */
+    public void setRadioPower(int serial, boolean powerOn, boolean forEmergencyCall,
+            boolean preferredForEmergencyCall) throws RemoteException {
+        if (isEmpty()) return;
+        if (isAidl()) {
+            mModemProxy.setRadioPower(serial, powerOn, forEmergencyCall, preferredForEmergencyCall);
+        } else if (mHalVersion.greaterOrEqual(RIL.RADIO_HAL_VERSION_1_6)) {
+            ((android.hardware.radio.V1_6.IRadio) mRadioProxy).setRadioPower_1_6(serial, powerOn,
+                    forEmergencyCall, preferredForEmergencyCall);
+        } else if (mHalVersion.greaterOrEqual(RIL.RADIO_HAL_VERSION_1_5)) {
+            ((android.hardware.radio.V1_5.IRadio) mRadioProxy).setRadioPower_1_5(serial, powerOn,
+                    forEmergencyCall, preferredForEmergencyCall);
+        } else {
+            mRadioProxy.setRadioPower(serial, powerOn);
+        }
+    }
+}