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