Home | History | Annotate | Download | only in telephony
      1 /*
      2  * Copyright (C) 2016 The Android Open Source Project
      3  *
      4  * Licensed under the Apache License, Version 2.0 (the "License");
      5  * you may not use this file except in compliance with the License.
      6  * You may obtain a copy of the License at
      7  *
      8  *      http://www.apache.org/licenses/LICENSE-2.0
      9  *
     10  * Unless required by applicable law or agreed to in writing, software
     11  * distributed under the License is distributed on an "AS IS" BASIS,
     12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     13  * See the License for the specific language governing permissions and
     14  * limitations under the License.
     15  */
     16 
     17 package com.android.internal.telephony;
     18 
     19 import static com.android.internal.telephony.RILConstants.RIL_UNSOL_CALL_RING;
     20 import static com.android.internal.telephony.RILConstants.RIL_UNSOL_CARRIER_INFO_IMSI_ENCRYPTION;
     21 import static com.android.internal.telephony.RILConstants.RIL_UNSOL_CDMA_CALL_WAITING;
     22 import static com.android.internal.telephony.RILConstants.RIL_UNSOL_CDMA_INFO_REC;
     23 import static com.android.internal.telephony.RILConstants.RIL_UNSOL_CDMA_OTA_PROVISION_STATUS;
     24 import static com.android.internal.telephony.RILConstants.RIL_UNSOL_CDMA_RUIM_SMS_STORAGE_FULL;
     25 import static com.android.internal.telephony.RILConstants.RIL_UNSOL_CDMA_SUBSCRIPTION_SOURCE_CHANGED;
     26 import static com.android.internal.telephony.RILConstants.RIL_UNSOL_CELL_INFO_LIST;
     27 import static com.android.internal.telephony.RILConstants.RIL_UNSOL_DATA_CALL_LIST_CHANGED;
     28 import static com.android.internal.telephony.RILConstants.RIL_UNSOL_ENTER_EMERGENCY_CALLBACK_MODE;
     29 import static com.android.internal.telephony.RILConstants.RIL_UNSOL_EXIT_EMERGENCY_CALLBACK_MODE;
     30 import static com.android.internal.telephony.RILConstants.RIL_UNSOL_HARDWARE_CONFIG_CHANGED;
     31 import static com.android.internal.telephony.RILConstants.RIL_UNSOL_LCEDATA_RECV;
     32 import static com.android.internal.telephony.RILConstants.RIL_UNSOL_MODEM_RESTART;
     33 import static com.android.internal.telephony.RILConstants.RIL_UNSOL_NETWORK_SCAN_RESULT;
     34 import static com.android.internal.telephony.RILConstants.RIL_UNSOL_NITZ_TIME_RECEIVED;
     35 import static com.android.internal.telephony.RILConstants.RIL_UNSOL_ON_SS;
     36 import static com.android.internal.telephony.RILConstants.RIL_UNSOL_ON_USSD;
     37 import static com.android.internal.telephony.RILConstants.RIL_UNSOL_PCO_DATA;
     38 import static com.android.internal.telephony.RILConstants.RIL_UNSOL_RADIO_CAPABILITY;
     39 import static com.android.internal.telephony.RILConstants.RIL_UNSOL_RESEND_INCALL_MUTE;
     40 import static com.android.internal.telephony.RILConstants.RIL_UNSOL_RESPONSE_CALL_STATE_CHANGED;
     41 import static com.android.internal.telephony.RILConstants.RIL_UNSOL_RESPONSE_CDMA_NEW_SMS;
     42 import static com.android.internal.telephony.RILConstants.RIL_UNSOL_RESPONSE_IMS_NETWORK_STATE_CHANGED;
     43 import static com.android.internal.telephony.RILConstants.RIL_UNSOL_RESPONSE_NETWORK_STATE_CHANGED;
     44 import static com.android.internal.telephony.RILConstants.RIL_UNSOL_RESPONSE_NEW_BROADCAST_SMS;
     45 import static com.android.internal.telephony.RILConstants.RIL_UNSOL_RESPONSE_NEW_SMS;
     46 import static com.android.internal.telephony.RILConstants.RIL_UNSOL_RESPONSE_NEW_SMS_ON_SIM;
     47 import static com.android.internal.telephony.RILConstants.RIL_UNSOL_RESPONSE_NEW_SMS_STATUS_REPORT;
     48 import static com.android.internal.telephony.RILConstants.RIL_UNSOL_RESPONSE_RADIO_STATE_CHANGED;
     49 import static com.android.internal.telephony.RILConstants.RIL_UNSOL_RESPONSE_SIM_STATUS_CHANGED;
     50 import static com.android.internal.telephony.RILConstants.RIL_UNSOL_RESTRICTED_STATE_CHANGED;
     51 import static com.android.internal.telephony.RILConstants.RIL_UNSOL_RIL_CONNECTED;
     52 import static com.android.internal.telephony.RILConstants.RIL_UNSOL_RINGBACK_TONE;
     53 import static com.android.internal.telephony.RILConstants.RIL_UNSOL_SIGNAL_STRENGTH;
     54 import static com.android.internal.telephony.RILConstants.RIL_UNSOL_SIM_REFRESH;
     55 import static com.android.internal.telephony.RILConstants.RIL_UNSOL_SIM_SMS_STORAGE_FULL;
     56 import static com.android.internal.telephony.RILConstants.RIL_UNSOL_SRVCC_STATE_NOTIFY;
     57 import static com.android.internal.telephony.RILConstants.RIL_UNSOL_STK_CALL_SETUP;
     58 import static com.android.internal.telephony.RILConstants.RIL_UNSOL_STK_CC_ALPHA_NOTIFY;
     59 import static com.android.internal.telephony.RILConstants.RIL_UNSOL_STK_EVENT_NOTIFY;
     60 import static com.android.internal.telephony.RILConstants.RIL_UNSOL_STK_PROACTIVE_COMMAND;
     61 import static com.android.internal.telephony.RILConstants.RIL_UNSOL_STK_SESSION_END;
     62 import static com.android.internal.telephony.RILConstants.RIL_UNSOL_SUPP_SVC_NOTIFICATION;
     63 import static com.android.internal.telephony.RILConstants.RIL_UNSOL_UICC_SUBSCRIPTION_STATUS_CHANGED;
     64 import static com.android.internal.telephony.RILConstants.RIL_UNSOL_VOICE_RADIO_TECH_CHANGED;
     65 import static com.android.internal.telephony.RILConstants.RIL_UNSOl_CDMA_PRL_CHANGED;
     66 
     67 import android.hardware.radio.V1_0.CdmaCallWaiting;
     68 import android.hardware.radio.V1_0.CdmaInformationRecord;
     69 import android.hardware.radio.V1_0.CdmaLineControlInfoRecord;
     70 import android.hardware.radio.V1_0.CdmaNumberInfoRecord;
     71 import android.hardware.radio.V1_0.CdmaRedirectingNumberInfoRecord;
     72 import android.hardware.radio.V1_0.CdmaSignalInfoRecord;
     73 import android.hardware.radio.V1_0.CdmaSmsMessage;
     74 import android.hardware.radio.V1_0.CdmaT53AudioControlInfoRecord;
     75 import android.hardware.radio.V1_0.CfData;
     76 import android.hardware.radio.V1_0.LceDataInfo;
     77 import android.hardware.radio.V1_0.PcoDataInfo;
     78 import android.hardware.radio.V1_0.SetupDataCallResult;
     79 import android.hardware.radio.V1_0.SimRefreshResult;
     80 import android.hardware.radio.V1_0.SsInfoData;
     81 import android.hardware.radio.V1_0.StkCcUnsolSsResult;
     82 import android.hardware.radio.V1_0.SuppSvcNotification;
     83 import android.hardware.radio.V1_1.IRadioIndication;
     84 import android.hardware.radio.V1_1.KeepaliveStatus;
     85 import android.os.AsyncResult;
     86 import android.os.SystemProperties;
     87 import android.telephony.CellInfo;
     88 import android.telephony.PcoData;
     89 import android.telephony.SignalStrength;
     90 import android.telephony.SmsMessage;
     91 
     92 import com.android.internal.telephony.cdma.CdmaCallWaitingNotification;
     93 import com.android.internal.telephony.cdma.CdmaInformationRecords;
     94 import com.android.internal.telephony.cdma.SmsMessageConverter;
     95 import com.android.internal.telephony.dataconnection.DataCallResponse;
     96 import com.android.internal.telephony.gsm.SsData;
     97 import com.android.internal.telephony.gsm.SuppServiceNotification;
     98 import com.android.internal.telephony.nano.TelephonyProto.SmsSession;
     99 import com.android.internal.telephony.uicc.IccRefreshResponse;
    100 import com.android.internal.telephony.uicc.IccUtils;
    101 
    102 import java.util.ArrayList;
    103 
    104 public class RadioIndication extends IRadioIndication.Stub {
    105     RIL mRil;
    106 
    107     RadioIndication(RIL ril) {
    108         mRil = ril;
    109     }
    110 
    111     /**
    112      * Indicates when radio state changes.
    113      * @param indicationType RadioIndicationType
    114      * @param radioState android.hardware.radio.V1_0.RadioState
    115      */
    116     public void radioStateChanged(int indicationType, int radioState) {
    117         mRil.processIndication(indicationType);
    118 
    119         CommandsInterface.RadioState newState = getRadioStateFromInt(radioState);
    120         if (RIL.RILJ_LOGD) {
    121             mRil.unsljLogMore(RIL_UNSOL_RESPONSE_RADIO_STATE_CHANGED, "radioStateChanged: " +
    122                     newState);
    123         }
    124 
    125         mRil.setRadioState(newState);
    126     }
    127 
    128     public void callStateChanged(int indicationType) {
    129         mRil.processIndication(indicationType);
    130 
    131         if (RIL.RILJ_LOGD) mRil.unsljLog(RIL_UNSOL_RESPONSE_CALL_STATE_CHANGED);
    132 
    133         mRil.mCallStateRegistrants.notifyRegistrants();
    134     }
    135 
    136     /**
    137      * Indicates when either voice or data network state changed
    138      * @param indicationType RadioIndicationType
    139      */
    140     public void networkStateChanged(int indicationType) {
    141         mRil.processIndication(indicationType);
    142 
    143         if (RIL.RILJ_LOGD) mRil.unsljLog(RIL_UNSOL_RESPONSE_NETWORK_STATE_CHANGED);
    144 
    145         mRil.mNetworkStateRegistrants.notifyRegistrants();
    146     }
    147 
    148     public void newSms(int indicationType, ArrayList<Byte> pdu) {
    149         mRil.processIndication(indicationType);
    150 
    151         byte[] pduArray = RIL.arrayListToPrimitiveArray(pdu);
    152         if (RIL.RILJ_LOGD) mRil.unsljLog(RIL_UNSOL_RESPONSE_NEW_SMS);
    153 
    154         mRil.writeMetricsNewSms(SmsSession.Event.Tech.SMS_GSM,
    155                 SmsSession.Event.Format.SMS_FORMAT_3GPP);
    156 
    157         SmsMessage sms = SmsMessage.newFromCMT(pduArray);
    158         if (mRil.mGsmSmsRegistrant != null) {
    159             mRil.mGsmSmsRegistrant.notifyRegistrant(new AsyncResult(null, sms, null));
    160         }
    161     }
    162 
    163     public void newSmsStatusReport(int indicationType, ArrayList<Byte> pdu) {
    164         mRil.processIndication(indicationType);
    165 
    166         byte[] pduArray = RIL.arrayListToPrimitiveArray(pdu);
    167         if (RIL.RILJ_LOGD) mRil.unsljLog(RIL_UNSOL_RESPONSE_NEW_SMS_STATUS_REPORT);
    168 
    169         if (mRil.mSmsStatusRegistrant != null) {
    170             mRil.mSmsStatusRegistrant.notifyRegistrant(new AsyncResult(null, pduArray, null));
    171         }
    172     }
    173 
    174     public void newSmsOnSim(int indicationType, int recordNumber) {
    175         mRil.processIndication(indicationType);
    176 
    177         if (RIL.RILJ_LOGD) mRil.unsljLog(RIL_UNSOL_RESPONSE_NEW_SMS_ON_SIM);
    178 
    179         if (mRil.mSmsOnSimRegistrant != null) {
    180             mRil.mSmsOnSimRegistrant.notifyRegistrant(new AsyncResult(null, recordNumber, null));
    181         }
    182     }
    183 
    184     public void onUssd(int indicationType, int ussdModeType, String msg) {
    185         mRil.processIndication(indicationType);
    186 
    187         if (RIL.RILJ_LOGD) mRil.unsljLogMore(RIL_UNSOL_ON_USSD, "" + ussdModeType);
    188 
    189         // todo: Clean this up with a parcelable class for better self-documentation
    190         String[] resp = new String[2];
    191         resp[0] = "" + ussdModeType;
    192         resp[1] = msg;
    193         if (mRil.mUSSDRegistrant != null) {
    194             mRil.mUSSDRegistrant.notifyRegistrant(new AsyncResult (null, resp, null));
    195         }
    196     }
    197 
    198     public void nitzTimeReceived(int indicationType, String nitzTime, long receivedTime) {
    199         mRil.processIndication(indicationType);
    200 
    201         if (RIL.RILJ_LOGD) mRil.unsljLogRet(RIL_UNSOL_NITZ_TIME_RECEIVED, nitzTime);
    202 
    203         // todo: Clean this up with a parcelable class for better self-documentation
    204         Object[] result = new Object[2];
    205         result[0] = nitzTime;
    206         result[1] = receivedTime;
    207 
    208         boolean ignoreNitz = SystemProperties.getBoolean(
    209                 TelephonyProperties.PROPERTY_IGNORE_NITZ, false);
    210 
    211         if (ignoreNitz) {
    212             if (RIL.RILJ_LOGD) mRil.riljLog("ignoring UNSOL_NITZ_TIME_RECEIVED");
    213         } else {
    214             if (mRil.mNITZTimeRegistrant != null) {
    215                 mRil.mNITZTimeRegistrant.notifyRegistrant(new AsyncResult (null, result, null));
    216             }
    217             // in case NITZ time registrant isn't registered yet, or a new registrant
    218             // registers later
    219             mRil.mLastNITZTimeInfo = result;
    220         }
    221     }
    222 
    223     public void currentSignalStrength(int indicationType,
    224                                       android.hardware.radio.V1_0.SignalStrength signalStrength) {
    225         mRil.processIndication(indicationType);
    226 
    227         SignalStrength ss = RIL.convertHalSignalStrength(signalStrength);
    228         // Note this is set to "verbose" because it happens frequently
    229         if (RIL.RILJ_LOGV) mRil.unsljLogvRet(RIL_UNSOL_SIGNAL_STRENGTH, ss);
    230 
    231         if (mRil.mSignalStrengthRegistrant != null) {
    232             mRil.mSignalStrengthRegistrant.notifyRegistrant(new AsyncResult (null, ss, null));
    233         }
    234     }
    235 
    236     public void dataCallListChanged(int indicationType, ArrayList<SetupDataCallResult> dcList) {
    237         mRil.processIndication(indicationType);
    238 
    239         ArrayList<DataCallResponse> response = new ArrayList<>();
    240 
    241         for (SetupDataCallResult dcResult : dcList) {
    242             response.add(RIL.convertDataCallResult(dcResult));
    243         }
    244 
    245         if (RIL.RILJ_LOGD) mRil.unsljLogRet(RIL_UNSOL_DATA_CALL_LIST_CHANGED, response);
    246 
    247         mRil.mDataCallListChangedRegistrants.notifyRegistrants(
    248                 new AsyncResult(null, response, null));
    249     }
    250 
    251     public void suppSvcNotify(int indicationType, SuppSvcNotification suppSvcNotification) {
    252         mRil.processIndication(indicationType);
    253 
    254         SuppServiceNotification notification = new SuppServiceNotification();
    255         notification.notificationType = suppSvcNotification.isMT ? 1 : 0;
    256         notification.code = suppSvcNotification.code;
    257         notification.index = suppSvcNotification.index;
    258         notification.type = suppSvcNotification.type;
    259         notification.number = suppSvcNotification.number;
    260 
    261         if (RIL.RILJ_LOGD) mRil.unsljLogRet(RIL_UNSOL_SUPP_SVC_NOTIFICATION, notification);
    262 
    263         if (mRil.mSsnRegistrant != null) {
    264             mRil.mSsnRegistrant.notifyRegistrant(new AsyncResult (null, notification, null));
    265         }
    266     }
    267 
    268     public void stkSessionEnd(int indicationType) {
    269         mRil.processIndication(indicationType);
    270 
    271         if (RIL.RILJ_LOGD) mRil.unsljLog(RIL_UNSOL_STK_SESSION_END);
    272 
    273         if (mRil.mCatSessionEndRegistrant != null) {
    274             mRil.mCatSessionEndRegistrant.notifyRegistrant(new AsyncResult (null, null, null));
    275         }
    276     }
    277 
    278     public void stkProactiveCommand(int indicationType, String cmd) {
    279         mRil.processIndication(indicationType);
    280 
    281         if (RIL.RILJ_LOGD) mRil.unsljLog(RIL_UNSOL_STK_PROACTIVE_COMMAND);
    282 
    283         if (mRil.mCatProCmdRegistrant != null) {
    284             mRil.mCatProCmdRegistrant.notifyRegistrant(new AsyncResult (null, cmd, null));
    285         }
    286     }
    287 
    288     public void stkEventNotify(int indicationType, String cmd) {
    289         mRil.processIndication(indicationType);
    290 
    291         if (RIL.RILJ_LOGD) mRil.unsljLog(RIL_UNSOL_STK_EVENT_NOTIFY);
    292 
    293         if (mRil.mCatEventRegistrant != null) {
    294             mRil.mCatEventRegistrant.notifyRegistrant(new AsyncResult (null, cmd, null));
    295         }
    296     }
    297 
    298     public void stkCallSetup(int indicationType, long timeout) {
    299         mRil.processIndication(indicationType);
    300 
    301         if (RIL.RILJ_LOGD) mRil.unsljLogRet(RIL_UNSOL_STK_CALL_SETUP, timeout);
    302 
    303         if (mRil.mCatCallSetUpRegistrant != null) {
    304             mRil.mCatCallSetUpRegistrant.notifyRegistrant(new AsyncResult (null, timeout, null));
    305         }
    306     }
    307 
    308     public void simSmsStorageFull(int indicationType) {
    309         mRil.processIndication(indicationType);
    310 
    311         if (RIL.RILJ_LOGD) mRil.unsljLog(RIL_UNSOL_SIM_SMS_STORAGE_FULL);
    312 
    313         if (mRil.mIccSmsFullRegistrant != null) {
    314             mRil.mIccSmsFullRegistrant.notifyRegistrant();
    315         }
    316     }
    317 
    318     public void simRefresh(int indicationType, SimRefreshResult refreshResult) {
    319         mRil.processIndication(indicationType);
    320 
    321         IccRefreshResponse response = new IccRefreshResponse();
    322         response.refreshResult = refreshResult.type;
    323         response.efId = refreshResult.efId;
    324         response.aid = refreshResult.aid;
    325 
    326         if (RIL.RILJ_LOGD) mRil.unsljLogRet(RIL_UNSOL_SIM_REFRESH, response);
    327 
    328         mRil.mIccRefreshRegistrants.notifyRegistrants(new AsyncResult (null, response, null));
    329     }
    330 
    331     public void callRing(int indicationType, boolean isGsm, CdmaSignalInfoRecord record) {
    332         mRil.processIndication(indicationType);
    333 
    334         char response[] = null;
    335 
    336         // Ignore record for gsm
    337         if (!isGsm) {
    338             // todo: Clean this up with a parcelable class for better self-documentation
    339             response = new char[4];
    340             response[0] = (char) (record.isPresent ? 1 : 0);
    341             response[1] = (char) record.signalType;
    342             response[2] = (char) record.alertPitch;
    343             response[3] = (char) record.signal;
    344             mRil.writeMetricsCallRing(response);
    345         }
    346 
    347         if (RIL.RILJ_LOGD) mRil.unsljLogRet(RIL_UNSOL_CALL_RING, response);
    348 
    349         if (mRil.mRingRegistrant != null) {
    350             mRil.mRingRegistrant.notifyRegistrant(new AsyncResult (null, response, null));
    351         }
    352     }
    353 
    354     public void simStatusChanged(int indicationType) {
    355         mRil.processIndication(indicationType);
    356 
    357         if (RIL.RILJ_LOGD) mRil.unsljLog(RIL_UNSOL_RESPONSE_SIM_STATUS_CHANGED);
    358 
    359         mRil.mIccStatusChangedRegistrants.notifyRegistrants();
    360     }
    361 
    362     public void cdmaNewSms(int indicationType, CdmaSmsMessage msg) {
    363         mRil.processIndication(indicationType);
    364 
    365         if (RIL.RILJ_LOGD) mRil.unsljLog(RIL_UNSOL_RESPONSE_CDMA_NEW_SMS);
    366 
    367         mRil.writeMetricsNewSms(SmsSession.Event.Tech.SMS_CDMA,
    368                 SmsSession.Event.Format.SMS_FORMAT_3GPP2);
    369 
    370         // todo: conversion from CdmaSmsMessage to SmsMessage should be contained in this class so
    371         // that usage of auto-generated HAL classes is limited to this file
    372         SmsMessage sms = SmsMessageConverter.newSmsMessageFromCdmaSmsMessage(msg);
    373         if (mRil.mCdmaSmsRegistrant != null) {
    374             mRil.mCdmaSmsRegistrant.notifyRegistrant(new AsyncResult(null, sms, null));
    375         }
    376     }
    377 
    378     public void newBroadcastSms(int indicationType, ArrayList<Byte> data) {
    379         mRil.processIndication(indicationType);
    380 
    381         byte response[] = RIL.arrayListToPrimitiveArray(data);
    382         if (RIL.RILJ_LOGD) {
    383             mRil.unsljLogvRet(RIL_UNSOL_RESPONSE_NEW_BROADCAST_SMS,
    384                     IccUtils.bytesToHexString(response));
    385         }
    386 
    387         if (mRil.mGsmBroadcastSmsRegistrant != null) {
    388             mRil.mGsmBroadcastSmsRegistrant.notifyRegistrant(new AsyncResult(null, response, null));
    389         }
    390     }
    391 
    392     public void cdmaRuimSmsStorageFull(int indicationType) {
    393         mRil.processIndication(indicationType);
    394 
    395         if (RIL.RILJ_LOGD) mRil.unsljLog(RIL_UNSOL_CDMA_RUIM_SMS_STORAGE_FULL);
    396 
    397         if (mRil.mIccSmsFullRegistrant != null) {
    398             mRil.mIccSmsFullRegistrant.notifyRegistrant();
    399         }
    400     }
    401 
    402     public void restrictedStateChanged(int indicationType, int state) {
    403         mRil.processIndication(indicationType);
    404 
    405         if (RIL.RILJ_LOGD) mRil.unsljLogvRet(RIL_UNSOL_RESTRICTED_STATE_CHANGED, state);
    406 
    407         if (mRil.mRestrictedStateRegistrant != null) {
    408             mRil.mRestrictedStateRegistrant.notifyRegistrant(new AsyncResult (null, state, null));
    409         }
    410     }
    411 
    412     public void enterEmergencyCallbackMode(int indicationType) {
    413         mRil.processIndication(indicationType);
    414 
    415         if (RIL.RILJ_LOGD) mRil.unsljLog(RIL_UNSOL_ENTER_EMERGENCY_CALLBACK_MODE);
    416 
    417         if (mRil.mEmergencyCallbackModeRegistrant != null) {
    418             mRil.mEmergencyCallbackModeRegistrant.notifyRegistrant();
    419         }
    420     }
    421 
    422     public void cdmaCallWaiting(int indicationType, CdmaCallWaiting callWaitingRecord) {
    423         mRil.processIndication(indicationType);
    424 
    425         // todo: create a CdmaCallWaitingNotification constructor that takes in these fields to make
    426         // sure no fields are missing
    427         CdmaCallWaitingNotification notification = new CdmaCallWaitingNotification();
    428         notification.number = callWaitingRecord.number;
    429         notification.numberPresentation = CdmaCallWaitingNotification.presentationFromCLIP(
    430                 callWaitingRecord.numberPresentation);
    431         notification.name = callWaitingRecord.name;
    432         notification.namePresentation = notification.numberPresentation;
    433         notification.isPresent = callWaitingRecord.signalInfoRecord.isPresent ? 1 : 0;
    434         notification.signalType = callWaitingRecord.signalInfoRecord.signalType;
    435         notification.alertPitch = callWaitingRecord.signalInfoRecord.alertPitch;
    436         notification.signal = callWaitingRecord.signalInfoRecord.signal;
    437         notification.numberType = callWaitingRecord.numberType;
    438         notification.numberPlan = callWaitingRecord.numberPlan;
    439 
    440         if (RIL.RILJ_LOGD) mRil.unsljLogRet(RIL_UNSOL_CDMA_CALL_WAITING, notification);
    441 
    442         mRil.mCallWaitingInfoRegistrants.notifyRegistrants(
    443                 new AsyncResult (null, notification, null));
    444     }
    445 
    446     public void cdmaOtaProvisionStatus(int indicationType, int status) {
    447         mRil.processIndication(indicationType);
    448 
    449         int response[] = new int[1];
    450         response[0] = status;
    451 
    452         if (RIL.RILJ_LOGD) mRil.unsljLogRet(RIL_UNSOL_CDMA_OTA_PROVISION_STATUS, response);
    453 
    454         mRil.mOtaProvisionRegistrants.notifyRegistrants(new AsyncResult (null, response, null));
    455     }
    456 
    457     public void cdmaInfoRec(int indicationType,
    458                             android.hardware.radio.V1_0.CdmaInformationRecords records) {
    459         mRil.processIndication(indicationType);
    460 
    461         int numberOfInfoRecs = records.infoRec.size();
    462         for (int i = 0; i < numberOfInfoRecs; i++) {
    463             CdmaInformationRecord record = records.infoRec.get(i);
    464             int id = record.name;
    465             CdmaInformationRecords cdmaInformationRecords;
    466             switch (id) {
    467                 case CdmaInformationRecords.RIL_CDMA_DISPLAY_INFO_REC:
    468                 case CdmaInformationRecords.RIL_CDMA_EXTENDED_DISPLAY_INFO_REC:
    469                     CdmaInformationRecords.CdmaDisplayInfoRec cdmaDisplayInfoRec =
    470                             new CdmaInformationRecords.CdmaDisplayInfoRec(id,
    471                             record.display.get(0).alphaBuf);
    472                     cdmaInformationRecords = new CdmaInformationRecords(cdmaDisplayInfoRec);
    473                     break;
    474 
    475                 case CdmaInformationRecords.RIL_CDMA_CALLED_PARTY_NUMBER_INFO_REC:
    476                 case CdmaInformationRecords.RIL_CDMA_CALLING_PARTY_NUMBER_INFO_REC:
    477                 case CdmaInformationRecords.RIL_CDMA_CONNECTED_NUMBER_INFO_REC:
    478                     CdmaNumberInfoRecord numInfoRecord = record.number.get(0);
    479                     CdmaInformationRecords.CdmaNumberInfoRec cdmaNumberInfoRec =
    480                             new CdmaInformationRecords.CdmaNumberInfoRec(id,
    481                             numInfoRecord.number,
    482                             numInfoRecord.numberType,
    483                             numInfoRecord.numberPlan,
    484                             numInfoRecord.pi,
    485                             numInfoRecord.si);
    486                     cdmaInformationRecords = new CdmaInformationRecords(cdmaNumberInfoRec);
    487                     break;
    488 
    489                 case CdmaInformationRecords.RIL_CDMA_SIGNAL_INFO_REC:
    490                     CdmaSignalInfoRecord signalInfoRecord = record.signal.get(0);
    491                     CdmaInformationRecords.CdmaSignalInfoRec cdmaSignalInfoRec =
    492                             new CdmaInformationRecords.CdmaSignalInfoRec(
    493                             signalInfoRecord.isPresent ? 1 : 0,
    494                             signalInfoRecord.signalType,
    495                             signalInfoRecord.alertPitch,
    496                             signalInfoRecord.signal);
    497                     cdmaInformationRecords = new CdmaInformationRecords(cdmaSignalInfoRec);
    498                     break;
    499 
    500                 case CdmaInformationRecords.RIL_CDMA_REDIRECTING_NUMBER_INFO_REC:
    501                     CdmaRedirectingNumberInfoRecord redirectingNumberInfoRecord =
    502                             record.redir.get(0);
    503                     CdmaInformationRecords.CdmaRedirectingNumberInfoRec
    504                             cdmaRedirectingNumberInfoRec =
    505                             new CdmaInformationRecords.CdmaRedirectingNumberInfoRec(
    506                             redirectingNumberInfoRecord.redirectingNumber.number,
    507                             redirectingNumberInfoRecord.redirectingNumber.numberType,
    508                             redirectingNumberInfoRecord.redirectingNumber.numberPlan,
    509                             redirectingNumberInfoRecord.redirectingNumber.pi,
    510                             redirectingNumberInfoRecord.redirectingNumber.si,
    511                             redirectingNumberInfoRecord.redirectingReason);
    512                     cdmaInformationRecords = new CdmaInformationRecords(
    513                             cdmaRedirectingNumberInfoRec);
    514                     break;
    515 
    516                 case CdmaInformationRecords.RIL_CDMA_LINE_CONTROL_INFO_REC:
    517                     CdmaLineControlInfoRecord lineControlInfoRecord = record.lineCtrl.get(0);
    518                     CdmaInformationRecords.CdmaLineControlInfoRec cdmaLineControlInfoRec =
    519                             new CdmaInformationRecords.CdmaLineControlInfoRec(
    520                             lineControlInfoRecord.lineCtrlPolarityIncluded,
    521                             lineControlInfoRecord.lineCtrlToggle,
    522                             lineControlInfoRecord.lineCtrlReverse,
    523                             lineControlInfoRecord.lineCtrlPowerDenial);
    524                     cdmaInformationRecords = new CdmaInformationRecords(cdmaLineControlInfoRec);
    525                     break;
    526 
    527                 case CdmaInformationRecords.RIL_CDMA_T53_CLIR_INFO_REC:
    528                     CdmaInformationRecords.CdmaT53ClirInfoRec cdmaT53ClirInfoRec =
    529                             new CdmaInformationRecords.CdmaT53ClirInfoRec(record.clir.get(0).cause);
    530                     cdmaInformationRecords = new CdmaInformationRecords(cdmaT53ClirInfoRec);
    531                     break;
    532 
    533                 case CdmaInformationRecords.RIL_CDMA_T53_AUDIO_CONTROL_INFO_REC:
    534                     CdmaT53AudioControlInfoRecord audioControlInfoRecord = record.audioCtrl.get(0);
    535                     CdmaInformationRecords.CdmaT53AudioControlInfoRec cdmaT53AudioControlInfoRec =
    536                             new CdmaInformationRecords.CdmaT53AudioControlInfoRec(
    537                             audioControlInfoRecord.upLink,
    538                             audioControlInfoRecord.downLink);
    539                     cdmaInformationRecords = new CdmaInformationRecords(cdmaT53AudioControlInfoRec);
    540                     break;
    541 
    542                 default:
    543                     throw new RuntimeException("RIL_UNSOL_CDMA_INFO_REC: unsupported record. Got "
    544                             + CdmaInformationRecords.idToString(id) + " ");
    545             }
    546 
    547             if (RIL.RILJ_LOGD) mRil.unsljLogRet(RIL_UNSOL_CDMA_INFO_REC, cdmaInformationRecords);
    548             mRil.notifyRegistrantsCdmaInfoRec(cdmaInformationRecords);
    549         }
    550     }
    551 
    552     public void indicateRingbackTone(int indicationType, boolean start) {
    553         mRil.processIndication(indicationType);
    554 
    555         if (RIL.RILJ_LOGD) mRil.unsljLogvRet(RIL_UNSOL_RINGBACK_TONE, start);
    556 
    557         mRil.mRingbackToneRegistrants.notifyRegistrants(new AsyncResult(null, start, null));
    558     }
    559 
    560     public void resendIncallMute(int indicationType) {
    561         mRil.processIndication(indicationType);
    562 
    563         if (RIL.RILJ_LOGD) mRil.unsljLog(RIL_UNSOL_RESEND_INCALL_MUTE);
    564 
    565         mRil.mResendIncallMuteRegistrants.notifyRegistrants();
    566     }
    567 
    568     public void cdmaSubscriptionSourceChanged(int indicationType, int cdmaSource) {
    569         mRil.processIndication(indicationType);
    570 
    571         int response[] = new int[1];
    572         response[0] = cdmaSource;
    573 
    574         if (RIL.RILJ_LOGD) mRil.unsljLogRet(RIL_UNSOL_CDMA_SUBSCRIPTION_SOURCE_CHANGED, response);
    575 
    576         mRil.mCdmaSubscriptionChangedRegistrants.notifyRegistrants(
    577                 new AsyncResult (null, response, null));
    578     }
    579 
    580     public void cdmaPrlChanged(int indicationType, int version) {
    581         mRil.processIndication(indicationType);
    582 
    583         int response[] = new int[1];
    584         response[0] = version;
    585 
    586         if (RIL.RILJ_LOGD) mRil.unsljLogRet(RIL_UNSOl_CDMA_PRL_CHANGED, response);
    587 
    588         mRil.mCdmaPrlChangedRegistrants.notifyRegistrants(
    589                 new AsyncResult (null, response, null));
    590     }
    591 
    592     public void exitEmergencyCallbackMode(int indicationType) {
    593         mRil.processIndication(indicationType);
    594 
    595         if (RIL.RILJ_LOGD) mRil.unsljLog(RIL_UNSOL_EXIT_EMERGENCY_CALLBACK_MODE);
    596 
    597         mRil.mExitEmergencyCallbackModeRegistrants.notifyRegistrants();
    598     }
    599 
    600     public void rilConnected(int indicationType) {
    601         mRil.processIndication(indicationType);
    602 
    603         if (RIL.RILJ_LOGD) mRil.unsljLog(RIL_UNSOL_RIL_CONNECTED);
    604 
    605         // Initial conditions
    606         mRil.setRadioPower(false, null);
    607         mRil.setCdmaSubscriptionSource(mRil.mCdmaSubscription, null);
    608         mRil.setCellInfoListRate();
    609         // todo: this should not require a version number now. Setting it to latest RIL version for
    610         // now.
    611         mRil.notifyRegistrantsRilConnectionChanged(15);
    612     }
    613 
    614     public void voiceRadioTechChanged(int indicationType, int rat) {
    615         mRil.processIndication(indicationType);
    616 
    617         int response[] = new int[1];
    618         response[0] = rat;
    619 
    620         if (RIL.RILJ_LOGD) mRil.unsljLogRet(RIL_UNSOL_VOICE_RADIO_TECH_CHANGED, response);
    621 
    622         mRil.mVoiceRadioTechChangedRegistrants.notifyRegistrants(
    623                 new AsyncResult (null, response, null));
    624     }
    625 
    626     public void cellInfoList(int indicationType,
    627                              ArrayList<android.hardware.radio.V1_0.CellInfo> records) {
    628         mRil.processIndication(indicationType);
    629 
    630         ArrayList<CellInfo> response = RIL.convertHalCellInfoList(records);
    631 
    632         if (RIL.RILJ_LOGD) mRil.unsljLogRet(RIL_UNSOL_CELL_INFO_LIST, response);
    633 
    634         mRil.mRilCellInfoListRegistrants.notifyRegistrants(new AsyncResult (null, response, null));
    635     }
    636 
    637     /** Incremental network scan results */
    638     public void networkScanResult(int indicationType,
    639                                   android.hardware.radio.V1_1.NetworkScanResult result) {
    640         responseCellInfos(indicationType, result);
    641     }
    642 
    643     public void imsNetworkStateChanged(int indicationType) {
    644         mRil.processIndication(indicationType);
    645 
    646         if (RIL.RILJ_LOGD) mRil.unsljLog(RIL_UNSOL_RESPONSE_IMS_NETWORK_STATE_CHANGED);
    647 
    648         mRil.mImsNetworkStateChangedRegistrants.notifyRegistrants();
    649     }
    650 
    651     public void subscriptionStatusChanged(int indicationType, boolean activate) {
    652         mRil.processIndication(indicationType);
    653 
    654         int response[] = new int[1];
    655         response[0] = activate ? 1 : 0;
    656 
    657         if (RIL.RILJ_LOGD) mRil.unsljLogRet(RIL_UNSOL_UICC_SUBSCRIPTION_STATUS_CHANGED, response);
    658 
    659         mRil.mSubscriptionStatusRegistrants.notifyRegistrants(
    660                 new AsyncResult (null, response, null));
    661     }
    662 
    663     public void srvccStateNotify(int indicationType, int state) {
    664         mRil.processIndication(indicationType);
    665 
    666         int response[] = new int[1];
    667         response[0] = state;
    668 
    669         if (RIL.RILJ_LOGD) mRil.unsljLogRet(RIL_UNSOL_SRVCC_STATE_NOTIFY, response);
    670 
    671         mRil.writeMetricsSrvcc(state);
    672 
    673         mRil.mSrvccStateRegistrants.notifyRegistrants(
    674                 new AsyncResult (null, response, null));
    675     }
    676 
    677     public void hardwareConfigChanged(
    678             int indicationType,
    679             ArrayList<android.hardware.radio.V1_0.HardwareConfig> configs) {
    680         mRil.processIndication(indicationType);
    681 
    682         ArrayList<HardwareConfig> response = RIL.convertHalHwConfigList(configs, mRil);
    683 
    684         if (RIL.RILJ_LOGD) mRil.unsljLogRet(RIL_UNSOL_HARDWARE_CONFIG_CHANGED, response);
    685 
    686         mRil.mHardwareConfigChangeRegistrants.notifyRegistrants(
    687                 new AsyncResult (null, response, null));
    688     }
    689 
    690     public void radioCapabilityIndication(int indicationType,
    691                                           android.hardware.radio.V1_0.RadioCapability rc) {
    692         mRil.processIndication(indicationType);
    693 
    694         RadioCapability response = RIL.convertHalRadioCapability(rc, mRil);
    695 
    696         if (RIL.RILJ_LOGD) mRil.unsljLogRet(RIL_UNSOL_RADIO_CAPABILITY, response);
    697 
    698         mRil.mPhoneRadioCapabilityChangedRegistrants.notifyRegistrants(
    699                 new AsyncResult (null, response, null));
    700     }
    701 
    702     public void onSupplementaryServiceIndication(int indicationType, StkCcUnsolSsResult ss) {
    703         mRil.processIndication(indicationType);
    704 
    705         int num;
    706         SsData ssData = new SsData();
    707 
    708         ssData.serviceType = ssData.ServiceTypeFromRILInt(ss.serviceType);
    709         ssData.requestType = ssData.RequestTypeFromRILInt(ss.requestType);
    710         ssData.teleserviceType = ssData.TeleserviceTypeFromRILInt(ss.teleserviceType);
    711         ssData.serviceClass = ss.serviceClass; // This is service class sent in the SS request.
    712         ssData.result = ss.result; // This is the result of the SS request.
    713 
    714         if (ssData.serviceType.isTypeCF() &&
    715                 ssData.requestType.isTypeInterrogation()) {
    716             CfData cfData = ss.cfData.get(0);
    717             num = cfData.cfInfo.size();
    718             ssData.cfInfo = new CallForwardInfo[num];
    719 
    720             for (int i = 0; i < num; i++) {
    721                 android.hardware.radio.V1_0.CallForwardInfo cfInfo = cfData.cfInfo.get(i);
    722                 ssData.cfInfo[i] = new CallForwardInfo();
    723 
    724                 ssData.cfInfo[i].status = cfInfo.status;
    725                 ssData.cfInfo[i].reason = cfInfo.reason;
    726                 ssData.cfInfo[i].serviceClass = cfInfo.serviceClass;
    727                 ssData.cfInfo[i].toa = cfInfo.toa;
    728                 ssData.cfInfo[i].number = cfInfo.number;
    729                 ssData.cfInfo[i].timeSeconds = cfInfo.timeSeconds;
    730 
    731                 mRil.riljLog("[SS Data] CF Info " + i + " : " +  ssData.cfInfo[i]);
    732             }
    733         } else {
    734             SsInfoData ssInfo = ss.ssInfo.get(0);
    735             num = ssInfo.ssInfo.size();
    736             ssData.ssInfo = new int[num];
    737             for (int i = 0; i < num; i++) {
    738                 ssData.ssInfo[i] = ssInfo.ssInfo.get(i);
    739                 mRil.riljLog("[SS Data] SS Info " + i + " : " +  ssData.ssInfo[i]);
    740             }
    741         }
    742 
    743         if (RIL.RILJ_LOGD) mRil.unsljLogRet(RIL_UNSOL_ON_SS, ssData);
    744 
    745         if (mRil.mSsRegistrant != null) {
    746             mRil.mSsRegistrant.notifyRegistrant(new AsyncResult(null, ssData, null));
    747         }
    748     }
    749 
    750     public void stkCallControlAlphaNotify(int indicationType, String alpha) {
    751         mRil.processIndication(indicationType);
    752 
    753         if (RIL.RILJ_LOGD) mRil.unsljLogRet(RIL_UNSOL_STK_CC_ALPHA_NOTIFY, alpha);
    754 
    755         if (mRil.mCatCcAlphaRegistrant != null) {
    756             mRil.mCatCcAlphaRegistrant.notifyRegistrant(new AsyncResult (null, alpha, null));
    757         }
    758     }
    759 
    760     public void lceData(int indicationType, LceDataInfo lce) {
    761         mRil.processIndication(indicationType);
    762 
    763         ArrayList<Integer> response = RIL.convertHalLceData(lce, mRil);
    764 
    765         if (RIL.RILJ_LOGD) mRil.unsljLogRet(RIL_UNSOL_LCEDATA_RECV, response);
    766 
    767         if (mRil.mLceInfoRegistrant != null) {
    768             mRil.mLceInfoRegistrant.notifyRegistrant(new AsyncResult(null, response, null));
    769         }
    770     }
    771 
    772     public void pcoData(int indicationType, PcoDataInfo pco) {
    773         mRil.processIndication(indicationType);
    774 
    775         PcoData response = new PcoData(pco.cid,
    776                 pco.bearerProto,
    777                 pco.pcoId,
    778                 RIL.arrayListToPrimitiveArray(pco.contents));
    779 
    780         if (RIL.RILJ_LOGD) mRil.unsljLogRet(RIL_UNSOL_PCO_DATA, response);
    781 
    782         mRil.mPcoDataRegistrants.notifyRegistrants(new AsyncResult(null, response, null));
    783     }
    784 
    785     public void modemReset(int indicationType, String reason) {
    786         mRil.processIndication(indicationType);
    787 
    788         if (RIL.RILJ_LOGD) mRil.unsljLogRet(RIL_UNSOL_MODEM_RESTART, reason);
    789 
    790         mRil.writeMetricsModemRestartEvent(reason);
    791         mRil.mModemResetRegistrants.notifyRegistrants(new AsyncResult(null, reason, null));
    792     }
    793 
    794     /**
    795      * Indicates when the carrier info to encrypt IMSI is being requested
    796      * @param indicationType RadioIndicationType
    797      */
    798     public void carrierInfoForImsiEncryption(int indicationType) {
    799         mRil.processIndication(indicationType);
    800 
    801         if (RIL.RILJ_LOGD) mRil.unsljLogRet(RIL_UNSOL_CARRIER_INFO_IMSI_ENCRYPTION, null);
    802 
    803         mRil.mCarrierInfoForImsiEncryptionRegistrants.notifyRegistrants(
    804                 new AsyncResult(null, null, null));
    805     }
    806 
    807     /**
    808      * Indicates a change in the status of an ongoing Keepalive session
    809      * @param indicationType RadioIndicationType
    810      * @param keepaliveStatus Status of the ongoing Keepalive session
    811      */
    812     public void keepaliveStatus(int indicationType, KeepaliveStatus keepaliveStatus) {
    813         throw new UnsupportedOperationException("keepaliveStatus Indications are not implemented");
    814     }
    815 
    816     private CommandsInterface.RadioState getRadioStateFromInt(int stateInt) {
    817         CommandsInterface.RadioState state;
    818 
    819         switch(stateInt) {
    820             case android.hardware.radio.V1_0.RadioState.OFF:
    821                 state = CommandsInterface.RadioState.RADIO_OFF;
    822                 break;
    823             case android.hardware.radio.V1_0.RadioState.UNAVAILABLE:
    824                 state = CommandsInterface.RadioState.RADIO_UNAVAILABLE;
    825                 break;
    826             case android.hardware.radio.V1_0.RadioState.ON:
    827                 state = CommandsInterface.RadioState.RADIO_ON;
    828                 break;
    829             default:
    830                 throw new RuntimeException("Unrecognized RadioState: " + stateInt);
    831         }
    832         return state;
    833     }
    834 
    835     private void responseCellInfos(int indicationType,
    836                                    android.hardware.radio.V1_1.NetworkScanResult result) {
    837         mRil.processIndication(indicationType);
    838 
    839         NetworkScanResult nsr = null;
    840         ArrayList<CellInfo> infos = RIL.convertHalCellInfoList(result.networkInfos);
    841         nsr = new NetworkScanResult(result.status, result.error, infos);
    842         if (RIL.RILJ_LOGD) mRil.unsljLogRet(RIL_UNSOL_NETWORK_SCAN_RESULT, nsr);
    843         mRil.mRilNetworkScanResultRegistrants.notifyRegistrants(new AsyncResult(null, nsr, null));
    844     }
    845 }
    846