1 package com.android.internal.telephony;
2 
3 import com.android.ims.ImsConfig;
4 import com.android.ims.ImsReasonInfo;
5 import com.android.ims.internal.ImsCallSession;
6 import com.android.internal.telephony.dataconnection.DataCallResponse;
7 import com.android.internal.telephony.imsphone.ImsPhoneCall;
8 
9 import android.content.ComponentName;
10 import android.content.Context;
11 import android.content.Intent;
12 import android.content.ServiceConnection;
13 import android.net.ConnectivityMetricsLogger;
14 import android.os.Bundle;
15 import android.os.IBinder;
16 import android.os.Parcel;
17 import android.os.RemoteException;
18 import android.telephony.ServiceState;
19 import android.util.Log;
20 import android.util.SparseArray;
21 
22 import java.util.ArrayList;
23 
24 import static com.android.internal.telephony.RILConstants.*;
25 
26 /**
27  * Log telephony events
28  *
29  * @hide
30  */
31 public 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 
TelephonyEventLog(int phoneId)161     public TelephonyEventLog(int phoneId) {
162         super();
163 
164         mPhoneId = phoneId;
165     }
166 
writeEvent(int tag, Bundle data)167     private void writeEvent(int tag, Bundle data) {
168         writeEvent(System.currentTimeMillis(), tag, -1, -1, data);
169     }
170 
writeEvent(int tag, int param1, int param2)171     private void writeEvent(int tag, int param1, int param2) {
172         writeEvent(System.currentTimeMillis(), tag, param1, param2, null);
173     }
174 
writeEvent(int tag, int param1, int param2, Bundle data)175     private void writeEvent(int tag, int param1, int param2, Bundle data) {
176         writeEvent(System.currentTimeMillis(), tag, param1, param2, data);
177     }
178 
writeEvent(long timestamp, int tag, int param1, int param2, Bundle data)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 
equals(Object a, Object b)203     public static boolean equals(Object a, Object b) {
204         return (a == null ? b == null : a.equals(b));
205     }
206 
writeServiceStateChanged(ServiceState serviceState)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 
writeSetAirplaneMode(boolean enabled)271     public void writeSetAirplaneMode(boolean enabled) {
272         writeEvent(TAG_SETTINGS, SETTING_AIRPLANE_MODE, enabled ? 1 : 0);
273     }
274 
writeSetCellDataEnabled(boolean enabled)275     public void writeSetCellDataEnabled(boolean enabled) {
276         writeEvent(TAG_SETTINGS, SETTING_CELL_DATA_ENABLED, enabled ? 1 : 0);
277     }
278 
writeSetDataRoamingEnabled(boolean enabled)279     public void writeSetDataRoamingEnabled(boolean enabled) {
280         writeEvent(TAG_SETTINGS, SETTING_DATA_ROAMING_ENABLED, enabled ? 1 : 0);
281     }
282 
writeSetPreferredNetworkType(int mode)283     public void writeSetPreferredNetworkType(int mode) {
284         writeEvent(TAG_SETTINGS, SETTING_PREFERRED_NETWORK_MODE, mode);
285     }
286 
writeSetWifiEnabled(boolean enabled)287     public void writeSetWifiEnabled(boolean enabled) {
288         writeEvent(TAG_SETTINGS, SETTING_WIFI_ENABLED, enabled ? 1 : 0);
289     }
290 
writeSetWfcMode(int mode)291     public void writeSetWfcMode(int mode) {
292         writeEvent(TAG_SETTINGS, SETTING_WFC_MODE, mode);
293     }
294 
writeImsSetFeatureValue(int feature, int network, int value, int status)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 
writeOnImsConnectionState(int state, ImsReasonInfo reasonInfo)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 
writeOnImsCapabilities(boolean[] capabilities)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 
writeRilSetupDataCall(int rilSerial, int radioTechnology, int profile, String apn, String user, String password, int authType, String protocol)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 
writeRilDeactivateDataCall(int rilSerial, int cid, int reason)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 
writeRilDataCallList(ArrayList<DataCallResponse> dcsList)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 
writeRilDial(int rilSerial, int clirMode, UUSInfo uusInfo)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 
writeRilCallRing(char[] response)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 
writeRilHangup(int rilSerial, int req, int gsmIndex)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 
writeRilAnswer(int rilSerial)401     public void writeRilAnswer(int rilSerial) {
402         writeEvent(TAG_RIL_REQUEST, RIL_REQUEST_ANSWER, rilSerial, null);
403     }
404 
writeRilSrvcc(int rilSrvccState)405     public void writeRilSrvcc(int rilSrvccState) {
406         writeEvent(TAG_RIL_UNSOL_RESPONSE, RIL_UNSOL_SRVCC_STATE_NOTIFY, rilSrvccState, null);
407     }
408 
writeRilSendSms(int rilSerial, int req)409     public void writeRilSendSms(int rilSerial, int req) {
410         writeEvent(TAG_RIL_REQUEST, req, rilSerial, null);
411     }
412 
writeRilNewSms(int response)413     public void writeRilNewSms(int response) {
414         writeEvent(TAG_RIL_UNSOL_RESPONSE, response, -1, null);
415     }
416 
writeOnRilSolicitedResponse(int rilSerial, int rilError, int rilRequest, Object ret)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 
writeOnRilTimeoutResponse(int rilSerial, int rilRequest)455     public void writeOnRilTimeoutResponse(int rilSerial, int rilRequest) {
456         writeEvent(TAG_RIL_TIMEOUT_RESPONSE, rilRequest, rilSerial, null);
457     }
458 
writePhoneState(PhoneConstants.State phoneState)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      */
writeImsCallState(ImsCallSession session, ImsPhoneCall.State callState)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 
writeImsCallEvent(int tag, ImsCallSession session)492     private void writeImsCallEvent(int tag, ImsCallSession session) {
493         writeEvent(tag, getCallId(session), -1);
494     }
495 
writeImsCallEvent(int tag, ImsCallSession session, ImsReasonInfo reasonInfo)496     private void writeImsCallEvent(int tag, ImsCallSession session, ImsReasonInfo reasonInfo) {
497         writeEvent(tag, getCallId(session), -1,imsReasonInfoToBundle(reasonInfo));
498     }
499 
imsReasonInfoToBundle(ImsReasonInfo reasonInfo)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 
writeOnImsCallStart(ImsCallSession session, String callee)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 
writeOnImsCallStartConference(ImsCallSession session, String[] participants)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 
writeOnImsCallReceive(ImsCallSession session)523     public void writeOnImsCallReceive(ImsCallSession session) {
524         writeImsCallEvent(TAG_IMS_CALL_RECEIVE, session);
525     }
526 
writeOnImsCallAccept(ImsCallSession session)527     public void writeOnImsCallAccept(ImsCallSession session) {
528         writeImsCallEvent(TAG_IMS_CALL_ACCEPT, session);
529     }
530 
writeOnImsCallReject(ImsCallSession session)531     public void writeOnImsCallReject(ImsCallSession session) {
532         writeImsCallEvent(TAG_IMS_CALL_REJECT, session);
533     }
534 
writeOnImsCallTerminate(ImsCallSession session)535     public void writeOnImsCallTerminate(ImsCallSession session) {
536         writeImsCallEvent(TAG_IMS_CALL_TERMINATE, session);
537     }
538 
writeOnImsCallHold(ImsCallSession session)539     public void writeOnImsCallHold(ImsCallSession session) {
540         writeImsCallEvent(TAG_IMS_CALL_HOLD, session);
541     }
542 
writeOnImsCallResume(ImsCallSession session)543     public void writeOnImsCallResume(ImsCallSession session) {
544         writeImsCallEvent(TAG_IMS_CALL_RESUME, session);
545     }
546 
writeOnImsCallProgressing(ImsCallSession session)547     public void writeOnImsCallProgressing(ImsCallSession session) {
548         writeImsCallEvent(TAG_IMS_CALL_PROGRESSING, session);
549     }
550 
writeOnImsCallStarted(ImsCallSession session)551     public void writeOnImsCallStarted(ImsCallSession session) {
552         writeImsCallEvent(TAG_IMS_CALL_STARTED, session);
553     }
554 
writeOnImsCallStartFailed(ImsCallSession session, ImsReasonInfo reasonInfo)555     public void writeOnImsCallStartFailed(ImsCallSession session, ImsReasonInfo reasonInfo) {
556         writeImsCallEvent(TAG_IMS_CALL_START_FAILED, session, reasonInfo);
557     }
558 
writeOnImsCallTerminated(ImsCallSession session, ImsReasonInfo reasonInfo)559     public void writeOnImsCallTerminated(ImsCallSession session, ImsReasonInfo reasonInfo) {
560         writeImsCallEvent(TAG_IMS_CALL_TERMINATED, session, reasonInfo);
561     }
562 
writeOnImsCallHeld(ImsCallSession session)563     public void writeOnImsCallHeld(ImsCallSession session) {
564         writeImsCallEvent(TAG_IMS_CALL_HELD, session);
565     }
566 
writeOnImsCallHoldReceived(ImsCallSession session)567     public void writeOnImsCallHoldReceived(ImsCallSession session) {
568         writeImsCallEvent(TAG_IMS_CALL_HOLD_RECEIVED, session);
569     }
570 
writeOnImsCallHoldFailed(ImsCallSession session, ImsReasonInfo reasonInfo)571     public void writeOnImsCallHoldFailed(ImsCallSession session, ImsReasonInfo reasonInfo) {
572         writeImsCallEvent(TAG_IMS_CALL_HOLD_FAILED, session, reasonInfo);
573     }
574 
writeOnImsCallResumed(ImsCallSession session)575     public void writeOnImsCallResumed(ImsCallSession session) {
576         writeImsCallEvent(TAG_IMS_CALL_RESUMED, session);
577     }
578 
writeOnImsCallResumeReceived(ImsCallSession session)579     public void writeOnImsCallResumeReceived(ImsCallSession session) {
580         writeImsCallEvent(TAG_IMS_CALL_RESUME_RECEIVED, session);
581     }
582 
writeOnImsCallResumeFailed(ImsCallSession session, ImsReasonInfo reasonInfo)583     public void writeOnImsCallResumeFailed(ImsCallSession session, ImsReasonInfo reasonInfo) {
584         writeImsCallEvent(TAG_IMS_CALL_RESUME_FAILED, session, reasonInfo);
585     }
586 
writeOnImsCallHandover(ImsCallSession session, int srcAccessTech, int targetAccessTech, ImsReasonInfo reasonInfo)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 
writeOnImsCallHandoverFailed(ImsCallSession session, int srcAccessTech, int targetAccessTech, ImsReasonInfo reasonInfo)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      */
getCallId(ImsCallSession session)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 
imsHandoverToBundle(int srcAccessTech, int targetAccessTech, ImsReasonInfo reasonInfo)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