Merge "Do not treat NULL response as error for getAllowedCarriers"
diff --git a/include/telephony/ril.h b/include/telephony/ril.h
index 5bf5e17..2012403 100644
--- a/include/telephony/ril.h
+++ b/include/telephony/ril.h
@@ -75,7 +75,9 @@
  * RIL_VERSION = 15 : New commands added:
  *                    RIL_REQUEST_SEND_DEVICE_STATE,
  *                    RIL_REQUEST_SET_UNSOLICITED_RESPONSE_FILTER,
- *                    RIL_REQUEST_SET_SIM_CARD_POWER
+ *                    RIL_REQUEST_SET_SIM_CARD_POWER,
+ *                    RIL_REQUEST_SET_CARRIER_INFO_IMSI_ENCRYPTION,
+ *                    RIL_UNSOL_CARRIER_INFO_IMSI_ENCRYPTION
  *                    The new parameters for RIL_REQUEST_SETUP_DATA_CALL,
  *                    Updated data structures: RIL_DataProfileInfo_v15, RIL_InitialAttachApn_v15
  *                    New data structure RIL_DataRegistrationStateResponse,
@@ -731,6 +733,16 @@
                                          */
 } RIL_CarrierRestrictions;
 
+typedef struct {
+  const uint8_t * carrierKey;            /* Public Key from the Carrier used to encrypt the
+                                          * IMSI/IMPI.
+                                          */
+  const char * KeyIdentifier;            /* The keyIdentifier Attribute value pair that helps
+                                          * a server locate the private key to decrypt the
+                                          * permanent identity.
+                                          */
+} RIL_CarrierInfoForImsiEncryption;
+
 /* See RIL_REQUEST_LAST_CALL_FAIL_CAUSE */
 typedef enum {
     CALL_FAIL_UNOBTAINABLE_NUMBER = 1,
@@ -5329,6 +5341,28 @@
   *  INVALID_ARGUMENTS
   */
 #define RIL_REQUEST_SET_SIM_CARD_POWER 140
+
+/**
+ * RIL_REQUEST_SET_CARRIER_INFO_IMSI_ENCRYPTION
+ *
+ * Provide Carrier specific information to the modem that will be used to
+ * encrypt the IMSI and IMPI. Sent by the framework during boot, carrier
+ * switch and everytime we receive a new certificate.
+ *
+ * "data" is the RIL_CarrierInfoForImsiEncryption * structure.
+ *
+ * "response" is NULL
+ *
+ * Valid errors:
+ *  RIL_E_SUCCESS
+ *  RIL_E_RADIO_NOT_AVAILABLE
+ *  SIM_ABSENT
+ *  RIL_E_REQUEST_NOT_SUPPORTED
+ *  INVALID_ARGUMENTS
+ *  MODEM_INTERNAL_FAILURE
+ */
+#define RIL_REQUEST_SET_CARRIER_INFO_IMSI_ENCRYPTION 141
+
 /***********************************************************************/
 
 /**
@@ -5960,6 +5994,17 @@
   */
 #define RIL_UNSOL_PCO_DATA 1046
 
+/**
+ * RIL_UNSOL_CARRIER_INFO_IMSI_ENCRYPTION
+ *
+ * Called when the modem needs Carrier specific information that will
+ * be used to encrypt IMSI and IMPI.
+ *
+ * "data" is NULL
+ *
+ */
+#define RIL_UNSOL_CARRIER_INFO_IMSI_ENCRYPTION 1047
+
 /***********************************************************************/
 
 
diff --git a/libril/Android.mk b/libril/Android.mk
index a5fb3f0..27083ef 100644
--- a/libril/Android.mk
+++ b/libril/Android.mk
@@ -19,6 +19,7 @@
     libhardware_legacy \
     librilutils \
     android.hardware.radio@1.0 \
+    android.hardware.radio@1.1 \
     android.hardware.radio.deprecated@1.0 \
     libhidlbase  \
     libhidltransport \
diff --git a/libril/ril.cpp b/libril/ril.cpp
index 7a28fa4..bd5e02e 100644
--- a/libril/ril.cpp
+++ b/libril/ril.cpp
@@ -1174,6 +1174,7 @@
         case RIL_REQUEST_GET_ACTIVITY_INFO: return "GET_ACTIVITY_INFO";
         case RIL_REQUEST_SET_CARRIER_RESTRICTIONS: return "SET_CARRIER_RESTRICTIONS";
         case RIL_REQUEST_GET_CARRIER_RESTRICTIONS: return "GET_CARRIER_RESTRICTIONS";
+        case RIL_REQUEST_SET_CARRIER_INFO_IMSI_ENCRYPTION: return "SET_CARRIER_INFO_IMSI_ENCRYPTION";
         case RIL_RESPONSE_ACKNOWLEDGEMENT: return "RESPONSE_ACKNOWLEDGEMENT";
         case RIL_UNSOL_RESPONSE_RADIO_STATE_CHANGED: return "UNSOL_RESPONSE_RADIO_STATE_CHANGED";
         case RIL_UNSOL_RESPONSE_CALL_STATE_CHANGED: return "UNSOL_RESPONSE_CALL_STATE_CHANGED";
@@ -1218,6 +1219,7 @@
         case RIL_UNSOL_HARDWARE_CONFIG_CHANGED: return "UNSOL_HARDWARE_CONFIG_CHANGED";
         case RIL_UNSOL_DC_RT_INFO_CHANGED: return "UNSOL_DC_RT_INFO_CHANGED";
         case RIL_UNSOL_RADIO_CAPABILITY: return "UNSOL_RADIO_CAPABILITY";
+        case RIL_UNSOL_CARRIER_INFO_IMSI_ENCRYPTION: return "UNSOL_CARRIER_INFO_IMSI_ENCRYPTION";
         case RIL_UNSOL_ON_SS: return "UNSOL_ON_SS";
         case RIL_UNSOL_STK_CC_ALPHA_NOTIFY: return "UNSOL_STK_CC_ALPHA_NOTIFY";
         case RIL_UNSOL_LCEDATA_RECV: return "UNSOL_LCEDATA_RECV";
diff --git a/libril/ril_commands.h b/libril/ril_commands.h
index c9ec0cc..6518a4e 100644
--- a/libril/ril_commands.h
+++ b/libril/ril_commands.h
@@ -155,3 +155,4 @@
     {RIL_REQUEST_SEND_DEVICE_STATE, radio::sendDeviceStateResponse},
     {RIL_REQUEST_SET_UNSOLICITED_RESPONSE_FILTER, radio::setIndicationFilterResponse},
     {RIL_REQUEST_SET_SIM_CARD_POWER, radio::setSimCardPowerResponse},
+    {RIL_REQUEST_SET_CARRIER_INFO_IMSI_ENCRYPTION, radio::setCarrierInfoForImsiEncryptionResponse},
diff --git a/libril/ril_service.cpp b/libril/ril_service.cpp
index c1f47fd..b71f83a 100644
--- a/libril/ril_service.cpp
+++ b/libril/ril_service.cpp
@@ -16,7 +16,10 @@
 
 #define LOG_TAG "RILC"
 
-#include <android/hardware/radio/1.0/IRadio.h>
+#include <android/hardware/radio/1.1/IRadio.h>
+#include <android/hardware/radio/1.1/IRadioResponse.h>
+#include <android/hardware/radio/1.1/IRadioIndication.h>
+
 #include <android/hardware/radio/deprecated/1.0/IOemHook.h>
 
 #include <hwbinder/IPCThreadState.h>
@@ -99,7 +102,7 @@
 
 void convertRilCellInfoListToHal(void *response, size_t responseLen, hidl_vec<CellInfo>& records);
 
-struct RadioImpl : public IRadio {
+struct RadioImpl : public ::android::hardware::radio::V1_1::IRadio {
     int32_t mSlotId;
     sp<IRadioResponse> mRadioResponse;
     sp<IRadioIndication> mRadioIndication;
@@ -425,6 +428,10 @@
 
     Return<void> responseAcknowledgement();
 
+    Return<void> setCarrierInfoForImsiEncryption(int32_t serial,
+            const ::android::hardware::hidl_vec<uint8_t>& carrierKey,
+            const hidl_string& keyIdentifier);
+
     void checkReturnStatus(Return<void>& ret);
 };
 
@@ -2677,6 +2684,14 @@
     return Void();
 }
 
+Return<void> RadioImpl::setCarrierInfoForImsiEncryption(int32_t serial,
+        const ::android::hardware::hidl_vec<uint8_t>& carrierKey,
+        const hidl_string& keyIdentifier) {
+    RLOGD("setCarrierInfoForImsiEncryption: serial %d", serial);
+    dispatchRaw(serial, mSlotId, RIL_REQUEST_SET_CARRIER_INFO_IMSI_ENCRYPTION, carrierKey);
+    return Void();
+}
+
 /***************************************************************************************************
  * RESPONSE FUNCTIONS
  * Functions above are used for requests going from framework to vendor code. The ones below are
@@ -6239,6 +6254,32 @@
     return 0;
 }
 
+int radio::setCarrierInfoForImsiEncryptionResponse(int slotId,
+                               int responseType, int serial, RIL_Errno e,
+                               void *response, size_t responseLen) {
+    RLOGD("setCarrierInfoForImsiEncryptionResponse: serial %d", serial);
+    if (radioService[slotId]->mRadioResponse != NULL) {
+        RadioResponseInfo responseInfo = {};
+        populateResponseInfo(responseInfo, serial, responseType, e);
+        Return<sp<::android::hardware::radio::V1_1::IRadioResponse>> ret =
+            ::android::hardware::radio::V1_1::IRadioResponse::castFrom(
+            radioService[slotId]->mRadioResponse);
+        if (ret.isOk()) {
+            sp<::android::hardware::radio::V1_1::IRadioResponse> radioResponseV1_1 = ret;
+            Return<void> retStatus
+                   = radioResponseV1_1->setCarrierInfoForImsiEncryptionResponse(responseInfo);
+            radioService[slotId]->checkReturnStatus(retStatus);
+        } else {
+            RLOGE("setCarrierInfoForImsiEncryptionResponse: ret.isOk() == false for "
+                    "radioService[%d]" , slotId);
+        }
+    } else {
+        RLOGE("setCarrierInfoForImsiEncryptionResponse: radioService[%d]->mRadioResponse == NULL",
+                slotId);
+    }
+    return 0;
+}
+
 int radio::setIndicationFilterResponse(int slotId,
                               int responseType, int serial, RIL_Errno e,
                               void *response, size_t responselen) {
@@ -7928,6 +7969,34 @@
     return 0;
 }
 
+int radio::carrierInfoForImsiEncryption(int slotId,
+                                  int indicationType, int token, RIL_Errno e, void *response,
+                                  size_t responseLen) {
+    if (radioService[slotId] != NULL && radioService[slotId]->mRadioIndication != NULL) {
+        if (response == NULL || responseLen == 0) {
+            RLOGE("carrierInfoForImsiEncryption: invalid response");
+            return 0;
+        }
+        RLOGD("carrierInfoForImsiEncryption");
+        Return<sp<::android::hardware::radio::V1_1::IRadioIndication>> ret =
+            ::android::hardware::radio::V1_1::IRadioIndication::castFrom(
+            radioService[slotId]->mRadioIndication);
+        if (ret.isOk()) {
+            sp<::android::hardware::radio::V1_1::IRadioIndication> radioIndicationV1_1 = ret;
+            Return<void> retStatus = radioIndicationV1_1->carrierInfoForImsiEncryption(
+                    convertIntToRadioIndicationType(indicationType));
+            radioService[slotId]->checkReturnStatus(retStatus);
+        } else {
+            RLOGE("carrierInfoForImsiEncryptionResponse: ret.isOk() == false for radioService[%d]",
+                    slotId);
+        }
+    } else {
+        RLOGE("carrierInfoForImsiEncryption: radioService[%d]->mRadioIndication == NULL", slotId);
+    }
+
+    return 0;
+}
+
 int radio::oemHookRawInd(int slotId,
                          int indicationType, int token, RIL_Errno e, void *response,
                          size_t responseLen) {
@@ -7982,7 +8051,8 @@
         radioService[i]->mSlotId = i;
         oemHookService[i] = new OemHookImpl;
         oemHookService[i]->mSlotId = i;
-        RLOGD("registerService: starting IRadio %s", serviceNames[i]);
+        RLOGD("registerService: starting android::hardware::radio::V1_1::IRadio %s",
+                serviceNames[i]);
         android::status_t status = radioService[i]->registerAsService(serviceNames[i]);
         status = oemHookService[i]->registerAsService(serviceNames[i]);
 
diff --git a/libril/ril_service.h b/libril/ril_service.h
index 441b587..e10f66b 100644
--- a/libril/ril_service.h
+++ b/libril/ril_service.h
@@ -709,8 +709,16 @@
                                int responseType, int serial, RIL_Errno e,
                                void *response, size_t responseLen);
 
+int setCarrierInfoForImsiEncryptionResponse(int slotId,
+                                            int responseType, int serial, RIL_Errno e,
+                                            void *response, size_t responseLen);
+
+int carrierInfoForImsiEncryption(int slotId,
+                        int responseType, int serial, RIL_Errno e,
+                        void *response, size_t responseLen);
+
 pthread_rwlock_t * getRadioServiceRwlock(int slotId);
 
 }   // namespace radio
 
-#endif  // RIL_SERVICE_H
\ No newline at end of file
+#endif  // RIL_SERVICE_H
diff --git a/libril/ril_unsol_commands.h b/libril/ril_unsol_commands.h
index 0b25361..03a1c14 100644
--- a/libril/ril_unsol_commands.h
+++ b/libril/ril_unsol_commands.h
@@ -61,3 +61,4 @@
     {RIL_UNSOL_STK_CC_ALPHA_NOTIFY, radio::stkCallControlAlphaNotifyInd, WAKE_PARTIAL},
     {RIL_UNSOL_LCEDATA_RECV, radio::lceDataInd, WAKE_PARTIAL},
     {RIL_UNSOL_PCO_DATA, radio::pcoDataInd, WAKE_PARTIAL},
+    {RIL_UNSOL_CARRIER_INFO_IMSI_ENCRYPTION, radio::carrierInfoForImsiEncryption, WAKE_PARTIAL},