diff options
author | Xavier Ducrohet <xav@android.com> | 2011-02-28 09:51:38 -0800 |
---|---|---|
committer | Android Git Automerger <android-git-automerger@android.com> | 2011-02-28 09:51:38 -0800 |
commit | ce57a7f35344e76689d30f45964d1e37b78280cb (patch) | |
tree | 880399208681c04fb55a240b9317b65fc135c91b /telephony | |
parent | e630e5f49ba15005172dceeda7299569b2d2351f (diff) | |
parent | 6504490cde3ec5d48321d539e654d1f2072b33f9 (diff) | |
download | frameworks_base-ce57a7f35344e76689d30f45964d1e37b78280cb.zip frameworks_base-ce57a7f35344e76689d30f45964d1e37b78280cb.tar.gz frameworks_base-ce57a7f35344e76689d30f45964d1e37b78280cb.tar.bz2 |
am 6504490c: am dff6b8e7: Merge "Add --non-constant-id to aapt."
* commit '6504490cde3ec5d48321d539e654d1f2072b33f9':
GpsLocationProvider: Clean up HAL initialization/cleanup sequence
Fixed GSM encoded network initiated position request
Ensuring thread-safe usage of DateFormat.
Fixing infinite loop for zero duration.
Fix for an infinite loop while scrolling lists.
WAPPushManager, WAP Push over SMS message handler
Add --non-constant-id to aapt.
Diffstat (limited to 'telephony')
4 files changed, 323 insertions, 4 deletions
diff --git a/telephony/java/com/android/internal/telephony/IWapPushManager.aidl b/telephony/java/com/android/internal/telephony/IWapPushManager.aidl new file mode 100644 index 0000000..d5ecb94 --- /dev/null +++ b/telephony/java/com/android/internal/telephony/IWapPushManager.aidl @@ -0,0 +1,52 @@ +/* + * Copyright (C) 2010 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; + +interface IWapPushManager { + /** + * Processes WAP push message and triggers the receiver application registered + * in the application ID table. + */ + int processMessage(String app_id, String content_type, in Intent intent); + + /** + * Add receiver application into the application ID table. + * Returns true if inserting the information is successfull. Inserting the duplicated + * record in the application ID table is not allowed. Use update/delete method. + */ + boolean addPackage(String x_app_id, String content_type, + String package_name, String class_name, + int app_type, boolean need_signature, boolean further_processing); + + /** + * Updates receiver application that is last added. + * Returns true if updating the information is successfull. + */ + boolean updatePackage(String x_app_id, String content_type, + String package_name, String class_name, + int app_type, boolean need_signature, boolean further_processing); + + /** + * Delites receiver application information. + * Returns true if deleting is successfull. + */ + boolean deletePackage(String x_app_id, String content_type, + String package_name, String class_name); +} + diff --git a/telephony/java/com/android/internal/telephony/WapPushManagerParams.java b/telephony/java/com/android/internal/telephony/WapPushManagerParams.java new file mode 100644 index 0000000..11e5ff9 --- /dev/null +++ b/telephony/java/com/android/internal/telephony/WapPushManagerParams.java @@ -0,0 +1,70 @@ +/* + * Copyright (C) 2010 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; + +/** + * WapPushManager constant value definitions + */ +public class WapPushManagerParams { + /** + * Application type activity + */ + public static final int APP_TYPE_ACTIVITY = 0; + + /** + * Application type service + */ + public static final int APP_TYPE_SERVICE = 1; + + /** + * Process Message return value + * Message is handled + */ + public static final int MESSAGE_HANDLED = 0x1; + + /** + * Process Message return value + * Application ID or content type was not found in the application ID table + */ + public static final int APP_QUERY_FAILED = 0x2; + + /** + * Process Message return value + * Receiver application signature check failed + */ + public static final int SIGNATURE_NO_MATCH = 0x4; + + /** + * Process Message return value + * Receiver application was not found + */ + public static final int INVALID_RECEIVER_NAME = 0x8; + + /** + * Process Message return value + * Unknown exception + */ + public static final int EXCEPTION_CAUGHT = 0x10; + + /** + * Process Message return value + * Need further processing after WapPushManager message processing + */ + public static final int FURTHER_PROCESSING = 0x8000; + +} + diff --git a/telephony/java/com/android/internal/telephony/WapPushOverSms.java b/telephony/java/com/android/internal/telephony/WapPushOverSms.java index 2f5d3ec..7704667 100644 --- a/telephony/java/com/android/internal/telephony/WapPushOverSms.java +++ b/telephony/java/com/android/internal/telephony/WapPushOverSms.java @@ -14,15 +14,20 @@ * limitations under the License. */ + package com.android.internal.telephony; import android.app.Activity; import android.content.Context; +import android.content.ComponentName; import android.content.Intent; +import android.content.ServiceConnection; import android.provider.Telephony; import android.provider.Telephony.Sms.Intents; import android.util.Config; import android.util.Log; +import android.os.IBinder; +import android.os.RemoteException; /** * WAP push handler class. @@ -42,11 +47,83 @@ public class WapPushOverSms { */ private final int WAKE_LOCK_TIMEOUT = 5000; + private final int BIND_RETRY_INTERVAL = 1000; + /** + * A handle to WapPushManager interface + */ + private WapPushConnection mWapConn = null; + private class WapPushConnection implements ServiceConnection { + private IWapPushManager mWapPushMan; + private Context mOwner; + + public WapPushConnection(Context ownerContext) { + mOwner = ownerContext; + } + + public void onServiceConnected(ComponentName name, IBinder service) { + mWapPushMan = IWapPushManager.Stub.asInterface(service); + if (Config.DEBUG) Log.v(LOG_TAG, "wappush manager connected to " + + mOwner.hashCode()); + } + + public void onServiceDisconnected(ComponentName name) { + mWapPushMan = null; + if (Config.DEBUG) Log.v(LOG_TAG, "wappush manager disconnected."); + // WapPushManager must be always attached. + rebindWapPushManager(); + } + + /** + * bind WapPushManager + */ + public void bindWapPushManager() { + if (mWapPushMan != null) return; + + final ServiceConnection wapPushConnection = this; + + mOwner.bindService(new Intent(IWapPushManager.class.getName()), + wapPushConnection, Context.BIND_AUTO_CREATE); + } + + /** + * rebind WapPushManager + * This method is called when WapPushManager is disconnected unexpectedly. + */ + private void rebindWapPushManager() { + if (mWapPushMan != null) return; + + final ServiceConnection wapPushConnection = this; + new Thread() { + public void run() { + while (mWapPushMan == null) { + mOwner.bindService(new Intent(IWapPushManager.class.getName()), + wapPushConnection, Context.BIND_AUTO_CREATE); + try { + Thread.sleep(BIND_RETRY_INTERVAL); + } catch (InterruptedException e) { + if (Config.DEBUG) Log.v(LOG_TAG, "sleep interrupted."); + } + } + } + }.start(); + } + + /** + * Returns interface to WapPushManager + */ + public IWapPushManager getWapPushManager() { + return mWapPushMan; + } + } + public WapPushOverSms(Phone phone, SMSDispatcher smsDispatcher) { mSmsDispatcher = smsDispatcher; mContext = phone.getContext(); + mWapConn = new WapPushConnection(mContext); + mWapConn.bindWapPushManager(); } + /** * 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. @@ -106,16 +183,15 @@ public class WapPushOverSms { } String mimeType = pduDecoder.getValueString(); - + long binaryContentType = pduDecoder.getValue32(); index += pduDecoder.getDecodedDataLength(); byte[] header = new byte[headerLength]; System.arraycopy(pdu, headerStartIndex, header, 0, header.length); byte[] intentData; - String permission; - if (mimeType.equals(WspTypeDecoder.CONTENT_TYPE_B_PUSH_CO)) { + if (mimeType != null && mimeType.equals(WspTypeDecoder.CONTENT_TYPE_B_PUSH_CO)) { intentData = pdu; } else { int dataIndex = headerStartIndex + headerLength; @@ -123,6 +199,62 @@ public class WapPushOverSms { System.arraycopy(pdu, dataIndex, intentData, 0, intentData.length); } + /** + * Seek for application ID field in WSP header. + * If application ID is found, WapPushManager substitute the message + * processing. Since WapPushManager is optional module, if WapPushManager + * is not found, legacy message processing will be continued. + */ + if (pduDecoder.seekXWapApplicationId(index, index + headerLength - 1)) { + index = (int) pduDecoder.getValue32(); + pduDecoder.decodeXWapApplicationId(index); + String wapAppId = pduDecoder.getValueString(); + if (wapAppId == null) { + wapAppId = Integer.toString((int) pduDecoder.getValue32()); + } + + String contentType = ((mimeType == null) ? + Long.toString(binaryContentType) : mimeType); + if (Config.DEBUG) Log.v(LOG_TAG, "appid found: " + wapAppId + ":" + contentType); + + try { + boolean processFurther = true; + IWapPushManager wapPushMan = mWapConn.getWapPushManager(); + + if (wapPushMan == null) { + if (Config.DEBUG) Log.w(LOG_TAG, "wap push manager not found!"); + } else { + Intent intent = new Intent(); + intent.putExtra("transactionId", transactionId); + intent.putExtra("pduType", pduType); + intent.putExtra("header", header); + intent.putExtra("data", intentData); + intent.putExtra("contentTypeParameters", + pduDecoder.getContentParameters()); + + int procRet = wapPushMan.processMessage(wapAppId, contentType, intent); + if (Config.DEBUG) Log.v(LOG_TAG, "procRet:" + procRet); + if ((procRet & WapPushManagerParams.MESSAGE_HANDLED) > 0 + && (procRet & WapPushManagerParams.FURTHER_PROCESSING) == 0) { + processFurther = false; + } + } + if (!processFurther) { + return Intents.RESULT_SMS_HANDLED; + } + } catch (RemoteException e) { + if (Config.DEBUG) Log.w(LOG_TAG, "remote func failed..."); + } + } + if (Config.DEBUG) Log.v(LOG_TAG, "fall back to existing handler"); + + if (mimeType == null) { + if (Config.DEBUG) Log.w(LOG_TAG, "Header Content-Type error."); + return Intents.RESULT_SMS_GENERIC_ERROR; + } + + String permission; + if (mimeType.equals(WspTypeDecoder.CONTENT_TYPE_B_MMS)) { permission = "android.permission.RECEIVE_MMS"; } else { @@ -141,4 +273,4 @@ public class WapPushOverSms { return Activity.RESULT_OK; } -}
\ No newline at end of file +} diff --git a/telephony/java/com/android/internal/telephony/WspTypeDecoder.java b/telephony/java/com/android/internal/telephony/WspTypeDecoder.java index 6bf6b13..c8dd718 100644 --- a/telephony/java/com/android/internal/telephony/WspTypeDecoder.java +++ b/telephony/java/com/android/internal/telephony/WspTypeDecoder.java @@ -37,6 +37,7 @@ public class WspTypeDecoder { private final static HashMap<Integer, String> WELL_KNOWN_PARAMETERS = new HashMap<Integer, String>(); + public static final int PARAMETER_ID_X_WAP_APPLICATION_ID = 0x2f; private static final int Q_VALUE = 0x00; static { @@ -603,6 +604,70 @@ public class WspTypeDecoder { } /** + * Seek for the "X-Wap-Application-Id" field for WSP pdu + * + * @param startIndex The starting position of seek pointer + * @param endIndex Valid seek area end point + * + * @return false when error(not a X-Wap-Application-Id) occur + * return value can be retrieved by getValue32() + */ + public boolean seekXWapApplicationId(int startIndex, int endIndex) { + int index = startIndex; + + try { + for (index = startIndex; index <= endIndex; ) { + /** + * 8.4.1.1 Field name + * Field name is integer or text. + */ + if (decodeIntegerValue(index)) { + int fieldValue = (int) getValue32(); + + if (fieldValue == PARAMETER_ID_X_WAP_APPLICATION_ID) { + unsigned32bit = index + 1; + return true; + } + } else { + if (!decodeTextString(index)) return false; + } + index += getDecodedDataLength(); + if (index > endIndex) return false; + + /** + * 8.4.1.2 Field values + * Value Interpretation of First Octet + * 0 - 30 This octet is followed by the indicated number (0 - 30) + of data octets + * 31 This octet is followed by a uintvar, which indicates the number + * of data octets after it + * 32 - 127 The value is a text string, terminated by a zero octet + (NUL character) + * 128 - 255 It is an encoded 7-bit value; this header has no more data + */ + byte val = wspData[index]; + if (0 <= val && val <= WAP_PDU_SHORT_LENGTH_MAX) { + index += wspData[index] + 1; + } else if (val == WAP_PDU_LENGTH_QUOTE) { + if (index + 1 >= endIndex) return false; + index++; + if (!decodeUintvarInteger(index)) return false; + index += getDecodedDataLength(); + } else if (WAP_PDU_LENGTH_QUOTE < val && val <= 127) { + if (!decodeTextString(index)) return false; + index += getDecodedDataLength(); + } else { + index++; + } + } + } catch (ArrayIndexOutOfBoundsException e) { + //seek application ID failed. WSP header might be corrupted + return false; + } + return false; + } + + /** * Decode the "X-Wap-Content-URI" type for WSP pdu * * @param startIndex The starting position of the "X-Wap-Content-URI" in this pdu |