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