private void loadSpnOverrides() { FileReader spnReader; File spnFile = new File(Environment.getRootDirectory(), PARTNER_SPN_OVERRIDE_PATH); File oemSpnFile = new File(Environment.getOemDirectory(), OEM_SPN_OVERRIDE_PATH); if (oemSpnFile.exists()) { // OEM image exist SPN xml, get the timestamp from OEM & System image for comparison. long oemSpnTime = oemSpnFile.lastModified(); long sysSpnTime = spnFile.lastModified(); Rlog.d(LOG_TAG, "SPN Timestamp: oemTime = " + oemSpnTime + " sysTime = " + sysSpnTime); // To get the newer version of SPN from OEM image if (oemSpnTime > sysSpnTime) { Rlog.d(LOG_TAG, "SPN in OEM image is newer than System image"); spnFile = oemSpnFile; } } else { // No SPN in OEM image, so load it from system image. Rlog.d( LOG_TAG, "No SPN in OEM image = " + oemSpnFile.getPath() + " Load SPN from system image"); } try { spnReader = new FileReader(spnFile); } catch (FileNotFoundException e) { Rlog.w(LOG_TAG, "Can not open " + spnFile.getAbsolutePath()); return; } try { XmlPullParser parser = Xml.newPullParser(); parser.setInput(spnReader); XmlUtils.beginDocument(parser, "spnOverrides"); while (true) { XmlUtils.nextElement(parser); String name = parser.getName(); if (!"spnOverride".equals(name)) { break; } String numeric = parser.getAttributeValue(null, "numeric"); String data = parser.getAttributeValue(null, "spn"); mCarrierSpnMap.put(numeric, data); } spnReader.close(); } catch (XmlPullParserException e) { Rlog.w(LOG_TAG, "Exception in spn-conf parser " + e); } catch (IOException e) { Rlog.w(LOG_TAG, "Exception in spn-conf parser " + e); } }
/** * Create an SmsMessage from an SMS EF record. * * @param index Index of SMS record. This should be index in ArrayList returned by * SmsManager.getAllMessagesFromSim + 1. * @param data Record data. * @return An SmsMessage representing the record. * @hide */ public static SmsMessage createFromEfRecord(int index, byte[] data) { try { SmsMessage msg = new SmsMessage(); msg.mIndexOnIcc = index; // First byte is status: RECEIVED_READ, RECEIVED_UNREAD, STORED_SENT, // or STORED_UNSENT // See TS 51.011 10.5.3 if ((data[0] & 1) == 0) { Rlog.w(LOG_TAG, "SMS parsing failed: Trying to parse a free record"); return null; } else { msg.mStatusOnIcc = data[0] & 0x07; } int size = data.length - 1; // Note: Data may include trailing FF's. That's OK; message // should still parse correctly. byte[] pdu = new byte[size]; System.arraycopy(data, 1, pdu, 0, size); msg.parsePdu(pdu); return msg; } catch (RuntimeException ex) { Rlog.e(LOG_TAG, "SMS PDU parsing failed: ", ex); return null; } }
/** * @return a geographical description string for the specified number. * @see com.android.i18n.phonenumbers.PhoneNumberOfflineGeocoder */ private static String getGeoDescription(Context context, String number) { if (VDBG) Rlog.v(TAG, "getGeoDescription('" + number + "')..."); if (TextUtils.isEmpty(number)) { return null; } PhoneNumberUtil util = PhoneNumberUtil.getInstance(); PhoneNumberOfflineGeocoder geocoder = PhoneNumberOfflineGeocoder.getInstance(); Locale locale = context.getResources().getConfiguration().locale; String countryIso = getCurrentCountryIso(context, locale); PhoneNumber pn = null; try { if (VDBG) Rlog.v(TAG, "parsing '" + number + "' for countryIso '" + countryIso + "'..."); pn = util.parse(number, countryIso); if (VDBG) Rlog.v(TAG, "- parsed number: " + pn); } catch (NumberParseException e) { Rlog.w(TAG, "getGeoDescription: NumberParseException for incoming number '" + number + "'"); } if (pn != null) { String description = geocoder.getDescriptionForNumber(pn, locale); if (VDBG) Rlog.v(TAG, "- got description: '" + description + "'"); return description; } else { return null; } }
/** * Returns the column index to use to find the "person_id" field in the specified cursor, based on * the contact URI that was originally queried. * * <p>This is a helper function for the getCallerInfo() method that takes a Cursor. Looking up the * person_id is nontrivial (compared to all the other CallerInfo fields) since the column we need * to use depends on what query we originally ran. * * <p>Watch out: be sure to not do any database access in this method, since it's run from the UI * thread (see comments below for more info.) * * @return the columnIndex to use (with cursor.getLong()) to get the person_id, or -1 if we * couldn't figure out what colum to use. * <p>TODO: Add a unittest for this method. (This is a little tricky to test, since we'll need * a live contacts database to test against, preloaded with at least some phone numbers and * SIP addresses. And we'll probably have to hardcode the column indexes we expect, so the * test might break whenever the contacts schema changes. But we can at least make sure we * handle all the URI patterns we claim to, and that the mime types match what we expect...) */ private static int getColumnIndexForPersonId(Uri contactRef, Cursor cursor) { // TODO: This is pretty ugly now, see bug 2269240 for // more details. The column to use depends upon the type of URL: // - content://com.android.contacts/data/phones ==> use the "contact_id" column // - content://com.android.contacts/phone_lookup ==> use the "_ID" column // - content://com.android.contacts/data ==> use the "contact_id" column // If it's none of the above, we leave columnIndex=-1 which means // that the person_id field will be left unset. // // The logic here *used* to be based on the mime type of contactRef // (for example Phone.CONTENT_ITEM_TYPE would tell us to use the // RawContacts.CONTACT_ID column). But looking up the mime type requires // a call to context.getContentResolver().getType(contactRef), which // isn't safe to do from the UI thread since it can cause an ANR if // the contacts provider is slow or blocked (like during a sync.) // // So instead, figure out the column to use for person_id by just // looking at the URI itself. if (VDBG) Rlog.v(TAG, "- getColumnIndexForPersonId: contactRef URI = '" + contactRef + "'..."); // Warning: Do not enable the following logging (due to ANR risk.) // if (VDBG) Rlog.v(TAG, "- MIME type: " // + context.getContentResolver().getType(contactRef)); String url = contactRef.toString(); String columnName = null; if (url.startsWith("content://com.android.contacts/data/phones")) { // Direct lookup in the Phone table. // MIME type: Phone.CONTENT_ITEM_TYPE (= "vnd.android.cursor.item/phone_v2") if (VDBG) Rlog.v(TAG, "'data/phones' URI; using RawContacts.CONTACT_ID"); columnName = RawContacts.CONTACT_ID; } else if (url.startsWith("content://com.android.contacts/data")) { // Direct lookup in the Data table. // MIME type: Data.CONTENT_TYPE (= "vnd.android.cursor.dir/data") if (VDBG) Rlog.v(TAG, "'data' URI; using Data.CONTACT_ID"); // (Note Data.CONTACT_ID and RawContacts.CONTACT_ID are equivalent.) columnName = Data.CONTACT_ID; } else if (url.startsWith("content://com.android.contacts/phone_lookup")) { // Lookup in the PhoneLookup table, which provides "fuzzy matching" // for phone numbers. // MIME type: PhoneLookup.CONTENT_TYPE (= "vnd.android.cursor.dir/phone_lookup") if (VDBG) Rlog.v(TAG, "'phone_lookup' URI; using PhoneLookup._ID"); columnName = PhoneLookup._ID; } else { Rlog.w(TAG, "Unexpected prefix for contactRef '" + url + "'"); } int columnIndex = (columnName != null) ? cursor.getColumnIndex(columnName) : -1; if (VDBG) Rlog.v( TAG, "==> Using column '" + columnName + "' (columnIndex = " + columnIndex + ") for person_id lookup..."); return columnIndex; }
/*package*/ void separate(GsmConnection conn) throws CallStateException { if (conn.owner != this) { throw new CallStateException( "GsmConnection " + conn + "does not belong to GsmCallTracker " + this); } try { cm.separateConnection(conn.getGSMIndex(), obtainCompleteMessage(EVENT_SEPARATE_RESULT)); } catch (CallStateException ex) { // Ignore "connection not found" // Call may have hung up already Rlog.w(LOG_TAG, "GsmCallTracker WARN: separate() on absent connection " + conn); } }
/** @return The ISO 3166-1 two letters country code of the country the user is in. */ private static String getCurrentCountryIso(Context context, Locale locale) { String countryIso = null; CountryDetector detector = (CountryDetector) context.getSystemService(Context.COUNTRY_DETECTOR); if (detector != null) { Country country = detector.detectCountry(); if (country != null) { countryIso = country.getCountryIso(); } else { Rlog.e(TAG, "CountryDetector.detectCountry() returned null."); } } if (countryIso == null) { countryIso = locale.getCountry(); Rlog.w(TAG, "No CountryDetector; falling back to countryIso based on locale: " + countryIso); } return countryIso; }
/*package*/ void hangup(GsmConnection conn) throws CallStateException { if (conn.owner != this) { throw new CallStateException( "GsmConnection " + conn + "does not belong to GsmCallTracker " + this); } if (conn == pendingMO) { // We're hanging up an outgoing call that doesn't have it's // GSM index assigned yet if (Phone.DEBUG_PHONE) log("hangup: set hangupPendingMO to true"); hangupPendingMO = true; } else { try { cm.hangupConnection(conn.getGSMIndex(), obtainCompleteMessage()); } catch (CallStateException ex) { // Ignore "connection not found" // Call may have hung up already Rlog.w(LOG_TAG, "GsmCallTracker WARN: hangup() on absent connection " + conn); } } conn.onHangupLocal(); }
@Override public boolean isUssdRequest() { Rlog.w(LOG_TAG, "isUssdRequest is not implemented in CdmaMmiCode"); return false; }
/** * Get an SMS-SUBMIT PDU for a destination address and a message using the specified encoding. * * @param scAddress Service Centre address. Null means use default. * @param encoding Encoding defined by constants in * com.android.internal.telephony.SmsConstants.ENCODING_* * @param languageTable * @param languageShiftTable * @return a <code>SubmitPdu</code> containing the encoded SC address, if applicable, and the * encoded message. Returns null on encode error. * @hide */ public static SubmitPdu getSubmitPdu( String scAddress, String destinationAddress, String message, boolean statusReportRequested, byte[] header, int encoding, int languageTable, int languageShiftTable) { // Perform null parameter checks. if (message == null || destinationAddress == null) { return null; } if (encoding == ENCODING_UNKNOWN) { // Find the best encoding to use TextEncodingDetails ted = calculateLength(message, false); encoding = ted.codeUnitSize; languageTable = ted.languageTable; languageShiftTable = ted.languageShiftTable; if (encoding == ENCODING_7BIT && (languageTable != 0 || languageShiftTable != 0)) { if (header != null) { SmsHeader smsHeader = SmsHeader.fromByteArray(header); if (smsHeader.languageTable != languageTable || smsHeader.languageShiftTable != languageShiftTable) { Rlog.w( LOG_TAG, "Updating language table in SMS header: " + smsHeader.languageTable + " -> " + languageTable + ", " + smsHeader.languageShiftTable + " -> " + languageShiftTable); smsHeader.languageTable = languageTable; smsHeader.languageShiftTable = languageShiftTable; header = SmsHeader.toByteArray(smsHeader); } } else { SmsHeader smsHeader = new SmsHeader(); smsHeader.languageTable = languageTable; smsHeader.languageShiftTable = languageShiftTable; header = SmsHeader.toByteArray(smsHeader); } } } SubmitPdu ret = new SubmitPdu(); // MTI = SMS-SUBMIT, UDHI = header != null byte mtiByte = (byte) (0x01 | (header != null ? 0x40 : 0x00)); ByteArrayOutputStream bo = getSubmitPduHead(scAddress, destinationAddress, mtiByte, statusReportRequested, ret); // User Data (and length) byte[] userData; try { if (encoding == ENCODING_7BIT) { userData = GsmAlphabet.stringToGsm7BitPackedWithHeader( message, header, languageTable, languageShiftTable); } else { // assume UCS-2 try { userData = encodeUCS2(message, header); } catch (UnsupportedEncodingException uex) { Rlog.e(LOG_TAG, "Implausible UnsupportedEncodingException ", uex); return null; } } } catch (EncodeException ex) { // Encoding to the 7-bit alphabet failed. Let's see if we can // send it as a UCS-2 encoded message try { userData = encodeUCS2(message, header); encoding = ENCODING_16BIT; } catch (UnsupportedEncodingException uex) { Rlog.e(LOG_TAG, "Implausible UnsupportedEncodingException ", uex); return null; } } if (encoding == ENCODING_7BIT) { if ((0xff & userData[0]) > MAX_USER_DATA_SEPTETS) { // Message too long Rlog.e(LOG_TAG, "Message too long (" + (0xff & userData[0]) + " septets)"); return null; } // TP-Data-Coding-Scheme // Default encoding, uncompressed // To test writing messages to the SIM card, change this value 0x00 // to 0x12, which means "bits 1 and 0 contain message class, and the // class is 2". Note that this takes effect for the sender. In other // words, messages sent by the phone with this change will end up on // the receiver's SIM card. You can then send messages to yourself // (on a phone with this change) and they'll end up on the SIM card. bo.write(0x00); } else { // assume UCS-2 if ((0xff & userData[0]) > MAX_USER_DATA_BYTES) { // Message too long Rlog.e(LOG_TAG, "Message too long (" + (0xff & userData[0]) + " bytes)"); return null; } // TP-Data-Coding-Scheme // UCS-2 encoding, uncompressed bo.write(0x08); } // (no TP-Validity-Period) bo.write(userData, 0, userData.length); ret.encodedMessage = bo.toByteArray(); return ret; }
/** * Parses the User Data of an SMS. * * @param p The current PduParser. * @param hasUserDataHeader Indicates whether a header is present in the User Data. */ private void parseUserData(PduParser p, boolean hasUserDataHeader) { boolean hasMessageClass = false; boolean userDataCompressed = false; int encodingType = ENCODING_UNKNOWN; // Look up the data encoding scheme if ((mDataCodingScheme & 0x80) == 0) { userDataCompressed = (0 != (mDataCodingScheme & 0x20)); hasMessageClass = (0 != (mDataCodingScheme & 0x10)); if (userDataCompressed) { Rlog.w( LOG_TAG, "4 - Unsupported SMS data coding scheme " + "(compression) " + (mDataCodingScheme & 0xff)); } else { switch ((mDataCodingScheme >> 2) & 0x3) { case 0: // GSM 7 bit default alphabet encodingType = ENCODING_7BIT; break; case 2: // UCS 2 (16bit) encodingType = ENCODING_16BIT; break; case 1: // 8 bit data // Support decoding the user data payload as pack GSM 8-bit (a GSM alphabet string // that's stored in 8-bit unpacked format) characters. Resources r = Resources.getSystem(); if (r.getBoolean(au.com.wallaceit.voicemail.R.bool.config_sms_decode_gsm_8bit_data)) { encodingType = ENCODING_8BIT; break; } case 3: // reserved Rlog.w(LOG_TAG, "1 - Unsupported SMS data coding scheme " + (mDataCodingScheme & 0xff)); encodingType = ENCODING_8BIT; break; } } } else if ((mDataCodingScheme & 0xf0) == 0xf0) { hasMessageClass = true; userDataCompressed = false; if (0 == (mDataCodingScheme & 0x04)) { // GSM 7 bit default alphabet encodingType = ENCODING_7BIT; } else { // 8 bit data encodingType = ENCODING_8BIT; } } else if ((mDataCodingScheme & 0xF0) == 0xC0 || (mDataCodingScheme & 0xF0) == 0xD0 || (mDataCodingScheme & 0xF0) == 0xE0) { // 3GPP TS 23.038 V7.0.0 (2006-03) section 4 // 0xC0 == 7 bit, don't store // 0xD0 == 7 bit, store // 0xE0 == UCS-2, store if ((mDataCodingScheme & 0xF0) == 0xE0) { encodingType = ENCODING_16BIT; } else { encodingType = ENCODING_7BIT; } userDataCompressed = false; boolean active = ((mDataCodingScheme & 0x08) == 0x08); // bit 0x04 reserved // VM - If TP-UDH is present, these values will be overwritten if ((mDataCodingScheme & 0x03) == 0x00) { mIsMwi = true; /* Indicates vmail */ mMwiSense = active; /* Indicates vmail notification set/clear */ mMwiDontStore = ((mDataCodingScheme & 0xF0) == 0xC0); /* Set voice mail count based on notification bit */ if (active == true) { mVoiceMailCount = -1; // unknown number of messages waiting } else { mVoiceMailCount = 0; // no unread messages } Rlog.w( LOG_TAG, "MWI in DCS for Vmail. DCS = " + (mDataCodingScheme & 0xff) + " Dont store = " + mMwiDontStore + " vmail count = " + mVoiceMailCount); } else { mIsMwi = false; Rlog.w(LOG_TAG, "MWI in DCS for fax/email/other: " + (mDataCodingScheme & 0xff)); } } else if ((mDataCodingScheme & 0xC0) == 0x80) { // 3GPP TS 23.038 V7.0.0 (2006-03) section 4 // 0x80..0xBF == Reserved coding groups if (mDataCodingScheme == 0x84) { // This value used for KSC5601 by carriers in Korea. encodingType = ENCODING_KSC5601; } else { Rlog.w(LOG_TAG, "5 - Unsupported SMS data coding scheme " + (mDataCodingScheme & 0xff)); } } else { Rlog.w(LOG_TAG, "3 - Unsupported SMS data coding scheme " + (mDataCodingScheme & 0xff)); } // set both the user data and the user data header. int count = p.constructUserData(hasUserDataHeader, encodingType == ENCODING_7BIT); this.mUserData = p.getUserData(); this.mUserDataHeader = p.getUserDataHeader(); /* * Look for voice mail indication in TP_UDH TS23.040 9.2.3.24 * ieid = 1 (0x1) (SPECIAL_SMS_MSG_IND) * ieidl =2 octets * ieda msg_ind_type = 0x00 (voice mail; discard sms )or * = 0x80 (voice mail; store sms) * msg_count = 0x00 ..0xFF */ if (hasUserDataHeader && (mUserDataHeader.specialSmsMsgList.size() != 0)) { for (SmsHeader.SpecialSmsMsg msg : mUserDataHeader.specialSmsMsgList) { int msgInd = msg.msgIndType & 0xff; /* * TS 23.040 V6.8.1 Sec 9.2.3.24.2 * bits 1 0 : basic message indication type * bits 4 3 2 : extended message indication type * bits 6 5 : Profile id bit 7 storage type */ if ((msgInd == 0) || (msgInd == 0x80)) { mIsMwi = true; if (msgInd == 0x80) { /* Store message because TP_UDH indicates so*/ mMwiDontStore = false; } else if (mMwiDontStore == false) { /* Storage bit is not set by TP_UDH * Check for conflict * between message storage bit in TP_UDH * & DCS. The message shall be stored if either of * the one indicates so. * TS 23.040 V6.8.1 Sec 9.2.3.24.2 */ if (!((((mDataCodingScheme & 0xF0) == 0xD0) || ((mDataCodingScheme & 0xF0) == 0xE0)) && ((mDataCodingScheme & 0x03) == 0x00))) { /* Even DCS did not have voice mail with Storage bit * 3GPP TS 23.038 V7.0.0 section 4 * So clear this flag*/ mMwiDontStore = true; } } mVoiceMailCount = msg.msgCount & 0xff; /* * In the event of a conflict between message count setting * and DCS then the Message Count in the TP-UDH shall * override the indication in the TP-DCS. Set voice mail * notification based on count in TP-UDH */ if (mVoiceMailCount > 0) mMwiSense = true; else mMwiSense = false; Rlog.w( LOG_TAG, "MWI in TP-UDH for Vmail. Msg Ind = " + msgInd + " Dont store = " + mMwiDontStore + " Vmail count = " + mVoiceMailCount); /* * There can be only one IE for each type of message * indication in TP_UDH. In the event they are duplicated * last occurence will be used. Hence the for loop */ } else { Rlog.w( LOG_TAG, "TP_UDH fax/email/" + "extended msg/multisubscriber profile. Msg Ind = " + msgInd); } } // end of for } // end of if UDH switch (encodingType) { case ENCODING_UNKNOWN: mMessageBody = null; break; case ENCODING_8BIT: // Support decoding the user data payload as pack GSM 8-bit (a GSM alphabet string // that's stored in 8-bit unpacked format) characters. Resources r = Resources.getSystem(); if (r.getBoolean(au.com.wallaceit.voicemail.R.bool.config_sms_decode_gsm_8bit_data)) { mMessageBody = p.getUserDataGSM8bit(count); } else { mMessageBody = null; } break; case ENCODING_7BIT: mMessageBody = p.getUserDataGSM7Bit( count, hasUserDataHeader ? mUserDataHeader.languageTable : 0, hasUserDataHeader ? mUserDataHeader.languageShiftTable : 0); break; case ENCODING_16BIT: mMessageBody = p.getUserDataUCS2(count); break; case ENCODING_KSC5601: mMessageBody = p.getUserDataKSC5601(count); break; } if (VDBG) Rlog.v(LOG_TAG, "SMS message body (raw): '" + mMessageBody + "'"); if (mMessageBody != null) { parseMessageBody(); } if (!hasMessageClass) { messageClass = MessageClass.UNKNOWN; } else { switch (mDataCodingScheme & 0x3) { case 0: messageClass = MessageClass.CLASS_0; break; case 1: messageClass = MessageClass.CLASS_1; break; case 2: messageClass = MessageClass.CLASS_2; break; case 3: messageClass = MessageClass.CLASS_3; break; } } }
/** * getCallerInfo given a Cursor. * * @param context the context used to retrieve string constants * @param contactRef the URI to attach to this CallerInfo object * @param cursor the first object in the cursor is used to build the CallerInfo object. * @return the CallerInfo which contains the caller id for the given number. The returned * CallerInfo is null if no number is supplied. */ public static CallerInfo getCallerInfo(Context context, Uri contactRef, Cursor cursor) { CallerInfo info = new CallerInfo(); info.photoResource = 0; info.phoneLabel = null; info.numberType = 0; info.numberLabel = null; info.cachedPhoto = null; info.isCachedPhotoCurrent = false; info.contactExists = false; if (VDBG) Rlog.v(TAG, "getCallerInfo() based on cursor..."); if (cursor != null) { if (cursor.moveToFirst()) { // TODO: photo_id is always available but not taken // care of here. Maybe we should store it in the // CallerInfo object as well. int columnIndex; // Look for the name columnIndex = cursor.getColumnIndex(PhoneLookup.DISPLAY_NAME); if (columnIndex != -1) { info.name = cursor.getString(columnIndex); } // Look for the number columnIndex = cursor.getColumnIndex(PhoneLookup.NUMBER); if (columnIndex != -1) { info.phoneNumber = cursor.getString(columnIndex); } // Look for the normalized number columnIndex = cursor.getColumnIndex(PhoneLookup.NORMALIZED_NUMBER); if (columnIndex != -1) { info.normalizedNumber = cursor.getString(columnIndex); } // Look for the label/type combo columnIndex = cursor.getColumnIndex(PhoneLookup.LABEL); if (columnIndex != -1) { int typeColumnIndex = cursor.getColumnIndex(PhoneLookup.TYPE); if (typeColumnIndex != -1) { info.numberType = cursor.getInt(typeColumnIndex); info.numberLabel = cursor.getString(columnIndex); info.phoneLabel = Phone.getDisplayLabel(context, info.numberType, info.numberLabel).toString(); } } // Look for the person_id. columnIndex = getColumnIndexForPersonId(contactRef, cursor); if (columnIndex != -1) { final long contactId = cursor.getLong(columnIndex); if (contactId != 0 && !Contacts.isEnterpriseContactId(contactId)) { info.contactIdOrZero = contactId; if (VDBG) { Rlog.v(TAG, "==> got info.contactIdOrZero: " + info.contactIdOrZero); } } } else { // No valid columnIndex, so we can't look up person_id. Rlog.w(TAG, "Couldn't find contact_id column for " + contactRef); // Watch out: this means that anything that depends on // person_id will be broken (like contact photo lookups in // the in-call UI, for example.) } // Contact lookupKey columnIndex = cursor.getColumnIndex(PhoneLookup.LOOKUP_KEY); if (columnIndex != -1) { info.lookupKey = cursor.getString(columnIndex); } // Display photo URI. columnIndex = cursor.getColumnIndex(PhoneLookup.PHOTO_URI); if ((columnIndex != -1) && (cursor.getString(columnIndex) != null)) { info.contactDisplayPhotoUri = Uri.parse(cursor.getString(columnIndex)); } else { info.contactDisplayPhotoUri = null; } // look for the custom ringtone, create from the string stored // in the database. columnIndex = cursor.getColumnIndex(PhoneLookup.CUSTOM_RINGTONE); if ((columnIndex != -1) && (cursor.getString(columnIndex) != null)) { info.contactRingtoneUri = Uri.parse(cursor.getString(columnIndex)); } else { info.contactRingtoneUri = null; } // look for the send to voicemail flag, set it to true only // under certain circumstances. columnIndex = cursor.getColumnIndex(PhoneLookup.SEND_TO_VOICEMAIL); info.shouldSendToVoicemail = (columnIndex != -1) && ((cursor.getInt(columnIndex)) == 1); info.contactExists = true; } cursor.close(); cursor = null; } info.needUpdate = false; info.name = normalize(info.name); info.contactRefUri = contactRef; return info; }
/** log */ private static void log(String s) { Rlog.w(LOG_TAG, s); }
@Override protected RILRequest processSolicited(Parcel p) { int serial, error; boolean found = false; serial = p.readInt(); error = p.readInt(); RILRequest rr; rr = findAndRemoveRequestFromList(serial); if (rr == null) { Rlog.w(RILJ_LOG_TAG, "Unexpected solicited response! sn: " + serial + " error: " + error); return null; } Object ret = null; if (error == 0 || p.dataAvail() > 0) { // either command succeeds or command fails but with data payload try { switch (rr.mRequest) { /* cat libs/telephony/ril_commands.h \ | egrep "^ *{RIL_" \ | sed -re 's/\{([^,]+),[^,]+,([^}]+).+/case \1: ret = \2(p); break;/' */ case RIL_REQUEST_GET_SIM_STATUS: ret = responseIccCardStatus(p); break; case RIL_REQUEST_ENTER_SIM_PIN: ret = responseInts(p); break; case RIL_REQUEST_ENTER_SIM_PUK: ret = responseInts(p); break; case RIL_REQUEST_ENTER_SIM_PIN2: ret = responseInts(p); break; case RIL_REQUEST_ENTER_SIM_PUK2: ret = responseInts(p); break; case RIL_REQUEST_CHANGE_SIM_PIN: ret = responseInts(p); break; case RIL_REQUEST_CHANGE_SIM_PIN2: ret = responseInts(p); break; case RIL_REQUEST_ENTER_NETWORK_DEPERSONALIZATION: ret = responseInts(p); break; case RIL_REQUEST_GET_CURRENT_CALLS: ret = responseCallList(p); break; case RIL_REQUEST_DIAL: ret = responseVoid(p); break; case RIL_REQUEST_GET_IMSI: ret = responseString(p); break; case RIL_REQUEST_HANGUP: ret = responseVoid(p); break; case RIL_REQUEST_HANGUP_WAITING_OR_BACKGROUND: ret = responseVoid(p); break; case RIL_REQUEST_HANGUP_FOREGROUND_RESUME_BACKGROUND: { if (mTestingEmergencyCall.getAndSet(false)) { if (mEmergencyCallbackModeRegistrant != null) { riljLog("testing emergency call, notify ECM Registrants"); mEmergencyCallbackModeRegistrant.notifyRegistrant(); } } ret = responseVoid(p); break; } case RIL_REQUEST_SWITCH_WAITING_OR_HOLDING_AND_ACTIVE: ret = responseVoid(p); break; case RIL_REQUEST_CONFERENCE: ret = responseVoid(p); break; case RIL_REQUEST_UDUB: ret = responseVoid(p); break; case RIL_REQUEST_LAST_CALL_FAIL_CAUSE: ret = responseInts(p); break; case RIL_REQUEST_SIGNAL_STRENGTH: ret = responseSignalStrength(p); break; // modification start // prevent exceptions from happenimg because the null value is null or a hexadecimel. so // convert if it is not null case RIL_REQUEST_VOICE_REGISTRATION_STATE: ret = responseVoiceDataRegistrationState(p); break; case RIL_REQUEST_DATA_REGISTRATION_STATE: ret = responseVoiceDataRegistrationState(p); break; // this fixes bogus values the modem creates // sometimes the ril may print out // (always on sprint) // sprint: (empty,empty,31000) // this problemaic on sprint, lte won't start, response is slow // speeds up response time on eherpderpd/lte networks case RIL_REQUEST_OPERATOR: ret = operatorCheck(p); break; // end modification case RIL_REQUEST_RADIO_POWER: ret = responseVoid(p); break; case RIL_REQUEST_DTMF: ret = responseVoid(p); break; case RIL_REQUEST_SEND_SMS: ret = responseSMS(p); break; case RIL_REQUEST_SEND_SMS_EXPECT_MORE: ret = responseSMS(p); break; case RIL_REQUEST_SETUP_DATA_CALL: ret = responseSetupDataCall(p); break; case RIL_REQUEST_SIM_IO: ret = responseICC_IO(p); break; case RIL_REQUEST_SEND_USSD: ret = responseVoid(p); break; case RIL_REQUEST_CANCEL_USSD: ret = responseVoid(p); break; case RIL_REQUEST_GET_CLIR: ret = responseInts(p); break; case RIL_REQUEST_SET_CLIR: ret = responseVoid(p); break; case RIL_REQUEST_QUERY_CALL_FORWARD_STATUS: ret = responseCallForward(p); break; case RIL_REQUEST_SET_CALL_FORWARD: ret = responseVoid(p); break; case RIL_REQUEST_QUERY_CALL_WAITING: ret = responseInts(p); break; case RIL_REQUEST_SET_CALL_WAITING: ret = responseVoid(p); break; case RIL_REQUEST_SMS_ACKNOWLEDGE: ret = responseVoid(p); break; case RIL_REQUEST_GET_IMEI: ret = responseString(p); break; case RIL_REQUEST_GET_IMEISV: ret = responseString(p); break; case RIL_REQUEST_ANSWER: ret = responseVoid(p); break; case RIL_REQUEST_DEACTIVATE_DATA_CALL: ret = responseVoid(p); break; case RIL_REQUEST_QUERY_FACILITY_LOCK: ret = responseInts(p); break; case RIL_REQUEST_SET_FACILITY_LOCK: ret = responseInts(p); break; case RIL_REQUEST_CHANGE_BARRING_PASSWORD: ret = responseVoid(p); break; case RIL_REQUEST_QUERY_NETWORK_SELECTION_MODE: ret = responseInts(p); break; case RIL_REQUEST_SET_NETWORK_SELECTION_AUTOMATIC: ret = responseVoid(p); break; case RIL_REQUEST_SET_NETWORK_SELECTION_MANUAL: ret = responseVoid(p); break; case RIL_REQUEST_QUERY_AVAILABLE_NETWORKS: ret = responseOperatorInfos(p); break; case RIL_REQUEST_DTMF_START: ret = responseVoid(p); break; case RIL_REQUEST_DTMF_STOP: ret = responseVoid(p); break; case RIL_REQUEST_BASEBAND_VERSION: ret = responseString(p); break; case RIL_REQUEST_SEPARATE_CONNECTION: ret = responseVoid(p); break; case RIL_REQUEST_SET_MUTE: ret = responseVoid(p); break; case RIL_REQUEST_GET_MUTE: ret = responseInts(p); break; case RIL_REQUEST_QUERY_CLIP: ret = responseInts(p); break; case RIL_REQUEST_LAST_DATA_CALL_FAIL_CAUSE: ret = responseInts(p); break; case RIL_REQUEST_DATA_CALL_LIST: ret = responseDataCallList(p); break; case RIL_REQUEST_RESET_RADIO: ret = responseVoid(p); break; case RIL_REQUEST_OEM_HOOK_RAW: ret = responseRaw(p); break; case RIL_REQUEST_OEM_HOOK_STRINGS: ret = responseStrings(p); break; case RIL_REQUEST_SCREEN_STATE: ret = responseVoid(p); break; case RIL_REQUEST_SET_SUPP_SVC_NOTIFICATION: ret = responseVoid(p); break; case RIL_REQUEST_WRITE_SMS_TO_SIM: ret = responseInts(p); break; case RIL_REQUEST_DELETE_SMS_ON_SIM: ret = responseVoid(p); break; case RIL_REQUEST_SET_BAND_MODE: ret = responseVoid(p); break; case RIL_REQUEST_QUERY_AVAILABLE_BAND_MODE: ret = responseInts(p); break; case RIL_REQUEST_STK_GET_PROFILE: ret = responseString(p); break; case RIL_REQUEST_STK_SET_PROFILE: ret = responseVoid(p); break; case RIL_REQUEST_STK_SEND_ENVELOPE_COMMAND: ret = responseString(p); break; case RIL_REQUEST_STK_SEND_TERMINAL_RESPONSE: ret = responseVoid(p); break; case RIL_REQUEST_STK_HANDLE_CALL_SETUP_REQUESTED_FROM_SIM: ret = responseInts(p); break; case RIL_REQUEST_EXPLICIT_CALL_TRANSFER: ret = responseVoid(p); break; case RIL_REQUEST_SET_PREFERRED_NETWORK_TYPE: ret = responseVoid(p); break; case RIL_REQUEST_GET_PREFERRED_NETWORK_TYPE: ret = responseGetPreferredNetworkType(p); break; case RIL_REQUEST_GET_NEIGHBORING_CELL_IDS: ret = responseCellList(p); break; case RIL_REQUEST_SET_LOCATION_UPDATES: ret = responseVoid(p); break; case RIL_REQUEST_CDMA_SET_SUBSCRIPTION_SOURCE: ret = responseVoid(p); break; case RIL_REQUEST_CDMA_SET_ROAMING_PREFERENCE: ret = responseVoid(p); break; case RIL_REQUEST_CDMA_QUERY_ROAMING_PREFERENCE: ret = responseInts(p); break; case RIL_REQUEST_SET_TTY_MODE: ret = responseVoid(p); break; case RIL_REQUEST_QUERY_TTY_MODE: ret = responseInts(p); break; case RIL_REQUEST_CDMA_SET_PREFERRED_VOICE_PRIVACY_MODE: ret = responseVoid(p); break; case RIL_REQUEST_CDMA_QUERY_PREFERRED_VOICE_PRIVACY_MODE: ret = responseInts(p); break; case RIL_REQUEST_CDMA_FLASH: ret = responseVoid(p); break; case RIL_REQUEST_CDMA_BURST_DTMF: ret = responseVoid(p); break; case RIL_REQUEST_CDMA_SEND_SMS: ret = responseSMS(p); break; case RIL_REQUEST_CDMA_SMS_ACKNOWLEDGE: ret = responseVoid(p); break; case RIL_REQUEST_GSM_GET_BROADCAST_CONFIG: ret = responseGmsBroadcastConfig(p); break; case RIL_REQUEST_GSM_SET_BROADCAST_CONFIG: ret = responseVoid(p); break; case RIL_REQUEST_GSM_BROADCAST_ACTIVATION: ret = responseVoid(p); break; case RIL_REQUEST_CDMA_GET_BROADCAST_CONFIG: ret = responseCdmaBroadcastConfig(p); break; case RIL_REQUEST_CDMA_SET_BROADCAST_CONFIG: ret = responseVoid(p); break; case RIL_REQUEST_CDMA_BROADCAST_ACTIVATION: ret = responseVoid(p); break; case RIL_REQUEST_CDMA_VALIDATE_AND_WRITE_AKEY: ret = responseVoid(p); break; case RIL_REQUEST_CDMA_SUBSCRIPTION: ret = responseStrings(p); break; case RIL_REQUEST_CDMA_WRITE_SMS_TO_RUIM: ret = responseInts(p); break; case RIL_REQUEST_CDMA_DELETE_SMS_ON_RUIM: ret = responseVoid(p); break; case RIL_REQUEST_DEVICE_IDENTITY: ret = responseStrings(p); break; case RIL_REQUEST_GET_SMSC_ADDRESS: ret = responseString(p); break; case RIL_REQUEST_SET_SMSC_ADDRESS: ret = responseVoid(p); break; case RIL_REQUEST_EXIT_EMERGENCY_CALLBACK_MODE: ret = responseVoid(p); break; case RIL_REQUEST_REPORT_SMS_MEMORY_STATUS: ret = responseVoid(p); break; case RIL_REQUEST_REPORT_STK_SERVICE_IS_RUNNING: ret = responseVoid(p); break; case RIL_REQUEST_CDMA_GET_SUBSCRIPTION_SOURCE: ret = responseInts(p); break; case RIL_REQUEST_ISIM_AUTHENTICATION: ret = responseString(p); break; case RIL_REQUEST_ACKNOWLEDGE_INCOMING_GSM_SMS_WITH_PDU: ret = responseVoid(p); break; case RIL_REQUEST_STK_SEND_ENVELOPE_WITH_STATUS: ret = responseICC_IO(p); break; case RIL_REQUEST_VOICE_RADIO_TECH: ret = responseInts(p); break; case RIL_REQUEST_GET_CELL_INFO_LIST: ret = responseCellInfoList(p); break; case RIL_REQUEST_SET_UNSOL_CELL_INFO_LIST_RATE: ret = responseVoid(p); break; case RIL_REQUEST_SET_INITIAL_ATTACH_APN: ret = responseVoid(p); break; case RIL_REQUEST_IMS_REGISTRATION_STATE: ret = responseInts(p); break; case RIL_REQUEST_IMS_SEND_SMS: ret = responseSMS(p); break; default: throw new RuntimeException("Unrecognized solicited response: " + rr.mRequest); // break; } } catch (Throwable tr) { // Exceptions here usually mean invalid RIL responses Rlog.w( RILJ_LOG_TAG, rr.serialString() + "< " + requestToString(rr.mRequest) + " exception, possible invalid RIL response", tr); if (rr.mResult != null) { AsyncResult.forMessage(rr.mResult, null, tr); rr.mResult.sendToTarget(); } return rr; } } // Here and below fake RIL_UNSOL_RESPONSE_SIM_STATUS_CHANGED, see b/7255789. // This is needed otherwise we don't automatically transition to the main lock // screen when the pin or puk is entered incorrectly. switch (rr.mRequest) { case RIL_REQUEST_ENTER_SIM_PUK: case RIL_REQUEST_ENTER_SIM_PUK2: if (mIccStatusChangedRegistrants != null) { if (RILJ_LOGD) { riljLog( "ON enter sim puk fakeSimStatusChanged: reg count=" + mIccStatusChangedRegistrants.size()); } mIccStatusChangedRegistrants.notifyRegistrants(); } break; } if (error != 0) { switch (rr.mRequest) { case RIL_REQUEST_ENTER_SIM_PIN: case RIL_REQUEST_ENTER_SIM_PIN2: case RIL_REQUEST_CHANGE_SIM_PIN: case RIL_REQUEST_CHANGE_SIM_PIN2: case RIL_REQUEST_SET_FACILITY_LOCK: if (mIccStatusChangedRegistrants != null) { if (RILJ_LOGD) { riljLog( "ON some errors fakeSimStatusChanged: reg count=" + mIccStatusChangedRegistrants.size()); } mIccStatusChangedRegistrants.notifyRegistrants(); } break; } rr.onError(error, ret); } else { if (RILJ_LOGD) riljLog( rr.serialString() + "< " + requestToString(rr.mRequest) + " " + retToString(rr.mRequest, ret)); if (rr.mResult != null) { AsyncResult.forMessage(rr.mResult, ret, null); rr.mResult.sendToTarget(); } } return rr; }