/*
 * 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.smspush.unitTests;

import android.app.Activity;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.ServiceConnection;
import android.os.IBinder;
import android.os.RemoteException;
import android.provider.Telephony.Sms.Intents;
import android.test.ServiceTestCase;
import android.util.Log;

import com.android.internal.telephony.IccUtils;
import com.android.internal.telephony.IWapPushManager;
import com.android.internal.telephony.WapPushManagerParams;
import com.android.internal.telephony.WspTypeDecoder;
import com.android.internal.util.HexDump;
import com.android.smspush.WapPushManager;

import java.util.Random;

/**
 * This is a simple framework for a test of a Service.  See {@link android.test.ServiceTestCase
 * ServiceTestCase} for more information on how to write and extend service tests.
 *
 * To run this test, you can type:
 * adb shell am instrument -w \
 * -e class com.android.smspush.unitTests.WapPushTest \
 * com.android.smspush.unitTests/android.test.InstrumentationTestRunner
 */
public class WapPushTest extends ServiceTestCase<WapPushManager> {
    private static final String LOG_TAG = "WAP PUSH";
    private static final boolean LOCAL_LOGV = false;
    private static final int TIME_WAIT = 100;

    protected int mAppIdValue = 0x8002;
    protected String mAppIdName = "x-wap-application:*";
    protected int mContentTypeValue = 0x030a;
    protected String mContentTypeName = "application/vnd.wap.sic";

    protected String mPackageName;
    protected String mClassName;

    protected byte[] mGsmHeader = {
            (byte) 0x00, // sc address
            (byte) 0x40, // TP-MTI
            (byte) 0x04, // sender address length?
            (byte) 0x81, (byte) 0x55, (byte) 0x45, // sender address?
            (byte) 0x00, // data schema
            (byte) 0x00, // proto ID
            (byte) 0x01, (byte) 0x60, (byte) 0x12, (byte) 0x31,
            (byte) 0x74, (byte) 0x34, (byte) 0x63 // time stamp
    };

    protected byte[] mUserDataHeader = {
            (byte) 0x07, // UDH len
            (byte) 0x06, // header len
            (byte) 0x05, // port addressing type?
            (byte) 0x00, // dummy
            (byte) 0x0B, (byte) 0x84, // dest port
            (byte) 0x23, (byte) 0xF0 // src port
    };

    protected byte[] mWspHeader;

    protected byte[] mMessageBody = {
            (byte) 0x00,
            (byte) 0x01,
            (byte) 0x02,
            (byte) 0x03,
            (byte) 0x04,
            (byte) 0x05,
            (byte) 0x06,
            (byte) 0x07,
            (byte) 0x08,
            (byte) 0x09,
            (byte) 0x0a,
            (byte) 0x0b,
            (byte) 0x0c,
            (byte) 0x0d,
            (byte) 0x0e,
            (byte) 0x0f
    };

    protected int mWspHeaderStart;
    protected int mWspHeaderLen;
    protected int mWspContentTypeStart;

    /**
     * OMA application ID in binary form
     * http://www.openmobilealliance.org/tech/omna/omna-push-app-id.aspx
     */
    final int[] OMA_APPLICATION_ID_VALUES = new int[] {
            0x00,
            0x01,
            0x02,
            0x03,
            0x04,
            0x05,
            0x06,
            0x07,
            0x08,
            0x09,
            0x0A,
            0x8000,
            0x8001,
            0x8002,
            0x8003,
            0x8004,
            0x8005,
            0x8006,
            0x8007,
            0x8008,
            0x8009,
            0x800B,
            0x8010
    };

    /**
     * OMA application ID in string form
     * http://www.openmobilealliance.org/tech/omna/omna-push-app-id.aspx
     */
    final String[] OMA_APPLICATION_ID_NAMES = new String[] {
            "x-wap-application:*",
            "x-wap-application:push.sia",
            "x-wap-application:wml.ua",
            "x-wap-application:wta.ua",
            "x-wap-application:mms.ua",
            "x-wap-application:push.syncml",
            "x-wap-application:loc.ua",
            "x-wap-application:syncml.dm",
            "x-wap-application:drm.ua",
            "x-wap-application:emn.ua",
            "x-wap-application:wv.ua",
            "x-wap-microsoft:localcontent.ua",
            "x-wap-microsoft:IMclient.ua",
            "x-wap-docomo:imode.mail.ua",
            "x-wap-docomo:imode.mr.ua",
            "x-wap-docomo:imode.mf.ua",
            "x-motorola:location.ua",
            "x-motorola:now.ua",
            "x-motorola:otaprov.ua",
            "x-motorola:browser.ua",
            "x-motorola:splash.ua",
            "x-wap-nai:mvsw.command",
            "x-wap-openwave:iota.ua"
    };

    /**
     * OMA content type in binary form
     * http://www.openmobilealliance.org/tech/omna/omna-wsp-content-type.aspx
     */
    final int[] OMA_CONTENT_TYPE_VALUES = new int[] {
            0x00,
            0x01,
            0x02,
            0x03,
            0x04,
            0x05,
            0x06,
            0x07,
            0x08,
            0x09,
            0x0A,
            0x0B,
            0x0C,
            0x0D,
            0x0E,
            0x0F,
            0x10,
            0x11,
            0x12,
            0x13,
            0x14,
            0x15,
            0x16,
            0x17,
            0x18,
            0x19,
            0x1A,
            0x1B,
            0x1C,
            0x1D,
            0x1E,
            0x1F,
            0x20,
            0x21,
            0x22,
            0x23,
            0x24,
            0x25,
            0x26,
            0x27,
            0x28,
            0x29,
            0x2A,
            0x2B,
            0x2C,
            0x2D,
            0x2E,
            0x2F,
            0x30,
            0x31,
            0x32,
            0x33,
            0x34,
            0x35,
            0x36,
            0x37,
            0x38,
            0x39,
            0x3A,
            0x3B,
            0x3C,
            0x3D,
            0x3E,
            0x3F,
            0x40,
            0x41,
            0x42,
            0x43,
            0x44,
            0x45,
            0x46,
            0x47,
            0x48,
            0x49,
            0x4A,
            0x4B,
            0x4C,
            0x4D,
            0x4E,
            0x4F,
            0x50,
            0x51,
            0x52,
            0x53,
            0x54,
//            0x55,
//            0x56,
//            0x57,
//            0x58,
            0x0201,
            0x0202,
            0x0203,
            0x0204,
            0x0205,
            0x0206,
            0x0207,
            0x0208,
            0x0209,
            0x020A,
            0x020B,
            0x020C,
            0x0300,
            0x0301,
            0x0302,
            0x0303,
            0x0304,
            0x0305,
            0x0306,
            0x0307,
            0x0308,
            0x0309,
            0x030A,
            0x030B,
            0x030C,
            0x030D,
            0x030E,
            0x030F,
            0x0310,
            0x0311,
            0x0312,
            0x0313,
            0x0314,
            0x0315,
            0x0316,
            0x0317,
            0x0318,
            0x0319,
            0x031A,
            0x031B
            /*0x031C,
              0x031D*/
    };

    /**
     * OMA content type in string form
     * http://www.openmobilealliance.org/tech/omna/omna-wsp-content-type.aspx
     */
    final String[] OMA_CONTENT_TYPE_NAMES = new String[] {
            "*/*",
            "text/*",
            "text/html",
            "text/plain",
            "text/x-hdml",
            "text/x-ttml",
            "text/x-vCalendar",
            "text/x-vCard",
            "text/vnd.wap.wml",
            "text/vnd.wap.wmlscript",
            "text/vnd.wap.wta-event",
            "multipart/*",
            "multipart/mixed",
            "multipart/form-data",
            "multipart/byterantes",
            "multipart/alternative",
            "application/*",
            "application/java-vm",
            "application/x-www-form-urlencoded",
            "application/x-hdmlc",
            "application/vnd.wap.wmlc",
            "application/vnd.wap.wmlscriptc",
            "application/vnd.wap.wta-eventc",
            "application/vnd.wap.uaprof",
            "application/vnd.wap.wtls-ca-certificate",
            "application/vnd.wap.wtls-user-certificate",
            "application/x-x509-ca-cert",
            "application/x-x509-user-cert",
            "image/*",
            "image/gif",
            "image/jpeg",
            "image/tiff",
            "image/png",
            "image/vnd.wap.wbmp",
            "application/vnd.wap.multipart.*",
            "application/vnd.wap.multipart.mixed",
            "application/vnd.wap.multipart.form-data",
            "application/vnd.wap.multipart.byteranges",
            "application/vnd.wap.multipart.alternative",
            "application/xml",
            "text/xml",
            "application/vnd.wap.wbxml",
            "application/x-x968-cross-cert",
            "application/x-x968-ca-cert",
            "application/x-x968-user-cert",
            "text/vnd.wap.si",
            "application/vnd.wap.sic",
            "text/vnd.wap.sl",
            "application/vnd.wap.slc",
            "text/vnd.wap.co",
            "application/vnd.wap.coc",
            "application/vnd.wap.multipart.related",
            "application/vnd.wap.sia",
            "text/vnd.wap.connectivity-xml",
            "application/vnd.wap.connectivity-wbxml",
            "application/pkcs7-mime",
            "application/vnd.wap.hashed-certificate",
            "application/vnd.wap.signed-certificate",
            "application/vnd.wap.cert-response",
            "application/xhtml+xml",
            "application/wml+xml",
            "text/css",
            "application/vnd.wap.mms-message",
            "application/vnd.wap.rollover-certificate",
            "application/vnd.wap.locc+wbxml",
            "application/vnd.wap.loc+xml",
            "application/vnd.syncml.dm+wbxml",
            "application/vnd.syncml.dm+xml",
            "application/vnd.syncml.notification",
            "application/vnd.wap.xhtml+xml",
            "application/vnd.wv.csp.cir",
            "application/vnd.oma.dd+xml",
            "application/vnd.oma.drm.message",
            "application/vnd.oma.drm.content",
            "application/vnd.oma.drm.rights+xml",
            "application/vnd.oma.drm.rights+wbxml",
            "application/vnd.wv.csp+xml",
            "application/vnd.wv.csp+wbxml",
            "application/vnd.syncml.ds.notification",
            "audio/*",
            "video/*",
            "application/vnd.oma.dd2+xml",
            "application/mikey",
            "application/vnd.oma.dcd",
            "application/vnd.oma.dcdc",
//            "text/x-vMessage",
//            "application/vnd.omads-email+wbxml",
//            "text/x-vBookmark",
//            "application/vnd.syncml.dm.notification",
            "application/vnd.uplanet.cacheop-wbxml",
            "application/vnd.uplanet.signal",
            "application/vnd.uplanet.alert-wbxml",
            "application/vnd.uplanet.list-wbxml",
            "application/vnd.uplanet.listcmd-wbxml",
            "application/vnd.uplanet.channel-wbxml",
            "application/vnd.uplanet.provisioning-status-uri",
            "x-wap.multipart/vnd.uplanet.header-set",
            "application/vnd.uplanet.bearer-choice-wbxml",
            "application/vnd.phonecom.mmc-wbxml",
            "application/vnd.nokia.syncset+wbxml",
            "image/x-up-wpng",
            "application/iota.mmc-wbxml",
            "application/iota.mmc-xml",
            "application/vnd.syncml+xml",
            "application/vnd.syncml+wbxml",
            "text/vnd.wap.emn+xml",
            "text/calendar",
            "application/vnd.omads-email+xml",
            "application/vnd.omads-file+xml",
            "application/vnd.omads-folder+xml",
            "text/directory;profile=vCard",
            "application/vnd.wap.emn+wbxml",
            "application/vnd.nokia.ipdc-purchase-response",
            "application/vnd.motorola.screen3+xml",
            "application/vnd.motorola.screen3+gzip",
            "application/vnd.cmcc.setting+wbxml",
            "application/vnd.cmcc.bombing+wbxml",
            "application/vnd.docomo.pf",
            "application/vnd.docomo.ub",
            "application/vnd.omaloc-supl-init",
            "application/vnd.oma.group-usage-list+xml",
            "application/oma-directory+xml",
            "application/vnd.docomo.pf2",
            "application/vnd.oma.drm.roap-trigger+wbxml",
            "application/vnd.sbm.mid2",
            "application/vnd.wmf.bootstrap",
            "application/vnc.cmcc.dcd+xml",
            "application/vnd.sbm.cid",
            "application/vnd.oma.bcast.provisioningtrigger",
            /*"application/vnd.docomo.dm",
              "application/vnd.oma.scidm.messages+xml"*/
    };

    private IDataVerify mIVerify = null;

    ServiceConnection mConn = new ServiceConnection() {
            public void onServiceConnected(ComponentName name, IBinder service) {
                Log.v(LOG_TAG, "data verify interface connected.");
                mIVerify = IDataVerify.Stub.asInterface(service);
            }
            public void onServiceDisconnected(ComponentName name) {
            }
        };

    /**
     * Main WapPushManager test module constructor
     */
    public WapPushTest() {
        super(WapPushManager.class);
        mClassName = this.getClass().getName();
        mPackageName = this.getClass().getPackage().getName();
    }

    /**
     * Initialize the verifier
     */
    @Override
    public void setUp() {
        try {
            super.setUp();
            // get verifier
            getContext().bindService(new Intent(IDataVerify.class.getName()),
                    mConn, Context.BIND_AUTO_CREATE);
        } catch (Exception e) {
            Log.w(LOG_TAG, "super exception");
        }
        // Log.d(LOG_TAG, "test setup");
    }

    private IWapPushManager mWapPush = null;
    IWapPushManager getInterface() {
        if (mWapPush != null) return mWapPush;
        Intent startIntent = new Intent();
        startIntent.setClass(getContext(), WapPushManager.class);
        IBinder service = bindService(startIntent);

        mWapPush = IWapPushManager.Stub.asInterface(service);
        return mWapPush;
    }

    /*
     * All methods need to start with 'test'.
     * Use various assert methods to pass/fail the test case.
     */
    protected void utAddPackage(boolean need_sig, boolean more_proc) {
        IWapPushManager iwapman = getInterface();

        // insert new data
        try {
            assertTrue(iwapman.addPackage(
                    Integer.toString(mAppIdValue),
                    Integer.toString(mContentTypeValue),
                    mPackageName, mClassName,
                    WapPushManagerParams.APP_TYPE_SERVICE, need_sig, more_proc));
        } catch (RemoteException e) {
            assertTrue(false);
        }

        // verify the data
        WapPushManager wpman = getService();
        assertTrue(wpman.verifyData(Integer.toString(mAppIdValue),
                Integer.toString(mContentTypeValue),
                mPackageName, mClassName,
                WapPushManagerParams.APP_TYPE_SERVICE, need_sig, more_proc));
    }

    /**
     * Add package test
     */
    public void testAddPackage1() {
        int originalAppIdValue = mAppIdValue;
        int originalContentTypeValue  = mContentTypeValue;

        utAddPackage(true, true);
        mAppIdValue += 10;
        utAddPackage(true, false);
        mContentTypeValue += 20;
        utAddPackage(false, true);
        mContentTypeValue += 20;
        utAddPackage(false, false);

        mAppIdValue = originalAppIdValue;
        mContentTypeValue = originalContentTypeValue;

        // clean up data
        try {
            IWapPushManager iwapman = getInterface();
            iwapman.deletePackage(Integer.toString(mAppIdValue),
                    Integer.toString(mContentTypeValue), mPackageName, mClassName);
            mAppIdValue += 10;
            iwapman.deletePackage(Integer.toString(mAppIdValue),
                    Integer.toString(mContentTypeValue), mPackageName, mClassName);
            mContentTypeValue += 20;
            iwapman.deletePackage(Integer.toString(mAppIdValue),
                    Integer.toString(mContentTypeValue), mPackageName, mClassName);
            mContentTypeValue += 20;
            iwapman.deletePackage(Integer.toString(mAppIdValue),
                    Integer.toString(mContentTypeValue), mPackageName, mClassName);
        } catch (RemoteException e) {
            assertTrue(false);
        }
        mAppIdValue = originalAppIdValue;
        mContentTypeValue = originalContentTypeValue;
    }

    /**
     * Add duprecated package test.
     */
    public void testAddPackage2() {
        try {
            IWapPushManager iwapman = getInterface();

            // set up data
            iwapman.addPackage(Integer.toString(mAppIdValue),
                    Integer.toString(mContentTypeValue), mPackageName, mClassName, 0,
                    false, false);
            iwapman.addPackage(Integer.toString(mAppIdValue + 10),
                    Integer.toString(mContentTypeValue), mPackageName, mClassName, 0,
                    false, false);
            iwapman.addPackage(Integer.toString(mAppIdValue),
                    Integer.toString(mContentTypeValue + 10), mPackageName, mClassName, 0,
                    false, false);

            assertFalse(iwapman.addPackage(Integer.toString(mAppIdValue),
                    Integer.toString(mContentTypeValue), mPackageName, mClassName, 0,
                    false, false));
            assertFalse(iwapman.addPackage(Integer.toString(mAppIdValue + 10),
                    Integer.toString(mContentTypeValue), mPackageName, mClassName, 0,
                    false, false));
            assertFalse(iwapman.addPackage(Integer.toString(mAppIdValue),
                    Integer.toString(mContentTypeValue + 10), mPackageName, mClassName, 0,
                    false, false));

            // clean up data
            iwapman.deletePackage(Integer.toString(mAppIdValue),
                    Integer.toString(mContentTypeValue), mPackageName, mClassName);
            iwapman.deletePackage(Integer.toString(mAppIdValue + 10),
                    Integer.toString(mContentTypeValue), mPackageName, mClassName);
            iwapman.deletePackage(Integer.toString(mAppIdValue),
                    Integer.toString(mContentTypeValue + 10), mPackageName, mClassName);
        } catch (RemoteException e) {
            assertTrue(false);
        }
    }

    protected void utUpdatePackage(boolean need_sig, boolean more_proc) {
        IWapPushManager iwapman = getInterface();

        // insert new data
        try {
            assertTrue(iwapman.updatePackage(
                    Integer.toString(mAppIdValue),
                    Integer.toString(mContentTypeValue),
                    mPackageName, mClassName,
                    WapPushManagerParams.APP_TYPE_SERVICE, need_sig, more_proc));
        } catch (RemoteException e) {
            assertTrue(false);
        }

        // verify the data
        WapPushManager wpman = getService();
        assertTrue(wpman.verifyData(
                Integer.toString(mAppIdValue),
                Integer.toString(mContentTypeValue),
                mPackageName, mClassName,
                WapPushManagerParams.APP_TYPE_SERVICE, need_sig, more_proc));
    }

    /**
     * Updating package test
     */
    public void testUpdatePackage1() {
        int originalAppIdValue = mAppIdValue;
        int originalContentTypeValue  = mContentTypeValue;

        // set up data
        try {
            IWapPushManager iwapman = getInterface();

            iwapman.addPackage(Integer.toString(mAppIdValue),
                    Integer.toString(mContentTypeValue), mPackageName, mClassName,
                    0, false, false);
            mAppIdValue += 10;
            iwapman.addPackage(Integer.toString(mAppIdValue),
                    Integer.toString(mContentTypeValue), mPackageName, mClassName,
                    0, false, false);
            mContentTypeValue += 20;
            iwapman.addPackage(Integer.toString(mAppIdValue),
                    Integer.toString(mContentTypeValue), mPackageName, mClassName,
                    0, false, false);
            mContentTypeValue += 20;
            iwapman.addPackage(Integer.toString(mAppIdValue),
                    Integer.toString(mContentTypeValue), mPackageName, mClassName,
                    0, false, false);
        } catch (RemoteException e) {
            assertTrue(false);
        }

        mAppIdValue = originalAppIdValue;
        mContentTypeValue = originalContentTypeValue;
        utUpdatePackage(false, false);
        mAppIdValue += 10;
        utUpdatePackage(false, true);
        mContentTypeValue += 20;
        utUpdatePackage(true, false);
        mContentTypeValue += 20;
        utUpdatePackage(true, true);

        mAppIdValue = originalAppIdValue;
        mContentTypeValue = originalContentTypeValue;

        // clean up data
        try {
            IWapPushManager iwapman = getInterface();

            iwapman.deletePackage(Integer.toString(mAppIdValue),
                    Integer.toString(mContentTypeValue), mPackageName, mClassName);
            mAppIdValue += 10;
            iwapman.deletePackage(Integer.toString(mAppIdValue),
                    Integer.toString(mContentTypeValue), mPackageName, mClassName);
            mContentTypeValue += 20;
            iwapman.deletePackage(Integer.toString(mAppIdValue),
                    Integer.toString(mContentTypeValue), mPackageName, mClassName);
            mContentTypeValue += 20;
            iwapman.deletePackage(Integer.toString(mAppIdValue),
                    Integer.toString(mContentTypeValue), mPackageName, mClassName);
        } catch (RemoteException e) {
            assertTrue(false);
        }
        mAppIdValue = originalAppIdValue;
        mContentTypeValue = originalContentTypeValue;
    }

    /**
     * Updating invalid package test
     */
    public void testUpdatePackage2() {
        int originalAppIdValue = mAppIdValue;
        int originalContentTypeValue  = mContentTypeValue;

        try {
            // set up data
            IWapPushManager iwapman = getInterface();

            iwapman.addPackage(Integer.toString(mAppIdValue),
                    Integer.toString(mContentTypeValue), mPackageName, mClassName,
                    0, false, false);
            assertFalse(iwapman.updatePackage(
                    Integer.toString(mAppIdValue + 10),
                    Integer.toString(mContentTypeValue),
                    mPackageName, mClassName, 0, false, false));
            assertFalse(iwapman.updatePackage(
                    Integer.toString(mAppIdValue),
                    Integer.toString(mContentTypeValue + 10),
                    mPackageName, mClassName, 0, false, false));
            assertTrue(iwapman.updatePackage(
                    Integer.toString(mAppIdValue),
                    Integer.toString(mContentTypeValue),
                    mPackageName + "dummy_data", mClassName, 0, false, false));
            assertTrue(iwapman.updatePackage(
                    Integer.toString(mAppIdValue),
                    Integer.toString(mContentTypeValue),
                    mPackageName, mClassName + "dummy_data", 0, false, false));
            // clean up data
            iwapman.deletePackage(Integer.toString(mAppIdValue),
                    Integer.toString(mContentTypeValue), mPackageName, mClassName);
            iwapman.deletePackage(Integer.toString(mAppIdValue),
                    Integer.toString(mContentTypeValue), mPackageName,
                    mClassName + "dummy_data");
        } catch (RemoteException e) {
            assertTrue(false);
        }
    }

    protected void utDeletePackage() {
        IWapPushManager iwapman = getInterface();

        try {
            assertTrue(iwapman.deletePackage(
                    Integer.toString(mAppIdValue),
                    Integer.toString(mContentTypeValue),
                    mPackageName, mClassName));
        } catch (RemoteException e) {
            assertTrue(false);
        }

        // verify the data
        WapPushManager wpman = getService();
        assertTrue(!wpman.isDataExist(
                Integer.toString(mAppIdValue),
                Integer.toString(mContentTypeValue),
                mPackageName, mClassName));
    }

    /**
     * Deleting package test
     */
    public void testDeletePackage1() {
        int originalAppIdValue = mAppIdValue;
        int originalContentTypeValue  = mContentTypeValue;

        // set up data
        try {
            IWapPushManager iwapman = getInterface();

            iwapman.addPackage(Integer.toString(mAppIdValue),
                    Integer.toString(mContentTypeValue), mPackageName, mClassName,
                    0, false, false);
            mAppIdValue += 10;
            iwapman.addPackage(Integer.toString(mAppIdValue),
                    Integer.toString(mContentTypeValue), mPackageName, mClassName,
                    0, false, false);
            mContentTypeValue += 20;
            iwapman.addPackage(Integer.toString(mAppIdValue),
                    Integer.toString(mContentTypeValue), mPackageName, mClassName,
                    0, false, false);
            mContentTypeValue += 20;
            iwapman.addPackage(Integer.toString(mAppIdValue),
                    Integer.toString(mContentTypeValue), mPackageName, mClassName,
                    0, false, false);
        } catch (RemoteException e) {
            assertTrue(false);
        }

        mAppIdValue = originalAppIdValue;
        mContentTypeValue = originalContentTypeValue;
        utDeletePackage();
        mAppIdValue += 10;
        utDeletePackage();
        mContentTypeValue += 20;
        utDeletePackage();
        mContentTypeValue += 20;
        utDeletePackage();

        mAppIdValue = originalAppIdValue;
        mContentTypeValue = originalContentTypeValue;
    }

    /**
     * Deleting invalid package test
     */
    public void testDeletePackage2() {
        int originalAppIdValue = mAppIdValue;
        int originalContentTypeValue  = mContentTypeValue;

        try {
            // set up data
            IWapPushManager iwapman = getInterface();

            iwapman.addPackage(Integer.toString(mAppIdValue),
                    Integer.toString(mContentTypeValue), mPackageName, mClassName,
                    0, false, false);

            assertFalse(iwapman.deletePackage(Integer.toString(mAppIdValue + 10),
                    Integer.toString(mContentTypeValue), mPackageName, mClassName));
            assertFalse(iwapman.deletePackage(Integer.toString(mAppIdValue),
                    Integer.toString(mContentTypeValue + 20), mPackageName, mClassName));
            assertFalse(iwapman.deletePackage(Integer.toString(mAppIdValue + 10),
                    Integer.toString(mContentTypeValue + 20), mPackageName, mClassName));

            iwapman.deletePackage(Integer.toString(mAppIdValue),
                    Integer.toString(mContentTypeValue), mPackageName, mClassName);

        } catch (RemoteException e) {
            assertTrue(false);
        }
    }


    protected int encodeUint32(int uint32Val, byte[] arr, int start) {
        int bit = 1;
        int topbit = 0;
        int encodeLen;
        int tmpVal;

        assertTrue(uint32Val >= 0);
        for (int i = 0; i < 31; i++) {
            if ((bit & uint32Val) > 0) topbit = i;
            bit = (bit << 1);
        }
        encodeLen = topbit/7 + 1;
        if (arr == null) return encodeLen;

        //Log.d(LOG_TAG, "uint32Val = " + Integer.toHexString(uint32Val) + ", topbit = "
        //      + topbit + ", encodeLen = " + encodeLen);

        tmpVal = uint32Val;
        for (int i = encodeLen - 1; i >= 0; i--) {
            long val = 0;
            if (i < encodeLen - 1) val = 0x80;
            val |= tmpVal & 0x7f;
            arr[start + i] = (byte) (val & 0xFF);
            tmpVal = (tmpVal >> 7);
        }
        return encodeLen;
    }

    protected int encodeShortInt(int sintVal, byte[] arr, int start) {
        int encodeLen = 0;

        if (sintVal >= 0x80) return encodeLen;
        encodeLen = 1;
        arr[start] = (byte) (sintVal | 0x80);
        return encodeLen;
    }


    /**
     * Generate Random WSP header with integer application ID
     */
    protected void createRandomWspHeader(byte[] arr, Random rd, int headerStart,
            boolean noAppId) {

        boolean appIdAdded = false;

        Log.d(LOG_TAG, "headerStart = " + headerStart + ", appId = " + mAppIdValue
                + "(" + Integer.toHexString(mAppIdValue) + ")");
        Log.d(LOG_TAG, "random arr length:" + arr.length);
        String typename[] = new String[] { "short int", "long int", "string", "uint32"};

        while (!appIdAdded) {
            int type;
            int index = headerStart;
            int len = arr.length;
            int i;
            boolean addAppid = false;
            int tmpVal = 0;
            int tmpVal2 = 0;

            while (true) {
                int add;

                /*
                 * field name
                 * 0: short int
                 * 1: long int
                 * 2: text
                 * (no uint for param value)
                 */
                type = rd.nextInt(3);
                switch (type) {
                case 0: // header short integer
                    if (index > 100 && !appIdAdded) addAppid = true;
                    add = 1;
                    break;
                case 1: // header long int
                    add = 1 + rd.nextInt(29);
                    break;
                default: // header string
                    add = 2 + rd.nextInt(10);
                    break;
                }
                if (index + add >= len) break;

                // fill header name
                switch (type) {
                case 0: // header short integer
                    if (!addAppid) {
                        do {
                            arr[index] = (byte) (0x80 | rd.nextInt(128));
                        } while (arr[index] == (byte) 0xaf);
                    } else {
                        Log.d(LOG_TAG, "appId added.");
                        arr[index] = (byte) 0xaf;
                        // if noAppId case, appId fld must be decieved.
                        if (noAppId) arr[index]++;
                    }
                    break;
                case 1: // header long int
                    arr[index] = (byte) (add - 1);
                    tmpVal2 = 0;
                    for (i = 1; i < add; i++) {
                        tmpVal = rd.nextInt(255);
                        tmpVal2 = (tmpVal2 << 8) | tmpVal;
                        arr[index + i] = (byte) tmpVal;
                    }
                    // don't set application id
                    if (tmpVal2 == 0x2f) arr[index + 1]++;
                    break;
                default: // header string
                    for (i = 0; i < add - 1; i++) {
                        tmpVal = rd.nextInt(127);
                        if (tmpVal < 32) tmpVal= (32 + tmpVal);
                        arr[index + i] = (byte) tmpVal;
                    }
                    arr[index + i] = (byte) 0x0;
                    break;
                }

                if (LOCAL_LOGV) {
                    Log.d(LOG_TAG, "field name index:" + index);
                    Log.d(LOG_TAG, "type:" + typename[type] + ", add:" + add);
                    if (type != 2) {
                        for (i = index; i< index + add; i++) {
                            System.out.print(Integer.toHexString(0xff & arr[i]));
                            System.out.print(' ');
                        }
                    } else {
                        System.out.print(Integer.toHexString(0xff & arr[index]));
                        System.out.print(' ');
                        String str = new String(arr, index + 1, add - 2);
                        for (i = 0; i < str.length(); i++) {
                            System.out.print(str.charAt(i));
                            System.out.print(' ');
                        }
                    }
                    System.out.print('\n');
                }
                index += add;


                /*
                 * field value
                 * 0: short int
                 * 1: long int
                 * 2: text
                 * 3: uint
                 */
                if (addAppid) {
                    type = 1;
                } else {
                    type = rd.nextInt(4);
                }
                switch (type) {
                case 0: // header short integer
                    add = 1;
                    break;
                case 1: // header long int
                    if (addAppid) {
                        int bit = 1;
                        int topBit = 0;

                        for (i = 0; i < 31; i++) {
                            if ((mAppIdValue & bit) > 0) topBit = i;
                            bit = (bit << 1);
                        }
                        add = 2 + topBit/8;
                    } else {
                        add = 1 + rd.nextInt(29);
                    }
                    break;
                case 2: // header string
                    add = 2 + rd.nextInt(10);
                    break;
                default: // uint32
                    add = 6;
                }
                if (index + add >= len) break;

                // fill field value
                switch (type) {
                case 0: // header short int
                    arr[index] = (byte) (0x80 | rd.nextInt(128));
                    break;
                case 1: // header long int
                    if (addAppid) {
                        addAppid = false;
                        appIdAdded = true;

                        arr[index] = (byte) (add - 1);
                        tmpVal = mAppIdValue;
                        for (i = add; i > 1; i--) {
                            arr[index + i - 1] = (byte) (tmpVal & 0xff);
                            tmpVal = (tmpVal >> 8);
                        }
                    } else {
                        arr[index] = (byte) (add - 1);
                        for (i = 1; i < add; i++) {
                            arr[index + i] = (byte) rd.nextInt(255);
                        }
                    }
                    break;
                case 2:// header string
                    for (i = 0; i < add - 1; i++) {
                        tmpVal = rd.nextInt(127);
                        if (tmpVal < 32) tmpVal= (32 + tmpVal);
                        arr[index + i] = (byte) tmpVal;
                    }
                    arr[index + i] = (byte) 0x0;
                    break;
                default: // header uvarint
                    arr[index] = (byte) 31;
                    tmpVal = rd.nextInt(0x0FFFFFFF);
                    add = 1 + encodeUint32(tmpVal, null, index + 1);
                    encodeUint32(tmpVal, arr, index + 1);
                    break;

                }

                if (LOCAL_LOGV) {
                    Log.d(LOG_TAG, "field value index:" + index);
                    Log.d(LOG_TAG, "type:" + typename[type] + ", add:" + add);
                    if (type != 2) {
                        for (i = index; i< index + add; i++) {
                            System.out.print(Integer.toHexString(0xff & arr[i]));
                            System.out.print(' ');
                        }
                    } else {
                        System.out.print(Integer.toHexString(0xff & arr[index]));
                        System.out.print(' ');
                        String str = new String(arr, index + 1, add - 2);
                        for (i = 0; i < str.length(); i++) {
                            System.out.print(str.charAt(i));
                            System.out.print(' ');
                        }
                    }
                    System.out.print('\n');
                }
                index += add;
            }
            if (noAppId) break;
        }

        Log.d(LOG_TAG, HexDump.dumpHexString(arr));
    }

    /**
     * Generate Random WSP header with string application ID
     */
    protected void createRandomWspHeaderStrAppId(byte[] arr, Random rd, int headerStart,
            boolean randomStr) {

        boolean appIdAdded = false;

        Log.d(LOG_TAG, "random arr length:" + arr.length);
        String typename[] = new String[] { "short int", "long int", "string", "uint32"};

        while (!appIdAdded) {
            int type;
            int index = headerStart;
            int len = arr.length;
            int i;
            boolean addAppid = false;
            int tmpVal = 0;
            int tmpVal2 = 0;

            while (true) {
                int add;

                /*
                 * field name
                 * 0: short int
                 * 1: long int
                 * 2: text
                 * (no uint for param value)
                 */
                type = rd.nextInt(3);
                switch (type) {
                case 0: // header short integer
                    if (index > 100 && !appIdAdded) addAppid = true;
                    add = 1;
                    break;
                case 1: // header long int
                    add = 1 + rd.nextInt(29);
                    break;
                default: // header string
                    add = 2 + rd.nextInt(10);
                    break;
                }
                if (index + add >= len) break;

                // fill header name
                switch (type) {
                case 0: // header short integer
                    if (!addAppid) {
                        do {
                            arr[index] = (byte) (0x80 | rd.nextInt(128));
                        } while (arr[index] == (byte) 0xaf);
                    } else {
                        Log.d(LOG_TAG, "appId added.");
                        arr[index] = (byte) 0xaf;
                    }
                    break;
                case 1: // header long int
                    arr[index] = (byte) (add - 1);
                    tmpVal2 = 0;
                    for (i = 1; i < add; i++) {
                        tmpVal = rd.nextInt(255);
                        tmpVal2 = (tmpVal2 << 8) | tmpVal;
                        arr[index + i] = (byte) tmpVal;
                    }
                    // don't set application id
                    if (tmpVal2 == 0x2f) arr[index + 1]++;
                    break;
                default: // header string
                    for (i = 0; i < add - 1; i++) {
                        tmpVal = rd.nextInt(127);
                        if (tmpVal < 32) tmpVal= (32 + tmpVal);
                        arr[index + i] = (byte) tmpVal;
                    }
                    arr[index + i] = (byte) 0x0;
                    break;
                }

                if (LOCAL_LOGV) {
                    Log.d(LOG_TAG, "field name index:" + index);
                    Log.d(LOG_TAG, "type:" + typename[type] + ", add:" + add);
                    if (type != 2) {
                        for (i = index; i < index + add; i++) {
                            System.out.print(Integer.toHexString(0xff & arr[i]));
                            System.out.print(' ');
                        }
                    } else {
                        System.out.print(Integer.toHexString(0xff & arr[index]));
                        System.out.print(' ');
                        String str = new String(arr, index + 1, add - 2);
                        for (i = 0; i < str.length(); i++) {
                            System.out.print(str.charAt(i));
                            System.out.print(' ');
                        }
                    }
                    System.out.print('\n');
                }
                index += add;


                /*
                 * field value
                 * 0: short int
                 * 1: long int
                 * 2: text
                 * 3: uint
                 */
                if (addAppid) {
                    type = 2;
                } else {
                    type = rd.nextInt(4);
                }
                switch (type) {
                case 0: // header short integer
                    add = 1;
                    break;
                case 1: // header long int
                    add = 1 + rd.nextInt(29);
                    break;
                case 2: // header string
                    if (addAppid) {
                        if (randomStr) {
                            add = 1 + rd.nextInt(10);
                            byte[] randStr= new byte[add];
                            for (i = 0; i < add; i++) {
                                tmpVal = rd.nextInt(127);
                                if (tmpVal < 32) tmpVal= (32 + tmpVal);
                                randStr[i] = (byte) tmpVal;
                            }
                            mAppIdName = new String(randStr);
                        }
                        add = mAppIdName.length() + 1;
                    } else {
                        add = 2 + rd.nextInt(10);
                    }
                    break;
                default: // uint32
                    add = 6;
                }
                if (index + add >= len) break;

                // fill field value
                switch (type) {
                case 0: // header short int
                    arr[index] = (byte) (0x80 | rd.nextInt(128));
                    break;
                case 1: // header long int
                    arr[index] = (byte) (add - 1);
                    for (i = 1; i < add; i++)
                        arr[index + i] = (byte) rd.nextInt(255);
                    break;
                case 2:// header string
                    if (addAppid) {
                        addAppid = false;
                        appIdAdded = true;
                        for (i = 0; i < add - 1; i++) {
                            arr[index + i] = (byte) (mAppIdName.charAt(i));
                        }
                        Log.d(LOG_TAG, "mAppIdName added [" + mAppIdName + "]");
                    } else {
                        for (i = 0; i < add - 1; i++) {
                            tmpVal = rd.nextInt(127);
                            if (tmpVal < 32) tmpVal= (32 + tmpVal);
                            arr[index + i] = (byte) tmpVal;
                        }
                    }
                    arr[index + i] = (byte) 0x0;
                    break;
                default: // header uvarint
                    arr[index] = (byte) 31;
                    tmpVal = rd.nextInt(0x0FFFFFFF);
                    add = 1 + encodeUint32(tmpVal, null, index + 1);
                    encodeUint32(tmpVal, arr, index + 1);
                    break;

                }

                if (LOCAL_LOGV) {
                    Log.d(LOG_TAG, "field value index:" + index);
                    Log.d(LOG_TAG, "type:" + typename[type] + ", add:" + add);
                    if (type != 2) {
                        for (i = index; i < index + add; i++) {
                            System.out.print(Integer.toHexString(0xff & arr[i]));
                            System.out.print(' ');
                        }
                    } else {
                        System.out.print(Integer.toHexString(0xff & arr[index]));
                        System.out.print(' ');
                        String str = new String(arr, index + 1, add - 2);
                        for (i = 0; i < str.length(); i++) {
                            System.out.print(str.charAt(i));
                            System.out.print(' ');
                        }
                    }
                    System.out.print('\n');
                }
                index += add;
            }
        }

        Log.d(LOG_TAG, "headerStart = " + headerStart + ", mAppIdName = " + mAppIdName);
        Log.d(LOG_TAG, HexDump.dumpHexString(arr));
    }

    protected byte[] createPDU(int testNum) {
        byte[] array = null;
        // byte[] wsp = null;

        switch (testNum) {
            // sample pdu
        case 1:
            byte[] array1 = {
                    (byte) 0x00, // TID
                    (byte) 0x06, // Type = wap push
                    (byte) 0x00, // Length to be set later.

                    // Content-Type
                    (byte) 0x03, (byte) 0x02,
                    (byte) ((mContentTypeValue >> 8) & 0xff),
                    (byte) (mContentTypeValue & 0xff),

                    // Application-id
                    (byte) 0xaf, (byte) 0x02,
                    (byte) ((mAppIdValue >> 8) & 0xff),
                    (byte) (mAppIdValue& 0xff)
            };
            array1[2] = (byte) (array1.length - 3);
            mWspHeader = array1;
            mWspHeaderStart = mGsmHeader.length + mUserDataHeader.length + 7;
            mWspHeaderLen = array1.length;
            break;

            // invalid wsp header
        case 2:
            byte[] array2 = {
                    (byte) 0x00, // invalid data
            };
            mWspHeader = array2;
            mWspHeaderStart = mGsmHeader.length + mUserDataHeader.length;
            mWspHeaderLen = array2.length;
            break;

            // random wsp header
        case 3:
            Random rd = new Random();
            int arrSize = 150 + rd.nextInt(100);
            byte[] array3 = new byte[arrSize];
            int hdrEncodeLen;

            array3[0] = (byte) 0x0;
            array3[1] = (byte) 0x6;
            hdrEncodeLen = encodeUint32(array3.length, null, 2);
            hdrEncodeLen = encodeUint32(array3.length - hdrEncodeLen - 2, array3, 2);
            array3[hdrEncodeLen + 2] = (byte) 0x3;
            array3[hdrEncodeLen + 3] = (byte) 0x2;
            array3[hdrEncodeLen + 4] = (byte) ((mContentTypeValue >> 8) & 0xff);
            array3[hdrEncodeLen + 5] = (byte) (mContentTypeValue & 0xff);
            createRandomWspHeader(array3, rd, hdrEncodeLen + 6, false);
            mWspHeaderStart = mGsmHeader.length + mUserDataHeader.length + hdrEncodeLen + 6;
            mWspHeaderLen = array3.length;

            Log.d(LOG_TAG, "mContentTypeValue = " + mContentTypeValue
                    + "(" + Integer.toHexString(mContentTypeValue) + ")");

            mWspHeader = array3;
            break;

            // random wsp header w/o appid
        case 4:
            rd = new Random();
            arrSize = 150 + rd.nextInt(100);
            array3 = new byte[arrSize];

            array3[0] = (byte) 0x0;
            array3[1] = (byte) 0x6;
            hdrEncodeLen = encodeUint32(array3.length, null, 2);
            hdrEncodeLen = encodeUint32(array3.length - hdrEncodeLen - 2, array3, 2);
            array3[hdrEncodeLen + 2] = (byte) 0x3;
            array3[hdrEncodeLen + 3] = (byte) 0x2;
            array3[hdrEncodeLen + 4] = (byte) ((mContentTypeValue >> 8) & 0xff);
            array3[hdrEncodeLen + 5] = (byte) (mContentTypeValue & 0xff);
            createRandomWspHeader(array3, rd, hdrEncodeLen + 6, true);
            mWspHeaderStart = mGsmHeader.length + mUserDataHeader.length + hdrEncodeLen + 6;
            mWspHeaderLen = array3.length;

            Log.d(LOG_TAG, "mContentTypeValue = " + mContentTypeValue
                    + "(" + Integer.toHexString(mContentTypeValue) + ")");

            mWspHeader = array3;
            break;

            // random wsp header w/ random appid string
        case 5:
            rd = new Random();
            arrSize = 150 + rd.nextInt(100);
            array3 = new byte[arrSize];

            array3[0] = (byte) 0x0;
            array3[1] = (byte) 0x6;
            hdrEncodeLen = encodeUint32(array3.length, null, 2);
            hdrEncodeLen = encodeUint32(array3.length - hdrEncodeLen - 2, array3, 2);
            array3[hdrEncodeLen + 2] = (byte) 0x3;
            array3[hdrEncodeLen + 3] = (byte) 0x2;
            array3[hdrEncodeLen + 4] = (byte) ((mContentTypeValue >> 8) & 0xff);
            array3[hdrEncodeLen + 5] = (byte) (mContentTypeValue & 0xff);
            createRandomWspHeaderStrAppId(array3, rd, hdrEncodeLen + 6, true);
            mWspHeaderStart = mGsmHeader.length + mUserDataHeader.length + hdrEncodeLen + 6;
            mWspHeaderLen = array3.length;

            Log.d(LOG_TAG, "mContentTypeValue = " + mContentTypeValue
                    + "(" + Integer.toHexString(mContentTypeValue) + ")");

            mWspHeader = array3;
            break;

            // random wsp header w/ OMA appid string
        case 6:
            rd = new Random();
            arrSize = 150 + rd.nextInt(100);
            array3 = new byte[arrSize];

            array3[0] = (byte) 0x0;
            array3[1] = (byte) 0x6;
            hdrEncodeLen = encodeUint32(array3.length, null, 2);
            hdrEncodeLen = encodeUint32(array3.length - hdrEncodeLen - 2, array3, 2);
            array3[hdrEncodeLen + 2] = (byte) 0x3;
            array3[hdrEncodeLen + 3] = (byte) 0x2;
            array3[hdrEncodeLen + 4] = (byte) ((mContentTypeValue >> 8) & 0xff);
            array3[hdrEncodeLen + 5] = (byte) (mContentTypeValue & 0xff);
            createRandomWspHeaderStrAppId(array3, rd, hdrEncodeLen + 6, false);
            mWspHeaderStart = mGsmHeader.length + mUserDataHeader.length + hdrEncodeLen + 6;
            mWspHeaderLen = array3.length;

            Log.d(LOG_TAG, "mContentTypeValue = " + mContentTypeValue
                    + "(" + Integer.toHexString(mContentTypeValue) + ")");

            mWspHeader = array3;
            break;

            // random wsp header w/ OMA content type
        case 7:
            rd = new Random();
            arrSize = 150 + rd.nextInt(100);
            array3 = new byte[arrSize];

            array3[0] = (byte) 0x0;
            array3[1] = (byte) 0x6;
            hdrEncodeLen = encodeUint32(array3.length, null, 2);
            hdrEncodeLen = encodeUint32(array3.length - hdrEncodeLen - 2, array3, 2);

            // encode content type
            int contentLen = mContentTypeName.length();
            int next = 2 + hdrEncodeLen;
            mWspContentTypeStart = mGsmHeader.length + mUserDataHeader.length + next;
            // next += encodeUint32(contentLen, array3, next);
            int i;
            Log.d(LOG_TAG, "mContentTypeName = " + mContentTypeName
                    + ", contentLen = " + contentLen);

            for (i = 0; i < contentLen; i++) {
                array3[next + i] = (byte) mContentTypeName.charAt(i);
            }
            array3[next + i] = (byte) 0x0;

            createRandomWspHeader(array3, rd, next + contentLen + 1, false);
            mWspHeaderStart = mGsmHeader.length + mUserDataHeader.length
                    + next + contentLen + 1;
            mWspHeaderLen = array3.length;

            mWspHeader = array3;
            break;

            // random wsp header w/ OMA content type, OMA app ID
        case 8:
            rd = new Random();
            arrSize = 150 + rd.nextInt(100);
            array3 = new byte[arrSize];

            array3[0] = (byte) 0x0;
            array3[1] = (byte) 0x6;
            hdrEncodeLen = encodeUint32(array3.length, null, 2);
            hdrEncodeLen = encodeUint32(array3.length - hdrEncodeLen - 2, array3, 2);

            // encode content type
            contentLen = mContentTypeName.length();
            next = 2 + hdrEncodeLen;
            mWspContentTypeStart = mGsmHeader.length + mUserDataHeader.length + next;
            // next += encodeUint32(contentLen, array3, next);
            Log.d(LOG_TAG, "mContentTypeName = " + mContentTypeName
                    + ", contentLen = " + contentLen);

            for (i = 0; i < contentLen; i++) {
                array3[next + i] = (byte) mContentTypeName.charAt(i);
            }
            array3[next + i] = (byte) 0x0;

            createRandomWspHeaderStrAppId(array3, rd, next + contentLen + 1, false);
            mWspHeaderStart = mGsmHeader.length + mUserDataHeader.length
                    + next + contentLen + 1;
            mWspHeaderLen = array3.length;

            mWspHeader = array3;
            break;

        default:
            return null;
        }
        array = new byte[mGsmHeader.length + mUserDataHeader.length + mWspHeader.length
                + mMessageBody.length];
        System.arraycopy(mGsmHeader, 0, array, 0, mGsmHeader.length);
        System.arraycopy(mUserDataHeader, 0, array,
                mGsmHeader.length, mUserDataHeader.length);
        System.arraycopy(mWspHeader, 0, array,
                mGsmHeader.length + mUserDataHeader.length, mWspHeader.length);
        System.arraycopy(mMessageBody, 0, array,
                mGsmHeader.length + mUserDataHeader.length + mWspHeader.length, 
                mMessageBody.length);
        return array;

    }

    Intent createIntent(int pduType, int tranId) {
        Intent intent = new Intent();
        intent.putExtra("transactionId", tranId);
        intent.putExtra("pduType", pduType);
        intent.putExtra("header", mGsmHeader);
        intent.putExtra("data", mMessageBody);
        // intent.putExtra("contentTypeParameters", null);
        return intent;
    }

    /**
     * Message processing test, start activity
     */
    public void testProcessMsg1() {
        byte[] pdu = createPDU(1);
        int headerLen = pdu.length -
                (mGsmHeader.length + mUserDataHeader.length + mMessageBody.length);
        int pduType = 6;
        int tranId = 0;
        String originalPackageName = mPackageName;
        String originalClassName = mClassName;

        try {

            mClassName = "com.android.smspush.unitTests.ReceiverActivity";

            // set up data
            IWapPushManager iwapman = getInterface();
            iwapman.addPackage(Integer.toString(mAppIdValue),
                    Integer.toString(mContentTypeValue), mPackageName, mClassName,
                    WapPushManagerParams.APP_TYPE_ACTIVITY, false, false);

            assertTrue((iwapman.processMessage(
                    Integer.toString(mAppIdValue),
                    Integer.toString(mContentTypeValue),
                    createIntent(pduType, tranId))
                    & WapPushManagerParams.MESSAGE_HANDLED) ==
                    WapPushManagerParams.MESSAGE_HANDLED);

            // clean up data
            iwapman.deletePackage(Integer.toString(mAppIdValue),
                    Integer.toString(mContentTypeValue), mPackageName, mClassName);

        } catch (RemoteException e) {
            assertTrue(false);
        }

        mPackageName = originalPackageName;
        mClassName = originalClassName;
    }

    /**
     * Message processing test, start service
     */
    public void testProcessMsg2() {
        byte[] pdu = createPDU(1);
        int headerLen = pdu.length - (mGsmHeader.length +
                mUserDataHeader.length + mMessageBody.length);
        int pduType = 6;
        int tranId = 0;
        String originalPackageName = mPackageName;
        String originalClassName = mClassName;

        try {

            mClassName = "com.android.smspush.unitTests.ReceiverService";

            // set up data
            IWapPushManager iwapman = getInterface();

            iwapman.addPackage(Integer.toString(mAppIdValue),
                    Integer.toString(mContentTypeValue), mPackageName, mClassName,
                    WapPushManagerParams.APP_TYPE_SERVICE, false, false);

            assertTrue((iwapman.processMessage(
                    Integer.toString(mAppIdValue),
                    Integer.toString(mContentTypeValue),
                    createIntent(pduType, tranId))
                    & WapPushManagerParams.MESSAGE_HANDLED) ==
                    WapPushManagerParams.MESSAGE_HANDLED);

            // clean up data
            iwapman.deletePackage(Integer.toString(mAppIdValue),
                    Integer.toString(mContentTypeValue), mPackageName, mClassName);

        } catch (RemoteException e) {
            assertTrue(false);
        }

        mPackageName = originalPackageName;
        mClassName = originalClassName;
    }

    /**
     * Message processing test, no signature
     */
    public void testProcessMsg3() {
        byte[] pdu = createPDU(1);
        int headerLen = pdu.length -
                (mGsmHeader.length + mUserDataHeader.length + mMessageBody.length);
        int pduType = 6;
        int tranId = 0;
        String originalPackageName = mPackageName;
        String originalClassName = mClassName;

        try {

            mPackageName = "com.android.development";
            mClassName = "com.android.development.Development";

            // set up data
            IWapPushManager iwapman = getInterface();

            iwapman.addPackage(Integer.toString(mAppIdValue),
                    Integer.toString(mContentTypeValue), mPackageName, mClassName,
                    WapPushManagerParams.APP_TYPE_SERVICE, true, false);

            assertFalse((iwapman.processMessage(
                    Integer.toString(mAppIdValue),
                    Integer.toString(mContentTypeValue),
                    createIntent(pduType, tranId))
                    & WapPushManagerParams.MESSAGE_HANDLED) ==
                    WapPushManagerParams.MESSAGE_HANDLED);

            // clean up data
            iwapman.deletePackage(Integer.toString(mAppIdValue),
                    Integer.toString(mContentTypeValue), mPackageName, mClassName);

        } catch (RemoteException e) {
            assertTrue(false);
        }

        mPackageName = originalPackageName;
        mClassName = originalClassName;
    }

    IDataVerify getVerifyInterface() {
        while (mIVerify == null) {
            // wait for the activity receive data.
            try {
                Thread.sleep(TIME_WAIT);
            } catch (InterruptedException e) {}
        }
        return mIVerify;
    }


    /**
     * Message processing test, received body data verification test
     */
    public void testProcessMsg4() {
        byte[] originalMessageBody = mMessageBody;
        mMessageBody = new byte[] {
                (byte) 0xee,
                (byte) 0xff,
                (byte) 0xee,
                (byte) 0xff,
                (byte) 0xee,
                (byte) 0xff,
                (byte) 0xee,
                (byte) 0xff,
                (byte) 0xee,
                (byte) 0xff,
                (byte) 0xee,
                (byte) 0xff,
        };

        byte[] pdu = createPDU(1);
        int headerLen = pdu.length -
                (mGsmHeader.length + mUserDataHeader.length + mMessageBody.length);
        int pduType = 6;
        int tranId = 0;
        String originalPackageName = mPackageName;
        String originalClassName = mClassName;

        try {
            IWapPushManager iwapman = getInterface();
            IDataVerify dataverify = getVerifyInterface();

            dataverify.resetData();

            // set up data
            mClassName = "com.android.smspush.unitTests.ReceiverActivity";
            iwapman.addPackage(Integer.toString(mAppIdValue),
                    Integer.toString(mContentTypeValue), mPackageName, mClassName,
                    WapPushManagerParams.APP_TYPE_ACTIVITY, false, false);

            iwapman.processMessage(
                    Integer.toString(mAppIdValue),
                    Integer.toString(mContentTypeValue),
                    createIntent(pduType, tranId));

            // clean up data
            iwapman.deletePackage(Integer.toString(mAppIdValue),
                    Integer.toString(mContentTypeValue), mPackageName, mClassName);

            assertTrue(dataverify.verifyData(mMessageBody));

            // set up data
            dataverify.resetData();
            mClassName = "com.android.smspush.unitTests.ReceiverService";
            mMessageBody = new byte[] {
                    (byte) 0xaa,
                    (byte) 0xbb,
                    (byte) 0x11,
                    (byte) 0x22,
                    (byte) 0xaa,
                    (byte) 0xbb,
                    (byte) 0x11,
                    (byte) 0x22,
                    (byte) 0xaa,
                    (byte) 0xbb,
                    (byte) 0x11,
                    (byte) 0x22,
                    (byte) 0xaa,
                    (byte) 0xbb,
                    (byte) 0x11,
                    (byte) 0x22,
                    (byte) 0xaa,
                    (byte) 0xbb,
                    (byte) 0x11,
                    (byte) 0x22,
                    (byte) 0xaa,
                    (byte) 0xbb,
                    (byte) 0x11,
                    (byte) 0x22,
            };
            pdu = createPDU(1);
            iwapman.addPackage(Integer.toString(mAppIdValue),
                    Integer.toString(mContentTypeValue), mPackageName, mClassName,
                    WapPushManagerParams.APP_TYPE_SERVICE, false, false);

            iwapman.processMessage(
                    Integer.toString(mAppIdValue),
                    Integer.toString(mContentTypeValue),
                    createIntent(pduType, tranId));

            // clean up data
            iwapman.deletePackage(Integer.toString(mAppIdValue),
                    Integer.toString(mContentTypeValue), mPackageName, mClassName);

            // Log.d(LOG_TAG, HexDump.dumpHexString(mMessageBody));
            assertTrue(dataverify.verifyData(mMessageBody));
        } catch (RemoteException e) {
            assertTrue(false);
        }

        mPackageName = originalPackageName;
        mClassName = originalClassName;
        mMessageBody = originalMessageBody;
    }

    /**
     * Message processing test, send invalid sms data
     */
    public void testProcessMsg5() {
        byte[] pdu = createPDU(2);
        int headerLen = pdu.length -
                (mGsmHeader.length + mUserDataHeader.length + mMessageBody.length);
        int pduType = 6;
        int tranId = 0;
        String originalPackageName = mPackageName;
        String originalClassName = mClassName;

        try {

            mClassName = "com.android.smspush.unitTests.ReceiverActivity";

            // set up data
            IWapPushManager iwapman = getInterface();
            iwapman.addPackage(Integer.toString(mAppIdValue),
                    Integer.toString(mContentTypeValue), mPackageName, mClassName,
                    WapPushManagerParams.APP_TYPE_ACTIVITY, false, false);

            assertTrue((iwapman.processMessage(
                    Integer.toString(mAppIdValue),
                    Integer.toString(mContentTypeValue),
                    createIntent(pduType, tranId))
                    & WapPushManagerParams.MESSAGE_HANDLED) ==
                    WapPushManagerParams.MESSAGE_HANDLED);

            // clean up data
            iwapman.deletePackage(Integer.toString(mAppIdValue),
                    Integer.toString(mContentTypeValue), mPackageName, mClassName);

        } catch (RemoteException e) {
            assertTrue(false);
        }

        mPackageName = originalPackageName;
        mClassName = originalClassName;
    }

    /**
     * Message processing test, no receiver application
     */
    public void testProcessMsg6() {
        byte[] pdu = createPDU(1);
        int headerLen = pdu.length -
                (mGsmHeader.length + mUserDataHeader.length + mMessageBody.length);
        int pduType = 6;
        int tranId = 0;
        String originalPackageName = mPackageName;
        String originalClassName = mClassName;

        try {

            mClassName = "com.android.smspush.unitTests.NoReceiver";

            // set up data
            IWapPushManager iwapman = getInterface();
            iwapman.addPackage(Integer.toString(mAppIdValue),
                    Integer.toString(mContentTypeValue), mPackageName, mClassName,
                    WapPushManagerParams.APP_TYPE_ACTIVITY, false, false);

            assertFalse((iwapman.processMessage(
                    Integer.toString(mAppIdValue),
                    Integer.toString(mContentTypeValue),
                    createIntent(pduType, tranId))
                    & WapPushManagerParams.MESSAGE_HANDLED) ==
                    WapPushManagerParams.MESSAGE_HANDLED);

            // clean up data
            iwapman.deletePackage(Integer.toString(mAppIdValue),
                    Integer.toString(mContentTypeValue), mPackageName, mClassName);

            // set up data
            iwapman.addPackage(Integer.toString(mAppIdValue),
                    Integer.toString(mContentTypeValue), mPackageName, mClassName,
                    WapPushManagerParams.APP_TYPE_SERVICE, false, false);

            assertFalse((iwapman.processMessage(
                    Integer.toString(mAppIdValue),
                    Integer.toString(mContentTypeValue),
                    createIntent(pduType, tranId))
                    & WapPushManagerParams.MESSAGE_HANDLED) ==
                    WapPushManagerParams.MESSAGE_HANDLED);

            // clean up data
            iwapman.deletePackage(Integer.toString(mAppIdValue),
                    Integer.toString(mContentTypeValue), mPackageName, mClassName);

        } catch (RemoteException e) {
            assertTrue(false);
        }

        mPackageName = originalPackageName;
        mClassName = originalClassName;
    }

    /**
     * WspTypeDecoder test, normal pdu
     */
    public void testDecoder1() {
        boolean res;
        int originalAppIdValue = mAppIdValue;
        Random rd = new Random();

        for (int i = 0; i < 10; i++) {
            mAppIdValue = rd.nextInt(0xFFFF);
            byte[] pdu = createPDU(1);
            WspTypeDecoder pduDecoder = new WspTypeDecoder(pdu);

            res = pduDecoder.seekXWapApplicationId(mWspHeaderStart,
                    mWspHeaderStart + mWspHeaderLen - 1);
            assertTrue(res);

            int index = (int) pduDecoder.getValue32();
            res = pduDecoder.decodeXWapApplicationId(index);
            assertTrue(res);

            Log.d(LOG_TAG, "mAppIdValue: " + mAppIdValue
                    + ", val: " + pduDecoder.getValue32());
            assertTrue(mAppIdValue == (int) pduDecoder.getValue32());
        }

        mAppIdValue = originalAppIdValue;
    }

    /**
     * WspTypeDecoder test, no header
     */
    public void testDecoder2() {
        boolean res;
        int originalAppIdValue = mAppIdValue;
        Random rd = new Random();

        mAppIdValue = rd.nextInt(0xFFFF);
        byte[] pdu = createPDU(2);
        WspTypeDecoder pduDecoder = new WspTypeDecoder(pdu);

        res = pduDecoder.seekXWapApplicationId(mWspHeaderStart,
                mWspHeaderStart + mWspHeaderLen - 1);
        assertFalse(res);

        mAppIdValue = originalAppIdValue;
    }

    /**
     * WspTypeDecoder test, decode appid test
     */
    public void testDecoder3() {
        boolean res;
        int originalAppIdValue = mAppIdValue;
        int originalContentTypeValue  = mContentTypeValue;
        Random rd = new Random();

        for (int i = 0; i < 100; i++) {
            mAppIdValue = rd.nextInt(0x0FFFFFFF);
            mContentTypeValue = rd.nextInt(0x0FFF);
            byte[] pdu = createPDU(3);
            WspTypeDecoder pduDecoder = new WspTypeDecoder(pdu);

            res = pduDecoder.seekXWapApplicationId(mWspHeaderStart,
                    mWspHeaderStart + mWspHeaderLen - 1);
            assertTrue(res);

            int index = (int) pduDecoder.getValue32();
            res = pduDecoder.decodeXWapApplicationId(index);
            assertTrue(res);

            Log.d(LOG_TAG, "mAppIdValue: " + mAppIdValue
                    + ", val: " + pduDecoder.getValue32());
            assertTrue(mAppIdValue == (int) pduDecoder.getValue32());
        }

        mAppIdValue = originalAppIdValue;
        mContentTypeValue = originalContentTypeValue;
    }

    /*
      public void testEnc() {
      byte[] arr = new byte[20];
      int index = 0;
      index += encodeUint32(0x87a5, arr, index);
      index += encodeUint32(0x1, arr, index);
      index += encodeUint32(0x9b, arr, index);
      index += encodeUint32(0x10, arr, index);
      index += encodeUint32(0xe0887, arr, index);
      index += encodeUint32(0x791a23d0, arr, index);

      Log.d(LOG_TAG, HexDump.dumpHexString(arr));
      }
    */

    /**
     * WspTypeDecoder test, no appid test
     */
    public void testDecoder4() {
        boolean res;
        int originalAppIdValue = mAppIdValue;
        int originalContentTypeValue  = mContentTypeValue;
        Random rd = new Random();

        for (int i = 0; i < 100; i++) {
            mAppIdValue = rd.nextInt(0x0FFFFFFF);
            mContentTypeValue = rd.nextInt(0x0FFF);
            byte[] pdu = createPDU(4);
            WspTypeDecoder pduDecoder = new WspTypeDecoder(pdu);

            res = pduDecoder.seekXWapApplicationId(mWspHeaderStart,
                    mWspHeaderStart + mWspHeaderLen - 1);
            assertFalse(res);

        }

        mAppIdValue = originalAppIdValue;
        mContentTypeValue = originalContentTypeValue;
    }

    /**
     * WspTypeDecoder test, decode string appid test
     */
    public void testDecoder5() {
        boolean res;
        String originalAppIdName = mAppIdName;
        int originalContentTypeValue  = mContentTypeValue;
        Random rd = new Random();

        for (int i = 0; i < 10; i++) {
            mAppIdValue = rd.nextInt(0x0FFFFFFF);
            mContentTypeValue = rd.nextInt(0x0FFF);
            byte[] pdu = createPDU(5);
            WspTypeDecoder pduDecoder = new WspTypeDecoder(pdu);

            res = pduDecoder.seekXWapApplicationId(mWspHeaderStart,
                    mWspHeaderStart + mWspHeaderLen - 1);
            assertTrue(res);

            int index = (int) pduDecoder.getValue32();
            res = pduDecoder.decodeXWapApplicationId(index);
            assertTrue(res);

            Log.d(LOG_TAG, "mAppIdValue: [" + mAppIdName + "], val: ["
                    + pduDecoder.getValueString() + "]");
            assertTrue(mAppIdName.equals(pduDecoder.getValueString()));
        }

        mAppIdName = originalAppIdName;
        mContentTypeValue = originalContentTypeValue;
    }

    /**
     * WspTypeDecoder test, decode string appid test
     */
    public void testDecoder6() {
        boolean res;
        String originalAppIdName = mAppIdName;
        int originalContentTypeValue  = mContentTypeValue;
        Random rd = new Random();

        for (int i = 0; i < OMA_APPLICATION_ID_NAMES.length; i++) {
            mAppIdName = OMA_APPLICATION_ID_NAMES[i];
            mContentTypeValue = rd.nextInt(0x0FFF);
            byte[] pdu = createPDU(6);
            WspTypeDecoder pduDecoder = new WspTypeDecoder(pdu);

            res = pduDecoder.seekXWapApplicationId(mWspHeaderStart,
                    mWspHeaderStart + mWspHeaderLen - 1);
            assertTrue(res);

            int index = (int) pduDecoder.getValue32();
            res = pduDecoder.decodeXWapApplicationId(index);
            assertTrue(res);

            Log.d(LOG_TAG, "mAppIdValue: [" + mAppIdName + "], val: ["
                    + pduDecoder.getValueString() + "]");
            assertTrue(mAppIdName.equals(pduDecoder.getValueString()));
        }

        mAppIdName = originalAppIdName;
        mContentTypeValue = originalContentTypeValue;
    }

    /**
     * WspTypeDecoder test, decode OMA content type
     */
    public void testDecoder7() {
        boolean res;
        String originalAppIdName = mAppIdName;
        int originalContentTypeValue  = mContentTypeValue;
        Random rd = new Random();

        for (int i = 0; i < OMA_CONTENT_TYPE_NAMES.length; i++) {
            mContentTypeName = OMA_CONTENT_TYPE_NAMES[i];
            byte[] pdu = createPDU(7);
            WspTypeDecoder pduDecoder = new WspTypeDecoder(pdu);

            res = pduDecoder.decodeContentType(mWspContentTypeStart);
            assertTrue(res);

            Log.d(LOG_TAG, "mContentTypeName: [" + mContentTypeName + "], val: ["
                    + pduDecoder.getValueString() + "]");
            assertTrue(mContentTypeName.equals(pduDecoder.getValueString()));
        }

        mAppIdName = originalAppIdName;
        mContentTypeValue = originalContentTypeValue;
    }


    /**
     * Copied from WapPushOverSms.
     * The code flow is not changed from the original.
     */
    public int dispatchWapPdu(byte[] pdu, IWapPushManager wapPushMan) {

        if (false) Log.d(LOG_TAG, "Rx: " + IccUtils.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 (false) Log.w(LOG_TAG, "Received non-PUSH WAP PDU. Type = " + pduType);
            return Intents.RESULT_SMS_HANDLED;
        }

        WspTypeDecoder 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 (false) Log.w(LOG_TAG, "Received PDU. Header Length error.");
            return Intents.RESULT_SMS_GENERIC_ERROR;
        }
        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 (false) Log.w(LOG_TAG, "Received PDU. Header Content-Type error.");
            return Intents.RESULT_SMS_GENERIC_ERROR;
        }

        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;

        if (mimeType != null && mimeType.equals(WspTypeDecoder.CONTENT_TYPE_B_PUSH_CO)) {
            intentData = pdu;
        } else {
            int dataIndex = headerStartIndex + headerLength;
            intentData = new byte[pdu.length - dataIndex];
            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 (false) Log.v(LOG_TAG, "appid found: " + wapAppId + ":" + contentType);

            try {
                boolean processFurther = true;
                // IWapPushManager wapPushMan = mWapConn.getWapPushManager();
                if (wapPushMan == null) {
                    if (false) 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 (false) 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 (false) Log.w(LOG_TAG, "remote func failed...");
            }
        }
        if (false) Log.v(LOG_TAG, "fall back to existing handler");

        return Activity.RESULT_OK;
    }

    protected byte[] retrieveWspBody() {
        byte[] array = new byte[mWspHeader.length + mMessageBody.length];

        System.arraycopy(mWspHeader, 0, array, 0, mWspHeader.length);
        System.arraycopy(mMessageBody, 0, array, mWspHeader.length, mMessageBody.length);
        return array;
    }

    protected String getContentTypeName(int ctypeVal) {
        int i;

        for (i = 0; i < OMA_CONTENT_TYPE_VALUES.length; i++) {
            if (ctypeVal == OMA_CONTENT_TYPE_VALUES[i]) {
                return OMA_CONTENT_TYPE_NAMES[i];
            }
        }
        return null;
    }

    protected boolean isContentTypeMapped(int ctypeVal) {
        int i;

        for (i = 0; i < OMA_CONTENT_TYPE_VALUES.length; i++) {
            if (ctypeVal == OMA_CONTENT_TYPE_VALUES[i]) return true;
        }
        return false;
    }

    /**
     * Integration test 1, simple case
     */
    public void testIntegration1() {
        boolean res;
        int originalAppIdValue = mAppIdValue;
        int originalContentTypeValue  = mContentTypeValue;
        String originalAppIdName = mAppIdName;
        String originalContentTypeName = mContentTypeName;
        String originalClassName = mClassName;
        byte[] originalMessageBody = mMessageBody;
        Random rd = new Random();

        mMessageBody = new byte[100 + rd.nextInt(100)];
        rd.nextBytes(mMessageBody);

        byte[] pdu = createPDU(1);
        byte[] wappushPdu = retrieveWspBody();


        mClassName = "com.android.smspush.unitTests.ReceiverActivity";
        // Phone dummy = new DummyPhone(getContext());
        // Phone gsm = PhoneFactory.getGsmPhone();
        // GSMPhone gsm = new GSMPhone(getContext(), new SimulatedCommands(), null, true);
        // WapPushOverSms dispatcher = new WapPushOverSms(dummy, null);

        try {
            // set up data
            IWapPushManager iwapman = getInterface();
            IDataVerify dataverify = getVerifyInterface();

            dataverify.resetData();

            if (isContentTypeMapped(mContentTypeValue)) {
                // content type is mapped
                mContentTypeName = getContentTypeName(mContentTypeValue);
                Log.d(LOG_TAG, "mContentTypeValue mapping "
                        + mContentTypeName + ":" + mContentTypeValue);
            } else {
                mContentTypeName = Integer.toString(mContentTypeValue);
            }
            iwapman.addPackage(Integer.toString(mAppIdValue),
                    mContentTypeName, mPackageName, mClassName,
                    WapPushManagerParams.APP_TYPE_ACTIVITY, false, false);

            dispatchWapPdu(wappushPdu, iwapman);

            // clean up data
            iwapman.deletePackage(Integer.toString(mAppIdValue),
                    mContentTypeName, mPackageName, mClassName);

            assertTrue(dataverify.verifyData(mMessageBody));
        } catch (RemoteException e) {
        }


        mClassName = originalClassName;
        mAppIdName = originalAppIdName;
        mContentTypeName = originalContentTypeName;
        mAppIdValue = originalAppIdValue;
        mContentTypeValue = originalContentTypeValue;
        mMessageBody = originalMessageBody;
    }

    /**
     * Integration test 2, random mAppIdValue(int), all OMA content type
     */
    public void testIntegration2() {
        boolean res;
        int originalAppIdValue = mAppIdValue;
        int originalContentTypeValue  = mContentTypeValue;
        String originalAppIdName = mAppIdName;
        String originalContentTypeName = mContentTypeName;
        String originalClassName = mClassName;
        byte[] originalMessageBody = mMessageBody;
        Random rd = new Random();

        IWapPushManager iwapman = getInterface();
        IDataVerify dataverify = getVerifyInterface();
        mClassName = "com.android.smspush.unitTests.ReceiverActivity";

        for (int i = 0; i < OMA_CONTENT_TYPE_NAMES.length; i++) {
            mContentTypeName = OMA_CONTENT_TYPE_NAMES[i];
            mAppIdValue = rd.nextInt(0x0FFFFFFF);

            mMessageBody = new byte[100 + rd.nextInt(100)];
            rd.nextBytes(mMessageBody);

            byte[] pdu = createPDU(7);
            byte[] wappushPdu = retrieveWspBody();

            try {
                dataverify.resetData();
                // set up data
                iwapman.addPackage(Integer.toString(mAppIdValue),
                        mContentTypeName, mPackageName, mClassName,
                        WapPushManagerParams.APP_TYPE_ACTIVITY, false, false);

                dispatchWapPdu(wappushPdu, iwapman);

                // clean up data
                iwapman.deletePackage(Integer.toString(mAppIdValue),
                        mContentTypeName, mPackageName, mClassName);

                if (mContentTypeName.equals(WspTypeDecoder.CONTENT_TYPE_B_PUSH_CO)) {
                    assertTrue(dataverify.verifyData(wappushPdu));
                } else {
                    assertTrue(dataverify.verifyData(mMessageBody));
                }
            } catch (RemoteException e) {
            }
        }


        mClassName = originalClassName;
        mAppIdName = originalAppIdName;
        mContentTypeName = originalContentTypeName;
        mAppIdValue = originalAppIdValue;
        mContentTypeValue = originalContentTypeValue;
        mMessageBody = originalMessageBody;
    }

    /**
     * Integration test 3, iterate OmaApplication ID, random binary content type
     */
    public void testIntegration3() {
        boolean res;
        int originalAppIdValue = mAppIdValue;
        int originalContentTypeValue  = mContentTypeValue;
        String originalAppIdName = mAppIdName;
        String originalContentTypeName = mContentTypeName;
        String originalClassName = mClassName;
        byte[] originalMessageBody = mMessageBody;
        Random rd = new Random();

        IWapPushManager iwapman = getInterface();
        IDataVerify dataverify = getVerifyInterface();
        mClassName = "com.android.smspush.unitTests.ReceiverService";

        for (int i = 0; i < OMA_APPLICATION_ID_NAMES.length; i++) {
            mAppIdName = OMA_APPLICATION_ID_NAMES[i];
            mContentTypeValue = rd.nextInt(0x0FFF);

            mMessageBody = new byte[100 + rd.nextInt(100)];
            rd.nextBytes(mMessageBody);

            byte[] pdu = createPDU(6);
            byte[] wappushPdu = retrieveWspBody();

            try {
                dataverify.resetData();
                // set up data
                if (isContentTypeMapped(mContentTypeValue)) {
                    // content type is mapped to integer value
                    mContentTypeName = getContentTypeName(mContentTypeValue);
                    Log.d(LOG_TAG, "mContentTypeValue mapping "
                            + mContentTypeValue + ":" + mContentTypeName);
                } else {
                    mContentTypeName = Integer.toString(mContentTypeValue);
                }

                iwapman.addPackage(mAppIdName,
                        mContentTypeName, mPackageName, mClassName,
                        WapPushManagerParams.APP_TYPE_SERVICE, false, false);

                dispatchWapPdu(wappushPdu, iwapman);

                // clean up data
                iwapman.deletePackage(mAppIdName,
                        mContentTypeName, mPackageName, mClassName);

                if (mContentTypeName.equals(WspTypeDecoder.CONTENT_TYPE_B_PUSH_CO)) {
                    assertTrue(dataverify.verifyData(wappushPdu));
                } else {
                    assertTrue(dataverify.verifyData(mMessageBody));
                }
            } catch (RemoteException e) {
            }
        }

        mClassName = originalClassName;
        mAppIdName = originalAppIdName;
        mContentTypeName = originalContentTypeName;
        mAppIdValue = originalAppIdValue;
        mContentTypeValue = originalContentTypeValue;
        mMessageBody = originalMessageBody;
    }

    /**
     * Integration test 4, iterate OmaApplication ID, Oma content type
     */
    public void testIntegration4() {
        boolean res;
        int originalAppIdValue = mAppIdValue;
        int originalContentTypeValue  = mContentTypeValue;
        String originalAppIdName = mAppIdName;
        String originalContentTypeName = mContentTypeName;
        String originalClassName = mClassName;
        byte[] originalMessageBody = mMessageBody;
        Random rd = new Random();

        IWapPushManager iwapman = getInterface();
        IDataVerify dataverify = getVerifyInterface();
        mClassName = "com.android.smspush.unitTests.ReceiverService";

        for (int i = 0; i < OMA_APPLICATION_ID_NAMES.length
                + OMA_CONTENT_TYPE_NAMES.length; i++) {
            mAppIdName = OMA_APPLICATION_ID_NAMES[rd.nextInt(OMA_APPLICATION_ID_NAMES.length)];
            int contIndex = rd.nextInt(OMA_CONTENT_TYPE_NAMES.length);
            mContentTypeName = OMA_CONTENT_TYPE_NAMES[contIndex];

            mMessageBody = new byte[100 + rd.nextInt(100)];
            rd.nextBytes(mMessageBody);

            byte[] pdu = createPDU(8);
            byte[] wappushPdu = retrieveWspBody();

            try {
                dataverify.resetData();
                // set up data
                iwapman.addPackage(mAppIdName,
                        mContentTypeName, mPackageName, mClassName,
                        WapPushManagerParams.APP_TYPE_SERVICE, false, false);

                dispatchWapPdu(wappushPdu, iwapman);

                // clean up data
                iwapman.deletePackage(mAppIdName,
                        mContentTypeName, mPackageName, mClassName);

                if (mContentTypeName.equals(WspTypeDecoder.CONTENT_TYPE_B_PUSH_CO)) {
                    assertTrue(dataverify.verifyData(wappushPdu));
                } else {
                    assertTrue(dataverify.verifyData(mMessageBody));
                }
            } catch (RemoteException e) {
            }
        }

        mClassName = originalClassName;
        mAppIdName = originalAppIdName;
        mContentTypeName = originalContentTypeName;
        mAppIdValue = originalAppIdValue;
        mContentTypeValue = originalContentTypeValue;
        mMessageBody = originalMessageBody;
    }

    /**
     * Integration test 5, iterate binary OmaApplication ID, Oma binary content type
     */
    public void testIntegration5() {
        boolean res;
        int originalAppIdValue = mAppIdValue;
        int originalContentTypeValue  = mContentTypeValue;
        String originalAppIdName = mAppIdName;
        String originalContentTypeName = mContentTypeName;
        String originalClassName = mClassName;
        byte[] originalMessageBody = mMessageBody;
        Random rd = new Random();

        IWapPushManager iwapman = getInterface();
        IDataVerify dataverify = getVerifyInterface();
        mClassName = "com.android.smspush.unitTests.ReceiverService";

        for (int i = 0; i < OMA_APPLICATION_ID_VALUES.length +
                    OMA_CONTENT_TYPE_VALUES.length; i++) {
            mAppIdValue = OMA_APPLICATION_ID_VALUES[rd.nextInt(
                    OMA_APPLICATION_ID_VALUES.length)];
            mContentTypeValue =
                    OMA_CONTENT_TYPE_VALUES[rd.nextInt(OMA_CONTENT_TYPE_VALUES.length)];

            mMessageBody = new byte[100 + rd.nextInt(100)];
            rd.nextBytes(mMessageBody);

            byte[] pdu = createPDU(3);
            byte[] wappushPdu = retrieveWspBody();

            try {
                dataverify.resetData();
                // set up data
                if (isContentTypeMapped(mContentTypeValue)) {
                    // content type is mapped to integer value
                    mContentTypeName = getContentTypeName(mContentTypeValue);
                    Log.d(LOG_TAG, "mContentTypeValue mapping "
                            + mContentTypeValue + ":" + mContentTypeName);
                } else {
                    mContentTypeName = Integer.toString(mContentTypeValue);
                }

                iwapman.addPackage(Integer.toString(mAppIdValue),
                        mContentTypeName, mPackageName, mClassName,
                        WapPushManagerParams.APP_TYPE_SERVICE, false, false);

                dispatchWapPdu(wappushPdu, iwapman);

                // clean up data
                iwapman.deletePackage(Integer.toString(mAppIdValue),
                        mContentTypeName, mPackageName, mClassName);

                if (mContentTypeName.equals(WspTypeDecoder.CONTENT_TYPE_B_PUSH_CO)) {
                    assertTrue(dataverify.verifyData(wappushPdu));
                } else {
                    assertTrue(dataverify.verifyData(mMessageBody));
                }
            } catch (RemoteException e) {
            }
        }

        mClassName = originalClassName;
        mAppIdName = originalAppIdName;
        mContentTypeName = originalContentTypeName;
        mAppIdValue = originalAppIdValue;
        mContentTypeValue = originalContentTypeValue;
        mMessageBody = originalMessageBody;
    }

}
