diff options
author | The Android Open Source Project <initial-contribution@android.com> | 2009-02-20 07:38:31 -0800 |
---|---|---|
committer | The Android Open Source Project <initial-contribution@android.com> | 2009-02-20 07:38:31 -0800 |
commit | 15ab3eae2ec3d73b3e8aa60b33ae41445bf83f4b (patch) | |
tree | d03d027a7ed97af616904e02a7b420babf40d44f /telephony | |
parent | 3001a035439d8134a7d70d796376d1dfbff3cdcd (diff) | |
download | frameworks_base-15ab3eae2ec3d73b3e8aa60b33ae41445bf83f4b.zip frameworks_base-15ab3eae2ec3d73b3e8aa60b33ae41445bf83f4b.tar.gz frameworks_base-15ab3eae2ec3d73b3e8aa60b33ae41445bf83f4b.tar.bz2 |
auto import from //branches/cupcake/...@132569
Diffstat (limited to 'telephony')
4 files changed, 609 insertions, 182 deletions
diff --git a/telephony/java/com/android/internal/telephony/WapPushOverSms.java b/telephony/java/com/android/internal/telephony/WapPushOverSms.java new file mode 100644 index 0000000..66fa943 --- /dev/null +++ b/telephony/java/com/android/internal/telephony/WapPushOverSms.java @@ -0,0 +1,211 @@ +/* + * Copyright (C) 2008 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.internal.telephony; + +import android.content.Intent; +import android.provider.Telephony.Sms.Intents; +import android.util.Config; +import android.util.Log; +import com.android.internal.telephony.gsm.GSMPhone; +import com.android.internal.telephony.gsm.SimUtils; + + +/** + * WAP push handler class. + * + * @hide + */ +public class WapPushOverSms { + private static final String LOG_TAG = "WAP PUSH"; + + private final GSMPhone mPhone; + private WspTypeDecoder pduDecoder; + + + public WapPushOverSms(GSMPhone phone) { + mPhone = phone; + } + + /** + * Dispatches inbound messages that are in the WAP PDU format. See + * wap-230-wsp-20010705-a section 8 for details on the WAP PDU format. + * + * @param pdu The WAP PDU, made up of one or more SMS PDUs + */ + public void dispatchWapPdu(byte[] pdu) { + + if (Config.LOGD) Log.d(LOG_TAG, "Rx: " + SimUtils.bytesToHexString(pdu)); + + int index = 0; + int transactionId = pdu[index++] & 0xFF; + int pduType = pdu[index++] & 0xFF; + int headerLength = 0; + + if ((pduType != WspTypeDecoder.PDU_TYPE_PUSH) && + (pduType != WspTypeDecoder.PDU_TYPE_CONFIRMED_PUSH)) { + if (Config.LOGD) Log.w(LOG_TAG, "Received non-PUSH WAP PDU. Type = " + pduType); + return; + } + + pduDecoder = new WspTypeDecoder(pdu); + + /** + * Parse HeaderLen(unsigned integer). + * From wap-230-wsp-20010705-a section 8.1.2 + * The maximum size of a uintvar is 32 bits. + * So it will be encoded in no more than 5 octets. + */ + if (pduDecoder.decodeUintvarInteger(index) == false) { + if (Config.LOGD) Log.w(LOG_TAG, "Received PDU. Header Length error."); + return; + } + headerLength = (int)pduDecoder.getValue32(); + index += pduDecoder.getDecodedDataLength(); + + int headerStartIndex = index; + + /** + * Parse Content-Type. + * From wap-230-wsp-20010705-a section 8.4.2.24 + * + * Content-type-value = Constrained-media | Content-general-form + * Content-general-form = Value-length Media-type + * Media-type = (Well-known-media | Extension-Media) *(Parameter) + * Value-length = Short-length | (Length-quote Length) + * Short-length = <Any octet 0-30> (octet <= WAP_PDU_SHORT_LENGTH_MAX) + * Length-quote = <Octet 31> (WAP_PDU_LENGTH_QUOTE) + * Length = Uintvar-integer + */ + if (pduDecoder.decodeContentType(index) == false) { + if (Config.LOGD) Log.w(LOG_TAG, "Received PDU. Header Content-Type error."); + return; + } + int binaryContentType; + String mimeType = pduDecoder.getValueString(); + if (mimeType == null) { + binaryContentType = (int)pduDecoder.getValue32(); + switch (binaryContentType) { + case WspTypeDecoder.CONTENT_TYPE_B_DRM_RIGHTS_XML: + mimeType = WspTypeDecoder.CONTENT_MIME_TYPE_B_DRM_RIGHTS_XML; + break; + case WspTypeDecoder.CONTENT_TYPE_B_DRM_RIGHTS_WBXML: + mimeType = WspTypeDecoder.CONTENT_MIME_TYPE_B_DRM_RIGHTS_WBXML; + break; + case WspTypeDecoder.CONTENT_TYPE_B_PUSH_SI: + mimeType = WspTypeDecoder.CONTENT_MIME_TYPE_B_PUSH_SI; + break; + case WspTypeDecoder.CONTENT_TYPE_B_PUSH_SL: + mimeType = WspTypeDecoder.CONTENT_MIME_TYPE_B_PUSH_SL; + break; + case WspTypeDecoder.CONTENT_TYPE_B_PUSH_CO: + mimeType = WspTypeDecoder.CONTENT_MIME_TYPE_B_PUSH_CO; + break; + case WspTypeDecoder.CONTENT_TYPE_B_MMS: + mimeType = WspTypeDecoder.CONTENT_MIME_TYPE_B_MMS; + break; + default: + if (Config.LOGD) { + Log.w(LOG_TAG, + "Received PDU. Unsupported Content-Type = " + binaryContentType); + } + return; + } + } else { + if (mimeType.equals(WspTypeDecoder.CONTENT_MIME_TYPE_B_DRM_RIGHTS_XML)) { + binaryContentType = WspTypeDecoder.CONTENT_TYPE_B_DRM_RIGHTS_XML; + } else if (mimeType.equals(WspTypeDecoder.CONTENT_MIME_TYPE_B_DRM_RIGHTS_WBXML)) { + binaryContentType = WspTypeDecoder.CONTENT_TYPE_B_DRM_RIGHTS_WBXML; + } else if (mimeType.equals(WspTypeDecoder.CONTENT_MIME_TYPE_B_PUSH_SI)) { + binaryContentType = WspTypeDecoder.CONTENT_TYPE_B_PUSH_SI; + } else if (mimeType.equals(WspTypeDecoder.CONTENT_MIME_TYPE_B_PUSH_SL)) { + binaryContentType = WspTypeDecoder.CONTENT_TYPE_B_PUSH_SL; + } else if (mimeType.equals(WspTypeDecoder.CONTENT_MIME_TYPE_B_PUSH_CO)) { + binaryContentType = WspTypeDecoder.CONTENT_TYPE_B_PUSH_CO; + } else if (mimeType.equals(WspTypeDecoder.CONTENT_MIME_TYPE_B_MMS)) { + binaryContentType = WspTypeDecoder.CONTENT_TYPE_B_MMS; + } else { + if (Config.LOGD) Log.w(LOG_TAG, "Received PDU. Unknown Content-Type = " + mimeType); + return; + } + } + index += pduDecoder.getDecodedDataLength(); + + int dataIndex = headerStartIndex + headerLength; + boolean dispatchedByApplication = false; + switch (binaryContentType) { + case WspTypeDecoder.CONTENT_TYPE_B_PUSH_CO: + dispatchWapPdu_PushCO(pdu, transactionId, pduType); + dispatchedByApplication = true; + break; + case WspTypeDecoder.CONTENT_TYPE_B_MMS: + dispatchWapPdu_MMS(pdu, transactionId, pduType, dataIndex); + dispatchedByApplication = true; + break; + default: + break; + } + if (dispatchedByApplication == false) { + dispatchWapPdu_default(pdu, transactionId, pduType, mimeType, dataIndex); + } + } + + + + private void dispatchWapPdu_default( + byte[] pdu, int transactionId, int pduType, String mimeType, int dataIndex) { + byte[] data; + + data = new byte[pdu.length - dataIndex]; + System.arraycopy(pdu, dataIndex, data, 0, data.length); + + Intent intent = new Intent(Intents.WAP_PUSH_RECEIVED_ACTION); + intent.setType(mimeType); + intent.putExtra("transactionId", transactionId); + intent.putExtra("pduType", pduType); + intent.putExtra("data", data); + + mPhone.getContext().sendBroadcast( + intent, "android.permission.RECEIVE_WAP_PUSH"); + } + + private void dispatchWapPdu_PushCO(byte[] pdu, int transactionId, int pduType) { + Intent intent = new Intent(Intents.WAP_PUSH_RECEIVED_ACTION); + intent.setType(WspTypeDecoder.CONTENT_MIME_TYPE_B_PUSH_CO); + intent.putExtra("transactionId", transactionId); + intent.putExtra("pduType", pduType); + intent.putExtra("data", pdu); + + mPhone.getContext().sendBroadcast( + intent, "android.permission.RECEIVE_WAP_PUSH"); + } + + private void dispatchWapPdu_MMS(byte[] pdu, int transactionId, int pduType, int dataIndex) { + byte[] data; + + data = new byte[pdu.length - dataIndex]; + System.arraycopy(pdu, dataIndex, data, 0, data.length); + + Intent intent = new Intent(Intents.WAP_PUSH_RECEIVED_ACTION); + intent.setType(WspTypeDecoder.CONTENT_MIME_TYPE_B_MMS); + intent.putExtra("transactionId", transactionId); + intent.putExtra("pduType", pduType); + intent.putExtra("data", data); + + mPhone.getContext().sendBroadcast( + intent, "android.permission.RECEIVE_MMS"); + } +} diff --git a/telephony/java/com/android/internal/telephony/WspTypeDecoder.java b/telephony/java/com/android/internal/telephony/WspTypeDecoder.java new file mode 100644 index 0000000..2984fa8 --- /dev/null +++ b/telephony/java/com/android/internal/telephony/WspTypeDecoder.java @@ -0,0 +1,344 @@ +/* + * Copyright (C) 2008 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.internal.telephony; + + +/** + * Implement the WSP data type decoder. + * + * @hide + */ +public class WspTypeDecoder { + + private static final int WAP_PDU_SHORT_LENGTH_MAX = 30; + private static final int WAP_PDU_LENGTH_QUOTE = 31; + + public static final int PDU_TYPE_PUSH = 0x06; + public static final int PDU_TYPE_CONFIRMED_PUSH = 0x07; + + public static final int CONTENT_TYPE_B_DRM_RIGHTS_XML = 0x4a; + public static final int CONTENT_TYPE_B_DRM_RIGHTS_WBXML = 0x4b; + public static final int CONTENT_TYPE_B_PUSH_SI = 0x2e; + public static final int CONTENT_TYPE_B_PUSH_SL = 0x30; + public static final int CONTENT_TYPE_B_PUSH_CO = 0x32; + public static final int CONTENT_TYPE_B_MMS = 0x3e; + + public static final String CONTENT_MIME_TYPE_B_DRM_RIGHTS_XML = + "application/vnd.oma.drm.rights+xml"; + public static final String CONTENT_MIME_TYPE_B_DRM_RIGHTS_WBXML = + "application/vnd.oma.drm.rights+wbxml"; + public static final String CONTENT_MIME_TYPE_B_PUSH_SI = "application/vnd.wap.sic"; + public static final String CONTENT_MIME_TYPE_B_PUSH_SL = "application/vnd.wap.slc"; + public static final String CONTENT_MIME_TYPE_B_PUSH_CO = "application/vnd.wap.coc"; + public static final String CONTENT_MIME_TYPE_B_MMS = "application/vnd.wap.mms-message"; + + public static final int PARAMETER_ID_X_WAP_APPLICATION_ID = 0x2f; + + + byte[] wspData; + int dataLength; + long unsigned32bit; + String stringValue; + + public WspTypeDecoder(byte[] pdu) { + wspData = pdu; + } + + /** + * Decode the "Text-string" type for WSP pdu + * + * @param startIndex The starting position of the "Text-string" in this pdu + * + * @return false when error(not a Text-string) occur + * return value can be retrieved by getValueString() method + * length of data in pdu can be retrieved by getValue32() method + */ + public boolean decodeTextString(int startIndex) { + int index = startIndex; + while (wspData[index] != 0) { + index++; + } + dataLength = index - startIndex + 1; + if (wspData[startIndex] == 127) { + stringValue = new String(wspData, startIndex+1, dataLength - 2); + } else { + stringValue = new String(wspData, startIndex, dataLength - 1); + } + return true; + } + + /** + * Decode the "Short-integer" type for WSP pdu + * + * @param startIndex The starting position of the "Short-integer" in this pdu + * + * @return false when error(not a Short-integer) occur + * return value can be retrieved by getValue32() method + * length of data in pdu can be retrieved by getValue32() method + */ + public boolean decodeShortInteger(int startIndex) { + if ((wspData[startIndex] & 0x80) == 0) { + return false; + } + unsigned32bit = wspData[startIndex] & 0x7f; + dataLength = 1; + return true; + } + + /** + * Decode the "Long-integer" type for WSP pdu + * + * @param startIndex The starting position of the "Long-integer" in this pdu + * + * @return false when error(not a Long-integer) occur + * return value can be retrieved by getValue32() method + * length of data in pdu can be retrieved by getValue32() method + */ + public boolean decodeLongInteger(int startIndex) { + int lengthMultiOctet = wspData[startIndex] & 0xff; + + if (lengthMultiOctet > WAP_PDU_SHORT_LENGTH_MAX) { + return false; + } + unsigned32bit = 0; + for (int i=1; i<=lengthMultiOctet; i++) { + unsigned32bit = (unsigned32bit << 8) | (wspData[startIndex+i] & 0xff); + } + dataLength = 1+lengthMultiOctet; + return true; + } + + /** + * Decode the "Integer-Value" type for WSP pdu + * + * @param startIndex The starting position of the "Integer-Value" in this pdu + * + * @return false when error(not a Integer-Value) occur + * return value can be retrieved by getValue32() method + * length of data in pdu can be retrieved by getValue32() method + */ + public boolean decodeIntegerValue(int startIndex) { + if (decodeShortInteger(startIndex) == true) { + return true; + } + return decodeLongInteger(startIndex); + } + + /** + * Decode the "Uintvar-integer" type for WSP pdu + * + * @param startIndex The starting position of the "Uintvar-integer" in this pdu + * + * @return false when error(not a Uintvar-integer) occur + * return value can be retrieved by getValue32() method + * length of data in pdu can be retrieved by getValue32() method + */ + public boolean decodeUintvarInteger(int startIndex) { + int index = startIndex; + + unsigned32bit = 0; + while ((wspData[index] & 0x80) != 0) { + if ((index - startIndex) >= 4) { + return false; + } + unsigned32bit = (unsigned32bit << 7) | (wspData[index] & 0x7f); + index++; + } + unsigned32bit = (unsigned32bit << 7) | (wspData[index] & 0x7f); + dataLength = index - startIndex + 1; + return true; + } + + /** + * Decode the "Value-length" type for WSP pdu + * + * @param startIndex The starting position of the "Value-length" in this pdu + * + * @return false when error(not a Value-length) occur + * return value can be retrieved by getValue32() method + * length of data in pdu can be retrieved by getValue32() method + */ + public boolean decodeValueLength(int startIndex) { + if ((wspData[startIndex] & 0xff) > WAP_PDU_LENGTH_QUOTE) { + return false; + } + if (wspData[startIndex] < WAP_PDU_LENGTH_QUOTE) { + unsigned32bit = wspData[startIndex]; + dataLength = 1; + } else { + decodeUintvarInteger(startIndex+1); + dataLength ++; + } + return true; + } + + /** + * Decode the "Extension-media" type for WSP pdu + * + * @param startIndex The starting position of the "Extension-media" in this pdu + * + * @return false when error(not a Extension-media) occur + * return value can be retrieved by getValueString() method + * length of data in pdu can be retrieved by getValue32() method + */ + public boolean decodeExtensionMedia(int startIndex) { + int index = startIndex; + while (wspData[index] != 0) { + index++; + } + dataLength = index - startIndex + 1; + stringValue = new String(wspData, startIndex, dataLength - 1); + return true; + } + + /** + * Decode the "Constrained-encoding" type for WSP pdu + * + * @param startIndex The starting position of the "Constrained-encoding" in this pdu + * + * @return false when error(not a Constrained-encoding) occur + * return value can be retrieved first by getValueString() and second by getValue32() method + * length of data in pdu can be retrieved by getValue32() method + */ + public boolean decodeConstrainedEncoding(int startIndex) { + if (decodeShortInteger(startIndex) == true) { + stringValue = null; + return true; + } + return decodeExtensionMedia(startIndex); + } + + /** + * Decode the "Content-type" type for WSP pdu + * + * @param startIndex The starting position of the "Content-type" in this pdu + * + * @return false when error(not a Content-type) occur + * return value can be retrieved first by getValueString() and second by getValue32() + * method length of data in pdu can be retrieved by getValue32() method + */ + public boolean decodeContentType(int startIndex) { + int mediaPrefixLength; + long mediaFieldLength; + + if (decodeValueLength(startIndex) == false) { + return decodeConstrainedEncoding(startIndex); + } + mediaPrefixLength = getDecodedDataLength(); + mediaFieldLength = getValue32(); + if (decodeIntegerValue(startIndex + mediaPrefixLength) == true) { + dataLength += mediaPrefixLength; + stringValue = null; + return true; + } + if (decodeExtensionMedia(startIndex + mediaPrefixLength) == true) { + dataLength += mediaPrefixLength; + return true; + } + return false; + } + + /** + * Decode the "Content length" type for WSP pdu + * + * @param startIndex The starting position of the "Content length" in this pdu + * + * @return false when error(not a Content length) occur + * return value can be retrieved by getValue32() method + * length of data in pdu can be retrieved by getValue32() method + */ + public boolean decodeContentLength(int startIndex) { + return decodeIntegerValue(startIndex); + } + + /** + * Decode the "Content location" type for WSP pdu + * + * @param startIndex The starting position of the "Content location" in this pdu + * + * @return false when error(not a Content location) occur + * return value can be retrieved by getValueString() method + * length of data in pdu can be retrieved by getValue32() method + */ + public boolean decodeContentLocation(int startIndex) { + return decodeTextString(startIndex); + } + + /** + * Decode the "X-Wap-Application-Id" type for WSP pdu + * + * @param startIndex The starting position of the "X-Wap-Application-Id" in this pdu + * + * @return false when error(not a X-Wap-Application-Id) occur + * return value can be retrieved first by getValueString() and second by getValue32() + * method length of data in pdu can be retrieved by getValue32() method + */ + public boolean decodeXWapApplicationId(int startIndex) { + if (decodeIntegerValue(startIndex) == true) { + stringValue = null; + return true; + } + return decodeTextString(startIndex); + } + + /** + * Decode the "X-Wap-Content-URI" type for WSP pdu + * + * @param startIndex The starting position of the "X-Wap-Content-URI" in this pdu + * + * @return false when error(not a X-Wap-Content-URI) occur + * return value can be retrieved by getValueString() method + * length of data in pdu can be retrieved by getValue32() method + */ + public boolean decodeXWapContentURI(int startIndex) { + return decodeTextString(startIndex); + } + + /** + * Decode the "X-Wap-Initiator-URI" type for WSP pdu + * + * @param startIndex The starting position of the "X-Wap-Initiator-URI" in this pdu + * + * @return false when error(not a X-Wap-Initiator-URI) occur + * return value can be retrieved by getValueString() method + * length of data in pdu can be retrieved by getValue32() method + */ + public boolean decodeXWapInitiatorURI(int startIndex) { + return decodeTextString(startIndex); + } + + /** + * The data length of latest operation. + */ + public int getDecodedDataLength() { + return dataLength; + } + + /** + * The 32-bits result of latest operation. + */ + public long getValue32() { + return unsigned32bit; + } + + /** + * The String result of latest operation. + */ + public String getValueString() { + return stringValue; + } +} diff --git a/telephony/java/com/android/internal/telephony/gsm/SMSDispatcher.java b/telephony/java/com/android/internal/telephony/gsm/SMSDispatcher.java index 4176004..6eea1d4 100644 --- a/telephony/java/com/android/internal/telephony/gsm/SMSDispatcher.java +++ b/telephony/java/com/android/internal/telephony/gsm/SMSDispatcher.java @@ -37,6 +37,7 @@ import android.provider.Settings; import android.provider.Telephony.Sms.Intents; import android.telephony.gsm.SmsMessage; import android.telephony.gsm.SmsManager; +import com.android.internal.telephony.WapPushOverSms; import android.telephony.ServiceState; import android.util.Config; import com.android.internal.util.HexDump; @@ -62,37 +63,6 @@ final class SMSDispatcher extends Handler { /** Default timeout for SMS sent query */ private static final int DEFAULT_SMS_TIMOUEOUT = 6000; - private static final int WAP_PDU_TYPE_PUSH = 0x06; - - private static final int WAP_PDU_TYPE_CONFIRMED_PUSH = 0x07; - - private static final byte DRM_RIGHTS_XML = (byte)0xca; - - private static final String DRM_RIGHTS_XML_MIME_TYPE = "application/vnd.oma.drm.rights+xml"; - - private static final byte DRM_RIGHTS_WBXML = (byte)0xcb; - - private static final String DRM_RIGHTS_WBXML_MIME_TYPE = - "application/vnd.oma.drm.rights+wbxml"; - - private static final byte WAP_SI_MIME_PORT = (byte)0xae; - - private static final String WAP_SI_MIME_TYPE = "application/vnd.wap.sic"; - - private static final byte WAP_SL_MIME_PORT = (byte)0xb0; - - private static final String WAP_SL_MIME_TYPE = "application/vnd.wap.slc"; - - private static final byte WAP_CO_MIME_PORT = (byte)0xb2; - - private static final String WAP_CO_MIME_TYPE = "application/vnd.wap.coc"; - - private static final int WAP_PDU_SHORT_LENGTH_MAX = 30; - - private static final int WAP_PDU_LENGTH_QUOTE = 31; - - private static final String MMS_MIME_TYPE = "application/vnd.wap.mms-message"; - private static final String[] RAW_PROJECTION = new String[] { "pdu", "sequence", @@ -124,6 +94,8 @@ final class SMSDispatcher extends Handler { private final GSMPhone mPhone; + private final WapPushOverSms mWapPush; + private final Context mContext; private final ContentResolver mResolver; @@ -208,6 +180,7 @@ final class SMSDispatcher extends Handler { SMSDispatcher(GSMPhone phone) { mPhone = phone; + mWapPush = new WapPushOverSms(phone); mContext = phone.getContext(); mResolver = mContext.getContentResolver(); mCm = phone.mCM; @@ -538,7 +511,7 @@ final class SMSDispatcher extends Handler { if (destPort != -1) { if (destPort == SmsHeader.PORT_WAP_PUSH) { - dispatchWapPdu(sms.getUserData()); + mWapPush.dispatchWapPdu(sms.getUserData()); } // The message was sent to a port, so concoct a URI for it dispatchPortAddressedPdus(pdus, destPort); @@ -621,7 +594,7 @@ final class SMSDispatcher extends Handler { } // Handle the PUSH - dispatchWapPdu(output.toByteArray()); + mWapPush.dispatchWapPdu(output.toByteArray()); break; } @@ -663,122 +636,6 @@ final class SMSDispatcher extends Handler { intent, "android.permission.RECEIVE_SMS"); } - /** - * Dispatches inbound messages that are in the WAP PDU format. See - * wap-230-wsp-20010705-a section 8 for details on the WAP PDU format. - * - * @param pdu The WAP PDU, made up of one or more SMS PDUs - */ - private void dispatchWapPdu(byte[] pdu) { - int index = 0; - int transactionId = pdu[index++] & 0xFF; - int pduType = pdu[index++] & 0xFF; - int headerLength = 0; - - if ((pduType != WAP_PDU_TYPE_PUSH) && - (pduType != WAP_PDU_TYPE_CONFIRMED_PUSH)) { - Log.w(TAG, "Received non-PUSH WAP PDU. Type = " + pduType); - return; - } - - /** - * Parse HeaderLen(unsigned integer). - * From wap-230-wsp-20010705-a section 8.1.2 - * The maximum size of a uintvar is 32 bits. - * So it will be encoded in no more than 5 octets. - */ - int temp = 0; - do { - temp = pdu[index++]; - headerLength = headerLength << 7; - headerLength |= temp & 0x7F; - } while ((temp & 0x80) != 0); - - int headerStartIndex = index; - - /** - * Parse Content-Type. - * From wap-230-wsp-20010705-a section 8.4.2.24 - * - * Content-type-value = Constrained-media | Content-general-form - * Content-general-form = Value-length Media-type - * Media-type = (Well-known-media | Extension-Media) *(Parameter) - * Value-length = Short-length | (Length-quote Length) - * Short-length = <Any octet 0-30> (octet <= WAP_PDU_SHORT_LENGTH_MAX) - * Length-quote = <Octet 31> (WAP_PDU_LENGTH_QUOTE) - * Length = Uintvar-integer - */ - // Parse Value-length. - if ((pdu[index] & 0xff) <= WAP_PDU_SHORT_LENGTH_MAX) { - // Short-length. - index++; - } else if (pdu[index] == WAP_PDU_LENGTH_QUOTE) { - // Skip Length-quote. - index++; - // Skip Length. - // Now we assume 8bit is enough to store the content-type length. - index++; - } - String mimeType; - switch (pdu[headerStartIndex]) - { - case DRM_RIGHTS_XML: - mimeType = DRM_RIGHTS_XML_MIME_TYPE; - break; - case DRM_RIGHTS_WBXML: - mimeType = DRM_RIGHTS_WBXML_MIME_TYPE; - break; - case WAP_SI_MIME_PORT: - // application/vnd.wap.sic - mimeType = WAP_SI_MIME_TYPE; - break; - case WAP_SL_MIME_PORT: - mimeType = WAP_SL_MIME_TYPE; - break; - case WAP_CO_MIME_PORT: - mimeType = WAP_CO_MIME_TYPE; - break; - default: - int start = index; - - // Skip text-string. - // Now we assume the mimetype is Extension-Media. - while (pdu[index++] != '\0') { - ; - } - mimeType = new String(pdu, start, index-start-1); - break; - } - - // XXX Skip the remainder of the header for now - int dataIndex = headerStartIndex + headerLength; - byte[] data; - if (pdu[headerStartIndex] == WAP_CO_MIME_PORT) - { - // because SMSDispatcher can't parse push headers "Content-Location" and - // X-Wap-Content-URI, so pass the whole push to CO application. - data = pdu; - } else - { - data = new byte[pdu.length - dataIndex]; - System.arraycopy(pdu, dataIndex, data, 0, data.length); - } - - // Notify listeners about the WAP PUSH - Intent intent = new Intent(Intents.WAP_PUSH_RECEIVED_ACTION); - intent.setType(mimeType); - intent.putExtra("transactionId", transactionId); - intent.putExtra("pduType", pduType); - intent.putExtra("data", data); - - if (mimeType.equals(MMS_MIME_TYPE)) { - mPhone.getContext().sendBroadcast( - intent, "android.permission.RECEIVE_MMS"); - } else { - mPhone.getContext().sendBroadcast( - intent, "android.permission.RECEIVE_WAP_PUSH"); - } - } /** * Send a multi-part text based SMS. @@ -913,7 +770,7 @@ final class SMSDispatcher extends Handler { sendSms(tracker); } } - + /** * Send a SMS * diff --git a/telephony/java/com/android/internal/telephony/gsm/ServiceStateTracker.java b/telephony/java/com/android/internal/telephony/gsm/ServiceStateTracker.java index f37d1eb..995173b 100644 --- a/telephony/java/com/android/internal/telephony/gsm/ServiceStateTracker.java +++ b/telephony/java/com/android/internal/telephony/gsm/ServiceStateTracker.java @@ -35,6 +35,7 @@ import android.database.ContentObserver; import android.os.AsyncResult; import android.os.Handler; import android.os.Message; +import android.os.PowerManager; import android.os.Registrant; import android.os.RegistrantList; import android.os.SystemClock; @@ -141,6 +142,9 @@ final class ServiceStateTracker extends Handler // Already sent the event-log for no gprs register private boolean mReportedGprsNoReg = false; + // Wake lock used while setting time of day. + private PowerManager.WakeLock mWakeLock; + private static final String WAKELOCK_TAG = "ServiceStateTracker"; // Keep track of SPN display rules, so we only broadcast intent if something changes. private String curSpn = null; @@ -230,7 +234,11 @@ final class ServiceStateTracker extends Handler cellLoc = new GsmCellLocation(); newCellLoc = new GsmCellLocation(); - cm.registerForAvailable(this, EVENT_RADIO_AVAILABLE, null); + PowerManager powerManager = + (PowerManager)phone.getContext().getSystemService(Context.POWER_SERVICE); + mWakeLock = powerManager.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, WAKELOCK_TAG); + + cm.registerForAvailable(this, EVENT_RADIO_AVAILABLE, null); cm.registerForRadioStateChanged(this, EVENT_RADIO_STATE_CHANGED, null); cm.registerForNetworkStateChanged(this, EVENT_NETWORK_STATE_CHANGED, null); @@ -1348,42 +1356,49 @@ final class ServiceStateTracker extends Handler return; } - if (getAutoTime()) { - long millisSinceNitzReceived - = SystemClock.elapsedRealtime() - nitzReceiveTime; + try { + mWakeLock.acquire(); - if (millisSinceNitzReceived < 0) { - // Sanity check: something is wrong - Log.i(LOG_TAG, "NITZ: not setting time, clock has rolled " - + "backwards since NITZ time was received, " - + nitz); - return; - } + if (getAutoTime()) { + long millisSinceNitzReceived + = SystemClock.elapsedRealtime() - nitzReceiveTime; + + if (millisSinceNitzReceived < 0) { + // Sanity check: something is wrong + Log.i(LOG_TAG, "NITZ: not setting time, clock has rolled " + + "backwards since NITZ time was received, " + + nitz); + return; + } - if (millisSinceNitzReceived > Integer.MAX_VALUE) { - // If the time is this far off, something is wrong > 24 days! - Log.i(LOG_TAG, "NITZ: not setting time, processing has taken " - + (millisSinceNitzReceived / (1000 * 60 * 60 * 24)) - + " days"); - return; - } + if (millisSinceNitzReceived > Integer.MAX_VALUE) { + // If the time is this far off, something is wrong > 24 days! + Log.i(LOG_TAG, "NITZ: not setting time, processing has taken " + + (millisSinceNitzReceived / (1000 * 60 * 60 * 24)) + + " days"); + return; + } - // Note: with range checks above, cast to int is safe - c.add(Calendar.MILLISECOND, (int)millisSinceNitzReceived); + // Note: with range checks above, cast to int is safe + c.add(Calendar.MILLISECOND, (int)millisSinceNitzReceived); - Log.i(LOG_TAG, "NITZ: Setting time of day to " + c.getTime() - + " NITZ receive delay(ms): " + millisSinceNitzReceived - + " gained(ms): " - + (c.getTimeInMillis() - System.currentTimeMillis()) - + " from " + nitz); + Log.i(LOG_TAG, "NITZ: Setting time of day to " + c.getTime() + + " NITZ receive delay(ms): " + millisSinceNitzReceived + + " gained(ms): " + + (c.getTimeInMillis() - System.currentTimeMillis()) + + " from " + nitz); - setAndBroadcastNetworkSetTime(c.getTimeInMillis()); - } - SystemProperties.set("gsm.nitz.time", String.valueOf(c.getTimeInMillis())); - saveNitzTime(c.getTimeInMillis()); - if (Config.LOGV) { - long end = SystemClock.elapsedRealtime(); - Log.v(LOG_TAG, "NITZ: end=" + end + " dur=" + (end - start)); + SystemClock.setCurrentTimeMillis(c.getTimeInMillis()); + Log.i(LOG_TAG, "NITZ: after Setting time of day"); + } + SystemProperties.set("gsm.nitz.time", String.valueOf(c.getTimeInMillis())); + saveNitzTime(c.getTimeInMillis()); + if (Config.LOGV) { + long end = SystemClock.elapsedRealtime(); + Log.v(LOG_TAG, "NITZ: end=" + end + " dur=" + (end - start)); + } + } finally { + mWakeLock.release(); } } catch (RuntimeException ex) { Log.e(LOG_TAG, "NITZ: Parsing NITZ time " + nitz, ex); |