1package com.android.internal.telephony;
2
3import com.android.ims.ImsConfig;
4import com.android.ims.ImsReasonInfo;
5import com.android.ims.internal.ImsCallSession;
6import com.android.internal.telephony.dataconnection.DataCallResponse;
7import com.android.internal.telephony.imsphone.ImsPhoneCall;
8
9import android.content.ComponentName;
10import android.content.Context;
11import android.content.Intent;
12import android.content.ServiceConnection;
13import android.net.ConnectivityMetricsLogger;
14import android.os.Bundle;
15import android.os.IBinder;
16import android.os.Parcel;
17import android.os.RemoteException;
18import android.telephony.ServiceState;
19import android.util.Log;
20import android.util.SparseArray;
21
22import java.util.ArrayList;
23
24import static com.android.internal.telephony.RILConstants.*;
25
26/**
27 * Log telephony events
28 *
29 * @hide
30 */
31public class TelephonyEventLog extends ConnectivityMetricsLogger {
32    private static String TAG = "TelephonyEventLog";
33    private static final boolean DBG = true;
34    private static final boolean VDBG = false; // STOPSHIP if true
35
36    public static final int TAG_SETTINGS = 1;
37    public static final int TAG_SERVICE_STATE = 2;
38    public static final int TAG_IMS_CONNECTION_STATE = 3;
39    public static final int TAG_IMS_CAPABILITIES = 4;
40
41    public static final int TAG_DATA_CALL_LIST = 5;
42
43    public static final int TAG_PHONE_STATE = 8;
44
45    public static final int TAG_RIL_REQUEST = 1001;
46    public static final int TAG_RIL_RESPONSE = 1002;
47    public static final int TAG_RIL_UNSOL_RESPONSE = 1003;
48    public static final int TAG_RIL_TIMEOUT_RESPONSE = 1004;
49
50    // IImsCallSession
51    public static final int TAG_IMS_CALL_START = 2001;
52    public static final int TAG_IMS_CALL_START_CONFERENCE = 2002;
53    public static final int TAG_IMS_CALL_RECEIVE = 2003;
54    public static final int TAG_IMS_CALL_ACCEPT = 2004;
55    public static final int TAG_IMS_CALL_REJECT = 2005;
56    public static final int TAG_IMS_CALL_TERMINATE = 2006;
57    public static final int TAG_IMS_CALL_HOLD = 2007;
58    public static final int TAG_IMS_CALL_RESUME = 2008;
59    public static final int TAG_IMS_CALL_MERGE = 2009;
60    public static final int TAG_IMS_CALL_UPDATE = 2010;
61
62    // IImsCallSessionListener
63    public static final int TAG_IMS_CALL_PROGRESSING = 2011;
64    public static final int TAG_IMS_CALL_STARTED = 2012;
65    public static final int TAG_IMS_CALL_START_FAILED = 2013;
66    public static final int TAG_IMS_CALL_TERMINATED = 2014;
67    public static final int TAG_IMS_CALL_HELD = 2015;
68    public static final int TAG_IMS_CALL_HOLD_FAILED = 2016;
69    public static final int TAG_IMS_CALL_HOLD_RECEIVED = 2017;
70    public static final int TAG_IMS_CALL_RESUMED = 2018;
71    public static final int TAG_IMS_CALL_RESUME_FAILED = 2019;
72    public static final int TAG_IMS_CALL_RESUME_RECEIVED = 2020;
73    public static final int TAG_IMS_CALL_UPDATED = 2021;
74    public static final int TAG_IMS_CALL_UPDATE_FAILED = 2022;
75    public static final int TAG_IMS_CALL_MERGED = 2023;
76    public static final int TAG_IMS_CALL_MERGE_FAILED = 2024;
77    public static final int TAG_IMS_CALL_HANDOVER = 2025;
78    public static final int TAG_IMS_CALL_HANDOVER_FAILED = 2026;
79
80    public static final int TAG_IMS_CALL_TTY_MODE_RECEIVED = 2027;
81
82    public static final int TAG_IMS_CONFERENCE_PARTICIPANTS_STATE_CHANGED = 2028;
83    public static final int TAG_IMS_MULTIPARTY_STATE_CHANGED = 2029;
84
85    public static final int TAG_IMS_CALL_STATE = 2030;
86
87    public static final int SETTING_AIRPLANE_MODE = 1;
88    public static final int SETTING_CELL_DATA_ENABLED = 2;
89    public static final int SETTING_DATA_ROAMING_ENABLED = 3;
90    public static final int SETTING_PREFERRED_NETWORK_MODE = 4;
91    public static final int SETTING_WIFI_ENABLED = 5;
92    public static final int SETTING_VO_LTE_ENABLED = 6;
93    public static final int SETTING_VO_WIFI_ENABLED = 7;
94    public static final int SETTING_WFC_MODE = 8;
95    public static final int SETTING_VI_LTE_ENABLED = 9;
96    public static final int SETTING_VI_WIFI_ENABLED = 10;
97
98    public static final int IMS_CONNECTION_STATE_CONNECTED = 1;
99    public static final int IMS_CONNECTION_STATE_PROGRESSING = 2;
100    public static final int IMS_CONNECTION_STATE_DISCONNECTED = 3;
101    public static final int IMS_CONNECTION_STATE_RESUMED = 4;
102    public static final int IMS_CONNECTION_STATE_SUSPENDED = 5;
103
104    public static final String DATA_KEY_PHONE_ID = "phoneId";
105    public static final String DATA_KEY_PARAM1 = "param1";
106    public static final String DATA_KEY_PARAM2 = "param2";
107
108    public static final String DATA_KEY_REASONINFO_CODE = "code";
109    public static final String DATA_KEY_REASONINFO_EXTRA_CODE = "extra-code";
110    public static final String DATA_KEY_REASONINFO_EXTRA_MESSAGE = "extra-message";
111    public static final String DATA_KEY_VOLTE = "VoLTE";
112    public static final String DATA_KEY_VILTE = "ViLTE";
113    public static final String DATA_KEY_VOWIFI = "VoWiFi";
114    public static final String DATA_KEY_VIWIFI = "ViWiFi";
115    public static final String DATA_KEY_UTLTE = "UTLTE";
116    public static final String DATA_KEY_UTWIFI = "UTWiFi";
117    public static final String DATA_KEY_RAT = "rat";
118    public static final String DATA_KEY_DATA_PROFILE = "profile";
119    public static final String DATA_KEY_APN = "apn";
120    public static final String DATA_KEY_PROTOCOL = "protocol";
121    public static final String DATA_KEY_DATA_DEACTIVATE_REASON = "reason";
122    public static final String DATA_KEY_DATA_CALL_STATUSES = "statuses";
123    public static final String DATA_KEY_DATA_CALL_CIDS = "cids";
124    public static final String DATA_KEY_DATA_CALL_ACTIVES = "actives";
125    public static final String DATA_KEY_DATA_CALL_TYPES = "types";
126    public static final String DATA_KEY_DATA_CALL_IFNAMES = "ifnames";
127    public static final String DATA_KEY_CLIR_MODE = "clirMode";
128    public static final String DATA_KEY_RIL_CALL_RING_RESPONSE = "response";
129    public static final String DATA_KEY_RIL_HANGUP_GSM_INDEX = "gsmIndex";
130    public static final String DATA_KEY_RIL_ERROR = "error";
131    public static final String DATA_KEY_DATA_CALL_STATUS = "status";
132    public static final String DATA_KEY_DATA_CALL_RETRY = "retry";
133    public static final String DATA_KEY_DATA_CALL_CID = "cid";
134    public static final String DATA_KEY_DATA_CALL_ACTIVE = "active";
135    public static final String DATA_KEY_DATA_CALL_TYPE = "type";
136    public static final String DATA_KEY_DATA_CALL_IFNAME = "ifname";
137    public static final String DATA_KEY_SMS_MESSAGE_REF = "messageRef";
138    public static final String DATA_KEY_SMS_ACK_PDU = "ackPDU";
139    public static final String DATA_KEY_SMS_ERROR_CODE = "errorCode";
140    public static final String DATA_KEY_CALLEE = "callee";
141    public static final String DATA_KEY_PARTICIPANTS = "participants";
142    public static final String DATA_KEY_SRC_TECH = "src-tech";
143    public static final String DATA_KEY_TARGET_TECH = "target-tech";
144
145    public static final String SERVICE_STATE_VOICE_REG_STATE = "regSt";
146    public static final String SERVICE_STATE_DATA_REG_STATE = "dataRegSt";
147    public static final String SERVICE_STATE_VOICE_ROAMING_TYPE = "roamingType";
148    public static final String SERVICE_STATE_DATA_ROAMING_TYPE = "dataRoamingType";
149    public static final String SERVICE_STATE_VOICE_ALPHA_LONG = "alphaLong";
150    public static final String SERVICE_STATE_VOICE_ALPNA_SHORT = "alphaShort";
151    public static final String SERVICE_STATE_VOICE_NUMERIC = "operator";
152    public static final String SERVICE_STATE_DATA_ALPHA_LONG = "dataAlphaLong";
153    public static final String SERVICE_STATE_DATA_ALPNA_SHORT = "dataAlphaShort";
154    public static final String SERVICE_STATE_DATA_NUMERIC = "dataOperator";
155    public static final String SERVICE_STATE_VOICE_RAT = "rat";
156    public static final String SERVICE_STATE_DATA_RAT = "dataRat";
157    public static final String SERVICE_STATE_EMERGENCY_ONLY = "emergencyOnly";
158
159    int mPhoneId;
160
161    public TelephonyEventLog(int phoneId) {
162        super();
163
164        mPhoneId = phoneId;
165    }
166
167    private void writeEvent(int tag, Bundle data) {
168        writeEvent(System.currentTimeMillis(), tag, -1, -1, data);
169    }
170
171    private void writeEvent(int tag, int param1, int param2) {
172        writeEvent(System.currentTimeMillis(), tag, param1, param2, null);
173    }
174
175    private void writeEvent(int tag, int param1, int param2, Bundle data) {
176        writeEvent(System.currentTimeMillis(), tag, param1, param2, data);
177    }
178
179    private void writeEvent(long timestamp, int tag, int param1, int param2, Bundle data) {
180        Bundle b = data;
181        if (b == null) {
182            b = new Bundle();
183        }
184        b.putInt(DATA_KEY_PHONE_ID, mPhoneId);
185        b.putInt(DATA_KEY_PARAM1, param1);
186        b.putInt(DATA_KEY_PARAM2, param2);
187
188        logEvent(timestamp, ConnectivityMetricsLogger.COMPONENT_TAG_TELEPHONY, tag, b);
189    }
190
191    private int mVoiceRegState = -1;
192    private int mDataRegState = -1;
193    private int mVoiceRoamingType = -1;
194    private int mDataRoamingType = -1;
195    private String mVoiceOperatorAlphaShort;
196    private String mVoiceOperatorNumeric;
197    private String mDataOperatorAlphaShort;
198    private String mDataOperatorNumeric;
199    private int mRilVoiceRadioTechnology = -1;
200    private int mRilDataRadioTechnology = -1;
201    private boolean mEmergencyOnly = false;
202
203    public static boolean equals(Object a, Object b) {
204        return (a == null ? b == null : a.equals(b));
205    }
206
207    public void writeServiceStateChanged(ServiceState serviceState) {
208        Bundle b = new Bundle();
209        boolean changed = false;
210        if (mVoiceRegState != serviceState.getVoiceRegState()) {
211            mVoiceRegState = serviceState.getVoiceRegState();
212            b.putInt(SERVICE_STATE_VOICE_REG_STATE, mVoiceRegState);
213            changed = true;
214        }
215        if (mDataRegState != serviceState.getDataRegState()) {
216            mDataRegState = serviceState.getDataRegState();
217            b.putInt(SERVICE_STATE_DATA_REG_STATE, mDataRegState);
218            changed = true;
219        }
220        if (mVoiceRoamingType != serviceState.getVoiceRoamingType()) {
221            mVoiceRoamingType = serviceState.getVoiceRoamingType();
222            b.putInt(SERVICE_STATE_VOICE_ROAMING_TYPE, mVoiceRoamingType);
223            changed = true;
224        }
225        if (mDataRoamingType != serviceState.getDataRoamingType()) {
226            mDataRoamingType = serviceState.getDataRoamingType();
227            b.putInt(SERVICE_STATE_DATA_ROAMING_TYPE, mDataRoamingType);
228            changed = true;
229        }
230        if (!equals(mVoiceOperatorAlphaShort, serviceState.getVoiceOperatorAlphaShort())
231                || !equals(mVoiceOperatorNumeric, serviceState.getVoiceOperatorNumeric())) {
232            // TODO: Evaluate if we need to send AlphaLong. AlphaShort+Numeric might be enough.
233            //b.putString(SERVICE_STATE_VOICE_ALPHA_LONG, serviceState.getVoiceOperatorAlphaLong());
234            mVoiceOperatorAlphaShort = serviceState.getVoiceOperatorAlphaShort();
235            mVoiceOperatorNumeric = serviceState.getVoiceOperatorNumeric();
236            b.putString(SERVICE_STATE_VOICE_ALPNA_SHORT, mVoiceOperatorAlphaShort);
237            b.putString(SERVICE_STATE_VOICE_NUMERIC, mVoiceOperatorNumeric);
238            changed = true;
239        }
240        if (!equals(mDataOperatorAlphaShort, serviceState.getDataOperatorAlphaShort())
241                || !equals(mDataOperatorNumeric, serviceState.getDataOperatorNumeric())) {
242            // TODO: Evaluate if we need to send AlphaLong. AlphaShort+Numeric might be enough.
243            //b.putString(SERVICE_STATE_DATA_ALPHA_LONG, serviceState.getDataOperatorAlphaLong());
244            mDataOperatorAlphaShort = serviceState.getDataOperatorAlphaShort();
245            mDataOperatorNumeric = serviceState.getDataOperatorNumeric();
246            b.putString(SERVICE_STATE_DATA_ALPNA_SHORT, mDataOperatorAlphaShort);
247            b.putString(SERVICE_STATE_DATA_NUMERIC, mDataOperatorNumeric);
248            changed = true;
249        }
250        if (mRilVoiceRadioTechnology != serviceState.getRilVoiceRadioTechnology()) {
251            mRilVoiceRadioTechnology = serviceState.getRilVoiceRadioTechnology();
252            b.putInt(SERVICE_STATE_VOICE_RAT, mRilVoiceRadioTechnology);
253            changed = true;
254        }
255        if (mRilDataRadioTechnology != serviceState.getRilDataRadioTechnology()) {
256            mRilDataRadioTechnology = serviceState.getRilDataRadioTechnology();
257            b.putInt(SERVICE_STATE_DATA_RAT, mRilDataRadioTechnology);
258            changed = true;
259        }
260        if (mEmergencyOnly != serviceState.isEmergencyOnly()) {
261            mEmergencyOnly = serviceState.isEmergencyOnly();
262            b.putBoolean(SERVICE_STATE_EMERGENCY_ONLY, mEmergencyOnly);
263            changed = true;
264        }
265
266        if (changed) {
267            writeEvent(TAG_SERVICE_STATE, b);
268        }
269    }
270
271    public void writeSetAirplaneMode(boolean enabled) {
272        writeEvent(TAG_SETTINGS, SETTING_AIRPLANE_MODE, enabled ? 1 : 0);
273    }
274
275    public void writeSetCellDataEnabled(boolean enabled) {
276        writeEvent(TAG_SETTINGS, SETTING_CELL_DATA_ENABLED, enabled ? 1 : 0);
277    }
278
279    public void writeSetDataRoamingEnabled(boolean enabled) {
280        writeEvent(TAG_SETTINGS, SETTING_DATA_ROAMING_ENABLED, enabled ? 1 : 0);
281    }
282
283    public void writeSetPreferredNetworkType(int mode) {
284        writeEvent(TAG_SETTINGS, SETTING_PREFERRED_NETWORK_MODE, mode);
285    }
286
287    public void writeSetWifiEnabled(boolean enabled) {
288        writeEvent(TAG_SETTINGS, SETTING_WIFI_ENABLED, enabled ? 1 : 0);
289    }
290
291    public void writeSetWfcMode(int mode) {
292        writeEvent(TAG_SETTINGS, SETTING_WFC_MODE, mode);
293    }
294
295    public void writeImsSetFeatureValue(int feature, int network, int value, int status) {
296        switch (feature) {
297            case ImsConfig.FeatureConstants.FEATURE_TYPE_VOICE_OVER_LTE:
298                writeEvent(TAG_SETTINGS, SETTING_VO_LTE_ENABLED, value);
299                break;
300            case ImsConfig.FeatureConstants.FEATURE_TYPE_VOICE_OVER_WIFI:
301                writeEvent(TAG_SETTINGS, SETTING_VO_WIFI_ENABLED, value);
302                break;
303            case ImsConfig.FeatureConstants.FEATURE_TYPE_VIDEO_OVER_LTE:
304                writeEvent(TAG_SETTINGS, SETTING_VI_LTE_ENABLED, value);
305                break;
306            case ImsConfig.FeatureConstants.FEATURE_TYPE_VIDEO_OVER_WIFI:
307                writeEvent(TAG_SETTINGS, SETTING_VI_WIFI_ENABLED, value);
308                break;
309        }
310    }
311
312    public void writeOnImsConnectionState(int state, ImsReasonInfo reasonInfo) {
313        writeEvent(TAG_IMS_CONNECTION_STATE, state, -1, imsReasonInfoToBundle(reasonInfo));
314    }
315
316    private final boolean[] mImsCapabilities = {false, false, false, false, false, false};
317
318    public void writeOnImsCapabilities(boolean[] capabilities) {
319        boolean changed = false;
320        for (int i = 0; i < capabilities.length; i++) {
321            if (mImsCapabilities[i] != capabilities[i]) {
322                mImsCapabilities[i] = capabilities[i];
323                changed = true;
324            }
325        }
326
327        if (changed) {
328            Bundle b = new Bundle();
329            b.putBoolean(DATA_KEY_VOLTE, capabilities[0]);
330            b.putBoolean(DATA_KEY_VILTE, capabilities[1]);
331            b.putBoolean(DATA_KEY_VOWIFI, capabilities[2]);
332            b.putBoolean(DATA_KEY_VIWIFI, capabilities[3]);
333            b.putBoolean(DATA_KEY_UTLTE, capabilities[4]);
334            b.putBoolean(DATA_KEY_UTWIFI, capabilities[5]);
335            writeEvent(TAG_IMS_CAPABILITIES, b);
336        }
337    }
338
339    public void writeRilSetupDataCall(int rilSerial,
340            int radioTechnology, int profile, String apn,
341            String user, String password, int authType, String protocol) {
342        Bundle b = new Bundle();
343        b.putInt(DATA_KEY_RAT, radioTechnology);
344        b.putInt(DATA_KEY_DATA_PROFILE, profile);
345        b.putString(DATA_KEY_APN, apn);
346        b.putString(DATA_KEY_PROTOCOL, protocol);
347        writeEvent(TAG_RIL_REQUEST, RIL_REQUEST_SETUP_DATA_CALL, rilSerial, b);
348    }
349
350    public void writeRilDeactivateDataCall(int rilSerial,
351            int cid, int reason) {
352        Bundle b = new Bundle();
353        b.putInt(DATA_KEY_DATA_CALL_CID, cid);
354        b.putInt(DATA_KEY_DATA_DEACTIVATE_REASON, reason);
355        writeEvent(TAG_RIL_REQUEST, RIL_REQUEST_DEACTIVATE_DATA_CALL, rilSerial, b);
356    }
357
358    public void writeRilDataCallList(ArrayList<DataCallResponse> dcsList) {
359        Bundle b = new Bundle();
360        int[] statuses = new int[dcsList.size()];
361        int[] cids = new int[dcsList.size()];
362        int[] actives = new int[dcsList.size()];
363        String[] types = new String[dcsList.size()];
364        String[] ifnames = new String[dcsList.size()];
365        for (int i = 0; i < dcsList.size(); i++) {
366            DataCallResponse dcs = dcsList.get(i);
367            statuses[i] = dcs.status;
368            cids[i] = dcs.cid;
369            actives[i] = dcs.active;
370            types[i] = dcs.type;
371            ifnames[i] = dcs.ifname;
372        }
373        b.putIntArray(DATA_KEY_DATA_CALL_STATUSES, statuses);
374        b.putIntArray(DATA_KEY_DATA_CALL_CIDS, cids);
375        b.putIntArray(DATA_KEY_DATA_CALL_ACTIVES, actives);
376        b.putStringArray(DATA_KEY_DATA_CALL_TYPES, types);
377        b.putStringArray(DATA_KEY_DATA_CALL_IFNAMES, ifnames);
378        writeEvent(TAG_DATA_CALL_LIST, -1, -1, b);
379    }
380
381    public void writeRilDial(int rilSerial,
382            int clirMode, UUSInfo uusInfo) {
383        Bundle b = new Bundle();
384        b.putInt(DATA_KEY_CLIR_MODE, clirMode);
385        writeEvent(TAG_RIL_REQUEST, RIL_REQUEST_DIAL, rilSerial, b);
386    }
387
388    public void writeRilCallRing(char[] response) {
389        Bundle b = new Bundle();
390        b.putCharArray(DATA_KEY_RIL_CALL_RING_RESPONSE, response);
391        writeEvent(TAG_RIL_UNSOL_RESPONSE, RIL_UNSOL_CALL_RING, -1, b);
392    }
393
394    public void writeRilHangup(int rilSerial, int req,
395            int gsmIndex) {
396        Bundle b = new Bundle();
397        b.putInt(DATA_KEY_RIL_HANGUP_GSM_INDEX, gsmIndex);
398        writeEvent(TAG_RIL_REQUEST, req, rilSerial, b);
399    }
400
401    public void writeRilAnswer(int rilSerial) {
402        writeEvent(TAG_RIL_REQUEST, RIL_REQUEST_ANSWER, rilSerial, null);
403    }
404
405    public void writeRilSrvcc(int rilSrvccState) {
406        writeEvent(TAG_RIL_UNSOL_RESPONSE, RIL_UNSOL_SRVCC_STATE_NOTIFY, rilSrvccState, null);
407    }
408
409    public void writeRilSendSms(int rilSerial, int req) {
410        writeEvent(TAG_RIL_REQUEST, req, rilSerial, null);
411    }
412
413    public void writeRilNewSms(int response) {
414        writeEvent(TAG_RIL_UNSOL_RESPONSE, response, -1, null);
415    }
416
417    public void writeOnRilSolicitedResponse(int rilSerial, int rilError, int rilRequest,
418            Object ret) {
419        Bundle b = new Bundle();
420        if (rilError != 0) b.putInt(DATA_KEY_RIL_ERROR, rilError);
421        switch (rilRequest) {
422            case RIL_REQUEST_SETUP_DATA_CALL:
423                DataCallResponse dataCall = (DataCallResponse)ret;
424                b.putInt(DATA_KEY_DATA_CALL_STATUS, dataCall.status);
425                b.putInt(DATA_KEY_DATA_CALL_RETRY, dataCall.suggestedRetryTime);
426                b.putInt(DATA_KEY_DATA_CALL_CID, dataCall.cid);
427                b.putInt(DATA_KEY_DATA_CALL_ACTIVE, dataCall.active);
428                b.putString(DATA_KEY_DATA_CALL_TYPE, dataCall.type);
429                b.putString(DATA_KEY_DATA_CALL_IFNAME, dataCall.ifname);
430                writeEvent(TAG_RIL_RESPONSE, rilRequest, rilSerial, b);
431                break;
432
433            case RIL_REQUEST_DEACTIVATE_DATA_CALL:
434            case RIL_REQUEST_HANGUP:
435            case RIL_REQUEST_HANGUP_WAITING_OR_BACKGROUND:
436            case RIL_REQUEST_HANGUP_FOREGROUND_RESUME_BACKGROUND:
437            case RIL_REQUEST_DIAL:
438            case RIL_REQUEST_ANSWER:
439                writeEvent(TAG_RIL_RESPONSE, rilRequest, rilSerial, b);
440                break;
441
442            case RIL_REQUEST_SEND_SMS:
443            case RIL_REQUEST_SEND_SMS_EXPECT_MORE:
444            case RIL_REQUEST_CDMA_SEND_SMS:
445            case RIL_REQUEST_IMS_SEND_SMS:
446                SmsResponse smsResponse = (SmsResponse)ret;
447                b.putInt(DATA_KEY_SMS_MESSAGE_REF, smsResponse.mMessageRef);
448                b.putString(DATA_KEY_SMS_ACK_PDU, smsResponse.mAckPdu);
449                b.putInt(DATA_KEY_SMS_ERROR_CODE, smsResponse.mErrorCode);
450                writeEvent(TAG_RIL_RESPONSE, rilRequest, rilSerial, b);
451                break;
452        }
453    }
454
455    public void writeOnRilTimeoutResponse(int rilSerial, int rilRequest) {
456        writeEvent(TAG_RIL_TIMEOUT_RESPONSE, rilRequest, rilSerial, null);
457    }
458
459    public void writePhoneState(PhoneConstants.State phoneState) {
460        int state;
461        switch (phoneState) {
462            case IDLE: state = 0; break;
463            case RINGING: state = 1; break;
464            case OFFHOOK: state = 2; break;
465            default: state = -1; break;
466        }
467        writeEvent(TAG_PHONE_STATE, state, -1);
468    }
469
470    /**
471     * Initial state
472     * @param session
473     * @param callState
474     */
475    public void writeImsCallState(ImsCallSession session, ImsPhoneCall.State callState) {
476        int state;
477        switch (callState) {
478            case IDLE: state = 0; break;
479            case ACTIVE: state = 1; break;
480            case HOLDING: state = 2; break;
481            case DIALING: state = 3; break;
482            case ALERTING: state = 4; break;
483            case INCOMING: state = 5; break;
484            case WAITING: state = 6; break;
485            case DISCONNECTED: state = 7; break;
486            case DISCONNECTING: state = 8; break;
487            default: state = -1; break;
488        }
489        writeEvent(TAG_IMS_CALL_STATE, getCallId(session), state);
490    }
491
492    private void writeImsCallEvent(int tag, ImsCallSession session) {
493        writeEvent(tag, getCallId(session), -1);
494    }
495
496    private void writeImsCallEvent(int tag, ImsCallSession session, ImsReasonInfo reasonInfo) {
497        writeEvent(tag, getCallId(session), -1,imsReasonInfoToBundle(reasonInfo));
498    }
499
500    private Bundle imsReasonInfoToBundle(ImsReasonInfo reasonInfo) {
501        if (reasonInfo != null) {
502            Bundle b = new Bundle();
503            b.putInt(DATA_KEY_REASONINFO_CODE, reasonInfo.mCode);
504            b.putInt(DATA_KEY_REASONINFO_EXTRA_CODE, reasonInfo.mExtraCode);
505            b.putString(DATA_KEY_REASONINFO_EXTRA_MESSAGE, reasonInfo.mExtraMessage);
506            return b;
507        }
508        return null;
509    }
510
511    public void writeOnImsCallStart(ImsCallSession session, String callee) {
512        Bundle b = new Bundle();
513        b.putString(DATA_KEY_CALLEE, callee);
514        writeEvent(TAG_IMS_CALL_START, getCallId(session), -1, b);
515    }
516
517    public void writeOnImsCallStartConference(ImsCallSession session, String[] participants) {
518        Bundle b = new Bundle();
519        b.putStringArray(DATA_KEY_PARTICIPANTS, participants);
520        writeEvent(TAG_IMS_CALL_START_CONFERENCE, getCallId(session), -1, b);
521    }
522
523    public void writeOnImsCallReceive(ImsCallSession session) {
524        writeImsCallEvent(TAG_IMS_CALL_RECEIVE, session);
525    }
526
527    public void writeOnImsCallAccept(ImsCallSession session) {
528        writeImsCallEvent(TAG_IMS_CALL_ACCEPT, session);
529    }
530
531    public void writeOnImsCallReject(ImsCallSession session) {
532        writeImsCallEvent(TAG_IMS_CALL_REJECT, session);
533    }
534
535    public void writeOnImsCallTerminate(ImsCallSession session) {
536        writeImsCallEvent(TAG_IMS_CALL_TERMINATE, session);
537    }
538
539    public void writeOnImsCallHold(ImsCallSession session) {
540        writeImsCallEvent(TAG_IMS_CALL_HOLD, session);
541    }
542
543    public void writeOnImsCallResume(ImsCallSession session) {
544        writeImsCallEvent(TAG_IMS_CALL_RESUME, session);
545    }
546
547    public void writeOnImsCallProgressing(ImsCallSession session) {
548        writeImsCallEvent(TAG_IMS_CALL_PROGRESSING, session);
549    }
550
551    public void writeOnImsCallStarted(ImsCallSession session) {
552        writeImsCallEvent(TAG_IMS_CALL_STARTED, session);
553    }
554
555    public void writeOnImsCallStartFailed(ImsCallSession session, ImsReasonInfo reasonInfo) {
556        writeImsCallEvent(TAG_IMS_CALL_START_FAILED, session, reasonInfo);
557    }
558
559    public void writeOnImsCallTerminated(ImsCallSession session, ImsReasonInfo reasonInfo) {
560        writeImsCallEvent(TAG_IMS_CALL_TERMINATED, session, reasonInfo);
561    }
562
563    public void writeOnImsCallHeld(ImsCallSession session) {
564        writeImsCallEvent(TAG_IMS_CALL_HELD, session);
565    }
566
567    public void writeOnImsCallHoldReceived(ImsCallSession session) {
568        writeImsCallEvent(TAG_IMS_CALL_HOLD_RECEIVED, session);
569    }
570
571    public void writeOnImsCallHoldFailed(ImsCallSession session, ImsReasonInfo reasonInfo) {
572        writeImsCallEvent(TAG_IMS_CALL_HOLD_FAILED, session, reasonInfo);
573    }
574
575    public void writeOnImsCallResumed(ImsCallSession session) {
576        writeImsCallEvent(TAG_IMS_CALL_RESUMED, session);
577    }
578
579    public void writeOnImsCallResumeReceived(ImsCallSession session) {
580        writeImsCallEvent(TAG_IMS_CALL_RESUME_RECEIVED, session);
581    }
582
583    public void writeOnImsCallResumeFailed(ImsCallSession session, ImsReasonInfo reasonInfo) {
584        writeImsCallEvent(TAG_IMS_CALL_RESUME_FAILED, session, reasonInfo);
585    }
586
587    public void writeOnImsCallHandover(ImsCallSession session,
588            int srcAccessTech, int targetAccessTech, ImsReasonInfo reasonInfo) {
589        Bundle b = imsHandoverToBundle(srcAccessTech, targetAccessTech, reasonInfo);
590        writeEvent(TAG_IMS_CALL_HANDOVER, getCallId(session), -1, b);
591    }
592
593    public void writeOnImsCallHandoverFailed(ImsCallSession session,
594            int srcAccessTech, int targetAccessTech, ImsReasonInfo reasonInfo) {
595        Bundle b = imsHandoverToBundle(srcAccessTech, targetAccessTech, reasonInfo);
596        writeEvent(TAG_IMS_CALL_HANDOVER_FAILED, getCallId(session), -1, b);
597    }
598
599    /**
600     * Extracts the call ID from an ImsSession.
601     *
602     * @param session The session.
603     * @return The call ID for the session, or -1 if none was found.
604     */
605    private int getCallId(ImsCallSession session) {
606        if (session == null) {
607            return -1;
608        }
609
610        try {
611            return Integer.parseInt(session.getCallId());
612        } catch (NumberFormatException nfe) {
613            return -1;
614        }
615    }
616
617    private Bundle imsHandoverToBundle(int srcAccessTech, int targetAccessTech,
618            ImsReasonInfo reasonInfo) {
619        Bundle b = new Bundle();
620        b.putInt(DATA_KEY_SRC_TECH, srcAccessTech);
621        b.putInt(DATA_KEY_TARGET_TECH, targetAccessTech);
622        b.putInt(DATA_KEY_REASONINFO_CODE, reasonInfo.mCode);
623        b.putInt(DATA_KEY_REASONINFO_EXTRA_CODE, reasonInfo.mExtraCode);
624        b.putString(DATA_KEY_REASONINFO_EXTRA_MESSAGE, reasonInfo.mExtraMessage);
625        return b;
626    }
627}
628