10825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville/*
20825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * Copyright (C) 2008 The Android Open Source Project
30825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville *
40825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * Licensed under the Apache License, Version 2.0 (the "License");
50825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * you may not use this file except in compliance with the License.
60825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * You may obtain a copy of the License at
70825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville *
80825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville *      http://www.apache.org/licenses/LICENSE-2.0
90825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville *
100825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * Unless required by applicable law or agreed to in writing, software
110825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * distributed under the License is distributed on an "AS IS" BASIS,
120825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
130825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * See the License for the specific language governing permissions and
140825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * limitations under the License.
150825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville */
160825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
170825495a331bb44df395a0cdb79fab85e68db5d5Wink Savillepackage com.android.internal.telephony;
180825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
190825495a331bb44df395a0cdb79fab85e68db5d5Wink Savilleimport android.app.Activity;
207fce994eb223105829becb6c26e3af7a9739752cDianne Hackbornimport android.app.AppOpsManager;
210d4bcdf379842af4b6304809156971e926f374f0Jake Hambyimport android.content.BroadcastReceiver;
220825495a331bb44df395a0cdb79fab85e68db5d5Wink Savilleimport android.content.ComponentName;
230d4bcdf379842af4b6304809156971e926f374f0Jake Hambyimport android.content.Context;
240825495a331bb44df395a0cdb79fab85e68db5d5Wink Savilleimport android.content.Intent;
250825495a331bb44df395a0cdb79fab85e68db5d5Wink Savilleimport android.content.ServiceConnection;
260825495a331bb44df395a0cdb79fab85e68db5d5Wink Savilleimport android.os.IBinder;
270825495a331bb44df395a0cdb79fab85e68db5d5Wink Savilleimport android.os.RemoteException;
280d4bcdf379842af4b6304809156971e926f374f0Jake Hambyimport android.provider.Telephony.Sms.Intents;
290d4bcdf379842af4b6304809156971e926f374f0Jake Hambyimport android.telephony.Rlog;
300825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
31d720945f2be5ea5fe0faf67e67d9ea0e184eba67Alex Yakavenkaimport com.android.internal.telephony.uicc.IccUtils;
32d720945f2be5ea5fe0faf67e67d9ea0e184eba67Alex Yakavenka
330825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville/**
340825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * WAP push handler class.
350825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville *
360825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * @hide
370825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville */
380d4bcdf379842af4b6304809156971e926f374f0Jake Hambypublic class WapPushOverSms implements ServiceConnection {
390d4bcdf379842af4b6304809156971e926f374f0Jake Hamby    private static final String TAG = "WAP PUSH";
400d4bcdf379842af4b6304809156971e926f374f0Jake Hamby    private static final boolean DBG = true;
410825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
420825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    private final Context mContext;
430825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
440d4bcdf379842af4b6304809156971e926f374f0Jake Hamby    /** Assigned from ServiceConnection callback on main threaad. */
450d4bcdf379842af4b6304809156971e926f374f0Jake Hamby    private volatile IWapPushManager mWapPushManager;
460825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
470d4bcdf379842af4b6304809156971e926f374f0Jake Hamby    @Override
480d4bcdf379842af4b6304809156971e926f374f0Jake Hamby    public void onServiceConnected(ComponentName name, IBinder service) {
490d4bcdf379842af4b6304809156971e926f374f0Jake Hamby        mWapPushManager = IWapPushManager.Stub.asInterface(service);
500d4bcdf379842af4b6304809156971e926f374f0Jake Hamby        if (DBG) Rlog.v(TAG, "wappush manager connected to " + hashCode());
510d4bcdf379842af4b6304809156971e926f374f0Jake Hamby    }
520825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
530d4bcdf379842af4b6304809156971e926f374f0Jake Hamby    @Override
540d4bcdf379842af4b6304809156971e926f374f0Jake Hamby    public void onServiceDisconnected(ComponentName name) {
550d4bcdf379842af4b6304809156971e926f374f0Jake Hamby        mWapPushManager = null;
560d4bcdf379842af4b6304809156971e926f374f0Jake Hamby        if (DBG) Rlog.v(TAG, "wappush manager disconnected.");
570d4bcdf379842af4b6304809156971e926f374f0Jake Hamby    }
580825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
590d4bcdf379842af4b6304809156971e926f374f0Jake Hamby    public WapPushOverSms(Context context) {
600d4bcdf379842af4b6304809156971e926f374f0Jake Hamby        mContext = context;
617d3118aa708e4d02bf65514ab3feda10cd05a619Dianne Hackborn        Intent intent = new Intent(IWapPushManager.class.getName());
627d3118aa708e4d02bf65514ab3feda10cd05a619Dianne Hackborn        ComponentName comp = intent.resolveSystemService(context.getPackageManager(), 0);
637d3118aa708e4d02bf65514ab3feda10cd05a619Dianne Hackborn        intent.setComponent(comp);
647d3118aa708e4d02bf65514ab3feda10cd05a619Dianne Hackborn        if (comp == null || !context.bindService(intent, this, Context.BIND_AUTO_CREATE)) {
6516d259bfedada60d6b772ee0c640df58830527dfWink Saville            Rlog.e(TAG, "bindService() for wappush manager failed");
6616d259bfedada60d6b772ee0c640df58830527dfWink Saville        } else {
6716d259bfedada60d6b772ee0c640df58830527dfWink Saville            if (DBG) Rlog.v(TAG, "bindService() for wappush manager succeeded");
680825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
690825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
700825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
710d4bcdf379842af4b6304809156971e926f374f0Jake Hamby    void dispose() {
7216d259bfedada60d6b772ee0c640df58830527dfWink Saville        if (mWapPushManager != null) {
7316d259bfedada60d6b772ee0c640df58830527dfWink Saville            if (DBG) Rlog.v(TAG, "dispose: unbind wappush manager");
7416d259bfedada60d6b772ee0c640df58830527dfWink Saville            mContext.unbindService(this);
7516d259bfedada60d6b772ee0c640df58830527dfWink Saville        } else {
7616d259bfedada60d6b772ee0c640df58830527dfWink Saville            Rlog.e(TAG, "dispose: not bound to a wappush manager");
7716d259bfedada60d6b772ee0c640df58830527dfWink Saville        }
780825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
790825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
800825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    /**
810825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * Dispatches inbound messages that are in the WAP PDU format. See
820825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * wap-230-wsp-20010705-a section 8 for details on the WAP PDU format.
830825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     *
840825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * @param pdu The WAP PDU, made up of one or more SMS PDUs
85cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville     * @return a result code from {@link android.provider.Telephony.Sms.Intents}, or
860825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     *         {@link Activity#RESULT_OK} if the message has been broadcast
870825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     *         to applications
880825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     */
890d4bcdf379842af4b6304809156971e926f374f0Jake Hamby    public int dispatchWapPdu(byte[] pdu, BroadcastReceiver receiver, InboundSmsHandler handler) {
900825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
910d4bcdf379842af4b6304809156971e926f374f0Jake Hamby        if (DBG) Rlog.d(TAG, "Rx: " + IccUtils.bytesToHexString(pdu));
920825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
939e17e21d115bb92b4dc094c205d59f73cdc6185aJake Hamby        try {
949e17e21d115bb92b4dc094c205d59f73cdc6185aJake Hamby            int index = 0;
959e17e21d115bb92b4dc094c205d59f73cdc6185aJake Hamby            int transactionId = pdu[index++] & 0xFF;
969e17e21d115bb92b4dc094c205d59f73cdc6185aJake Hamby            int pduType = pdu[index++] & 0xFF;
979e17e21d115bb92b4dc094c205d59f73cdc6185aJake Hamby
989e17e21d115bb92b4dc094c205d59f73cdc6185aJake Hamby            if ((pduType != WspTypeDecoder.PDU_TYPE_PUSH) &&
999e17e21d115bb92b4dc094c205d59f73cdc6185aJake Hamby                    (pduType != WspTypeDecoder.PDU_TYPE_CONFIRMED_PUSH)) {
1009e17e21d115bb92b4dc094c205d59f73cdc6185aJake Hamby                index = mContext.getResources().getInteger(
1019e17e21d115bb92b4dc094c205d59f73cdc6185aJake Hamby                        com.android.internal.R.integer.config_valid_wappush_index);
1029e17e21d115bb92b4dc094c205d59f73cdc6185aJake Hamby                if (index != -1) {
1039e17e21d115bb92b4dc094c205d59f73cdc6185aJake Hamby                    transactionId = pdu[index++] & 0xff;
1049e17e21d115bb92b4dc094c205d59f73cdc6185aJake Hamby                    pduType = pdu[index++] & 0xff;
1059e17e21d115bb92b4dc094c205d59f73cdc6185aJake Hamby                    if (DBG)
1069e17e21d115bb92b4dc094c205d59f73cdc6185aJake Hamby                        Rlog.d(TAG, "index = " + index + " PDU Type = " + pduType +
1079e17e21d115bb92b4dc094c205d59f73cdc6185aJake Hamby                                " transactionID = " + transactionId);
1089e17e21d115bb92b4dc094c205d59f73cdc6185aJake Hamby
1099e17e21d115bb92b4dc094c205d59f73cdc6185aJake Hamby                    // recheck wap push pduType
1109e17e21d115bb92b4dc094c205d59f73cdc6185aJake Hamby                    if ((pduType != WspTypeDecoder.PDU_TYPE_PUSH)
1119e17e21d115bb92b4dc094c205d59f73cdc6185aJake Hamby                            && (pduType != WspTypeDecoder.PDU_TYPE_CONFIRMED_PUSH)) {
1129e17e21d115bb92b4dc094c205d59f73cdc6185aJake Hamby                        if (DBG) Rlog.w(TAG, "Received non-PUSH WAP PDU. Type = " + pduType);
1139e17e21d115bb92b4dc094c205d59f73cdc6185aJake Hamby                        return Intents.RESULT_SMS_HANDLED;
1149e17e21d115bb92b4dc094c205d59f73cdc6185aJake Hamby                    }
1159e17e21d115bb92b4dc094c205d59f73cdc6185aJake Hamby                } else {
11613fa971b6c6eab1578f4732c8de6fa2ba3b57ce6Sungmin Choi                    if (DBG) Rlog.w(TAG, "Received non-PUSH WAP PDU. Type = " + pduType);
11713fa971b6c6eab1578f4732c8de6fa2ba3b57ce6Sungmin Choi                    return Intents.RESULT_SMS_HANDLED;
11813fa971b6c6eab1578f4732c8de6fa2ba3b57ce6Sungmin Choi                }
11913fa971b6c6eab1578f4732c8de6fa2ba3b57ce6Sungmin Choi            }
1200825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
1219e17e21d115bb92b4dc094c205d59f73cdc6185aJake Hamby            WspTypeDecoder pduDecoder = new WspTypeDecoder(pdu);
1229e17e21d115bb92b4dc094c205d59f73cdc6185aJake Hamby
1239e17e21d115bb92b4dc094c205d59f73cdc6185aJake Hamby            /**
1249e17e21d115bb92b4dc094c205d59f73cdc6185aJake Hamby             * Parse HeaderLen(unsigned integer).
1259e17e21d115bb92b4dc094c205d59f73cdc6185aJake Hamby             * From wap-230-wsp-20010705-a section 8.1.2
1269e17e21d115bb92b4dc094c205d59f73cdc6185aJake Hamby             * The maximum size of a uintvar is 32 bits.
1279e17e21d115bb92b4dc094c205d59f73cdc6185aJake Hamby             * So it will be encoded in no more than 5 octets.
1289e17e21d115bb92b4dc094c205d59f73cdc6185aJake Hamby             */
1299e17e21d115bb92b4dc094c205d59f73cdc6185aJake Hamby            if (pduDecoder.decodeUintvarInteger(index) == false) {
1309e17e21d115bb92b4dc094c205d59f73cdc6185aJake Hamby                if (DBG) Rlog.w(TAG, "Received PDU. Header Length error.");
1319e17e21d115bb92b4dc094c205d59f73cdc6185aJake Hamby                return Intents.RESULT_SMS_GENERIC_ERROR;
1329e17e21d115bb92b4dc094c205d59f73cdc6185aJake Hamby            }
1339e17e21d115bb92b4dc094c205d59f73cdc6185aJake Hamby            int headerLength = (int) pduDecoder.getValue32();
1349e17e21d115bb92b4dc094c205d59f73cdc6185aJake Hamby            index += pduDecoder.getDecodedDataLength();
1359e17e21d115bb92b4dc094c205d59f73cdc6185aJake Hamby
1369e17e21d115bb92b4dc094c205d59f73cdc6185aJake Hamby            int headerStartIndex = index;
1379e17e21d115bb92b4dc094c205d59f73cdc6185aJake Hamby
1389e17e21d115bb92b4dc094c205d59f73cdc6185aJake Hamby            /**
1399e17e21d115bb92b4dc094c205d59f73cdc6185aJake Hamby             * Parse Content-Type.
1409e17e21d115bb92b4dc094c205d59f73cdc6185aJake Hamby             * From wap-230-wsp-20010705-a section 8.4.2.24
1419e17e21d115bb92b4dc094c205d59f73cdc6185aJake Hamby             *
1429e17e21d115bb92b4dc094c205d59f73cdc6185aJake Hamby             * Content-type-value = Constrained-media | Content-general-form
1439e17e21d115bb92b4dc094c205d59f73cdc6185aJake Hamby             * Content-general-form = Value-length Media-type
1449e17e21d115bb92b4dc094c205d59f73cdc6185aJake Hamby             * Media-type = (Well-known-media | Extension-Media) *(Parameter)
1459e17e21d115bb92b4dc094c205d59f73cdc6185aJake Hamby             * Value-length = Short-length | (Length-quote Length)
1469e17e21d115bb92b4dc094c205d59f73cdc6185aJake Hamby             * Short-length = <Any octet 0-30>   (octet <= WAP_PDU_SHORT_LENGTH_MAX)
1479e17e21d115bb92b4dc094c205d59f73cdc6185aJake Hamby             * Length-quote = <Octet 31>         (WAP_PDU_LENGTH_QUOTE)
1489e17e21d115bb92b4dc094c205d59f73cdc6185aJake Hamby             * Length = Uintvar-integer
1499e17e21d115bb92b4dc094c205d59f73cdc6185aJake Hamby             */
1509e17e21d115bb92b4dc094c205d59f73cdc6185aJake Hamby            if (pduDecoder.decodeContentType(index) == false) {
1519e17e21d115bb92b4dc094c205d59f73cdc6185aJake Hamby                if (DBG) Rlog.w(TAG, "Received PDU. Header Content-Type error.");
1529e17e21d115bb92b4dc094c205d59f73cdc6185aJake Hamby                return Intents.RESULT_SMS_GENERIC_ERROR;
1539e17e21d115bb92b4dc094c205d59f73cdc6185aJake Hamby            }
1540825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
1559e17e21d115bb92b4dc094c205d59f73cdc6185aJake Hamby            String mimeType = pduDecoder.getValueString();
1569e17e21d115bb92b4dc094c205d59f73cdc6185aJake Hamby            long binaryContentType = pduDecoder.getValue32();
1579e17e21d115bb92b4dc094c205d59f73cdc6185aJake Hamby            index += pduDecoder.getDecodedDataLength();
1580825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
1599e17e21d115bb92b4dc094c205d59f73cdc6185aJake Hamby            byte[] header = new byte[headerLength];
1609e17e21d115bb92b4dc094c205d59f73cdc6185aJake Hamby            System.arraycopy(pdu, headerStartIndex, header, 0, header.length);
1610825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
1629e17e21d115bb92b4dc094c205d59f73cdc6185aJake Hamby            byte[] intentData;
1630825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
1649e17e21d115bb92b4dc094c205d59f73cdc6185aJake Hamby            if (mimeType != null && mimeType.equals(WspTypeDecoder.CONTENT_TYPE_B_PUSH_CO)) {
1659e17e21d115bb92b4dc094c205d59f73cdc6185aJake Hamby                intentData = pdu;
1669e17e21d115bb92b4dc094c205d59f73cdc6185aJake Hamby            } else {
1679e17e21d115bb92b4dc094c205d59f73cdc6185aJake Hamby                int dataIndex = headerStartIndex + headerLength;
1689e17e21d115bb92b4dc094c205d59f73cdc6185aJake Hamby                intentData = new byte[pdu.length - dataIndex];
1699e17e21d115bb92b4dc094c205d59f73cdc6185aJake Hamby                System.arraycopy(pdu, dataIndex, intentData, 0, intentData.length);
1700825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            }
1710825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
1729e17e21d115bb92b4dc094c205d59f73cdc6185aJake Hamby            /**
1739e17e21d115bb92b4dc094c205d59f73cdc6185aJake Hamby             * Seek for application ID field in WSP header.
1749e17e21d115bb92b4dc094c205d59f73cdc6185aJake Hamby             * If application ID is found, WapPushManager substitute the message
1759e17e21d115bb92b4dc094c205d59f73cdc6185aJake Hamby             * processing. Since WapPushManager is optional module, if WapPushManager
1769e17e21d115bb92b4dc094c205d59f73cdc6185aJake Hamby             * is not found, legacy message processing will be continued.
1779e17e21d115bb92b4dc094c205d59f73cdc6185aJake Hamby             */
1789e17e21d115bb92b4dc094c205d59f73cdc6185aJake Hamby            if (pduDecoder.seekXWapApplicationId(index, index + headerLength - 1)) {
1799e17e21d115bb92b4dc094c205d59f73cdc6185aJake Hamby                index = (int) pduDecoder.getValue32();
1809e17e21d115bb92b4dc094c205d59f73cdc6185aJake Hamby                pduDecoder.decodeXWapApplicationId(index);
1819e17e21d115bb92b4dc094c205d59f73cdc6185aJake Hamby                String wapAppId = pduDecoder.getValueString();
1829e17e21d115bb92b4dc094c205d59f73cdc6185aJake Hamby                if (wapAppId == null) {
1839e17e21d115bb92b4dc094c205d59f73cdc6185aJake Hamby                    wapAppId = Integer.toString((int) pduDecoder.getValue32());
1849e17e21d115bb92b4dc094c205d59f73cdc6185aJake Hamby                }
1850825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
1869e17e21d115bb92b4dc094c205d59f73cdc6185aJake Hamby                String contentType = ((mimeType == null) ?
1879e17e21d115bb92b4dc094c205d59f73cdc6185aJake Hamby                        Long.toString(binaryContentType) : mimeType);
1889e17e21d115bb92b4dc094c205d59f73cdc6185aJake Hamby                if (DBG) Rlog.v(TAG, "appid found: " + wapAppId + ":" + contentType);
1899e17e21d115bb92b4dc094c205d59f73cdc6185aJake Hamby
1909e17e21d115bb92b4dc094c205d59f73cdc6185aJake Hamby                try {
1919e17e21d115bb92b4dc094c205d59f73cdc6185aJake Hamby                    boolean processFurther = true;
1929e17e21d115bb92b4dc094c205d59f73cdc6185aJake Hamby                    IWapPushManager wapPushMan = mWapPushManager;
1939e17e21d115bb92b4dc094c205d59f73cdc6185aJake Hamby
1949e17e21d115bb92b4dc094c205d59f73cdc6185aJake Hamby                    if (wapPushMan == null) {
1959e17e21d115bb92b4dc094c205d59f73cdc6185aJake Hamby                        if (DBG) Rlog.w(TAG, "wap push manager not found!");
1969e17e21d115bb92b4dc094c205d59f73cdc6185aJake Hamby                    } else {
1979e17e21d115bb92b4dc094c205d59f73cdc6185aJake Hamby                        Intent intent = new Intent();
1989e17e21d115bb92b4dc094c205d59f73cdc6185aJake Hamby                        intent.putExtra("transactionId", transactionId);
1999e17e21d115bb92b4dc094c205d59f73cdc6185aJake Hamby                        intent.putExtra("pduType", pduType);
2009e17e21d115bb92b4dc094c205d59f73cdc6185aJake Hamby                        intent.putExtra("header", header);
2019e17e21d115bb92b4dc094c205d59f73cdc6185aJake Hamby                        intent.putExtra("data", intentData);
2029e17e21d115bb92b4dc094c205d59f73cdc6185aJake Hamby                        intent.putExtra("contentTypeParameters",
2039e17e21d115bb92b4dc094c205d59f73cdc6185aJake Hamby                                pduDecoder.getContentParameters());
2049e17e21d115bb92b4dc094c205d59f73cdc6185aJake Hamby
2059e17e21d115bb92b4dc094c205d59f73cdc6185aJake Hamby                        int procRet = wapPushMan.processMessage(wapAppId, contentType, intent);
2069e17e21d115bb92b4dc094c205d59f73cdc6185aJake Hamby                        if (DBG) Rlog.v(TAG, "procRet:" + procRet);
2079e17e21d115bb92b4dc094c205d59f73cdc6185aJake Hamby                        if ((procRet & WapPushManagerParams.MESSAGE_HANDLED) > 0
2089e17e21d115bb92b4dc094c205d59f73cdc6185aJake Hamby                                && (procRet & WapPushManagerParams.FURTHER_PROCESSING) == 0) {
2099e17e21d115bb92b4dc094c205d59f73cdc6185aJake Hamby                            processFurther = false;
2109e17e21d115bb92b4dc094c205d59f73cdc6185aJake Hamby                        }
2110825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    }
2129e17e21d115bb92b4dc094c205d59f73cdc6185aJake Hamby                    if (!processFurther) {
2139e17e21d115bb92b4dc094c205d59f73cdc6185aJake Hamby                        return Intents.RESULT_SMS_HANDLED;
2149e17e21d115bb92b4dc094c205d59f73cdc6185aJake Hamby                    }
2159e17e21d115bb92b4dc094c205d59f73cdc6185aJake Hamby                } catch (RemoteException e) {
2169e17e21d115bb92b4dc094c205d59f73cdc6185aJake Hamby                    if (DBG) Rlog.w(TAG, "remote func failed...");
2170825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                }
2180825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            }
2199e17e21d115bb92b4dc094c205d59f73cdc6185aJake Hamby            if (DBG) Rlog.v(TAG, "fall back to existing handler");
2200825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
2219e17e21d115bb92b4dc094c205d59f73cdc6185aJake Hamby            if (mimeType == null) {
2229e17e21d115bb92b4dc094c205d59f73cdc6185aJake Hamby                if (DBG) Rlog.w(TAG, "Header Content-Type error.");
2239e17e21d115bb92b4dc094c205d59f73cdc6185aJake Hamby                return Intents.RESULT_SMS_GENERIC_ERROR;
2249e17e21d115bb92b4dc094c205d59f73cdc6185aJake Hamby            }
2250825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
2269e17e21d115bb92b4dc094c205d59f73cdc6185aJake Hamby            String permission;
2279e17e21d115bb92b4dc094c205d59f73cdc6185aJake Hamby            int appOp;
2280825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
2299e17e21d115bb92b4dc094c205d59f73cdc6185aJake Hamby            if (mimeType.equals(WspTypeDecoder.CONTENT_TYPE_B_MMS)) {
2309e17e21d115bb92b4dc094c205d59f73cdc6185aJake Hamby                permission = android.Manifest.permission.RECEIVE_MMS;
2319e17e21d115bb92b4dc094c205d59f73cdc6185aJake Hamby                appOp = AppOpsManager.OP_RECEIVE_MMS;
2329e17e21d115bb92b4dc094c205d59f73cdc6185aJake Hamby            } else {
2339e17e21d115bb92b4dc094c205d59f73cdc6185aJake Hamby                permission = android.Manifest.permission.RECEIVE_WAP_PUSH;
2349e17e21d115bb92b4dc094c205d59f73cdc6185aJake Hamby                appOp = AppOpsManager.OP_RECEIVE_WAP_PUSH;
2359e17e21d115bb92b4dc094c205d59f73cdc6185aJake Hamby            }
2360825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
2379e17e21d115bb92b4dc094c205d59f73cdc6185aJake Hamby            Intent intent = new Intent(Intents.WAP_PUSH_DELIVER_ACTION);
2389e17e21d115bb92b4dc094c205d59f73cdc6185aJake Hamby            intent.setType(mimeType);
2399e17e21d115bb92b4dc094c205d59f73cdc6185aJake Hamby            intent.putExtra("transactionId", transactionId);
2409e17e21d115bb92b4dc094c205d59f73cdc6185aJake Hamby            intent.putExtra("pduType", pduType);
2419e17e21d115bb92b4dc094c205d59f73cdc6185aJake Hamby            intent.putExtra("header", header);
2429e17e21d115bb92b4dc094c205d59f73cdc6185aJake Hamby            intent.putExtra("data", intentData);
2439e17e21d115bb92b4dc094c205d59f73cdc6185aJake Hamby            intent.putExtra("contentTypeParameters", pduDecoder.getContentParameters());
2449e17e21d115bb92b4dc094c205d59f73cdc6185aJake Hamby
2459e17e21d115bb92b4dc094c205d59f73cdc6185aJake Hamby            // Direct the intent to only the default MMS app. If we can't find a default MMS app
2469e17e21d115bb92b4dc094c205d59f73cdc6185aJake Hamby            // then sent it to all broadcast receivers.
2479e17e21d115bb92b4dc094c205d59f73cdc6185aJake Hamby            ComponentName componentName = SmsApplication.getDefaultMmsApplication(mContext, true);
2489e17e21d115bb92b4dc094c205d59f73cdc6185aJake Hamby            if (componentName != null) {
2499e17e21d115bb92b4dc094c205d59f73cdc6185aJake Hamby                // Deliver MMS message only to this receiver
2509e17e21d115bb92b4dc094c205d59f73cdc6185aJake Hamby                intent.setComponent(componentName);
2519e17e21d115bb92b4dc094c205d59f73cdc6185aJake Hamby                if (DBG) Rlog.v(TAG, "Delivering MMS to: " + componentName.getPackageName() +
2529e17e21d115bb92b4dc094c205d59f73cdc6185aJake Hamby                        " " + componentName.getClassName());
2539e17e21d115bb92b4dc094c205d59f73cdc6185aJake Hamby            }
2545c3b6658d82f3af57161d5a34385dd95ea0f1abbDavid Braun
2559e17e21d115bb92b4dc094c205d59f73cdc6185aJake Hamby            handler.dispatchIntent(intent, permission, appOp, receiver);
2569e17e21d115bb92b4dc094c205d59f73cdc6185aJake Hamby            return Activity.RESULT_OK;
2579e17e21d115bb92b4dc094c205d59f73cdc6185aJake Hamby        } catch (ArrayIndexOutOfBoundsException aie) {
2589e17e21d115bb92b4dc094c205d59f73cdc6185aJake Hamby            // 0-byte WAP PDU or other unexpected WAP PDU contents can easily throw this;
2599e17e21d115bb92b4dc094c205d59f73cdc6185aJake Hamby            // log exception string without stack trace and return false.
2609e17e21d115bb92b4dc094c205d59f73cdc6185aJake Hamby            Rlog.e(TAG, "ignoring dispatchWapPdu() array index exception: " + aie);
2619e17e21d115bb92b4dc094c205d59f73cdc6185aJake Hamby            return Intents.RESULT_SMS_GENERIC_ERROR;
2629e17e21d115bb92b4dc094c205d59f73cdc6185aJake Hamby        }
2630825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
2640825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville}
265