1/*
2 * Copyright (C) 2010 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 *      http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17package com.android.smspush.unitTests;
18
19import android.app.Activity;
20import android.content.ComponentName;
21import android.content.Context;
22import android.content.Intent;
23import android.content.ServiceConnection;
24import android.os.IBinder;
25import android.os.RemoteException;
26import android.provider.Telephony.Sms.Intents;
27import android.test.ServiceTestCase;
28import android.util.Log;
29
30import com.android.internal.telephony.IccUtils;
31import com.android.internal.telephony.IWapPushManager;
32import com.android.internal.telephony.WapPushManagerParams;
33import com.android.internal.telephony.WspTypeDecoder;
34import com.android.internal.util.HexDump;
35import com.android.smspush.WapPushManager;
36
37import java.util.Random;
38
39/**
40 * This is a simple framework for a test of a Service.  See {@link android.test.ServiceTestCase
41 * ServiceTestCase} for more information on how to write and extend service tests.
42 *
43 * To run this test, you can type:
44 * adb shell am instrument -w \
45 * -e class com.android.smspush.unitTests.WapPushTest \
46 * com.android.smspush.unitTests/android.test.InstrumentationTestRunner
47 */
48public class WapPushTest extends ServiceTestCase<WapPushManager> {
49    private static final String LOG_TAG = "WAP PUSH";
50    private static final boolean LOCAL_LOGV = false;
51    private static final int TIME_WAIT = 100;
52
53    protected int mAppIdValue = 0x8002;
54    protected String mAppIdName = "x-wap-application:*";
55    protected int mContentTypeValue = 0x030a;
56    protected String mContentTypeName = "application/vnd.wap.sic";
57
58    protected String mPackageName;
59    protected String mClassName;
60
61    protected byte[] mGsmHeader = {
62            (byte) 0x00, // sc address
63            (byte) 0x40, // TP-MTI
64            (byte) 0x04, // sender address length?
65            (byte) 0x81, (byte) 0x55, (byte) 0x45, // sender address?
66            (byte) 0x00, // data schema
67            (byte) 0x00, // proto ID
68            (byte) 0x01, (byte) 0x60, (byte) 0x12, (byte) 0x31,
69            (byte) 0x74, (byte) 0x34, (byte) 0x63 // time stamp
70    };
71
72    protected byte[] mUserDataHeader = {
73            (byte) 0x07, // UDH len
74            (byte) 0x06, // header len
75            (byte) 0x05, // port addressing type?
76            (byte) 0x00, // dummy
77            (byte) 0x0B, (byte) 0x84, // dest port
78            (byte) 0x23, (byte) 0xF0 // src port
79    };
80
81    protected byte[] mWspHeader;
82
83    protected byte[] mMessageBody = {
84            (byte) 0x00,
85            (byte) 0x01,
86            (byte) 0x02,
87            (byte) 0x03,
88            (byte) 0x04,
89            (byte) 0x05,
90            (byte) 0x06,
91            (byte) 0x07,
92            (byte) 0x08,
93            (byte) 0x09,
94            (byte) 0x0a,
95            (byte) 0x0b,
96            (byte) 0x0c,
97            (byte) 0x0d,
98            (byte) 0x0e,
99            (byte) 0x0f
100    };
101
102    protected int mWspHeaderStart;
103    protected int mWspHeaderLen;
104    protected int mWspContentTypeStart;
105
106    /**
107     * OMA application ID in binary form
108     * http://www.openmobilealliance.org/tech/omna/omna-push-app-id.aspx
109     */
110    final int[] OMA_APPLICATION_ID_VALUES = new int[] {
111            0x00,
112            0x01,
113            0x02,
114            0x03,
115            0x04,
116            0x05,
117            0x06,
118            0x07,
119            0x08,
120            0x09,
121            0x0A,
122            0x8000,
123            0x8001,
124            0x8002,
125            0x8003,
126            0x8004,
127            0x8005,
128            0x8006,
129            0x8007,
130            0x8008,
131            0x8009,
132            0x800B,
133            0x8010
134    };
135
136    /**
137     * OMA application ID in string form
138     * http://www.openmobilealliance.org/tech/omna/omna-push-app-id.aspx
139     */
140    final String[] OMA_APPLICATION_ID_NAMES = new String[] {
141            "x-wap-application:*",
142            "x-wap-application:push.sia",
143            "x-wap-application:wml.ua",
144            "x-wap-application:wta.ua",
145            "x-wap-application:mms.ua",
146            "x-wap-application:push.syncml",
147            "x-wap-application:loc.ua",
148            "x-wap-application:syncml.dm",
149            "x-wap-application:drm.ua",
150            "x-wap-application:emn.ua",
151            "x-wap-application:wv.ua",
152            "x-wap-microsoft:localcontent.ua",
153            "x-wap-microsoft:IMclient.ua",
154            "x-wap-docomo:imode.mail.ua",
155            "x-wap-docomo:imode.mr.ua",
156            "x-wap-docomo:imode.mf.ua",
157            "x-motorola:location.ua",
158            "x-motorola:now.ua",
159            "x-motorola:otaprov.ua",
160            "x-motorola:browser.ua",
161            "x-motorola:splash.ua",
162            "x-wap-nai:mvsw.command",
163            "x-wap-openwave:iota.ua"
164    };
165
166    /**
167     * OMA content type in binary form
168     * http://www.openmobilealliance.org/tech/omna/omna-wsp-content-type.aspx
169     */
170    final int[] OMA_CONTENT_TYPE_VALUES = new int[] {
171            0x00,
172            0x01,
173            0x02,
174            0x03,
175            0x04,
176            0x05,
177            0x06,
178            0x07,
179            0x08,
180            0x09,
181            0x0A,
182            0x0B,
183            0x0C,
184            0x0D,
185            0x0E,
186            0x0F,
187            0x10,
188            0x11,
189            0x12,
190            0x13,
191            0x14,
192            0x15,
193            0x16,
194            0x17,
195            0x18,
196            0x19,
197            0x1A,
198            0x1B,
199            0x1C,
200            0x1D,
201            0x1E,
202            0x1F,
203            0x20,
204            0x21,
205            0x22,
206            0x23,
207            0x24,
208            0x25,
209            0x26,
210            0x27,
211            0x28,
212            0x29,
213            0x2A,
214            0x2B,
215            0x2C,
216            0x2D,
217            0x2E,
218            0x2F,
219            0x30,
220            0x31,
221            0x32,
222            0x33,
223            0x34,
224            0x35,
225            0x36,
226            0x37,
227            0x38,
228            0x39,
229            0x3A,
230            0x3B,
231            0x3C,
232            0x3D,
233            0x3E,
234            0x3F,
235            0x40,
236            0x41,
237            0x42,
238            0x43,
239            0x44,
240            0x45,
241            0x46,
242            0x47,
243            0x48,
244            0x49,
245            0x4A,
246            0x4B,
247            0x4C,
248            0x4D,
249            0x4E,
250            0x4F,
251            0x50,
252            0x51,
253            0x52,
254            0x53,
255            0x54,
256//            0x55,
257//            0x56,
258//            0x57,
259//            0x58,
260            0x0201,
261            0x0202,
262            0x0203,
263            0x0204,
264            0x0205,
265            0x0206,
266            0x0207,
267            0x0208,
268            0x0209,
269            0x020A,
270            0x020B,
271            0x020C,
272            0x0300,
273            0x0301,
274            0x0302,
275            0x0303,
276            0x0304,
277            0x0305,
278            0x0306,
279            0x0307,
280            0x0308,
281            0x0309,
282            0x030A,
283            0x030B,
284            0x030C,
285            0x030D,
286            0x030E,
287            0x030F,
288            0x0310,
289            0x0311,
290            0x0312,
291            0x0313,
292            0x0314,
293            0x0315,
294            0x0316,
295            0x0317,
296            0x0318,
297            0x0319,
298            0x031A,
299            0x031B
300            /*0x031C,
301              0x031D*/
302    };
303
304    /**
305     * OMA content type in string form
306     * http://www.openmobilealliance.org/tech/omna/omna-wsp-content-type.aspx
307     */
308    final String[] OMA_CONTENT_TYPE_NAMES = new String[] {
309            "*/*",
310            "text/*",
311            "text/html",
312            "text/plain",
313            "text/x-hdml",
314            "text/x-ttml",
315            "text/x-vCalendar",
316            "text/x-vCard",
317            "text/vnd.wap.wml",
318            "text/vnd.wap.wmlscript",
319            "text/vnd.wap.wta-event",
320            "multipart/*",
321            "multipart/mixed",
322            "multipart/form-data",
323            "multipart/byterantes",
324            "multipart/alternative",
325            "application/*",
326            "application/java-vm",
327            "application/x-www-form-urlencoded",
328            "application/x-hdmlc",
329            "application/vnd.wap.wmlc",
330            "application/vnd.wap.wmlscriptc",
331            "application/vnd.wap.wta-eventc",
332            "application/vnd.wap.uaprof",
333            "application/vnd.wap.wtls-ca-certificate",
334            "application/vnd.wap.wtls-user-certificate",
335            "application/x-x509-ca-cert",
336            "application/x-x509-user-cert",
337            "image/*",
338            "image/gif",
339            "image/jpeg",
340            "image/tiff",
341            "image/png",
342            "image/vnd.wap.wbmp",
343            "application/vnd.wap.multipart.*",
344            "application/vnd.wap.multipart.mixed",
345            "application/vnd.wap.multipart.form-data",
346            "application/vnd.wap.multipart.byteranges",
347            "application/vnd.wap.multipart.alternative",
348            "application/xml",
349            "text/xml",
350            "application/vnd.wap.wbxml",
351            "application/x-x968-cross-cert",
352            "application/x-x968-ca-cert",
353            "application/x-x968-user-cert",
354            "text/vnd.wap.si",
355            "application/vnd.wap.sic",
356            "text/vnd.wap.sl",
357            "application/vnd.wap.slc",
358            "text/vnd.wap.co",
359            "application/vnd.wap.coc",
360            "application/vnd.wap.multipart.related",
361            "application/vnd.wap.sia",
362            "text/vnd.wap.connectivity-xml",
363            "application/vnd.wap.connectivity-wbxml",
364            "application/pkcs7-mime",
365            "application/vnd.wap.hashed-certificate",
366            "application/vnd.wap.signed-certificate",
367            "application/vnd.wap.cert-response",
368            "application/xhtml+xml",
369            "application/wml+xml",
370            "text/css",
371            "application/vnd.wap.mms-message",
372            "application/vnd.wap.rollover-certificate",
373            "application/vnd.wap.locc+wbxml",
374            "application/vnd.wap.loc+xml",
375            "application/vnd.syncml.dm+wbxml",
376            "application/vnd.syncml.dm+xml",
377            "application/vnd.syncml.notification",
378            "application/vnd.wap.xhtml+xml",
379            "application/vnd.wv.csp.cir",
380            "application/vnd.oma.dd+xml",
381            "application/vnd.oma.drm.message",
382            "application/vnd.oma.drm.content",
383            "application/vnd.oma.drm.rights+xml",
384            "application/vnd.oma.drm.rights+wbxml",
385            "application/vnd.wv.csp+xml",
386            "application/vnd.wv.csp+wbxml",
387            "application/vnd.syncml.ds.notification",
388            "audio/*",
389            "video/*",
390            "application/vnd.oma.dd2+xml",
391            "application/mikey",
392            "application/vnd.oma.dcd",
393            "application/vnd.oma.dcdc",
394//            "text/x-vMessage",
395//            "application/vnd.omads-email+wbxml",
396//            "text/x-vBookmark",
397//            "application/vnd.syncml.dm.notification",
398            "application/vnd.uplanet.cacheop-wbxml",
399            "application/vnd.uplanet.signal",
400            "application/vnd.uplanet.alert-wbxml",
401            "application/vnd.uplanet.list-wbxml",
402            "application/vnd.uplanet.listcmd-wbxml",
403            "application/vnd.uplanet.channel-wbxml",
404            "application/vnd.uplanet.provisioning-status-uri",
405            "x-wap.multipart/vnd.uplanet.header-set",
406            "application/vnd.uplanet.bearer-choice-wbxml",
407            "application/vnd.phonecom.mmc-wbxml",
408            "application/vnd.nokia.syncset+wbxml",
409            "image/x-up-wpng",
410            "application/iota.mmc-wbxml",
411            "application/iota.mmc-xml",
412            "application/vnd.syncml+xml",
413            "application/vnd.syncml+wbxml",
414            "text/vnd.wap.emn+xml",
415            "text/calendar",
416            "application/vnd.omads-email+xml",
417            "application/vnd.omads-file+xml",
418            "application/vnd.omads-folder+xml",
419            "text/directory;profile=vCard",
420            "application/vnd.wap.emn+wbxml",
421            "application/vnd.nokia.ipdc-purchase-response",
422            "application/vnd.motorola.screen3+xml",
423            "application/vnd.motorola.screen3+gzip",
424            "application/vnd.cmcc.setting+wbxml",
425            "application/vnd.cmcc.bombing+wbxml",
426            "application/vnd.docomo.pf",
427            "application/vnd.docomo.ub",
428            "application/vnd.omaloc-supl-init",
429            "application/vnd.oma.group-usage-list+xml",
430            "application/oma-directory+xml",
431            "application/vnd.docomo.pf2",
432            "application/vnd.oma.drm.roap-trigger+wbxml",
433            "application/vnd.sbm.mid2",
434            "application/vnd.wmf.bootstrap",
435            "application/vnc.cmcc.dcd+xml",
436            "application/vnd.sbm.cid",
437            "application/vnd.oma.bcast.provisioningtrigger",
438            /*"application/vnd.docomo.dm",
439              "application/vnd.oma.scidm.messages+xml"*/
440    };
441
442    private IDataVerify mIVerify = null;
443
444    ServiceConnection mConn = new ServiceConnection() {
445            public void onServiceConnected(ComponentName name, IBinder service) {
446                Log.v(LOG_TAG, "data verify interface connected.");
447                mIVerify = IDataVerify.Stub.asInterface(service);
448            }
449            public void onServiceDisconnected(ComponentName name) {
450            }
451        };
452
453    /**
454     * Main WapPushManager test module constructor
455     */
456    public WapPushTest() {
457        super(WapPushManager.class);
458        mClassName = this.getClass().getName();
459        mPackageName = this.getClass().getPackage().getName();
460    }
461
462    /**
463     * Initialize the verifier
464     */
465    @Override
466    public void setUp() {
467        try {
468            super.setUp();
469            // get verifier
470            getContext().bindService(new Intent(IDataVerify.class.getName()),
471                    mConn, Context.BIND_AUTO_CREATE);
472        } catch (Exception e) {
473            Log.w(LOG_TAG, "super exception");
474        }
475        // Log.d(LOG_TAG, "test setup");
476    }
477
478    private IWapPushManager mWapPush = null;
479    IWapPushManager getInterface() {
480        if (mWapPush != null) return mWapPush;
481        Intent startIntent = new Intent();
482        startIntent.setClass(getContext(), WapPushManager.class);
483        IBinder service = bindService(startIntent);
484
485        mWapPush = IWapPushManager.Stub.asInterface(service);
486        return mWapPush;
487    }
488
489    /*
490     * All methods need to start with 'test'.
491     * Use various assert methods to pass/fail the test case.
492     */
493    protected void utAddPackage(boolean need_sig, boolean more_proc) {
494        IWapPushManager iwapman = getInterface();
495
496        // insert new data
497        try {
498            assertTrue(iwapman.addPackage(
499                    Integer.toString(mAppIdValue),
500                    Integer.toString(mContentTypeValue),
501                    mPackageName, mClassName,
502                    WapPushManagerParams.APP_TYPE_SERVICE, need_sig, more_proc));
503        } catch (RemoteException e) {
504            assertTrue(false);
505        }
506
507        // verify the data
508        WapPushManager wpman = getService();
509        assertTrue(wpman.verifyData(Integer.toString(mAppIdValue),
510                Integer.toString(mContentTypeValue),
511                mPackageName, mClassName,
512                WapPushManagerParams.APP_TYPE_SERVICE, need_sig, more_proc));
513    }
514
515    /**
516     * Add package test
517     */
518    public void testAddPackage1() {
519        int originalAppIdValue = mAppIdValue;
520        int originalContentTypeValue  = mContentTypeValue;
521
522        utAddPackage(true, true);
523        mAppIdValue += 10;
524        utAddPackage(true, false);
525        mContentTypeValue += 20;
526        utAddPackage(false, true);
527        mContentTypeValue += 20;
528        utAddPackage(false, false);
529
530        mAppIdValue = originalAppIdValue;
531        mContentTypeValue = originalContentTypeValue;
532
533        // clean up data
534        try {
535            IWapPushManager iwapman = getInterface();
536            iwapman.deletePackage(Integer.toString(mAppIdValue),
537                    Integer.toString(mContentTypeValue), mPackageName, mClassName);
538            mAppIdValue += 10;
539            iwapman.deletePackage(Integer.toString(mAppIdValue),
540                    Integer.toString(mContentTypeValue), mPackageName, mClassName);
541            mContentTypeValue += 20;
542            iwapman.deletePackage(Integer.toString(mAppIdValue),
543                    Integer.toString(mContentTypeValue), mPackageName, mClassName);
544            mContentTypeValue += 20;
545            iwapman.deletePackage(Integer.toString(mAppIdValue),
546                    Integer.toString(mContentTypeValue), mPackageName, mClassName);
547        } catch (RemoteException e) {
548            assertTrue(false);
549        }
550        mAppIdValue = originalAppIdValue;
551        mContentTypeValue = originalContentTypeValue;
552    }
553
554    /**
555     * Add duprecated package test.
556     */
557    public void testAddPackage2() {
558        try {
559            IWapPushManager iwapman = getInterface();
560
561            // set up data
562            iwapman.addPackage(Integer.toString(mAppIdValue),
563                    Integer.toString(mContentTypeValue), mPackageName, mClassName, 0,
564                    false, false);
565            iwapman.addPackage(Integer.toString(mAppIdValue + 10),
566                    Integer.toString(mContentTypeValue), mPackageName, mClassName, 0,
567                    false, false);
568            iwapman.addPackage(Integer.toString(mAppIdValue),
569                    Integer.toString(mContentTypeValue + 10), mPackageName, mClassName, 0,
570                    false, false);
571
572            assertFalse(iwapman.addPackage(Integer.toString(mAppIdValue),
573                    Integer.toString(mContentTypeValue), mPackageName, mClassName, 0,
574                    false, false));
575            assertFalse(iwapman.addPackage(Integer.toString(mAppIdValue + 10),
576                    Integer.toString(mContentTypeValue), mPackageName, mClassName, 0,
577                    false, false));
578            assertFalse(iwapman.addPackage(Integer.toString(mAppIdValue),
579                    Integer.toString(mContentTypeValue + 10), mPackageName, mClassName, 0,
580                    false, false));
581
582            // clean up data
583            iwapman.deletePackage(Integer.toString(mAppIdValue),
584                    Integer.toString(mContentTypeValue), mPackageName, mClassName);
585            iwapman.deletePackage(Integer.toString(mAppIdValue + 10),
586                    Integer.toString(mContentTypeValue), mPackageName, mClassName);
587            iwapman.deletePackage(Integer.toString(mAppIdValue),
588                    Integer.toString(mContentTypeValue + 10), mPackageName, mClassName);
589        } catch (RemoteException e) {
590            assertTrue(false);
591        }
592    }
593
594    protected void utUpdatePackage(boolean need_sig, boolean more_proc) {
595        IWapPushManager iwapman = getInterface();
596
597        // insert new data
598        try {
599            assertTrue(iwapman.updatePackage(
600                    Integer.toString(mAppIdValue),
601                    Integer.toString(mContentTypeValue),
602                    mPackageName, mClassName,
603                    WapPushManagerParams.APP_TYPE_SERVICE, need_sig, more_proc));
604        } catch (RemoteException e) {
605            assertTrue(false);
606        }
607
608        // verify the data
609        WapPushManager wpman = getService();
610        assertTrue(wpman.verifyData(
611                Integer.toString(mAppIdValue),
612                Integer.toString(mContentTypeValue),
613                mPackageName, mClassName,
614                WapPushManagerParams.APP_TYPE_SERVICE, need_sig, more_proc));
615    }
616
617    /**
618     * Updating package test
619     */
620    public void testUpdatePackage1() {
621        int originalAppIdValue = mAppIdValue;
622        int originalContentTypeValue  = mContentTypeValue;
623
624        // set up data
625        try {
626            IWapPushManager iwapman = getInterface();
627
628            iwapman.addPackage(Integer.toString(mAppIdValue),
629                    Integer.toString(mContentTypeValue), mPackageName, mClassName,
630                    0, false, false);
631            mAppIdValue += 10;
632            iwapman.addPackage(Integer.toString(mAppIdValue),
633                    Integer.toString(mContentTypeValue), mPackageName, mClassName,
634                    0, false, false);
635            mContentTypeValue += 20;
636            iwapman.addPackage(Integer.toString(mAppIdValue),
637                    Integer.toString(mContentTypeValue), mPackageName, mClassName,
638                    0, false, false);
639            mContentTypeValue += 20;
640            iwapman.addPackage(Integer.toString(mAppIdValue),
641                    Integer.toString(mContentTypeValue), mPackageName, mClassName,
642                    0, false, false);
643        } catch (RemoteException e) {
644            assertTrue(false);
645        }
646
647        mAppIdValue = originalAppIdValue;
648        mContentTypeValue = originalContentTypeValue;
649        utUpdatePackage(false, false);
650        mAppIdValue += 10;
651        utUpdatePackage(false, true);
652        mContentTypeValue += 20;
653        utUpdatePackage(true, false);
654        mContentTypeValue += 20;
655        utUpdatePackage(true, true);
656
657        mAppIdValue = originalAppIdValue;
658        mContentTypeValue = originalContentTypeValue;
659
660        // clean up data
661        try {
662            IWapPushManager iwapman = getInterface();
663
664            iwapman.deletePackage(Integer.toString(mAppIdValue),
665                    Integer.toString(mContentTypeValue), mPackageName, mClassName);
666            mAppIdValue += 10;
667            iwapman.deletePackage(Integer.toString(mAppIdValue),
668                    Integer.toString(mContentTypeValue), mPackageName, mClassName);
669            mContentTypeValue += 20;
670            iwapman.deletePackage(Integer.toString(mAppIdValue),
671                    Integer.toString(mContentTypeValue), mPackageName, mClassName);
672            mContentTypeValue += 20;
673            iwapman.deletePackage(Integer.toString(mAppIdValue),
674                    Integer.toString(mContentTypeValue), mPackageName, mClassName);
675        } catch (RemoteException e) {
676            assertTrue(false);
677        }
678        mAppIdValue = originalAppIdValue;
679        mContentTypeValue = originalContentTypeValue;
680    }
681
682    /**
683     * Updating invalid package test
684     */
685    public void testUpdatePackage2() {
686        int originalAppIdValue = mAppIdValue;
687        int originalContentTypeValue  = mContentTypeValue;
688
689        try {
690            // set up data
691            IWapPushManager iwapman = getInterface();
692
693            iwapman.addPackage(Integer.toString(mAppIdValue),
694                    Integer.toString(mContentTypeValue), mPackageName, mClassName,
695                    0, false, false);
696            assertFalse(iwapman.updatePackage(
697                    Integer.toString(mAppIdValue + 10),
698                    Integer.toString(mContentTypeValue),
699                    mPackageName, mClassName, 0, false, false));
700            assertFalse(iwapman.updatePackage(
701                    Integer.toString(mAppIdValue),
702                    Integer.toString(mContentTypeValue + 10),
703                    mPackageName, mClassName, 0, false, false));
704            assertTrue(iwapman.updatePackage(
705                    Integer.toString(mAppIdValue),
706                    Integer.toString(mContentTypeValue),
707                    mPackageName + "dummy_data", mClassName, 0, false, false));
708            assertTrue(iwapman.updatePackage(
709                    Integer.toString(mAppIdValue),
710                    Integer.toString(mContentTypeValue),
711                    mPackageName, mClassName + "dummy_data", 0, false, false));
712            // clean up data
713            iwapman.deletePackage(Integer.toString(mAppIdValue),
714                    Integer.toString(mContentTypeValue), mPackageName, mClassName);
715            iwapman.deletePackage(Integer.toString(mAppIdValue),
716                    Integer.toString(mContentTypeValue), mPackageName,
717                    mClassName + "dummy_data");
718        } catch (RemoteException e) {
719            assertTrue(false);
720        }
721    }
722
723    protected void utDeletePackage() {
724        IWapPushManager iwapman = getInterface();
725
726        try {
727            assertTrue(iwapman.deletePackage(
728                    Integer.toString(mAppIdValue),
729                    Integer.toString(mContentTypeValue),
730                    mPackageName, mClassName));
731        } catch (RemoteException e) {
732            assertTrue(false);
733        }
734
735        // verify the data
736        WapPushManager wpman = getService();
737        assertTrue(!wpman.isDataExist(
738                Integer.toString(mAppIdValue),
739                Integer.toString(mContentTypeValue),
740                mPackageName, mClassName));
741    }
742
743    /**
744     * Deleting package test
745     */
746    public void testDeletePackage1() {
747        int originalAppIdValue = mAppIdValue;
748        int originalContentTypeValue  = mContentTypeValue;
749
750        // set up data
751        try {
752            IWapPushManager iwapman = getInterface();
753
754            iwapman.addPackage(Integer.toString(mAppIdValue),
755                    Integer.toString(mContentTypeValue), mPackageName, mClassName,
756                    0, false, false);
757            mAppIdValue += 10;
758            iwapman.addPackage(Integer.toString(mAppIdValue),
759                    Integer.toString(mContentTypeValue), mPackageName, mClassName,
760                    0, false, false);
761            mContentTypeValue += 20;
762            iwapman.addPackage(Integer.toString(mAppIdValue),
763                    Integer.toString(mContentTypeValue), mPackageName, mClassName,
764                    0, false, false);
765            mContentTypeValue += 20;
766            iwapman.addPackage(Integer.toString(mAppIdValue),
767                    Integer.toString(mContentTypeValue), mPackageName, mClassName,
768                    0, false, false);
769        } catch (RemoteException e) {
770            assertTrue(false);
771        }
772
773        mAppIdValue = originalAppIdValue;
774        mContentTypeValue = originalContentTypeValue;
775        utDeletePackage();
776        mAppIdValue += 10;
777        utDeletePackage();
778        mContentTypeValue += 20;
779        utDeletePackage();
780        mContentTypeValue += 20;
781        utDeletePackage();
782
783        mAppIdValue = originalAppIdValue;
784        mContentTypeValue = originalContentTypeValue;
785    }
786
787    /**
788     * Deleting invalid package test
789     */
790    public void testDeletePackage2() {
791        int originalAppIdValue = mAppIdValue;
792        int originalContentTypeValue  = mContentTypeValue;
793
794        try {
795            // set up data
796            IWapPushManager iwapman = getInterface();
797
798            iwapman.addPackage(Integer.toString(mAppIdValue),
799                    Integer.toString(mContentTypeValue), mPackageName, mClassName,
800                    0, false, false);
801
802            assertFalse(iwapman.deletePackage(Integer.toString(mAppIdValue + 10),
803                    Integer.toString(mContentTypeValue), mPackageName, mClassName));
804            assertFalse(iwapman.deletePackage(Integer.toString(mAppIdValue),
805                    Integer.toString(mContentTypeValue + 20), mPackageName, mClassName));
806            assertFalse(iwapman.deletePackage(Integer.toString(mAppIdValue + 10),
807                    Integer.toString(mContentTypeValue + 20), mPackageName, mClassName));
808
809            iwapman.deletePackage(Integer.toString(mAppIdValue),
810                    Integer.toString(mContentTypeValue), mPackageName, mClassName);
811
812        } catch (RemoteException e) {
813            assertTrue(false);
814        }
815    }
816
817
818    protected int encodeUint32(int uint32Val, byte[] arr, int start) {
819        int bit = 1;
820        int topbit = 0;
821        int encodeLen;
822        int tmpVal;
823
824        assertTrue(uint32Val >= 0);
825        for (int i = 0; i < 31; i++) {
826            if ((bit & uint32Val) > 0) topbit = i;
827            bit = (bit << 1);
828        }
829        encodeLen = topbit/7 + 1;
830        if (arr == null) return encodeLen;
831
832        //Log.d(LOG_TAG, "uint32Val = " + Integer.toHexString(uint32Val) + ", topbit = "
833        //      + topbit + ", encodeLen = " + encodeLen);
834
835        tmpVal = uint32Val;
836        for (int i = encodeLen - 1; i >= 0; i--) {
837            long val = 0;
838            if (i < encodeLen - 1) val = 0x80;
839            val |= tmpVal & 0x7f;
840            arr[start + i] = (byte) (val & 0xFF);
841            tmpVal = (tmpVal >> 7);
842        }
843        return encodeLen;
844    }
845
846    protected int encodeShortInt(int sintVal, byte[] arr, int start) {
847        int encodeLen = 0;
848
849        if (sintVal >= 0x80) return encodeLen;
850        encodeLen = 1;
851        arr[start] = (byte) (sintVal | 0x80);
852        return encodeLen;
853    }
854
855
856    /**
857     * Generate Random WSP header with integer application ID
858     */
859    protected void createRandomWspHeader(byte[] arr, Random rd, int headerStart,
860            boolean noAppId) {
861
862        boolean appIdAdded = false;
863
864        Log.d(LOG_TAG, "headerStart = " + headerStart + ", appId = " + mAppIdValue
865                + "(" + Integer.toHexString(mAppIdValue) + ")");
866        Log.d(LOG_TAG, "random arr length:" + arr.length);
867        String typename[] = new String[] { "short int", "long int", "string", "uint32"};
868
869        while (!appIdAdded) {
870            int type;
871            int index = headerStart;
872            int len = arr.length;
873            int i;
874            boolean addAppid = false;
875            int tmpVal = 0;
876            int tmpVal2 = 0;
877
878            while (true) {
879                int add;
880
881                /*
882                 * field name
883                 * 0: short int
884                 * 1: long int
885                 * 2: text
886                 * (no uint for param value)
887                 */
888                type = rd.nextInt(3);
889                switch (type) {
890                case 0: // header short integer
891                    if (index > 100 && !appIdAdded) addAppid = true;
892                    add = 1;
893                    break;
894                case 1: // header long int
895                    add = 1 + rd.nextInt(29);
896                    break;
897                default: // header string
898                    add = 2 + rd.nextInt(10);
899                    break;
900                }
901                if (index + add >= len) break;
902
903                // fill header name
904                switch (type) {
905                case 0: // header short integer
906                    if (!addAppid) {
907                        do {
908                            arr[index] = (byte) (0x80 | rd.nextInt(128));
909                        } while (arr[index] == (byte) 0xaf);
910                    } else {
911                        Log.d(LOG_TAG, "appId added.");
912                        arr[index] = (byte) 0xaf;
913                        // if noAppId case, appId fld must be decieved.
914                        if (noAppId) arr[index]++;
915                    }
916                    break;
917                case 1: // header long int
918                    arr[index] = (byte) (add - 1);
919                    tmpVal2 = 0;
920                    for (i = 1; i < add; i++) {
921                        tmpVal = rd.nextInt(255);
922                        tmpVal2 = (tmpVal2 << 8) | tmpVal;
923                        arr[index + i] = (byte) tmpVal;
924                    }
925                    // don't set application id
926                    if (tmpVal2 == 0x2f) arr[index + 1]++;
927                    break;
928                default: // header string
929                    for (i = 0; i < add - 1; i++) {
930                        tmpVal = rd.nextInt(127);
931                        if (tmpVal < 32) tmpVal= (32 + tmpVal);
932                        arr[index + i] = (byte) tmpVal;
933                    }
934                    arr[index + i] = (byte) 0x0;
935                    break;
936                }
937
938                if (LOCAL_LOGV) {
939                    Log.d(LOG_TAG, "field name index:" + index);
940                    Log.d(LOG_TAG, "type:" + typename[type] + ", add:" + add);
941                    if (type != 2) {
942                        for (i = index; i< index + add; i++) {
943                            System.out.print(Integer.toHexString(0xff & arr[i]));
944                            System.out.print(' ');
945                        }
946                    } else {
947                        System.out.print(Integer.toHexString(0xff & arr[index]));
948                        System.out.print(' ');
949                        String str = new String(arr, index + 1, add - 2);
950                        for (i = 0; i < str.length(); i++) {
951                            System.out.print(str.charAt(i));
952                            System.out.print(' ');
953                        }
954                    }
955                    System.out.print('\n');
956                }
957                index += add;
958
959
960                /*
961                 * field value
962                 * 0: short int
963                 * 1: long int
964                 * 2: text
965                 * 3: uint
966                 */
967                if (addAppid) {
968                    type = 1;
969                } else {
970                    type = rd.nextInt(4);
971                }
972                switch (type) {
973                case 0: // header short integer
974                    add = 1;
975                    break;
976                case 1: // header long int
977                    if (addAppid) {
978                        int bit = 1;
979                        int topBit = 0;
980
981                        for (i = 0; i < 31; i++) {
982                            if ((mAppIdValue & bit) > 0) topBit = i;
983                            bit = (bit << 1);
984                        }
985                        add = 2 + topBit/8;
986                    } else {
987                        add = 1 + rd.nextInt(29);
988                    }
989                    break;
990                case 2: // header string
991                    add = 2 + rd.nextInt(10);
992                    break;
993                default: // uint32
994                    add = 6;
995                }
996                if (index + add >= len) break;
997
998                // fill field value
999                switch (type) {
1000                case 0: // header short int
1001                    arr[index] = (byte) (0x80 | rd.nextInt(128));
1002                    break;
1003                case 1: // header long int
1004                    if (addAppid) {
1005                        addAppid = false;
1006                        appIdAdded = true;
1007
1008                        arr[index] = (byte) (add - 1);
1009                        tmpVal = mAppIdValue;
1010                        for (i = add; i > 1; i--) {
1011                            arr[index + i - 1] = (byte) (tmpVal & 0xff);
1012                            tmpVal = (tmpVal >> 8);
1013                        }
1014                    } else {
1015                        arr[index] = (byte) (add - 1);
1016                        for (i = 1; i < add; i++) {
1017                            arr[index + i] = (byte) rd.nextInt(255);
1018                        }
1019                    }
1020                    break;
1021                case 2:// header string
1022                    for (i = 0; i < add - 1; i++) {
1023                        tmpVal = rd.nextInt(127);
1024                        if (tmpVal < 32) tmpVal= (32 + tmpVal);
1025                        arr[index + i] = (byte) tmpVal;
1026                    }
1027                    arr[index + i] = (byte) 0x0;
1028                    break;
1029                default: // header uvarint
1030                    arr[index] = (byte) 31;
1031                    tmpVal = rd.nextInt(0x0FFFFFFF);
1032                    add = 1 + encodeUint32(tmpVal, null, index + 1);
1033                    encodeUint32(tmpVal, arr, index + 1);
1034                    break;
1035
1036                }
1037
1038                if (LOCAL_LOGV) {
1039                    Log.d(LOG_TAG, "field value index:" + index);
1040                    Log.d(LOG_TAG, "type:" + typename[type] + ", add:" + add);
1041                    if (type != 2) {
1042                        for (i = index; i< index + add; i++) {
1043                            System.out.print(Integer.toHexString(0xff & arr[i]));
1044                            System.out.print(' ');
1045                        }
1046                    } else {
1047                        System.out.print(Integer.toHexString(0xff & arr[index]));
1048                        System.out.print(' ');
1049                        String str = new String(arr, index + 1, add - 2);
1050                        for (i = 0; i < str.length(); i++) {
1051                            System.out.print(str.charAt(i));
1052                            System.out.print(' ');
1053                        }
1054                    }
1055                    System.out.print('\n');
1056                }
1057                index += add;
1058            }
1059            if (noAppId) break;
1060        }
1061
1062        Log.d(LOG_TAG, HexDump.dumpHexString(arr));
1063    }
1064
1065    /**
1066     * Generate Random WSP header with string application ID
1067     */
1068    protected void createRandomWspHeaderStrAppId(byte[] arr, Random rd, int headerStart,
1069            boolean randomStr) {
1070
1071        boolean appIdAdded = false;
1072
1073        Log.d(LOG_TAG, "random arr length:" + arr.length);
1074        String typename[] = new String[] { "short int", "long int", "string", "uint32"};
1075
1076        while (!appIdAdded) {
1077            int type;
1078            int index = headerStart;
1079            int len = arr.length;
1080            int i;
1081            boolean addAppid = false;
1082            int tmpVal = 0;
1083            int tmpVal2 = 0;
1084
1085            while (true) {
1086                int add;
1087
1088                /*
1089                 * field name
1090                 * 0: short int
1091                 * 1: long int
1092                 * 2: text
1093                 * (no uint for param value)
1094                 */
1095                type = rd.nextInt(3);
1096                switch (type) {
1097                case 0: // header short integer
1098                    if (index > 100 && !appIdAdded) addAppid = true;
1099                    add = 1;
1100                    break;
1101                case 1: // header long int
1102                    add = 1 + rd.nextInt(29);
1103                    break;
1104                default: // header string
1105                    add = 2 + rd.nextInt(10);
1106                    break;
1107                }
1108                if (index + add >= len) break;
1109
1110                // fill header name
1111                switch (type) {
1112                case 0: // header short integer
1113                    if (!addAppid) {
1114                        do {
1115                            arr[index] = (byte) (0x80 | rd.nextInt(128));
1116                        } while (arr[index] == (byte) 0xaf);
1117                    } else {
1118                        Log.d(LOG_TAG, "appId added.");
1119                        arr[index] = (byte) 0xaf;
1120                    }
1121                    break;
1122                case 1: // header long int
1123                    arr[index] = (byte) (add - 1);
1124                    tmpVal2 = 0;
1125                    for (i = 1; i < add; i++) {
1126                        tmpVal = rd.nextInt(255);
1127                        tmpVal2 = (tmpVal2 << 8) | tmpVal;
1128                        arr[index + i] = (byte) tmpVal;
1129                    }
1130                    // don't set application id
1131                    if (tmpVal2 == 0x2f) arr[index + 1]++;
1132                    break;
1133                default: // header string
1134                    for (i = 0; i < add - 1; i++) {
1135                        tmpVal = rd.nextInt(127);
1136                        if (tmpVal < 32) tmpVal= (32 + tmpVal);
1137                        arr[index + i] = (byte) tmpVal;
1138                    }
1139                    arr[index + i] = (byte) 0x0;
1140                    break;
1141                }
1142
1143                if (LOCAL_LOGV) {
1144                    Log.d(LOG_TAG, "field name index:" + index);
1145                    Log.d(LOG_TAG, "type:" + typename[type] + ", add:" + add);
1146                    if (type != 2) {
1147                        for (i = index; i < index + add; i++) {
1148                            System.out.print(Integer.toHexString(0xff & arr[i]));
1149                            System.out.print(' ');
1150                        }
1151                    } else {
1152                        System.out.print(Integer.toHexString(0xff & arr[index]));
1153                        System.out.print(' ');
1154                        String str = new String(arr, index + 1, add - 2);
1155                        for (i = 0; i < str.length(); i++) {
1156                            System.out.print(str.charAt(i));
1157                            System.out.print(' ');
1158                        }
1159                    }
1160                    System.out.print('\n');
1161                }
1162                index += add;
1163
1164
1165                /*
1166                 * field value
1167                 * 0: short int
1168                 * 1: long int
1169                 * 2: text
1170                 * 3: uint
1171                 */
1172                if (addAppid) {
1173                    type = 2;
1174                } else {
1175                    type = rd.nextInt(4);
1176                }
1177                switch (type) {
1178                case 0: // header short integer
1179                    add = 1;
1180                    break;
1181                case 1: // header long int
1182                    add = 1 + rd.nextInt(29);
1183                    break;
1184                case 2: // header string
1185                    if (addAppid) {
1186                        if (randomStr) {
1187                            add = 1 + rd.nextInt(10);
1188                            byte[] randStr= new byte[add];
1189                            for (i = 0; i < add; i++) {
1190                                tmpVal = rd.nextInt(127);
1191                                if (tmpVal < 32) tmpVal= (32 + tmpVal);
1192                                randStr[i] = (byte) tmpVal;
1193                            }
1194                            mAppIdName = new String(randStr);
1195                        }
1196                        add = mAppIdName.length() + 1;
1197                    } else {
1198                        add = 2 + rd.nextInt(10);
1199                    }
1200                    break;
1201                default: // uint32
1202                    add = 6;
1203                }
1204                if (index + add >= len) break;
1205
1206                // fill field value
1207                switch (type) {
1208                case 0: // header short int
1209                    arr[index] = (byte) (0x80 | rd.nextInt(128));
1210                    break;
1211                case 1: // header long int
1212                    arr[index] = (byte) (add - 1);
1213                    for (i = 1; i < add; i++)
1214                        arr[index + i] = (byte) rd.nextInt(255);
1215                    break;
1216                case 2:// header string
1217                    if (addAppid) {
1218                        addAppid = false;
1219                        appIdAdded = true;
1220                        for (i = 0; i < add - 1; i++) {
1221                            arr[index + i] = (byte) (mAppIdName.charAt(i));
1222                        }
1223                        Log.d(LOG_TAG, "mAppIdName added [" + mAppIdName + "]");
1224                    } else {
1225                        for (i = 0; i < add - 1; i++) {
1226                            tmpVal = rd.nextInt(127);
1227                            if (tmpVal < 32) tmpVal= (32 + tmpVal);
1228                            arr[index + i] = (byte) tmpVal;
1229                        }
1230                    }
1231                    arr[index + i] = (byte) 0x0;
1232                    break;
1233                default: // header uvarint
1234                    arr[index] = (byte) 31;
1235                    tmpVal = rd.nextInt(0x0FFFFFFF);
1236                    add = 1 + encodeUint32(tmpVal, null, index + 1);
1237                    encodeUint32(tmpVal, arr, index + 1);
1238                    break;
1239
1240                }
1241
1242                if (LOCAL_LOGV) {
1243                    Log.d(LOG_TAG, "field value index:" + index);
1244                    Log.d(LOG_TAG, "type:" + typename[type] + ", add:" + add);
1245                    if (type != 2) {
1246                        for (i = index; i < index + add; i++) {
1247                            System.out.print(Integer.toHexString(0xff & arr[i]));
1248                            System.out.print(' ');
1249                        }
1250                    } else {
1251                        System.out.print(Integer.toHexString(0xff & arr[index]));
1252                        System.out.print(' ');
1253                        String str = new String(arr, index + 1, add - 2);
1254                        for (i = 0; i < str.length(); i++) {
1255                            System.out.print(str.charAt(i));
1256                            System.out.print(' ');
1257                        }
1258                    }
1259                    System.out.print('\n');
1260                }
1261                index += add;
1262            }
1263        }
1264
1265        Log.d(LOG_TAG, "headerStart = " + headerStart + ", mAppIdName = " + mAppIdName);
1266        Log.d(LOG_TAG, HexDump.dumpHexString(arr));
1267    }
1268
1269    protected byte[] createPDU(int testNum) {
1270        byte[] array = null;
1271        // byte[] wsp = null;
1272
1273        switch (testNum) {
1274            // sample pdu
1275        case 1:
1276            byte[] array1 = {
1277                    (byte) 0x00, // TID
1278                    (byte) 0x06, // Type = wap push
1279                    (byte) 0x00, // Length to be set later.
1280
1281                    // Content-Type
1282                    (byte) 0x03, (byte) 0x02,
1283                    (byte) ((mContentTypeValue >> 8) & 0xff),
1284                    (byte) (mContentTypeValue & 0xff),
1285
1286                    // Application-id
1287                    (byte) 0xaf, (byte) 0x02,
1288                    (byte) ((mAppIdValue >> 8) & 0xff),
1289                    (byte) (mAppIdValue& 0xff)
1290            };
1291            array1[2] = (byte) (array1.length - 3);
1292            mWspHeader = array1;
1293            mWspHeaderStart = mGsmHeader.length + mUserDataHeader.length + 7;
1294            mWspHeaderLen = array1.length;
1295            break;
1296
1297            // invalid wsp header
1298        case 2:
1299            byte[] array2 = {
1300                    (byte) 0x00, // invalid data
1301            };
1302            mWspHeader = array2;
1303            mWspHeaderStart = mGsmHeader.length + mUserDataHeader.length;
1304            mWspHeaderLen = array2.length;
1305            break;
1306
1307            // random wsp header
1308        case 3:
1309            Random rd = new Random();
1310            int arrSize = 150 + rd.nextInt(100);
1311            byte[] array3 = new byte[arrSize];
1312            int hdrEncodeLen;
1313
1314            array3[0] = (byte) 0x0;
1315            array3[1] = (byte) 0x6;
1316            hdrEncodeLen = encodeUint32(array3.length, null, 2);
1317            hdrEncodeLen = encodeUint32(array3.length - hdrEncodeLen - 2, array3, 2);
1318            array3[hdrEncodeLen + 2] = (byte) 0x3;
1319            array3[hdrEncodeLen + 3] = (byte) 0x2;
1320            array3[hdrEncodeLen + 4] = (byte) ((mContentTypeValue >> 8) & 0xff);
1321            array3[hdrEncodeLen + 5] = (byte) (mContentTypeValue & 0xff);
1322            createRandomWspHeader(array3, rd, hdrEncodeLen + 6, false);
1323            mWspHeaderStart = mGsmHeader.length + mUserDataHeader.length + hdrEncodeLen + 6;
1324            mWspHeaderLen = array3.length;
1325
1326            Log.d(LOG_TAG, "mContentTypeValue = " + mContentTypeValue
1327                    + "(" + Integer.toHexString(mContentTypeValue) + ")");
1328
1329            mWspHeader = array3;
1330            break;
1331
1332            // random wsp header w/o appid
1333        case 4:
1334            rd = new Random();
1335            arrSize = 150 + rd.nextInt(100);
1336            array3 = new byte[arrSize];
1337
1338            array3[0] = (byte) 0x0;
1339            array3[1] = (byte) 0x6;
1340            hdrEncodeLen = encodeUint32(array3.length, null, 2);
1341            hdrEncodeLen = encodeUint32(array3.length - hdrEncodeLen - 2, array3, 2);
1342            array3[hdrEncodeLen + 2] = (byte) 0x3;
1343            array3[hdrEncodeLen + 3] = (byte) 0x2;
1344            array3[hdrEncodeLen + 4] = (byte) ((mContentTypeValue >> 8) & 0xff);
1345            array3[hdrEncodeLen + 5] = (byte) (mContentTypeValue & 0xff);
1346            createRandomWspHeader(array3, rd, hdrEncodeLen + 6, true);
1347            mWspHeaderStart = mGsmHeader.length + mUserDataHeader.length + hdrEncodeLen + 6;
1348            mWspHeaderLen = array3.length;
1349
1350            Log.d(LOG_TAG, "mContentTypeValue = " + mContentTypeValue
1351                    + "(" + Integer.toHexString(mContentTypeValue) + ")");
1352
1353            mWspHeader = array3;
1354            break;
1355
1356            // random wsp header w/ random appid string
1357        case 5:
1358            rd = new Random();
1359            arrSize = 150 + rd.nextInt(100);
1360            array3 = new byte[arrSize];
1361
1362            array3[0] = (byte) 0x0;
1363            array3[1] = (byte) 0x6;
1364            hdrEncodeLen = encodeUint32(array3.length, null, 2);
1365            hdrEncodeLen = encodeUint32(array3.length - hdrEncodeLen - 2, array3, 2);
1366            array3[hdrEncodeLen + 2] = (byte) 0x3;
1367            array3[hdrEncodeLen + 3] = (byte) 0x2;
1368            array3[hdrEncodeLen + 4] = (byte) ((mContentTypeValue >> 8) & 0xff);
1369            array3[hdrEncodeLen + 5] = (byte) (mContentTypeValue & 0xff);
1370            createRandomWspHeaderStrAppId(array3, rd, hdrEncodeLen + 6, true);
1371            mWspHeaderStart = mGsmHeader.length + mUserDataHeader.length + hdrEncodeLen + 6;
1372            mWspHeaderLen = array3.length;
1373
1374            Log.d(LOG_TAG, "mContentTypeValue = " + mContentTypeValue
1375                    + "(" + Integer.toHexString(mContentTypeValue) + ")");
1376
1377            mWspHeader = array3;
1378            break;
1379
1380            // random wsp header w/ OMA appid string
1381        case 6:
1382            rd = new Random();
1383            arrSize = 150 + rd.nextInt(100);
1384            array3 = new byte[arrSize];
1385
1386            array3[0] = (byte) 0x0;
1387            array3[1] = (byte) 0x6;
1388            hdrEncodeLen = encodeUint32(array3.length, null, 2);
1389            hdrEncodeLen = encodeUint32(array3.length - hdrEncodeLen - 2, array3, 2);
1390            array3[hdrEncodeLen + 2] = (byte) 0x3;
1391            array3[hdrEncodeLen + 3] = (byte) 0x2;
1392            array3[hdrEncodeLen + 4] = (byte) ((mContentTypeValue >> 8) & 0xff);
1393            array3[hdrEncodeLen + 5] = (byte) (mContentTypeValue & 0xff);
1394            createRandomWspHeaderStrAppId(array3, rd, hdrEncodeLen + 6, false);
1395            mWspHeaderStart = mGsmHeader.length + mUserDataHeader.length + hdrEncodeLen + 6;
1396            mWspHeaderLen = array3.length;
1397
1398            Log.d(LOG_TAG, "mContentTypeValue = " + mContentTypeValue
1399                    + "(" + Integer.toHexString(mContentTypeValue) + ")");
1400
1401            mWspHeader = array3;
1402            break;
1403
1404            // random wsp header w/ OMA content type
1405        case 7:
1406            rd = new Random();
1407            arrSize = 150 + rd.nextInt(100);
1408            array3 = new byte[arrSize];
1409
1410            array3[0] = (byte) 0x0;
1411            array3[1] = (byte) 0x6;
1412            hdrEncodeLen = encodeUint32(array3.length, null, 2);
1413            hdrEncodeLen = encodeUint32(array3.length - hdrEncodeLen - 2, array3, 2);
1414
1415            // encode content type
1416            int contentLen = mContentTypeName.length();
1417            int next = 2 + hdrEncodeLen;
1418            mWspContentTypeStart = mGsmHeader.length + mUserDataHeader.length + next;
1419            // next += encodeUint32(contentLen, array3, next);
1420            int i;
1421            Log.d(LOG_TAG, "mContentTypeName = " + mContentTypeName
1422                    + ", contentLen = " + contentLen);
1423
1424            for (i = 0; i < contentLen; i++) {
1425                array3[next + i] = (byte) mContentTypeName.charAt(i);
1426            }
1427            array3[next + i] = (byte) 0x0;
1428
1429            createRandomWspHeader(array3, rd, next + contentLen + 1, false);
1430            mWspHeaderStart = mGsmHeader.length + mUserDataHeader.length
1431                    + next + contentLen + 1;
1432            mWspHeaderLen = array3.length;
1433
1434            mWspHeader = array3;
1435            break;
1436
1437            // random wsp header w/ OMA content type, OMA app ID
1438        case 8:
1439            rd = new Random();
1440            arrSize = 150 + rd.nextInt(100);
1441            array3 = new byte[arrSize];
1442
1443            array3[0] = (byte) 0x0;
1444            array3[1] = (byte) 0x6;
1445            hdrEncodeLen = encodeUint32(array3.length, null, 2);
1446            hdrEncodeLen = encodeUint32(array3.length - hdrEncodeLen - 2, array3, 2);
1447
1448            // encode content type
1449            contentLen = mContentTypeName.length();
1450            next = 2 + hdrEncodeLen;
1451            mWspContentTypeStart = mGsmHeader.length + mUserDataHeader.length + next;
1452            // next += encodeUint32(contentLen, array3, next);
1453            Log.d(LOG_TAG, "mContentTypeName = " + mContentTypeName
1454                    + ", contentLen = " + contentLen);
1455
1456            for (i = 0; i < contentLen; i++) {
1457                array3[next + i] = (byte) mContentTypeName.charAt(i);
1458            }
1459            array3[next + i] = (byte) 0x0;
1460
1461            createRandomWspHeaderStrAppId(array3, rd, next + contentLen + 1, false);
1462            mWspHeaderStart = mGsmHeader.length + mUserDataHeader.length
1463                    + next + contentLen + 1;
1464            mWspHeaderLen = array3.length;
1465
1466            mWspHeader = array3;
1467            break;
1468
1469        default:
1470            return null;
1471        }
1472        array = new byte[mGsmHeader.length + mUserDataHeader.length + mWspHeader.length
1473                + mMessageBody.length];
1474        System.arraycopy(mGsmHeader, 0, array, 0, mGsmHeader.length);
1475        System.arraycopy(mUserDataHeader, 0, array,
1476                mGsmHeader.length, mUserDataHeader.length);
1477        System.arraycopy(mWspHeader, 0, array,
1478                mGsmHeader.length + mUserDataHeader.length, mWspHeader.length);
1479        System.arraycopy(mMessageBody, 0, array,
1480                mGsmHeader.length + mUserDataHeader.length + mWspHeader.length,
1481                mMessageBody.length);
1482        return array;
1483
1484    }
1485
1486    Intent createIntent(int pduType, int tranId) {
1487        Intent intent = new Intent();
1488        intent.putExtra("transactionId", tranId);
1489        intent.putExtra("pduType", pduType);
1490        intent.putExtra("header", mGsmHeader);
1491        intent.putExtra("data", mMessageBody);
1492        // intent.putExtra("contentTypeParameters", null);
1493        return intent;
1494    }
1495
1496    /**
1497     * Message processing test, start activity
1498     */
1499    public void testProcessMsg1() {
1500        byte[] pdu = createPDU(1);
1501        int headerLen = pdu.length -
1502                (mGsmHeader.length + mUserDataHeader.length + mMessageBody.length);
1503        int pduType = 6;
1504        int tranId = 0;
1505        String originalPackageName = mPackageName;
1506        String originalClassName = mClassName;
1507
1508        try {
1509
1510            mClassName = "com.android.smspush.unitTests.ReceiverActivity";
1511
1512            // set up data
1513            IWapPushManager iwapman = getInterface();
1514            iwapman.addPackage(Integer.toString(mAppIdValue),
1515                    Integer.toString(mContentTypeValue), mPackageName, mClassName,
1516                    WapPushManagerParams.APP_TYPE_ACTIVITY, false, false);
1517
1518            assertTrue((iwapman.processMessage(
1519                    Integer.toString(mAppIdValue),
1520                    Integer.toString(mContentTypeValue),
1521                    createIntent(pduType, tranId))
1522                    & WapPushManagerParams.MESSAGE_HANDLED) ==
1523                    WapPushManagerParams.MESSAGE_HANDLED);
1524
1525            // clean up data
1526            iwapman.deletePackage(Integer.toString(mAppIdValue),
1527                    Integer.toString(mContentTypeValue), mPackageName, mClassName);
1528
1529        } catch (RemoteException e) {
1530            assertTrue(false);
1531        }
1532
1533        mPackageName = originalPackageName;
1534        mClassName = originalClassName;
1535    }
1536
1537    /**
1538     * Message processing test, start service
1539     */
1540    public void testProcessMsg2() {
1541        byte[] pdu = createPDU(1);
1542        int headerLen = pdu.length - (mGsmHeader.length +
1543                mUserDataHeader.length + mMessageBody.length);
1544        int pduType = 6;
1545        int tranId = 0;
1546        String originalPackageName = mPackageName;
1547        String originalClassName = mClassName;
1548
1549        try {
1550
1551            mClassName = "com.android.smspush.unitTests.ReceiverService";
1552
1553            // set up data
1554            IWapPushManager iwapman = getInterface();
1555
1556            iwapman.addPackage(Integer.toString(mAppIdValue),
1557                    Integer.toString(mContentTypeValue), mPackageName, mClassName,
1558                    WapPushManagerParams.APP_TYPE_SERVICE, false, false);
1559
1560            assertTrue((iwapman.processMessage(
1561                    Integer.toString(mAppIdValue),
1562                    Integer.toString(mContentTypeValue),
1563                    createIntent(pduType, tranId))
1564                    & WapPushManagerParams.MESSAGE_HANDLED) ==
1565                    WapPushManagerParams.MESSAGE_HANDLED);
1566
1567            // clean up data
1568            iwapman.deletePackage(Integer.toString(mAppIdValue),
1569                    Integer.toString(mContentTypeValue), mPackageName, mClassName);
1570
1571        } catch (RemoteException e) {
1572            assertTrue(false);
1573        }
1574
1575        mPackageName = originalPackageName;
1576        mClassName = originalClassName;
1577    }
1578
1579    /**
1580     * Message processing test, no signature
1581     */
1582    public void testProcessMsg3() {
1583        byte[] pdu = createPDU(1);
1584        int headerLen = pdu.length -
1585                (mGsmHeader.length + mUserDataHeader.length + mMessageBody.length);
1586        int pduType = 6;
1587        int tranId = 0;
1588        String originalPackageName = mPackageName;
1589        String originalClassName = mClassName;
1590
1591        try {
1592
1593            mPackageName = "com.android.development";
1594            mClassName = "com.android.development.Development";
1595
1596            // set up data
1597            IWapPushManager iwapman = getInterface();
1598
1599            iwapman.addPackage(Integer.toString(mAppIdValue),
1600                    Integer.toString(mContentTypeValue), mPackageName, mClassName,
1601                    WapPushManagerParams.APP_TYPE_SERVICE, true, false);
1602
1603            assertFalse((iwapman.processMessage(
1604                    Integer.toString(mAppIdValue),
1605                    Integer.toString(mContentTypeValue),
1606                    createIntent(pduType, tranId))
1607                    & WapPushManagerParams.MESSAGE_HANDLED) ==
1608                    WapPushManagerParams.MESSAGE_HANDLED);
1609
1610            // clean up data
1611            iwapman.deletePackage(Integer.toString(mAppIdValue),
1612                    Integer.toString(mContentTypeValue), mPackageName, mClassName);
1613
1614        } catch (RemoteException e) {
1615            assertTrue(false);
1616        }
1617
1618        mPackageName = originalPackageName;
1619        mClassName = originalClassName;
1620    }
1621
1622    IDataVerify getVerifyInterface() {
1623        while (mIVerify == null) {
1624            // wait for the activity receive data.
1625            try {
1626                Thread.sleep(TIME_WAIT);
1627            } catch (InterruptedException e) {}
1628        }
1629        return mIVerify;
1630    }
1631
1632
1633    /**
1634     * Message processing test, received body data verification test
1635     */
1636    public void testProcessMsg4() {
1637        byte[] originalMessageBody = mMessageBody;
1638        mMessageBody = new byte[] {
1639                (byte) 0xee,
1640                (byte) 0xff,
1641                (byte) 0xee,
1642                (byte) 0xff,
1643                (byte) 0xee,
1644                (byte) 0xff,
1645                (byte) 0xee,
1646                (byte) 0xff,
1647                (byte) 0xee,
1648                (byte) 0xff,
1649                (byte) 0xee,
1650                (byte) 0xff,
1651        };
1652
1653        byte[] pdu = createPDU(1);
1654        int headerLen = pdu.length -
1655                (mGsmHeader.length + mUserDataHeader.length + mMessageBody.length);
1656        int pduType = 6;
1657        int tranId = 0;
1658        String originalPackageName = mPackageName;
1659        String originalClassName = mClassName;
1660
1661        try {
1662            IWapPushManager iwapman = getInterface();
1663            IDataVerify dataverify = getVerifyInterface();
1664
1665            dataverify.resetData();
1666
1667            // set up data
1668            mClassName = "com.android.smspush.unitTests.ReceiverActivity";
1669            iwapman.addPackage(Integer.toString(mAppIdValue),
1670                    Integer.toString(mContentTypeValue), mPackageName, mClassName,
1671                    WapPushManagerParams.APP_TYPE_ACTIVITY, false, false);
1672
1673            iwapman.processMessage(
1674                    Integer.toString(mAppIdValue),
1675                    Integer.toString(mContentTypeValue),
1676                    createIntent(pduType, tranId));
1677
1678            // clean up data
1679            iwapman.deletePackage(Integer.toString(mAppIdValue),
1680                    Integer.toString(mContentTypeValue), mPackageName, mClassName);
1681
1682            assertTrue(dataverify.verifyData(mMessageBody));
1683
1684            // set up data
1685            dataverify.resetData();
1686            mClassName = "com.android.smspush.unitTests.ReceiverService";
1687            mMessageBody = new byte[] {
1688                    (byte) 0xaa,
1689                    (byte) 0xbb,
1690                    (byte) 0x11,
1691                    (byte) 0x22,
1692                    (byte) 0xaa,
1693                    (byte) 0xbb,
1694                    (byte) 0x11,
1695                    (byte) 0x22,
1696                    (byte) 0xaa,
1697                    (byte) 0xbb,
1698                    (byte) 0x11,
1699                    (byte) 0x22,
1700                    (byte) 0xaa,
1701                    (byte) 0xbb,
1702                    (byte) 0x11,
1703                    (byte) 0x22,
1704                    (byte) 0xaa,
1705                    (byte) 0xbb,
1706                    (byte) 0x11,
1707                    (byte) 0x22,
1708                    (byte) 0xaa,
1709                    (byte) 0xbb,
1710                    (byte) 0x11,
1711                    (byte) 0x22,
1712            };
1713            pdu = createPDU(1);
1714            iwapman.addPackage(Integer.toString(mAppIdValue),
1715                    Integer.toString(mContentTypeValue), mPackageName, mClassName,
1716                    WapPushManagerParams.APP_TYPE_SERVICE, false, false);
1717
1718            iwapman.processMessage(
1719                    Integer.toString(mAppIdValue),
1720                    Integer.toString(mContentTypeValue),
1721                    createIntent(pduType, tranId));
1722
1723            // clean up data
1724            iwapman.deletePackage(Integer.toString(mAppIdValue),
1725                    Integer.toString(mContentTypeValue), mPackageName, mClassName);
1726
1727            // Log.d(LOG_TAG, HexDump.dumpHexString(mMessageBody));
1728            assertTrue(dataverify.verifyData(mMessageBody));
1729        } catch (RemoteException e) {
1730            assertTrue(false);
1731        }
1732
1733        mPackageName = originalPackageName;
1734        mClassName = originalClassName;
1735        mMessageBody = originalMessageBody;
1736    }
1737
1738    /**
1739     * Message processing test, send invalid sms data
1740     */
1741    public void testProcessMsg5() {
1742        byte[] pdu = createPDU(2);
1743        int headerLen = pdu.length -
1744                (mGsmHeader.length + mUserDataHeader.length + mMessageBody.length);
1745        int pduType = 6;
1746        int tranId = 0;
1747        String originalPackageName = mPackageName;
1748        String originalClassName = mClassName;
1749
1750        try {
1751
1752            mClassName = "com.android.smspush.unitTests.ReceiverActivity";
1753
1754            // set up data
1755            IWapPushManager iwapman = getInterface();
1756            iwapman.addPackage(Integer.toString(mAppIdValue),
1757                    Integer.toString(mContentTypeValue), mPackageName, mClassName,
1758                    WapPushManagerParams.APP_TYPE_ACTIVITY, false, false);
1759
1760            assertTrue((iwapman.processMessage(
1761                    Integer.toString(mAppIdValue),
1762                    Integer.toString(mContentTypeValue),
1763                    createIntent(pduType, tranId))
1764                    & WapPushManagerParams.MESSAGE_HANDLED) ==
1765                    WapPushManagerParams.MESSAGE_HANDLED);
1766
1767            // clean up data
1768            iwapman.deletePackage(Integer.toString(mAppIdValue),
1769                    Integer.toString(mContentTypeValue), mPackageName, mClassName);
1770
1771        } catch (RemoteException e) {
1772            assertTrue(false);
1773        }
1774
1775        mPackageName = originalPackageName;
1776        mClassName = originalClassName;
1777    }
1778
1779    /**
1780     * Message processing test, no receiver application
1781     */
1782    public void testProcessMsg6() {
1783        byte[] pdu = createPDU(1);
1784        int headerLen = pdu.length -
1785                (mGsmHeader.length + mUserDataHeader.length + mMessageBody.length);
1786        int pduType = 6;
1787        int tranId = 0;
1788        String originalPackageName = mPackageName;
1789        String originalClassName = mClassName;
1790
1791        try {
1792
1793            mClassName = "com.android.smspush.unitTests.NoReceiver";
1794
1795            // set up data
1796            IWapPushManager iwapman = getInterface();
1797            iwapman.addPackage(Integer.toString(mAppIdValue),
1798                    Integer.toString(mContentTypeValue), mPackageName, mClassName,
1799                    WapPushManagerParams.APP_TYPE_ACTIVITY, false, false);
1800
1801            assertFalse((iwapman.processMessage(
1802                    Integer.toString(mAppIdValue),
1803                    Integer.toString(mContentTypeValue),
1804                    createIntent(pduType, tranId))
1805                    & WapPushManagerParams.MESSAGE_HANDLED) ==
1806                    WapPushManagerParams.MESSAGE_HANDLED);
1807
1808            // clean up data
1809            iwapman.deletePackage(Integer.toString(mAppIdValue),
1810                    Integer.toString(mContentTypeValue), mPackageName, mClassName);
1811
1812            // set up data
1813            iwapman.addPackage(Integer.toString(mAppIdValue),
1814                    Integer.toString(mContentTypeValue), mPackageName, mClassName,
1815                    WapPushManagerParams.APP_TYPE_SERVICE, false, false);
1816
1817            assertFalse((iwapman.processMessage(
1818                    Integer.toString(mAppIdValue),
1819                    Integer.toString(mContentTypeValue),
1820                    createIntent(pduType, tranId))
1821                    & WapPushManagerParams.MESSAGE_HANDLED) ==
1822                    WapPushManagerParams.MESSAGE_HANDLED);
1823
1824            // clean up data
1825            iwapman.deletePackage(Integer.toString(mAppIdValue),
1826                    Integer.toString(mContentTypeValue), mPackageName, mClassName);
1827
1828        } catch (RemoteException e) {
1829            assertTrue(false);
1830        }
1831
1832        mPackageName = originalPackageName;
1833        mClassName = originalClassName;
1834    }
1835
1836    /**
1837     * WspTypeDecoder test, normal pdu
1838     */
1839    public void testDecoder1() {
1840        boolean res;
1841        int originalAppIdValue = mAppIdValue;
1842        Random rd = new Random();
1843
1844        for (int i = 0; i < 10; i++) {
1845            mAppIdValue = rd.nextInt(0xFFFF);
1846            byte[] pdu = createPDU(1);
1847            WspTypeDecoder pduDecoder = new WspTypeDecoder(pdu);
1848
1849            res = pduDecoder.seekXWapApplicationId(mWspHeaderStart,
1850                    mWspHeaderStart + mWspHeaderLen - 1);
1851            assertTrue(res);
1852
1853            int index = (int) pduDecoder.getValue32();
1854            res = pduDecoder.decodeXWapApplicationId(index);
1855            assertTrue(res);
1856
1857            Log.d(LOG_TAG, "mAppIdValue: " + mAppIdValue
1858                    + ", val: " + pduDecoder.getValue32());
1859            assertTrue(mAppIdValue == (int) pduDecoder.getValue32());
1860        }
1861
1862        mAppIdValue = originalAppIdValue;
1863    }
1864
1865    /**
1866     * WspTypeDecoder test, no header
1867     */
1868    public void testDecoder2() {
1869        boolean res;
1870        int originalAppIdValue = mAppIdValue;
1871        Random rd = new Random();
1872
1873        mAppIdValue = rd.nextInt(0xFFFF);
1874        byte[] pdu = createPDU(2);
1875        WspTypeDecoder pduDecoder = new WspTypeDecoder(pdu);
1876
1877        res = pduDecoder.seekXWapApplicationId(mWspHeaderStart,
1878                mWspHeaderStart + mWspHeaderLen - 1);
1879        assertFalse(res);
1880
1881        mAppIdValue = originalAppIdValue;
1882    }
1883
1884    /**
1885     * WspTypeDecoder test, decode appid test
1886     */
1887    public void testDecoder3() {
1888        boolean res;
1889        int originalAppIdValue = mAppIdValue;
1890        int originalContentTypeValue  = mContentTypeValue;
1891        Random rd = new Random();
1892
1893        for (int i = 0; i < 100; i++) {
1894            mAppIdValue = rd.nextInt(0x0FFFFFFF);
1895            mContentTypeValue = rd.nextInt(0x0FFF);
1896            byte[] pdu = createPDU(3);
1897            WspTypeDecoder pduDecoder = new WspTypeDecoder(pdu);
1898
1899            res = pduDecoder.seekXWapApplicationId(mWspHeaderStart,
1900                    mWspHeaderStart + mWspHeaderLen - 1);
1901            assertTrue(res);
1902
1903            int index = (int) pduDecoder.getValue32();
1904            res = pduDecoder.decodeXWapApplicationId(index);
1905            assertTrue(res);
1906
1907            Log.d(LOG_TAG, "mAppIdValue: " + mAppIdValue
1908                    + ", val: " + pduDecoder.getValue32());
1909            assertTrue(mAppIdValue == (int) pduDecoder.getValue32());
1910        }
1911
1912        mAppIdValue = originalAppIdValue;
1913        mContentTypeValue = originalContentTypeValue;
1914    }
1915
1916    /*
1917      public void testEnc() {
1918      byte[] arr = new byte[20];
1919      int index = 0;
1920      index += encodeUint32(0x87a5, arr, index);
1921      index += encodeUint32(0x1, arr, index);
1922      index += encodeUint32(0x9b, arr, index);
1923      index += encodeUint32(0x10, arr, index);
1924      index += encodeUint32(0xe0887, arr, index);
1925      index += encodeUint32(0x791a23d0, arr, index);
1926
1927      Log.d(LOG_TAG, HexDump.dumpHexString(arr));
1928      }
1929    */
1930
1931    /**
1932     * WspTypeDecoder test, no appid test
1933     */
1934    public void testDecoder4() {
1935        boolean res;
1936        int originalAppIdValue = mAppIdValue;
1937        int originalContentTypeValue  = mContentTypeValue;
1938        Random rd = new Random();
1939
1940        for (int i = 0; i < 100; i++) {
1941            mAppIdValue = rd.nextInt(0x0FFFFFFF);
1942            mContentTypeValue = rd.nextInt(0x0FFF);
1943            byte[] pdu = createPDU(4);
1944            WspTypeDecoder pduDecoder = new WspTypeDecoder(pdu);
1945
1946            res = pduDecoder.seekXWapApplicationId(mWspHeaderStart,
1947                    mWspHeaderStart + mWspHeaderLen - 1);
1948            assertFalse(res);
1949
1950        }
1951
1952        mAppIdValue = originalAppIdValue;
1953        mContentTypeValue = originalContentTypeValue;
1954    }
1955
1956    /**
1957     * WspTypeDecoder test, decode string appid test
1958     */
1959    public void testDecoder5() {
1960        boolean res;
1961        String originalAppIdName = mAppIdName;
1962        int originalContentTypeValue  = mContentTypeValue;
1963        Random rd = new Random();
1964
1965        for (int i = 0; i < 10; i++) {
1966            mAppIdValue = rd.nextInt(0x0FFFFFFF);
1967            mContentTypeValue = rd.nextInt(0x0FFF);
1968            byte[] pdu = createPDU(5);
1969            WspTypeDecoder pduDecoder = new WspTypeDecoder(pdu);
1970
1971            res = pduDecoder.seekXWapApplicationId(mWspHeaderStart,
1972                    mWspHeaderStart + mWspHeaderLen - 1);
1973            assertTrue(res);
1974
1975            int index = (int) pduDecoder.getValue32();
1976            res = pduDecoder.decodeXWapApplicationId(index);
1977            assertTrue(res);
1978
1979            Log.d(LOG_TAG, "mAppIdValue: [" + mAppIdName + "], val: ["
1980                    + pduDecoder.getValueString() + "]");
1981            assertTrue(mAppIdName.equals(pduDecoder.getValueString()));
1982        }
1983
1984        mAppIdName = originalAppIdName;
1985        mContentTypeValue = originalContentTypeValue;
1986    }
1987
1988    /**
1989     * WspTypeDecoder test, decode string appid test
1990     */
1991    public void testDecoder6() {
1992        boolean res;
1993        String originalAppIdName = mAppIdName;
1994        int originalContentTypeValue  = mContentTypeValue;
1995        Random rd = new Random();
1996
1997        for (int i = 0; i < OMA_APPLICATION_ID_NAMES.length; i++) {
1998            mAppIdName = OMA_APPLICATION_ID_NAMES[i];
1999            mContentTypeValue = rd.nextInt(0x0FFF);
2000            byte[] pdu = createPDU(6);
2001            WspTypeDecoder pduDecoder = new WspTypeDecoder(pdu);
2002
2003            res = pduDecoder.seekXWapApplicationId(mWspHeaderStart,
2004                    mWspHeaderStart + mWspHeaderLen - 1);
2005            assertTrue(res);
2006
2007            int index = (int) pduDecoder.getValue32();
2008            res = pduDecoder.decodeXWapApplicationId(index);
2009            assertTrue(res);
2010
2011            Log.d(LOG_TAG, "mAppIdValue: [" + mAppIdName + "], val: ["
2012                    + pduDecoder.getValueString() + "]");
2013            assertTrue(mAppIdName.equals(pduDecoder.getValueString()));
2014        }
2015
2016        mAppIdName = originalAppIdName;
2017        mContentTypeValue = originalContentTypeValue;
2018    }
2019
2020    /**
2021     * WspTypeDecoder test, decode OMA content type
2022     */
2023    public void testDecoder7() {
2024        boolean res;
2025        String originalAppIdName = mAppIdName;
2026        int originalContentTypeValue  = mContentTypeValue;
2027        Random rd = new Random();
2028
2029        for (int i = 0; i < OMA_CONTENT_TYPE_NAMES.length; i++) {
2030            mContentTypeName = OMA_CONTENT_TYPE_NAMES[i];
2031            byte[] pdu = createPDU(7);
2032            WspTypeDecoder pduDecoder = new WspTypeDecoder(pdu);
2033
2034            res = pduDecoder.decodeContentType(mWspContentTypeStart);
2035            assertTrue(res);
2036
2037            Log.d(LOG_TAG, "mContentTypeName: [" + mContentTypeName + "], val: ["
2038                    + pduDecoder.getValueString() + "]");
2039            assertTrue(mContentTypeName.equals(pduDecoder.getValueString()));
2040        }
2041
2042        mAppIdName = originalAppIdName;
2043        mContentTypeValue = originalContentTypeValue;
2044    }
2045
2046
2047    /**
2048     * Copied from WapPushOverSms.
2049     * The code flow is not changed from the original.
2050     */
2051    public int dispatchWapPdu(byte[] pdu, IWapPushManager wapPushMan) {
2052
2053        if (false) Log.d(LOG_TAG, "Rx: " + IccUtils.bytesToHexString(pdu));
2054
2055        int index = 0;
2056        int transactionId = pdu[index++] & 0xFF;
2057        int pduType = pdu[index++] & 0xFF;
2058        int headerLength = 0;
2059
2060        if ((pduType != WspTypeDecoder.PDU_TYPE_PUSH) &&
2061                (pduType != WspTypeDecoder.PDU_TYPE_CONFIRMED_PUSH)) {
2062            if (false) Log.w(LOG_TAG, "Received non-PUSH WAP PDU. Type = " + pduType);
2063            return Intents.RESULT_SMS_HANDLED;
2064        }
2065
2066        WspTypeDecoder pduDecoder = new WspTypeDecoder(pdu);
2067
2068        /**
2069         * Parse HeaderLen(unsigned integer).
2070         * From wap-230-wsp-20010705-a section 8.1.2
2071         * The maximum size of a uintvar is 32 bits.
2072         * So it will be encoded in no more than 5 octets.
2073         */
2074        if (pduDecoder.decodeUintvarInteger(index) == false) {
2075            if (false) Log.w(LOG_TAG, "Received PDU. Header Length error.");
2076            return Intents.RESULT_SMS_GENERIC_ERROR;
2077        }
2078        headerLength = (int) pduDecoder.getValue32();
2079        index += pduDecoder.getDecodedDataLength();
2080
2081        int headerStartIndex = index;
2082
2083        /**
2084         * Parse Content-Type.
2085         * From wap-230-wsp-20010705-a section 8.4.2.24
2086         *
2087         * Content-type-value = Constrained-media | Content-general-form
2088         * Content-general-form = Value-length Media-type
2089         * Media-type = (Well-known-media | Extension-Media) *(Parameter)
2090         * Value-length = Short-length | (Length-quote Length)
2091         * Short-length = <Any octet 0-30>   (octet <= WAP_PDU_SHORT_LENGTH_MAX)
2092         * Length-quote = <Octet 31>         (WAP_PDU_LENGTH_QUOTE)
2093         * Length = Uintvar-integer
2094         */
2095        if (pduDecoder.decodeContentType(index) == false) {
2096            if (false) Log.w(LOG_TAG, "Received PDU. Header Content-Type error.");
2097            return Intents.RESULT_SMS_GENERIC_ERROR;
2098        }
2099
2100        String mimeType = pduDecoder.getValueString();
2101        long binaryContentType = pduDecoder.getValue32();
2102        index += pduDecoder.getDecodedDataLength();
2103
2104        byte[] header = new byte[headerLength];
2105        System.arraycopy(pdu, headerStartIndex, header, 0, header.length);
2106
2107        byte[] intentData;
2108
2109        if (mimeType != null && mimeType.equals(WspTypeDecoder.CONTENT_TYPE_B_PUSH_CO)) {
2110            intentData = pdu;
2111        } else {
2112            int dataIndex = headerStartIndex + headerLength;
2113            intentData = new byte[pdu.length - dataIndex];
2114            System.arraycopy(pdu, dataIndex, intentData, 0, intentData.length);
2115        }
2116
2117        /**
2118         * Seek for application ID field in WSP header.
2119         * If application ID is found, WapPushManager substitute the message
2120         * processing. Since WapPushManager is optional module, if WapPushManager
2121         * is not found, legacy message processing will be continued.
2122         */
2123        if (pduDecoder.seekXWapApplicationId(index, index + headerLength - 1)) {
2124            index = (int) pduDecoder.getValue32();
2125            pduDecoder.decodeXWapApplicationId(index);
2126            String wapAppId = pduDecoder.getValueString();
2127            if (wapAppId == null) {
2128                wapAppId = Integer.toString((int) pduDecoder.getValue32());
2129            }
2130
2131            String contentType = ((mimeType == null) ?
2132                    Long.toString(binaryContentType) : mimeType);
2133            if (false) Log.v(LOG_TAG, "appid found: " + wapAppId + ":" + contentType);
2134
2135            try {
2136                boolean processFurther = true;
2137                // IWapPushManager wapPushMan = mWapConn.getWapPushManager();
2138                if (wapPushMan == null) {
2139                    if (false) Log.w(LOG_TAG, "wap push manager not found!");
2140                } else {
2141                    Intent intent = new Intent();
2142                    intent.putExtra("transactionId", transactionId);
2143                    intent.putExtra("pduType", pduType);
2144                    intent.putExtra("header", header);
2145                    intent.putExtra("data", intentData);
2146                    intent.putExtra("contentTypeParameters",
2147                            pduDecoder.getContentParameters());
2148
2149                    int procRet = wapPushMan.processMessage(wapAppId, contentType, intent);
2150                    if (false) Log.v(LOG_TAG, "procRet:" + procRet);
2151                    if ((procRet & WapPushManagerParams.MESSAGE_HANDLED) > 0
2152                            && (procRet & WapPushManagerParams.FURTHER_PROCESSING) == 0) {
2153                        processFurther = false;
2154                    }
2155                }
2156                if (!processFurther) {
2157                    return Intents.RESULT_SMS_HANDLED;
2158                }
2159            } catch (RemoteException e) {
2160                if (false) Log.w(LOG_TAG, "remote func failed...");
2161            }
2162        }
2163        if (false) Log.v(LOG_TAG, "fall back to existing handler");
2164
2165        return Activity.RESULT_OK;
2166    }
2167
2168    protected byte[] retrieveWspBody() {
2169        byte[] array = new byte[mWspHeader.length + mMessageBody.length];
2170
2171        System.arraycopy(mWspHeader, 0, array, 0, mWspHeader.length);
2172        System.arraycopy(mMessageBody, 0, array, mWspHeader.length, mMessageBody.length);
2173        return array;
2174    }
2175
2176    protected String getContentTypeName(int ctypeVal) {
2177        int i;
2178
2179        for (i = 0; i < OMA_CONTENT_TYPE_VALUES.length; i++) {
2180            if (ctypeVal == OMA_CONTENT_TYPE_VALUES[i]) {
2181                return OMA_CONTENT_TYPE_NAMES[i];
2182            }
2183        }
2184        return null;
2185    }
2186
2187    protected boolean isContentTypeMapped(int ctypeVal) {
2188        int i;
2189
2190        for (i = 0; i < OMA_CONTENT_TYPE_VALUES.length; i++) {
2191            if (ctypeVal == OMA_CONTENT_TYPE_VALUES[i]) return true;
2192        }
2193        return false;
2194    }
2195
2196    /**
2197     * Integration test 1, simple case
2198     */
2199    public void testIntegration1() {
2200        boolean res;
2201        int originalAppIdValue = mAppIdValue;
2202        int originalContentTypeValue  = mContentTypeValue;
2203        String originalAppIdName = mAppIdName;
2204        String originalContentTypeName = mContentTypeName;
2205        String originalClassName = mClassName;
2206        byte[] originalMessageBody = mMessageBody;
2207        Random rd = new Random();
2208
2209        mMessageBody = new byte[100 + rd.nextInt(100)];
2210        rd.nextBytes(mMessageBody);
2211
2212        byte[] pdu = createPDU(1);
2213        byte[] wappushPdu = retrieveWspBody();
2214
2215
2216        mClassName = "com.android.smspush.unitTests.ReceiverActivity";
2217        // Phone dummy = new DummyPhone(getContext());
2218        // Phone gsm = PhoneFactory.getGsmPhone();
2219        // GSMPhone gsm = new GSMPhone(getContext(), new SimulatedCommands(), null, true);
2220        // WapPushOverSms dispatcher = new WapPushOverSms(dummy, null);
2221
2222        try {
2223            // set up data
2224            IWapPushManager iwapman = getInterface();
2225            IDataVerify dataverify = getVerifyInterface();
2226
2227            dataverify.resetData();
2228
2229            if (isContentTypeMapped(mContentTypeValue)) {
2230                // content type is mapped
2231                mContentTypeName = getContentTypeName(mContentTypeValue);
2232                Log.d(LOG_TAG, "mContentTypeValue mapping "
2233                        + mContentTypeName + ":" + mContentTypeValue);
2234            } else {
2235                mContentTypeName = Integer.toString(mContentTypeValue);
2236            }
2237            iwapman.addPackage(Integer.toString(mAppIdValue),
2238                    mContentTypeName, mPackageName, mClassName,
2239                    WapPushManagerParams.APP_TYPE_ACTIVITY, false, false);
2240
2241            dispatchWapPdu(wappushPdu, iwapman);
2242
2243            // clean up data
2244            iwapman.deletePackage(Integer.toString(mAppIdValue),
2245                    mContentTypeName, mPackageName, mClassName);
2246
2247            assertTrue(dataverify.verifyData(mMessageBody));
2248        } catch (RemoteException e) {
2249        }
2250
2251
2252        mClassName = originalClassName;
2253        mAppIdName = originalAppIdName;
2254        mContentTypeName = originalContentTypeName;
2255        mAppIdValue = originalAppIdValue;
2256        mContentTypeValue = originalContentTypeValue;
2257        mMessageBody = originalMessageBody;
2258    }
2259
2260    /**
2261     * Integration test 2, random mAppIdValue(int), all OMA content type
2262     */
2263    public void testIntegration2() {
2264        boolean res;
2265        int originalAppIdValue = mAppIdValue;
2266        int originalContentTypeValue  = mContentTypeValue;
2267        String originalAppIdName = mAppIdName;
2268        String originalContentTypeName = mContentTypeName;
2269        String originalClassName = mClassName;
2270        byte[] originalMessageBody = mMessageBody;
2271        Random rd = new Random();
2272
2273        IWapPushManager iwapman = getInterface();
2274        IDataVerify dataverify = getVerifyInterface();
2275        mClassName = "com.android.smspush.unitTests.ReceiverActivity";
2276
2277        for (int i = 0; i < OMA_CONTENT_TYPE_NAMES.length; i++) {
2278            mContentTypeName = OMA_CONTENT_TYPE_NAMES[i];
2279            mAppIdValue = rd.nextInt(0x0FFFFFFF);
2280
2281            mMessageBody = new byte[100 + rd.nextInt(100)];
2282            rd.nextBytes(mMessageBody);
2283
2284            byte[] pdu = createPDU(7);
2285            byte[] wappushPdu = retrieveWspBody();
2286
2287            try {
2288                dataverify.resetData();
2289                // set up data
2290                iwapman.addPackage(Integer.toString(mAppIdValue),
2291                        mContentTypeName, mPackageName, mClassName,
2292                        WapPushManagerParams.APP_TYPE_ACTIVITY, false, false);
2293
2294                dispatchWapPdu(wappushPdu, iwapman);
2295
2296                // clean up data
2297                iwapman.deletePackage(Integer.toString(mAppIdValue),
2298                        mContentTypeName, mPackageName, mClassName);
2299
2300                if (mContentTypeName.equals(WspTypeDecoder.CONTENT_TYPE_B_PUSH_CO)) {
2301                    assertTrue(dataverify.verifyData(wappushPdu));
2302                } else {
2303                    assertTrue(dataverify.verifyData(mMessageBody));
2304                }
2305            } catch (RemoteException e) {
2306            }
2307        }
2308
2309
2310        mClassName = originalClassName;
2311        mAppIdName = originalAppIdName;
2312        mContentTypeName = originalContentTypeName;
2313        mAppIdValue = originalAppIdValue;
2314        mContentTypeValue = originalContentTypeValue;
2315        mMessageBody = originalMessageBody;
2316    }
2317
2318    /**
2319     * Integration test 3, iterate OmaApplication ID, random binary content type
2320     */
2321    public void testIntegration3() {
2322        boolean res;
2323        int originalAppIdValue = mAppIdValue;
2324        int originalContentTypeValue  = mContentTypeValue;
2325        String originalAppIdName = mAppIdName;
2326        String originalContentTypeName = mContentTypeName;
2327        String originalClassName = mClassName;
2328        byte[] originalMessageBody = mMessageBody;
2329        Random rd = new Random();
2330
2331        IWapPushManager iwapman = getInterface();
2332        IDataVerify dataverify = getVerifyInterface();
2333        mClassName = "com.android.smspush.unitTests.ReceiverService";
2334
2335        for (int i = 0; i < OMA_APPLICATION_ID_NAMES.length; i++) {
2336            mAppIdName = OMA_APPLICATION_ID_NAMES[i];
2337            mContentTypeValue = rd.nextInt(0x0FFF);
2338
2339            mMessageBody = new byte[100 + rd.nextInt(100)];
2340            rd.nextBytes(mMessageBody);
2341
2342            byte[] pdu = createPDU(6);
2343            byte[] wappushPdu = retrieveWspBody();
2344
2345            try {
2346                dataverify.resetData();
2347                // set up data
2348                if (isContentTypeMapped(mContentTypeValue)) {
2349                    // content type is mapped to integer value
2350                    mContentTypeName = getContentTypeName(mContentTypeValue);
2351                    Log.d(LOG_TAG, "mContentTypeValue mapping "
2352                            + mContentTypeValue + ":" + mContentTypeName);
2353                } else {
2354                    mContentTypeName = Integer.toString(mContentTypeValue);
2355                }
2356
2357                iwapman.addPackage(mAppIdName,
2358                        mContentTypeName, mPackageName, mClassName,
2359                        WapPushManagerParams.APP_TYPE_SERVICE, false, false);
2360
2361                dispatchWapPdu(wappushPdu, iwapman);
2362
2363                // clean up data
2364                iwapman.deletePackage(mAppIdName,
2365                        mContentTypeName, mPackageName, mClassName);
2366
2367                if (mContentTypeName.equals(WspTypeDecoder.CONTENT_TYPE_B_PUSH_CO)) {
2368                    assertTrue(dataverify.verifyData(wappushPdu));
2369                } else {
2370                    assertTrue(dataverify.verifyData(mMessageBody));
2371                }
2372            } catch (RemoteException e) {
2373            }
2374        }
2375
2376        mClassName = originalClassName;
2377        mAppIdName = originalAppIdName;
2378        mContentTypeName = originalContentTypeName;
2379        mAppIdValue = originalAppIdValue;
2380        mContentTypeValue = originalContentTypeValue;
2381        mMessageBody = originalMessageBody;
2382    }
2383
2384    /**
2385     * Integration test 4, iterate OmaApplication ID, Oma content type
2386     */
2387    public void testIntegration4() {
2388        boolean res;
2389        int originalAppIdValue = mAppIdValue;
2390        int originalContentTypeValue  = mContentTypeValue;
2391        String originalAppIdName = mAppIdName;
2392        String originalContentTypeName = mContentTypeName;
2393        String originalClassName = mClassName;
2394        byte[] originalMessageBody = mMessageBody;
2395        Random rd = new Random();
2396
2397        IWapPushManager iwapman = getInterface();
2398        IDataVerify dataverify = getVerifyInterface();
2399        mClassName = "com.android.smspush.unitTests.ReceiverService";
2400
2401        for (int i = 0; i < OMA_APPLICATION_ID_NAMES.length
2402                + OMA_CONTENT_TYPE_NAMES.length; i++) {
2403            mAppIdName = OMA_APPLICATION_ID_NAMES[rd.nextInt(OMA_APPLICATION_ID_NAMES.length)];
2404            int contIndex = rd.nextInt(OMA_CONTENT_TYPE_NAMES.length);
2405            mContentTypeName = OMA_CONTENT_TYPE_NAMES[contIndex];
2406
2407            mMessageBody = new byte[100 + rd.nextInt(100)];
2408            rd.nextBytes(mMessageBody);
2409
2410            byte[] pdu = createPDU(8);
2411            byte[] wappushPdu = retrieveWspBody();
2412
2413            try {
2414                dataverify.resetData();
2415                // set up data
2416                iwapman.addPackage(mAppIdName,
2417                        mContentTypeName, mPackageName, mClassName,
2418                        WapPushManagerParams.APP_TYPE_SERVICE, false, false);
2419
2420                dispatchWapPdu(wappushPdu, iwapman);
2421
2422                // clean up data
2423                iwapman.deletePackage(mAppIdName,
2424                        mContentTypeName, mPackageName, mClassName);
2425
2426                if (mContentTypeName.equals(WspTypeDecoder.CONTENT_TYPE_B_PUSH_CO)) {
2427                    assertTrue(dataverify.verifyData(wappushPdu));
2428                } else {
2429                    assertTrue(dataverify.verifyData(mMessageBody));
2430                }
2431            } catch (RemoteException e) {
2432            }
2433        }
2434
2435        mClassName = originalClassName;
2436        mAppIdName = originalAppIdName;
2437        mContentTypeName = originalContentTypeName;
2438        mAppIdValue = originalAppIdValue;
2439        mContentTypeValue = originalContentTypeValue;
2440        mMessageBody = originalMessageBody;
2441    }
2442
2443    /**
2444     * Integration test 5, iterate binary OmaApplication ID, Oma binary content type
2445     */
2446    public void testIntegration5() {
2447        boolean res;
2448        int originalAppIdValue = mAppIdValue;
2449        int originalContentTypeValue  = mContentTypeValue;
2450        String originalAppIdName = mAppIdName;
2451        String originalContentTypeName = mContentTypeName;
2452        String originalClassName = mClassName;
2453        byte[] originalMessageBody = mMessageBody;
2454        Random rd = new Random();
2455
2456        IWapPushManager iwapman = getInterface();
2457        IDataVerify dataverify = getVerifyInterface();
2458        mClassName = "com.android.smspush.unitTests.ReceiverService";
2459
2460        for (int i = 0; i < OMA_APPLICATION_ID_VALUES.length +
2461                    OMA_CONTENT_TYPE_VALUES.length; i++) {
2462            mAppIdValue = OMA_APPLICATION_ID_VALUES[rd.nextInt(
2463                    OMA_APPLICATION_ID_VALUES.length)];
2464            mContentTypeValue =
2465                    OMA_CONTENT_TYPE_VALUES[rd.nextInt(OMA_CONTENT_TYPE_VALUES.length)];
2466
2467            mMessageBody = new byte[100 + rd.nextInt(100)];
2468            rd.nextBytes(mMessageBody);
2469
2470            byte[] pdu = createPDU(3);
2471            byte[] wappushPdu = retrieveWspBody();
2472
2473            try {
2474                dataverify.resetData();
2475                // set up data
2476                if (isContentTypeMapped(mContentTypeValue)) {
2477                    // content type is mapped to integer value
2478                    mContentTypeName = getContentTypeName(mContentTypeValue);
2479                    Log.d(LOG_TAG, "mContentTypeValue mapping "
2480                            + mContentTypeValue + ":" + mContentTypeName);
2481                } else {
2482                    mContentTypeName = Integer.toString(mContentTypeValue);
2483                }
2484
2485                iwapman.addPackage(Integer.toString(mAppIdValue),
2486                        mContentTypeName, mPackageName, mClassName,
2487                        WapPushManagerParams.APP_TYPE_SERVICE, false, false);
2488
2489                dispatchWapPdu(wappushPdu, iwapman);
2490
2491                // clean up data
2492                iwapman.deletePackage(Integer.toString(mAppIdValue),
2493                        mContentTypeName, mPackageName, mClassName);
2494
2495                if (mContentTypeName.equals(WspTypeDecoder.CONTENT_TYPE_B_PUSH_CO)) {
2496                    assertTrue(dataverify.verifyData(wappushPdu));
2497                } else {
2498                    assertTrue(dataverify.verifyData(mMessageBody));
2499                }
2500            } catch (RemoteException e) {
2501            }
2502        }
2503
2504        mClassName = originalClassName;
2505        mAppIdName = originalAppIdName;
2506        mContentTypeName = originalContentTypeName;
2507        mAppIdValue = originalAppIdValue;
2508        mContentTypeValue = originalContentTypeValue;
2509        mMessageBody = originalMessageBody;
2510    }
2511
2512}
2513