/*
 * 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.IWapPushManager;
import com.android.internal.telephony.WapPushManagerParams;
import com.android.internal.telephony.WspTypeDecoder;
import com.android.internal.telephony.uicc.IccUtils;
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 sqlite injection test
     */
    public void testAddPackage0() {
        String inject = "' union select 0,'com.android.settings','com.android.settings.Settings',0,0,0--";

        // insert new data
        IWapPushManager iwapman = getInterface();
        try {
            assertFalse(iwapman.addPackage(
                    inject,
                    Integer.toString(mContentTypeValue),
                    mPackageName, mClassName,
                    WapPushManagerParams.APP_TYPE_SERVICE, true, true));
        } catch (RemoteException e) {
            assertTrue(false);
        }
    }

    /**
     * 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;
    }

}
