summaryrefslogtreecommitdiffstats
path: root/telephony
diff options
context:
space:
mode:
authornoda <noda@nttdocomo.co.jp>2010-08-20 08:10:00 +0900
committernoda <noda@nttdocomo.co.jp>2011-02-18 00:31:24 +0900
commit7640caaf912a7eefacc3e2108c5afd70f7b072a4 (patch)
tree97f11557638e80122d456e6985677a42e9ca7753 /telephony
parent3769240b7976bfa50bb7bf235747b7f6bb7be08e (diff)
downloadframeworks_base-7640caaf912a7eefacc3e2108c5afd70f7b072a4.zip
frameworks_base-7640caaf912a7eefacc3e2108c5afd70f7b072a4.tar.gz
frameworks_base-7640caaf912a7eefacc3e2108c5afd70f7b072a4.tar.bz2
WAPPushManager, WAP Push over SMS message handler
The WAPPushManager is a new, optional service for handling WAP Push over SMS messages. This service allows a carrier to designate a high priority handler for specific WAP Push over SMS messages without affecting other WAP Push over SMS, binary SMS, or SMS text messages. It is also optional, so that it can be configured out of the target image resulting in no change in the WAP Push over SMS handling behavior compared to the current AOSP. - This patch contains the WAPPushManager itself, the associated test code, and the modifications to telephony to use the WAPPushManager. Change-Id: I4f7fb5b68fc666da9bdeeea525e8797ae317e4b5
Diffstat (limited to 'telephony')
-rw-r--r--telephony/java/com/android/internal/telephony/IWapPushManager.aidl52
-rw-r--r--telephony/java/com/android/internal/telephony/WapPushManagerParams.java70
-rw-r--r--telephony/java/com/android/internal/telephony/WapPushOverSms.java140
-rw-r--r--telephony/java/com/android/internal/telephony/WspTypeDecoder.java65
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