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.IWapPushManager;
31import com.android.internal.telephony.WapPushManagerParams;
32import com.android.internal.telephony.WspTypeDecoder;
33import com.android.internal.telephony.uicc.IccUtils;
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 sqlite injection test
556     */
557    public void testAddPackage0() {
558        String inject = "' union select 0,'com.android.settings','com.android.settings.Settings',0,0,0--";
559
560        // insert new data
561        IWapPushManager iwapman = getInterface();
562        try {
563            assertFalse(iwapman.addPackage(
564                    inject,
565                    Integer.toString(mContentTypeValue),
566                    mPackageName, mClassName,
567                    WapPushManagerParams.APP_TYPE_SERVICE, true, true));
568        } catch (RemoteException e) {
569            assertTrue(false);
570        }
571    }
572
573    /**
574     * Add duprecated package test.
575     */
576    public void testAddPackage2() {
577        try {
578            IWapPushManager iwapman = getInterface();
579
580            // set up data
581            iwapman.addPackage(Integer.toString(mAppIdValue),
582                    Integer.toString(mContentTypeValue), mPackageName, mClassName, 0,
583                    false, false);
584            iwapman.addPackage(Integer.toString(mAppIdValue + 10),
585                    Integer.toString(mContentTypeValue), mPackageName, mClassName, 0,
586                    false, false);
587            iwapman.addPackage(Integer.toString(mAppIdValue),
588                    Integer.toString(mContentTypeValue + 10), mPackageName, mClassName, 0,
589                    false, false);
590
591            assertFalse(iwapman.addPackage(Integer.toString(mAppIdValue),
592                    Integer.toString(mContentTypeValue), mPackageName, mClassName, 0,
593                    false, false));
594            assertFalse(iwapman.addPackage(Integer.toString(mAppIdValue + 10),
595                    Integer.toString(mContentTypeValue), mPackageName, mClassName, 0,
596                    false, false));
597            assertFalse(iwapman.addPackage(Integer.toString(mAppIdValue),
598                    Integer.toString(mContentTypeValue + 10), mPackageName, mClassName, 0,
599                    false, false));
600
601            // clean up data
602            iwapman.deletePackage(Integer.toString(mAppIdValue),
603                    Integer.toString(mContentTypeValue), mPackageName, mClassName);
604            iwapman.deletePackage(Integer.toString(mAppIdValue + 10),
605                    Integer.toString(mContentTypeValue), mPackageName, mClassName);
606            iwapman.deletePackage(Integer.toString(mAppIdValue),
607                    Integer.toString(mContentTypeValue + 10), mPackageName, mClassName);
608        } catch (RemoteException e) {
609            assertTrue(false);
610        }
611    }
612
613    protected void utUpdatePackage(boolean need_sig, boolean more_proc) {
614        IWapPushManager iwapman = getInterface();
615
616        // insert new data
617        try {
618            assertTrue(iwapman.updatePackage(
619                    Integer.toString(mAppIdValue),
620                    Integer.toString(mContentTypeValue),
621                    mPackageName, mClassName,
622                    WapPushManagerParams.APP_TYPE_SERVICE, need_sig, more_proc));
623        } catch (RemoteException e) {
624            assertTrue(false);
625        }
626
627        // verify the data
628        WapPushManager wpman = getService();
629        assertTrue(wpman.verifyData(
630                Integer.toString(mAppIdValue),
631                Integer.toString(mContentTypeValue),
632                mPackageName, mClassName,
633                WapPushManagerParams.APP_TYPE_SERVICE, need_sig, more_proc));
634    }
635
636    /**
637     * Updating package test
638     */
639    public void testUpdatePackage1() {
640        int originalAppIdValue = mAppIdValue;
641        int originalContentTypeValue  = mContentTypeValue;
642
643        // set up data
644        try {
645            IWapPushManager iwapman = getInterface();
646
647            iwapman.addPackage(Integer.toString(mAppIdValue),
648                    Integer.toString(mContentTypeValue), mPackageName, mClassName,
649                    0, false, false);
650            mAppIdValue += 10;
651            iwapman.addPackage(Integer.toString(mAppIdValue),
652                    Integer.toString(mContentTypeValue), mPackageName, mClassName,
653                    0, false, false);
654            mContentTypeValue += 20;
655            iwapman.addPackage(Integer.toString(mAppIdValue),
656                    Integer.toString(mContentTypeValue), mPackageName, mClassName,
657                    0, false, false);
658            mContentTypeValue += 20;
659            iwapman.addPackage(Integer.toString(mAppIdValue),
660                    Integer.toString(mContentTypeValue), mPackageName, mClassName,
661                    0, false, false);
662        } catch (RemoteException e) {
663            assertTrue(false);
664        }
665
666        mAppIdValue = originalAppIdValue;
667        mContentTypeValue = originalContentTypeValue;
668        utUpdatePackage(false, false);
669        mAppIdValue += 10;
670        utUpdatePackage(false, true);
671        mContentTypeValue += 20;
672        utUpdatePackage(true, false);
673        mContentTypeValue += 20;
674        utUpdatePackage(true, true);
675
676        mAppIdValue = originalAppIdValue;
677        mContentTypeValue = originalContentTypeValue;
678
679        // clean up data
680        try {
681            IWapPushManager iwapman = getInterface();
682
683            iwapman.deletePackage(Integer.toString(mAppIdValue),
684                    Integer.toString(mContentTypeValue), mPackageName, mClassName);
685            mAppIdValue += 10;
686            iwapman.deletePackage(Integer.toString(mAppIdValue),
687                    Integer.toString(mContentTypeValue), mPackageName, mClassName);
688            mContentTypeValue += 20;
689            iwapman.deletePackage(Integer.toString(mAppIdValue),
690                    Integer.toString(mContentTypeValue), mPackageName, mClassName);
691            mContentTypeValue += 20;
692            iwapman.deletePackage(Integer.toString(mAppIdValue),
693                    Integer.toString(mContentTypeValue), mPackageName, mClassName);
694        } catch (RemoteException e) {
695            assertTrue(false);
696        }
697        mAppIdValue = originalAppIdValue;
698        mContentTypeValue = originalContentTypeValue;
699    }
700
701    /**
702     * Updating invalid package test
703     */
704    public void testUpdatePackage2() {
705        int originalAppIdValue = mAppIdValue;
706        int originalContentTypeValue  = mContentTypeValue;
707
708        try {
709            // set up data
710            IWapPushManager iwapman = getInterface();
711
712            iwapman.addPackage(Integer.toString(mAppIdValue),
713                    Integer.toString(mContentTypeValue), mPackageName, mClassName,
714                    0, false, false);
715            assertFalse(iwapman.updatePackage(
716                    Integer.toString(mAppIdValue + 10),
717                    Integer.toString(mContentTypeValue),
718                    mPackageName, mClassName, 0, false, false));
719            assertFalse(iwapman.updatePackage(
720                    Integer.toString(mAppIdValue),
721                    Integer.toString(mContentTypeValue + 10),
722                    mPackageName, mClassName, 0, false, false));
723            assertTrue(iwapman.updatePackage(
724                    Integer.toString(mAppIdValue),
725                    Integer.toString(mContentTypeValue),
726                    mPackageName + "dummy_data", mClassName, 0, false, false));
727            assertTrue(iwapman.updatePackage(
728                    Integer.toString(mAppIdValue),
729                    Integer.toString(mContentTypeValue),
730                    mPackageName, mClassName + "dummy_data", 0, false, false));
731            // clean up data
732            iwapman.deletePackage(Integer.toString(mAppIdValue),
733                    Integer.toString(mContentTypeValue), mPackageName, mClassName);
734            iwapman.deletePackage(Integer.toString(mAppIdValue),
735                    Integer.toString(mContentTypeValue), mPackageName,
736                    mClassName + "dummy_data");
737        } catch (RemoteException e) {
738            assertTrue(false);
739        }
740    }
741
742    protected void utDeletePackage() {
743        IWapPushManager iwapman = getInterface();
744
745        try {
746            assertTrue(iwapman.deletePackage(
747                    Integer.toString(mAppIdValue),
748                    Integer.toString(mContentTypeValue),
749                    mPackageName, mClassName));
750        } catch (RemoteException e) {
751            assertTrue(false);
752        }
753
754        // verify the data
755        WapPushManager wpman = getService();
756        assertTrue(!wpman.isDataExist(
757                Integer.toString(mAppIdValue),
758                Integer.toString(mContentTypeValue),
759                mPackageName, mClassName));
760    }
761
762    /**
763     * Deleting package test
764     */
765    public void testDeletePackage1() {
766        int originalAppIdValue = mAppIdValue;
767        int originalContentTypeValue  = mContentTypeValue;
768
769        // set up data
770        try {
771            IWapPushManager iwapman = getInterface();
772
773            iwapman.addPackage(Integer.toString(mAppIdValue),
774                    Integer.toString(mContentTypeValue), mPackageName, mClassName,
775                    0, false, false);
776            mAppIdValue += 10;
777            iwapman.addPackage(Integer.toString(mAppIdValue),
778                    Integer.toString(mContentTypeValue), mPackageName, mClassName,
779                    0, false, false);
780            mContentTypeValue += 20;
781            iwapman.addPackage(Integer.toString(mAppIdValue),
782                    Integer.toString(mContentTypeValue), mPackageName, mClassName,
783                    0, false, false);
784            mContentTypeValue += 20;
785            iwapman.addPackage(Integer.toString(mAppIdValue),
786                    Integer.toString(mContentTypeValue), mPackageName, mClassName,
787                    0, false, false);
788        } catch (RemoteException e) {
789            assertTrue(false);
790        }
791
792        mAppIdValue = originalAppIdValue;
793        mContentTypeValue = originalContentTypeValue;
794        utDeletePackage();
795        mAppIdValue += 10;
796        utDeletePackage();
797        mContentTypeValue += 20;
798        utDeletePackage();
799        mContentTypeValue += 20;
800        utDeletePackage();
801
802        mAppIdValue = originalAppIdValue;
803        mContentTypeValue = originalContentTypeValue;
804    }
805
806    /**
807     * Deleting invalid package test
808     */
809    public void testDeletePackage2() {
810        int originalAppIdValue = mAppIdValue;
811        int originalContentTypeValue  = mContentTypeValue;
812
813        try {
814            // set up data
815            IWapPushManager iwapman = getInterface();
816
817            iwapman.addPackage(Integer.toString(mAppIdValue),
818                    Integer.toString(mContentTypeValue), mPackageName, mClassName,
819                    0, false, false);
820
821            assertFalse(iwapman.deletePackage(Integer.toString(mAppIdValue + 10),
822                    Integer.toString(mContentTypeValue), mPackageName, mClassName));
823            assertFalse(iwapman.deletePackage(Integer.toString(mAppIdValue),
824                    Integer.toString(mContentTypeValue + 20), mPackageName, mClassName));
825            assertFalse(iwapman.deletePackage(Integer.toString(mAppIdValue + 10),
826                    Integer.toString(mContentTypeValue + 20), mPackageName, mClassName));
827
828            iwapman.deletePackage(Integer.toString(mAppIdValue),
829                    Integer.toString(mContentTypeValue), mPackageName, mClassName);
830
831        } catch (RemoteException e) {
832            assertTrue(false);
833        }
834    }
835
836
837    protected int encodeUint32(int uint32Val, byte[] arr, int start) {
838        int bit = 1;
839        int topbit = 0;
840        int encodeLen;
841        int tmpVal;
842
843        assertTrue(uint32Val >= 0);
844        for (int i = 0; i < 31; i++) {
845            if ((bit & uint32Val) > 0) topbit = i;
846            bit = (bit << 1);
847        }
848        encodeLen = topbit/7 + 1;
849        if (arr == null) return encodeLen;
850
851        //Log.d(LOG_TAG, "uint32Val = " + Integer.toHexString(uint32Val) + ", topbit = "
852        //      + topbit + ", encodeLen = " + encodeLen);
853
854        tmpVal = uint32Val;
855        for (int i = encodeLen - 1; i >= 0; i--) {
856            long val = 0;
857            if (i < encodeLen - 1) val = 0x80;
858            val |= tmpVal & 0x7f;
859            arr[start + i] = (byte) (val & 0xFF);
860            tmpVal = (tmpVal >> 7);
861        }
862        return encodeLen;
863    }
864
865    protected int encodeShortInt(int sintVal, byte[] arr, int start) {
866        int encodeLen = 0;
867
868        if (sintVal >= 0x80) return encodeLen;
869        encodeLen = 1;
870        arr[start] = (byte) (sintVal | 0x80);
871        return encodeLen;
872    }
873
874
875    /**
876     * Generate Random WSP header with integer application ID
877     */
878    protected void createRandomWspHeader(byte[] arr, Random rd, int headerStart,
879            boolean noAppId) {
880
881        boolean appIdAdded = false;
882
883        Log.d(LOG_TAG, "headerStart = " + headerStart + ", appId = " + mAppIdValue
884                + "(" + Integer.toHexString(mAppIdValue) + ")");
885        Log.d(LOG_TAG, "random arr length:" + arr.length);
886        String typename[] = new String[] { "short int", "long int", "string", "uint32"};
887
888        while (!appIdAdded) {
889            int type;
890            int index = headerStart;
891            int len = arr.length;
892            int i;
893            boolean addAppid = false;
894            int tmpVal = 0;
895            int tmpVal2 = 0;
896
897            while (true) {
898                int add;
899
900                /*
901                 * field name
902                 * 0: short int
903                 * 1: long int
904                 * 2: text
905                 * (no uint for param value)
906                 */
907                type = rd.nextInt(3);
908                switch (type) {
909                case 0: // header short integer
910                    if (index > 100 && !appIdAdded) addAppid = true;
911                    add = 1;
912                    break;
913                case 1: // header long int
914                    add = 1 + rd.nextInt(29);
915                    break;
916                default: // header string
917                    add = 2 + rd.nextInt(10);
918                    break;
919                }
920                if (index + add >= len) break;
921
922                // fill header name
923                switch (type) {
924                case 0: // header short integer
925                    if (!addAppid) {
926                        do {
927                            arr[index] = (byte) (0x80 | rd.nextInt(128));
928                        } while (arr[index] == (byte) 0xaf);
929                    } else {
930                        Log.d(LOG_TAG, "appId added.");
931                        arr[index] = (byte) 0xaf;
932                        // if noAppId case, appId fld must be decieved.
933                        if (noAppId) arr[index]++;
934                    }
935                    break;
936                case 1: // header long int
937                    arr[index] = (byte) (add - 1);
938                    tmpVal2 = 0;
939                    for (i = 1; i < add; i++) {
940                        tmpVal = rd.nextInt(255);
941                        tmpVal2 = (tmpVal2 << 8) | tmpVal;
942                        arr[index + i] = (byte) tmpVal;
943                    }
944                    // don't set application id
945                    if (tmpVal2 == 0x2f) arr[index + 1]++;
946                    break;
947                default: // header string
948                    for (i = 0; i < add - 1; i++) {
949                        tmpVal = rd.nextInt(127);
950                        if (tmpVal < 32) tmpVal= (32 + tmpVal);
951                        arr[index + i] = (byte) tmpVal;
952                    }
953                    arr[index + i] = (byte) 0x0;
954                    break;
955                }
956
957                if (LOCAL_LOGV) {
958                    Log.d(LOG_TAG, "field name index:" + index);
959                    Log.d(LOG_TAG, "type:" + typename[type] + ", add:" + add);
960                    if (type != 2) {
961                        for (i = index; i< index + add; i++) {
962                            System.out.print(Integer.toHexString(0xff & arr[i]));
963                            System.out.print(' ');
964                        }
965                    } else {
966                        System.out.print(Integer.toHexString(0xff & arr[index]));
967                        System.out.print(' ');
968                        String str = new String(arr, index + 1, add - 2);
969                        for (i = 0; i < str.length(); i++) {
970                            System.out.print(str.charAt(i));
971                            System.out.print(' ');
972                        }
973                    }
974                    System.out.print('\n');
975                }
976                index += add;
977
978
979                /*
980                 * field value
981                 * 0: short int
982                 * 1: long int
983                 * 2: text
984                 * 3: uint
985                 */
986                if (addAppid) {
987                    type = 1;
988                } else {
989                    type = rd.nextInt(4);
990                }
991                switch (type) {
992                case 0: // header short integer
993                    add = 1;
994                    break;
995                case 1: // header long int
996                    if (addAppid) {
997                        int bit = 1;
998                        int topBit = 0;
999
1000                        for (i = 0; i < 31; i++) {
1001                            if ((mAppIdValue & bit) > 0) topBit = i;
1002                            bit = (bit << 1);
1003                        }
1004                        add = 2 + topBit/8;
1005                    } else {
1006                        add = 1 + rd.nextInt(29);
1007                    }
1008                    break;
1009                case 2: // header string
1010                    add = 2 + rd.nextInt(10);
1011                    break;
1012                default: // uint32
1013                    add = 6;
1014                }
1015                if (index + add >= len) break;
1016
1017                // fill field value
1018                switch (type) {
1019                case 0: // header short int
1020                    arr[index] = (byte) (0x80 | rd.nextInt(128));
1021                    break;
1022                case 1: // header long int
1023                    if (addAppid) {
1024                        addAppid = false;
1025                        appIdAdded = true;
1026
1027                        arr[index] = (byte) (add - 1);
1028                        tmpVal = mAppIdValue;
1029                        for (i = add; i > 1; i--) {
1030                            arr[index + i - 1] = (byte) (tmpVal & 0xff);
1031                            tmpVal = (tmpVal >> 8);
1032                        }
1033                    } else {
1034                        arr[index] = (byte) (add - 1);
1035                        for (i = 1; i < add; i++) {
1036                            arr[index + i] = (byte) rd.nextInt(255);
1037                        }
1038                    }
1039                    break;
1040                case 2:// header string
1041                    for (i = 0; i < add - 1; i++) {
1042                        tmpVal = rd.nextInt(127);
1043                        if (tmpVal < 32) tmpVal= (32 + tmpVal);
1044                        arr[index + i] = (byte) tmpVal;
1045                    }
1046                    arr[index + i] = (byte) 0x0;
1047                    break;
1048                default: // header uvarint
1049                    arr[index] = (byte) 31;
1050                    tmpVal = rd.nextInt(0x0FFFFFFF);
1051                    add = 1 + encodeUint32(tmpVal, null, index + 1);
1052                    encodeUint32(tmpVal, arr, index + 1);
1053                    break;
1054
1055                }
1056
1057                if (LOCAL_LOGV) {
1058                    Log.d(LOG_TAG, "field value index:" + index);
1059                    Log.d(LOG_TAG, "type:" + typename[type] + ", add:" + add);
1060                    if (type != 2) {
1061                        for (i = index; i< index + add; i++) {
1062                            System.out.print(Integer.toHexString(0xff & arr[i]));
1063                            System.out.print(' ');
1064                        }
1065                    } else {
1066                        System.out.print(Integer.toHexString(0xff & arr[index]));
1067                        System.out.print(' ');
1068                        String str = new String(arr, index + 1, add - 2);
1069                        for (i = 0; i < str.length(); i++) {
1070                            System.out.print(str.charAt(i));
1071                            System.out.print(' ');
1072                        }
1073                    }
1074                    System.out.print('\n');
1075                }
1076                index += add;
1077            }
1078            if (noAppId) break;
1079        }
1080
1081        Log.d(LOG_TAG, HexDump.dumpHexString(arr));
1082    }
1083
1084    /**
1085     * Generate Random WSP header with string application ID
1086     */
1087    protected void createRandomWspHeaderStrAppId(byte[] arr, Random rd, int headerStart,
1088            boolean randomStr) {
1089
1090        boolean appIdAdded = false;
1091
1092        Log.d(LOG_TAG, "random arr length:" + arr.length);
1093        String typename[] = new String[] { "short int", "long int", "string", "uint32"};
1094
1095        while (!appIdAdded) {
1096            int type;
1097            int index = headerStart;
1098            int len = arr.length;
1099            int i;
1100            boolean addAppid = false;
1101            int tmpVal = 0;
1102            int tmpVal2 = 0;
1103
1104            while (true) {
1105                int add;
1106
1107                /*
1108                 * field name
1109                 * 0: short int
1110                 * 1: long int
1111                 * 2: text
1112                 * (no uint for param value)
1113                 */
1114                type = rd.nextInt(3);
1115                switch (type) {
1116                case 0: // header short integer
1117                    if (index > 100 && !appIdAdded) addAppid = true;
1118                    add = 1;
1119                    break;
1120                case 1: // header long int
1121                    add = 1 + rd.nextInt(29);
1122                    break;
1123                default: // header string
1124                    add = 2 + rd.nextInt(10);
1125                    break;
1126                }
1127                if (index + add >= len) break;
1128
1129                // fill header name
1130                switch (type) {
1131                case 0: // header short integer
1132                    if (!addAppid) {
1133                        do {
1134                            arr[index] = (byte) (0x80 | rd.nextInt(128));
1135                        } while (arr[index] == (byte) 0xaf);
1136                    } else {
1137                        Log.d(LOG_TAG, "appId added.");
1138                        arr[index] = (byte) 0xaf;
1139                    }
1140                    break;
1141                case 1: // header long int
1142                    arr[index] = (byte) (add - 1);
1143                    tmpVal2 = 0;
1144                    for (i = 1; i < add; i++) {
1145                        tmpVal = rd.nextInt(255);
1146                        tmpVal2 = (tmpVal2 << 8) | tmpVal;
1147                        arr[index + i] = (byte) tmpVal;
1148                    }
1149                    // don't set application id
1150                    if (tmpVal2 == 0x2f) arr[index + 1]++;
1151                    break;
1152                default: // header string
1153                    for (i = 0; i < add - 1; i++) {
1154                        tmpVal = rd.nextInt(127);
1155                        if (tmpVal < 32) tmpVal= (32 + tmpVal);
1156                        arr[index + i] = (byte) tmpVal;
1157                    }
1158                    arr[index + i] = (byte) 0x0;
1159                    break;
1160                }
1161
1162                if (LOCAL_LOGV) {
1163                    Log.d(LOG_TAG, "field name index:" + index);
1164                    Log.d(LOG_TAG, "type:" + typename[type] + ", add:" + add);
1165                    if (type != 2) {
1166                        for (i = index; i < index + add; i++) {
1167                            System.out.print(Integer.toHexString(0xff & arr[i]));
1168                            System.out.print(' ');
1169                        }
1170                    } else {
1171                        System.out.print(Integer.toHexString(0xff & arr[index]));
1172                        System.out.print(' ');
1173                        String str = new String(arr, index + 1, add - 2);
1174                        for (i = 0; i < str.length(); i++) {
1175                            System.out.print(str.charAt(i));
1176                            System.out.print(' ');
1177                        }
1178                    }
1179                    System.out.print('\n');
1180                }
1181                index += add;
1182
1183
1184                /*
1185                 * field value
1186                 * 0: short int
1187                 * 1: long int
1188                 * 2: text
1189                 * 3: uint
1190                 */
1191                if (addAppid) {
1192                    type = 2;
1193                } else {
1194                    type = rd.nextInt(4);
1195                }
1196                switch (type) {
1197                case 0: // header short integer
1198                    add = 1;
1199                    break;
1200                case 1: // header long int
1201                    add = 1 + rd.nextInt(29);
1202                    break;
1203                case 2: // header string
1204                    if (addAppid) {
1205                        if (randomStr) {
1206                            add = 1 + rd.nextInt(10);
1207                            byte[] randStr= new byte[add];
1208                            for (i = 0; i < add; i++) {
1209                                tmpVal = rd.nextInt(127);
1210                                if (tmpVal < 32) tmpVal= (32 + tmpVal);
1211                                randStr[i] = (byte) tmpVal;
1212                            }
1213                            mAppIdName = new String(randStr);
1214                        }
1215                        add = mAppIdName.length() + 1;
1216                    } else {
1217                        add = 2 + rd.nextInt(10);
1218                    }
1219                    break;
1220                default: // uint32
1221                    add = 6;
1222                }
1223                if (index + add >= len) break;
1224
1225                // fill field value
1226                switch (type) {
1227                case 0: // header short int
1228                    arr[index] = (byte) (0x80 | rd.nextInt(128));
1229                    break;
1230                case 1: // header long int
1231                    arr[index] = (byte) (add - 1);
1232                    for (i = 1; i < add; i++)
1233                        arr[index + i] = (byte) rd.nextInt(255);
1234                    break;
1235                case 2:// header string
1236                    if (addAppid) {
1237                        addAppid = false;
1238                        appIdAdded = true;
1239                        for (i = 0; i < add - 1; i++) {
1240                            arr[index + i] = (byte) (mAppIdName.charAt(i));
1241                        }
1242                        Log.d(LOG_TAG, "mAppIdName added [" + mAppIdName + "]");
1243                    } else {
1244                        for (i = 0; i < add - 1; i++) {
1245                            tmpVal = rd.nextInt(127);
1246                            if (tmpVal < 32) tmpVal= (32 + tmpVal);
1247                            arr[index + i] = (byte) tmpVal;
1248                        }
1249                    }
1250                    arr[index + i] = (byte) 0x0;
1251                    break;
1252                default: // header uvarint
1253                    arr[index] = (byte) 31;
1254                    tmpVal = rd.nextInt(0x0FFFFFFF);
1255                    add = 1 + encodeUint32(tmpVal, null, index + 1);
1256                    encodeUint32(tmpVal, arr, index + 1);
1257                    break;
1258
1259                }
1260
1261                if (LOCAL_LOGV) {
1262                    Log.d(LOG_TAG, "field value index:" + index);
1263                    Log.d(LOG_TAG, "type:" + typename[type] + ", add:" + add);
1264                    if (type != 2) {
1265                        for (i = index; i < index + add; i++) {
1266                            System.out.print(Integer.toHexString(0xff & arr[i]));
1267                            System.out.print(' ');
1268                        }
1269                    } else {
1270                        System.out.print(Integer.toHexString(0xff & arr[index]));
1271                        System.out.print(' ');
1272                        String str = new String(arr, index + 1, add - 2);
1273                        for (i = 0; i < str.length(); i++) {
1274                            System.out.print(str.charAt(i));
1275                            System.out.print(' ');
1276                        }
1277                    }
1278                    System.out.print('\n');
1279                }
1280                index += add;
1281            }
1282        }
1283
1284        Log.d(LOG_TAG, "headerStart = " + headerStart + ", mAppIdName = " + mAppIdName);
1285        Log.d(LOG_TAG, HexDump.dumpHexString(arr));
1286    }
1287
1288    protected byte[] createPDU(int testNum) {
1289        byte[] array = null;
1290        // byte[] wsp = null;
1291
1292        switch (testNum) {
1293            // sample pdu
1294        case 1:
1295            byte[] array1 = {
1296                    (byte) 0x00, // TID
1297                    (byte) 0x06, // Type = wap push
1298                    (byte) 0x00, // Length to be set later.
1299
1300                    // Content-Type
1301                    (byte) 0x03, (byte) 0x02,
1302                    (byte) ((mContentTypeValue >> 8) & 0xff),
1303                    (byte) (mContentTypeValue & 0xff),
1304
1305                    // Application-id
1306                    (byte) 0xaf, (byte) 0x02,
1307                    (byte) ((mAppIdValue >> 8) & 0xff),
1308                    (byte) (mAppIdValue& 0xff)
1309            };
1310            array1[2] = (byte) (array1.length - 3);
1311            mWspHeader = array1;
1312            mWspHeaderStart = mGsmHeader.length + mUserDataHeader.length + 7;
1313            mWspHeaderLen = array1.length;
1314            break;
1315
1316            // invalid wsp header
1317        case 2:
1318            byte[] array2 = {
1319                    (byte) 0x00, // invalid data
1320            };
1321            mWspHeader = array2;
1322            mWspHeaderStart = mGsmHeader.length + mUserDataHeader.length;
1323            mWspHeaderLen = array2.length;
1324            break;
1325
1326            // random wsp header
1327        case 3:
1328            Random rd = new Random();
1329            int arrSize = 150 + rd.nextInt(100);
1330            byte[] array3 = new byte[arrSize];
1331            int hdrEncodeLen;
1332
1333            array3[0] = (byte) 0x0;
1334            array3[1] = (byte) 0x6;
1335            hdrEncodeLen = encodeUint32(array3.length, null, 2);
1336            hdrEncodeLen = encodeUint32(array3.length - hdrEncodeLen - 2, array3, 2);
1337            array3[hdrEncodeLen + 2] = (byte) 0x3;
1338            array3[hdrEncodeLen + 3] = (byte) 0x2;
1339            array3[hdrEncodeLen + 4] = (byte) ((mContentTypeValue >> 8) & 0xff);
1340            array3[hdrEncodeLen + 5] = (byte) (mContentTypeValue & 0xff);
1341            createRandomWspHeader(array3, rd, hdrEncodeLen + 6, false);
1342            mWspHeaderStart = mGsmHeader.length + mUserDataHeader.length + hdrEncodeLen + 6;
1343            mWspHeaderLen = array3.length;
1344
1345            Log.d(LOG_TAG, "mContentTypeValue = " + mContentTypeValue
1346                    + "(" + Integer.toHexString(mContentTypeValue) + ")");
1347
1348            mWspHeader = array3;
1349            break;
1350
1351            // random wsp header w/o appid
1352        case 4:
1353            rd = new Random();
1354            arrSize = 150 + rd.nextInt(100);
1355            array3 = new byte[arrSize];
1356
1357            array3[0] = (byte) 0x0;
1358            array3[1] = (byte) 0x6;
1359            hdrEncodeLen = encodeUint32(array3.length, null, 2);
1360            hdrEncodeLen = encodeUint32(array3.length - hdrEncodeLen - 2, array3, 2);
1361            array3[hdrEncodeLen + 2] = (byte) 0x3;
1362            array3[hdrEncodeLen + 3] = (byte) 0x2;
1363            array3[hdrEncodeLen + 4] = (byte) ((mContentTypeValue >> 8) & 0xff);
1364            array3[hdrEncodeLen + 5] = (byte) (mContentTypeValue & 0xff);
1365            createRandomWspHeader(array3, rd, hdrEncodeLen + 6, true);
1366            mWspHeaderStart = mGsmHeader.length + mUserDataHeader.length + hdrEncodeLen + 6;
1367            mWspHeaderLen = array3.length;
1368
1369            Log.d(LOG_TAG, "mContentTypeValue = " + mContentTypeValue
1370                    + "(" + Integer.toHexString(mContentTypeValue) + ")");
1371
1372            mWspHeader = array3;
1373            break;
1374
1375            // random wsp header w/ random appid string
1376        case 5:
1377            rd = new Random();
1378            arrSize = 150 + rd.nextInt(100);
1379            array3 = new byte[arrSize];
1380
1381            array3[0] = (byte) 0x0;
1382            array3[1] = (byte) 0x6;
1383            hdrEncodeLen = encodeUint32(array3.length, null, 2);
1384            hdrEncodeLen = encodeUint32(array3.length - hdrEncodeLen - 2, array3, 2);
1385            array3[hdrEncodeLen + 2] = (byte) 0x3;
1386            array3[hdrEncodeLen + 3] = (byte) 0x2;
1387            array3[hdrEncodeLen + 4] = (byte) ((mContentTypeValue >> 8) & 0xff);
1388            array3[hdrEncodeLen + 5] = (byte) (mContentTypeValue & 0xff);
1389            createRandomWspHeaderStrAppId(array3, rd, hdrEncodeLen + 6, true);
1390            mWspHeaderStart = mGsmHeader.length + mUserDataHeader.length + hdrEncodeLen + 6;
1391            mWspHeaderLen = array3.length;
1392
1393            Log.d(LOG_TAG, "mContentTypeValue = " + mContentTypeValue
1394                    + "(" + Integer.toHexString(mContentTypeValue) + ")");
1395
1396            mWspHeader = array3;
1397            break;
1398
1399            // random wsp header w/ OMA appid string
1400        case 6:
1401            rd = new Random();
1402            arrSize = 150 + rd.nextInt(100);
1403            array3 = new byte[arrSize];
1404
1405            array3[0] = (byte) 0x0;
1406            array3[1] = (byte) 0x6;
1407            hdrEncodeLen = encodeUint32(array3.length, null, 2);
1408            hdrEncodeLen = encodeUint32(array3.length - hdrEncodeLen - 2, array3, 2);
1409            array3[hdrEncodeLen + 2] = (byte) 0x3;
1410            array3[hdrEncodeLen + 3] = (byte) 0x2;
1411            array3[hdrEncodeLen + 4] = (byte) ((mContentTypeValue >> 8) & 0xff);
1412            array3[hdrEncodeLen + 5] = (byte) (mContentTypeValue & 0xff);
1413            createRandomWspHeaderStrAppId(array3, rd, hdrEncodeLen + 6, false);
1414            mWspHeaderStart = mGsmHeader.length + mUserDataHeader.length + hdrEncodeLen + 6;
1415            mWspHeaderLen = array3.length;
1416
1417            Log.d(LOG_TAG, "mContentTypeValue = " + mContentTypeValue
1418                    + "(" + Integer.toHexString(mContentTypeValue) + ")");
1419
1420            mWspHeader = array3;
1421            break;
1422
1423            // random wsp header w/ OMA content type
1424        case 7:
1425            rd = new Random();
1426            arrSize = 150 + rd.nextInt(100);
1427            array3 = new byte[arrSize];
1428
1429            array3[0] = (byte) 0x0;
1430            array3[1] = (byte) 0x6;
1431            hdrEncodeLen = encodeUint32(array3.length, null, 2);
1432            hdrEncodeLen = encodeUint32(array3.length - hdrEncodeLen - 2, array3, 2);
1433
1434            // encode content type
1435            int contentLen = mContentTypeName.length();
1436            int next = 2 + hdrEncodeLen;
1437            mWspContentTypeStart = mGsmHeader.length + mUserDataHeader.length + next;
1438            // next += encodeUint32(contentLen, array3, next);
1439            int i;
1440            Log.d(LOG_TAG, "mContentTypeName = " + mContentTypeName
1441                    + ", contentLen = " + contentLen);
1442
1443            for (i = 0; i < contentLen; i++) {
1444                array3[next + i] = (byte) mContentTypeName.charAt(i);
1445            }
1446            array3[next + i] = (byte) 0x0;
1447
1448            createRandomWspHeader(array3, rd, next + contentLen + 1, false);
1449            mWspHeaderStart = mGsmHeader.length + mUserDataHeader.length
1450                    + next + contentLen + 1;
1451            mWspHeaderLen = array3.length;
1452
1453            mWspHeader = array3;
1454            break;
1455
1456            // random wsp header w/ OMA content type, OMA app ID
1457        case 8:
1458            rd = new Random();
1459            arrSize = 150 + rd.nextInt(100);
1460            array3 = new byte[arrSize];
1461
1462            array3[0] = (byte) 0x0;
1463            array3[1] = (byte) 0x6;
1464            hdrEncodeLen = encodeUint32(array3.length, null, 2);
1465            hdrEncodeLen = encodeUint32(array3.length - hdrEncodeLen - 2, array3, 2);
1466
1467            // encode content type
1468            contentLen = mContentTypeName.length();
1469            next = 2 + hdrEncodeLen;
1470            mWspContentTypeStart = mGsmHeader.length + mUserDataHeader.length + next;
1471            // next += encodeUint32(contentLen, array3, next);
1472            Log.d(LOG_TAG, "mContentTypeName = " + mContentTypeName
1473                    + ", contentLen = " + contentLen);
1474
1475            for (i = 0; i < contentLen; i++) {
1476                array3[next + i] = (byte) mContentTypeName.charAt(i);
1477            }
1478            array3[next + i] = (byte) 0x0;
1479
1480            createRandomWspHeaderStrAppId(array3, rd, next + contentLen + 1, false);
1481            mWspHeaderStart = mGsmHeader.length + mUserDataHeader.length
1482                    + next + contentLen + 1;
1483            mWspHeaderLen = array3.length;
1484
1485            mWspHeader = array3;
1486            break;
1487
1488        default:
1489            return null;
1490        }
1491        array = new byte[mGsmHeader.length + mUserDataHeader.length + mWspHeader.length
1492                + mMessageBody.length];
1493        System.arraycopy(mGsmHeader, 0, array, 0, mGsmHeader.length);
1494        System.arraycopy(mUserDataHeader, 0, array,
1495                mGsmHeader.length, mUserDataHeader.length);
1496        System.arraycopy(mWspHeader, 0, array,
1497                mGsmHeader.length + mUserDataHeader.length, mWspHeader.length);
1498        System.arraycopy(mMessageBody, 0, array,
1499                mGsmHeader.length + mUserDataHeader.length + mWspHeader.length,
1500                mMessageBody.length);
1501        return array;
1502
1503    }
1504
1505    Intent createIntent(int pduType, int tranId) {
1506        Intent intent = new Intent();
1507        intent.putExtra("transactionId", tranId);
1508        intent.putExtra("pduType", pduType);
1509        intent.putExtra("header", mGsmHeader);
1510        intent.putExtra("data", mMessageBody);
1511        // intent.putExtra("contentTypeParameters", null);
1512        return intent;
1513    }
1514
1515    /**
1516     * Message processing test, start activity
1517     */
1518    public void testProcessMsg1() {
1519        byte[] pdu = createPDU(1);
1520        int headerLen = pdu.length -
1521                (mGsmHeader.length + mUserDataHeader.length + mMessageBody.length);
1522        int pduType = 6;
1523        int tranId = 0;
1524        String originalPackageName = mPackageName;
1525        String originalClassName = mClassName;
1526
1527        try {
1528
1529            mClassName = "com.android.smspush.unitTests.ReceiverActivity";
1530
1531            // set up data
1532            IWapPushManager iwapman = getInterface();
1533            iwapman.addPackage(Integer.toString(mAppIdValue),
1534                    Integer.toString(mContentTypeValue), mPackageName, mClassName,
1535                    WapPushManagerParams.APP_TYPE_ACTIVITY, false, false);
1536
1537            assertTrue((iwapman.processMessage(
1538                    Integer.toString(mAppIdValue),
1539                    Integer.toString(mContentTypeValue),
1540                    createIntent(pduType, tranId))
1541                    & WapPushManagerParams.MESSAGE_HANDLED) ==
1542                    WapPushManagerParams.MESSAGE_HANDLED);
1543
1544            // clean up data
1545            iwapman.deletePackage(Integer.toString(mAppIdValue),
1546                    Integer.toString(mContentTypeValue), mPackageName, mClassName);
1547
1548        } catch (RemoteException e) {
1549            assertTrue(false);
1550        }
1551
1552        mPackageName = originalPackageName;
1553        mClassName = originalClassName;
1554    }
1555
1556    /**
1557     * Message processing test, start service
1558     */
1559    public void testProcessMsg2() {
1560        byte[] pdu = createPDU(1);
1561        int headerLen = pdu.length - (mGsmHeader.length +
1562                mUserDataHeader.length + mMessageBody.length);
1563        int pduType = 6;
1564        int tranId = 0;
1565        String originalPackageName = mPackageName;
1566        String originalClassName = mClassName;
1567
1568        try {
1569
1570            mClassName = "com.android.smspush.unitTests.ReceiverService";
1571
1572            // set up data
1573            IWapPushManager iwapman = getInterface();
1574
1575            iwapman.addPackage(Integer.toString(mAppIdValue),
1576                    Integer.toString(mContentTypeValue), mPackageName, mClassName,
1577                    WapPushManagerParams.APP_TYPE_SERVICE, false, false);
1578
1579            assertTrue((iwapman.processMessage(
1580                    Integer.toString(mAppIdValue),
1581                    Integer.toString(mContentTypeValue),
1582                    createIntent(pduType, tranId))
1583                    & WapPushManagerParams.MESSAGE_HANDLED) ==
1584                    WapPushManagerParams.MESSAGE_HANDLED);
1585
1586            // clean up data
1587            iwapman.deletePackage(Integer.toString(mAppIdValue),
1588                    Integer.toString(mContentTypeValue), mPackageName, mClassName);
1589
1590        } catch (RemoteException e) {
1591            assertTrue(false);
1592        }
1593
1594        mPackageName = originalPackageName;
1595        mClassName = originalClassName;
1596    }
1597
1598    /**
1599     * Message processing test, no signature
1600     */
1601    public void testProcessMsg3() {
1602        byte[] pdu = createPDU(1);
1603        int headerLen = pdu.length -
1604                (mGsmHeader.length + mUserDataHeader.length + mMessageBody.length);
1605        int pduType = 6;
1606        int tranId = 0;
1607        String originalPackageName = mPackageName;
1608        String originalClassName = mClassName;
1609
1610        try {
1611
1612            mPackageName = "com.android.development";
1613            mClassName = "com.android.development.Development";
1614
1615            // set up data
1616            IWapPushManager iwapman = getInterface();
1617
1618            iwapman.addPackage(Integer.toString(mAppIdValue),
1619                    Integer.toString(mContentTypeValue), mPackageName, mClassName,
1620                    WapPushManagerParams.APP_TYPE_SERVICE, true, false);
1621
1622            assertFalse((iwapman.processMessage(
1623                    Integer.toString(mAppIdValue),
1624                    Integer.toString(mContentTypeValue),
1625                    createIntent(pduType, tranId))
1626                    & WapPushManagerParams.MESSAGE_HANDLED) ==
1627                    WapPushManagerParams.MESSAGE_HANDLED);
1628
1629            // clean up data
1630            iwapman.deletePackage(Integer.toString(mAppIdValue),
1631                    Integer.toString(mContentTypeValue), mPackageName, mClassName);
1632
1633        } catch (RemoteException e) {
1634            assertTrue(false);
1635        }
1636
1637        mPackageName = originalPackageName;
1638        mClassName = originalClassName;
1639    }
1640
1641    IDataVerify getVerifyInterface() {
1642        while (mIVerify == null) {
1643            // wait for the activity receive data.
1644            try {
1645                Thread.sleep(TIME_WAIT);
1646            } catch (InterruptedException e) {}
1647        }
1648        return mIVerify;
1649    }
1650
1651
1652    /**
1653     * Message processing test, received body data verification test
1654     */
1655    public void testProcessMsg4() {
1656        byte[] originalMessageBody = mMessageBody;
1657        mMessageBody = new byte[] {
1658                (byte) 0xee,
1659                (byte) 0xff,
1660                (byte) 0xee,
1661                (byte) 0xff,
1662                (byte) 0xee,
1663                (byte) 0xff,
1664                (byte) 0xee,
1665                (byte) 0xff,
1666                (byte) 0xee,
1667                (byte) 0xff,
1668                (byte) 0xee,
1669                (byte) 0xff,
1670        };
1671
1672        byte[] pdu = createPDU(1);
1673        int headerLen = pdu.length -
1674                (mGsmHeader.length + mUserDataHeader.length + mMessageBody.length);
1675        int pduType = 6;
1676        int tranId = 0;
1677        String originalPackageName = mPackageName;
1678        String originalClassName = mClassName;
1679
1680        try {
1681            IWapPushManager iwapman = getInterface();
1682            IDataVerify dataverify = getVerifyInterface();
1683
1684            dataverify.resetData();
1685
1686            // set up data
1687            mClassName = "com.android.smspush.unitTests.ReceiverActivity";
1688            iwapman.addPackage(Integer.toString(mAppIdValue),
1689                    Integer.toString(mContentTypeValue), mPackageName, mClassName,
1690                    WapPushManagerParams.APP_TYPE_ACTIVITY, false, false);
1691
1692            iwapman.processMessage(
1693                    Integer.toString(mAppIdValue),
1694                    Integer.toString(mContentTypeValue),
1695                    createIntent(pduType, tranId));
1696
1697            // clean up data
1698            iwapman.deletePackage(Integer.toString(mAppIdValue),
1699                    Integer.toString(mContentTypeValue), mPackageName, mClassName);
1700
1701            assertTrue(dataverify.verifyData(mMessageBody));
1702
1703            // set up data
1704            dataverify.resetData();
1705            mClassName = "com.android.smspush.unitTests.ReceiverService";
1706            mMessageBody = new byte[] {
1707                    (byte) 0xaa,
1708                    (byte) 0xbb,
1709                    (byte) 0x11,
1710                    (byte) 0x22,
1711                    (byte) 0xaa,
1712                    (byte) 0xbb,
1713                    (byte) 0x11,
1714                    (byte) 0x22,
1715                    (byte) 0xaa,
1716                    (byte) 0xbb,
1717                    (byte) 0x11,
1718                    (byte) 0x22,
1719                    (byte) 0xaa,
1720                    (byte) 0xbb,
1721                    (byte) 0x11,
1722                    (byte) 0x22,
1723                    (byte) 0xaa,
1724                    (byte) 0xbb,
1725                    (byte) 0x11,
1726                    (byte) 0x22,
1727                    (byte) 0xaa,
1728                    (byte) 0xbb,
1729                    (byte) 0x11,
1730                    (byte) 0x22,
1731            };
1732            pdu = createPDU(1);
1733            iwapman.addPackage(Integer.toString(mAppIdValue),
1734                    Integer.toString(mContentTypeValue), mPackageName, mClassName,
1735                    WapPushManagerParams.APP_TYPE_SERVICE, false, false);
1736
1737            iwapman.processMessage(
1738                    Integer.toString(mAppIdValue),
1739                    Integer.toString(mContentTypeValue),
1740                    createIntent(pduType, tranId));
1741
1742            // clean up data
1743            iwapman.deletePackage(Integer.toString(mAppIdValue),
1744                    Integer.toString(mContentTypeValue), mPackageName, mClassName);
1745
1746            // Log.d(LOG_TAG, HexDump.dumpHexString(mMessageBody));
1747            assertTrue(dataverify.verifyData(mMessageBody));
1748        } catch (RemoteException e) {
1749            assertTrue(false);
1750        }
1751
1752        mPackageName = originalPackageName;
1753        mClassName = originalClassName;
1754        mMessageBody = originalMessageBody;
1755    }
1756
1757    /**
1758     * Message processing test, send invalid sms data
1759     */
1760    public void testProcessMsg5() {
1761        byte[] pdu = createPDU(2);
1762        int headerLen = pdu.length -
1763                (mGsmHeader.length + mUserDataHeader.length + mMessageBody.length);
1764        int pduType = 6;
1765        int tranId = 0;
1766        String originalPackageName = mPackageName;
1767        String originalClassName = mClassName;
1768
1769        try {
1770
1771            mClassName = "com.android.smspush.unitTests.ReceiverActivity";
1772
1773            // set up data
1774            IWapPushManager iwapman = getInterface();
1775            iwapman.addPackage(Integer.toString(mAppIdValue),
1776                    Integer.toString(mContentTypeValue), mPackageName, mClassName,
1777                    WapPushManagerParams.APP_TYPE_ACTIVITY, false, false);
1778
1779            assertTrue((iwapman.processMessage(
1780                    Integer.toString(mAppIdValue),
1781                    Integer.toString(mContentTypeValue),
1782                    createIntent(pduType, tranId))
1783                    & WapPushManagerParams.MESSAGE_HANDLED) ==
1784                    WapPushManagerParams.MESSAGE_HANDLED);
1785
1786            // clean up data
1787            iwapman.deletePackage(Integer.toString(mAppIdValue),
1788                    Integer.toString(mContentTypeValue), mPackageName, mClassName);
1789
1790        } catch (RemoteException e) {
1791            assertTrue(false);
1792        }
1793
1794        mPackageName = originalPackageName;
1795        mClassName = originalClassName;
1796    }
1797
1798    /**
1799     * Message processing test, no receiver application
1800     */
1801    public void testProcessMsg6() {
1802        byte[] pdu = createPDU(1);
1803        int headerLen = pdu.length -
1804                (mGsmHeader.length + mUserDataHeader.length + mMessageBody.length);
1805        int pduType = 6;
1806        int tranId = 0;
1807        String originalPackageName = mPackageName;
1808        String originalClassName = mClassName;
1809
1810        try {
1811
1812            mClassName = "com.android.smspush.unitTests.NoReceiver";
1813
1814            // set up data
1815            IWapPushManager iwapman = getInterface();
1816            iwapman.addPackage(Integer.toString(mAppIdValue),
1817                    Integer.toString(mContentTypeValue), mPackageName, mClassName,
1818                    WapPushManagerParams.APP_TYPE_ACTIVITY, false, false);
1819
1820            assertFalse((iwapman.processMessage(
1821                    Integer.toString(mAppIdValue),
1822                    Integer.toString(mContentTypeValue),
1823                    createIntent(pduType, tranId))
1824                    & WapPushManagerParams.MESSAGE_HANDLED) ==
1825                    WapPushManagerParams.MESSAGE_HANDLED);
1826
1827            // clean up data
1828            iwapman.deletePackage(Integer.toString(mAppIdValue),
1829                    Integer.toString(mContentTypeValue), mPackageName, mClassName);
1830
1831            // set up data
1832            iwapman.addPackage(Integer.toString(mAppIdValue),
1833                    Integer.toString(mContentTypeValue), mPackageName, mClassName,
1834                    WapPushManagerParams.APP_TYPE_SERVICE, false, false);
1835
1836            assertFalse((iwapman.processMessage(
1837                    Integer.toString(mAppIdValue),
1838                    Integer.toString(mContentTypeValue),
1839                    createIntent(pduType, tranId))
1840                    & WapPushManagerParams.MESSAGE_HANDLED) ==
1841                    WapPushManagerParams.MESSAGE_HANDLED);
1842
1843            // clean up data
1844            iwapman.deletePackage(Integer.toString(mAppIdValue),
1845                    Integer.toString(mContentTypeValue), mPackageName, mClassName);
1846
1847        } catch (RemoteException e) {
1848            assertTrue(false);
1849        }
1850
1851        mPackageName = originalPackageName;
1852        mClassName = originalClassName;
1853    }
1854
1855    /**
1856     * WspTypeDecoder test, normal pdu
1857     */
1858    public void testDecoder1() {
1859        boolean res;
1860        int originalAppIdValue = mAppIdValue;
1861        Random rd = new Random();
1862
1863        for (int i = 0; i < 10; i++) {
1864            mAppIdValue = rd.nextInt(0xFFFF);
1865            byte[] pdu = createPDU(1);
1866            WspTypeDecoder pduDecoder = new WspTypeDecoder(pdu);
1867
1868            res = pduDecoder.seekXWapApplicationId(mWspHeaderStart,
1869                    mWspHeaderStart + mWspHeaderLen - 1);
1870            assertTrue(res);
1871
1872            int index = (int) pduDecoder.getValue32();
1873            res = pduDecoder.decodeXWapApplicationId(index);
1874            assertTrue(res);
1875
1876            Log.d(LOG_TAG, "mAppIdValue: " + mAppIdValue
1877                    + ", val: " + pduDecoder.getValue32());
1878            assertTrue(mAppIdValue == (int) pduDecoder.getValue32());
1879        }
1880
1881        mAppIdValue = originalAppIdValue;
1882    }
1883
1884    /**
1885     * WspTypeDecoder test, no header
1886     */
1887    public void testDecoder2() {
1888        boolean res;
1889        int originalAppIdValue = mAppIdValue;
1890        Random rd = new Random();
1891
1892        mAppIdValue = rd.nextInt(0xFFFF);
1893        byte[] pdu = createPDU(2);
1894        WspTypeDecoder pduDecoder = new WspTypeDecoder(pdu);
1895
1896        res = pduDecoder.seekXWapApplicationId(mWspHeaderStart,
1897                mWspHeaderStart + mWspHeaderLen - 1);
1898        assertFalse(res);
1899
1900        mAppIdValue = originalAppIdValue;
1901    }
1902
1903    /**
1904     * WspTypeDecoder test, decode appid test
1905     */
1906    public void testDecoder3() {
1907        boolean res;
1908        int originalAppIdValue = mAppIdValue;
1909        int originalContentTypeValue  = mContentTypeValue;
1910        Random rd = new Random();
1911
1912        for (int i = 0; i < 100; i++) {
1913            mAppIdValue = rd.nextInt(0x0FFFFFFF);
1914            mContentTypeValue = rd.nextInt(0x0FFF);
1915            byte[] pdu = createPDU(3);
1916            WspTypeDecoder pduDecoder = new WspTypeDecoder(pdu);
1917
1918            res = pduDecoder.seekXWapApplicationId(mWspHeaderStart,
1919                    mWspHeaderStart + mWspHeaderLen - 1);
1920            assertTrue(res);
1921
1922            int index = (int) pduDecoder.getValue32();
1923            res = pduDecoder.decodeXWapApplicationId(index);
1924            assertTrue(res);
1925
1926            Log.d(LOG_TAG, "mAppIdValue: " + mAppIdValue
1927                    + ", val: " + pduDecoder.getValue32());
1928            assertTrue(mAppIdValue == (int) pduDecoder.getValue32());
1929        }
1930
1931        mAppIdValue = originalAppIdValue;
1932        mContentTypeValue = originalContentTypeValue;
1933    }
1934
1935    /*
1936      public void testEnc() {
1937      byte[] arr = new byte[20];
1938      int index = 0;
1939      index += encodeUint32(0x87a5, arr, index);
1940      index += encodeUint32(0x1, arr, index);
1941      index += encodeUint32(0x9b, arr, index);
1942      index += encodeUint32(0x10, arr, index);
1943      index += encodeUint32(0xe0887, arr, index);
1944      index += encodeUint32(0x791a23d0, arr, index);
1945
1946      Log.d(LOG_TAG, HexDump.dumpHexString(arr));
1947      }
1948    */
1949
1950    /**
1951     * WspTypeDecoder test, no appid test
1952     */
1953    public void testDecoder4() {
1954        boolean res;
1955        int originalAppIdValue = mAppIdValue;
1956        int originalContentTypeValue  = mContentTypeValue;
1957        Random rd = new Random();
1958
1959        for (int i = 0; i < 100; i++) {
1960            mAppIdValue = rd.nextInt(0x0FFFFFFF);
1961            mContentTypeValue = rd.nextInt(0x0FFF);
1962            byte[] pdu = createPDU(4);
1963            WspTypeDecoder pduDecoder = new WspTypeDecoder(pdu);
1964
1965            res = pduDecoder.seekXWapApplicationId(mWspHeaderStart,
1966                    mWspHeaderStart + mWspHeaderLen - 1);
1967            assertFalse(res);
1968
1969        }
1970
1971        mAppIdValue = originalAppIdValue;
1972        mContentTypeValue = originalContentTypeValue;
1973    }
1974
1975    /**
1976     * WspTypeDecoder test, decode string appid test
1977     */
1978    public void testDecoder5() {
1979        boolean res;
1980        String originalAppIdName = mAppIdName;
1981        int originalContentTypeValue  = mContentTypeValue;
1982        Random rd = new Random();
1983
1984        for (int i = 0; i < 10; i++) {
1985            mAppIdValue = rd.nextInt(0x0FFFFFFF);
1986            mContentTypeValue = rd.nextInt(0x0FFF);
1987            byte[] pdu = createPDU(5);
1988            WspTypeDecoder pduDecoder = new WspTypeDecoder(pdu);
1989
1990            res = pduDecoder.seekXWapApplicationId(mWspHeaderStart,
1991                    mWspHeaderStart + mWspHeaderLen - 1);
1992            assertTrue(res);
1993
1994            int index = (int) pduDecoder.getValue32();
1995            res = pduDecoder.decodeXWapApplicationId(index);
1996            assertTrue(res);
1997
1998            Log.d(LOG_TAG, "mAppIdValue: [" + mAppIdName + "], val: ["
1999                    + pduDecoder.getValueString() + "]");
2000            assertTrue(mAppIdName.equals(pduDecoder.getValueString()));
2001        }
2002
2003        mAppIdName = originalAppIdName;
2004        mContentTypeValue = originalContentTypeValue;
2005    }
2006
2007    /**
2008     * WspTypeDecoder test, decode string appid test
2009     */
2010    public void testDecoder6() {
2011        boolean res;
2012        String originalAppIdName = mAppIdName;
2013        int originalContentTypeValue  = mContentTypeValue;
2014        Random rd = new Random();
2015
2016        for (int i = 0; i < OMA_APPLICATION_ID_NAMES.length; i++) {
2017            mAppIdName = OMA_APPLICATION_ID_NAMES[i];
2018            mContentTypeValue = rd.nextInt(0x0FFF);
2019            byte[] pdu = createPDU(6);
2020            WspTypeDecoder pduDecoder = new WspTypeDecoder(pdu);
2021
2022            res = pduDecoder.seekXWapApplicationId(mWspHeaderStart,
2023                    mWspHeaderStart + mWspHeaderLen - 1);
2024            assertTrue(res);
2025
2026            int index = (int) pduDecoder.getValue32();
2027            res = pduDecoder.decodeXWapApplicationId(index);
2028            assertTrue(res);
2029
2030            Log.d(LOG_TAG, "mAppIdValue: [" + mAppIdName + "], val: ["
2031                    + pduDecoder.getValueString() + "]");
2032            assertTrue(mAppIdName.equals(pduDecoder.getValueString()));
2033        }
2034
2035        mAppIdName = originalAppIdName;
2036        mContentTypeValue = originalContentTypeValue;
2037    }
2038
2039    /**
2040     * WspTypeDecoder test, decode OMA content type
2041     */
2042    public void testDecoder7() {
2043        boolean res;
2044        String originalAppIdName = mAppIdName;
2045        int originalContentTypeValue  = mContentTypeValue;
2046        Random rd = new Random();
2047
2048        for (int i = 0; i < OMA_CONTENT_TYPE_NAMES.length; i++) {
2049            mContentTypeName = OMA_CONTENT_TYPE_NAMES[i];
2050            byte[] pdu = createPDU(7);
2051            WspTypeDecoder pduDecoder = new WspTypeDecoder(pdu);
2052
2053            res = pduDecoder.decodeContentType(mWspContentTypeStart);
2054            assertTrue(res);
2055
2056            Log.d(LOG_TAG, "mContentTypeName: [" + mContentTypeName + "], val: ["
2057                    + pduDecoder.getValueString() + "]");
2058            assertTrue(mContentTypeName.equals(pduDecoder.getValueString()));
2059        }
2060
2061        mAppIdName = originalAppIdName;
2062        mContentTypeValue = originalContentTypeValue;
2063    }
2064
2065
2066    /**
2067     * Copied from WapPushOverSms.
2068     * The code flow is not changed from the original.
2069     */
2070    public int dispatchWapPdu(byte[] pdu, IWapPushManager wapPushMan) {
2071
2072        if (false) Log.d(LOG_TAG, "Rx: " + IccUtils.bytesToHexString(pdu));
2073
2074        int index = 0;
2075        int transactionId = pdu[index++] & 0xFF;
2076        int pduType = pdu[index++] & 0xFF;
2077        int headerLength = 0;
2078
2079        if ((pduType != WspTypeDecoder.PDU_TYPE_PUSH) &&
2080                (pduType != WspTypeDecoder.PDU_TYPE_CONFIRMED_PUSH)) {
2081            if (false) Log.w(LOG_TAG, "Received non-PUSH WAP PDU. Type = " + pduType);
2082            return Intents.RESULT_SMS_HANDLED;
2083        }
2084
2085        WspTypeDecoder pduDecoder = new WspTypeDecoder(pdu);
2086
2087        /**
2088         * Parse HeaderLen(unsigned integer).
2089         * From wap-230-wsp-20010705-a section 8.1.2
2090         * The maximum size of a uintvar is 32 bits.
2091         * So it will be encoded in no more than 5 octets.
2092         */
2093        if (pduDecoder.decodeUintvarInteger(index) == false) {
2094            if (false) Log.w(LOG_TAG, "Received PDU. Header Length error.");
2095            return Intents.RESULT_SMS_GENERIC_ERROR;
2096        }
2097        headerLength = (int) pduDecoder.getValue32();
2098        index += pduDecoder.getDecodedDataLength();
2099
2100        int headerStartIndex = index;
2101
2102        /**
2103         * Parse Content-Type.
2104         * From wap-230-wsp-20010705-a section 8.4.2.24
2105         *
2106         * Content-type-value = Constrained-media | Content-general-form
2107         * Content-general-form = Value-length Media-type
2108         * Media-type = (Well-known-media | Extension-Media) *(Parameter)
2109         * Value-length = Short-length | (Length-quote Length)
2110         * Short-length = <Any octet 0-30>   (octet <= WAP_PDU_SHORT_LENGTH_MAX)
2111         * Length-quote = <Octet 31>         (WAP_PDU_LENGTH_QUOTE)
2112         * Length = Uintvar-integer
2113         */
2114        if (pduDecoder.decodeContentType(index) == false) {
2115            if (false) Log.w(LOG_TAG, "Received PDU. Header Content-Type error.");
2116            return Intents.RESULT_SMS_GENERIC_ERROR;
2117        }
2118
2119        String mimeType = pduDecoder.getValueString();
2120        long binaryContentType = pduDecoder.getValue32();
2121        index += pduDecoder.getDecodedDataLength();
2122
2123        byte[] header = new byte[headerLength];
2124        System.arraycopy(pdu, headerStartIndex, header, 0, header.length);
2125
2126        byte[] intentData;
2127
2128        if (mimeType != null && mimeType.equals(WspTypeDecoder.CONTENT_TYPE_B_PUSH_CO)) {
2129            intentData = pdu;
2130        } else {
2131            int dataIndex = headerStartIndex + headerLength;
2132            intentData = new byte[pdu.length - dataIndex];
2133            System.arraycopy(pdu, dataIndex, intentData, 0, intentData.length);
2134        }
2135
2136        /**
2137         * Seek for application ID field in WSP header.
2138         * If application ID is found, WapPushManager substitute the message
2139         * processing. Since WapPushManager is optional module, if WapPushManager
2140         * is not found, legacy message processing will be continued.
2141         */
2142        if (pduDecoder.seekXWapApplicationId(index, index + headerLength - 1)) {
2143            index = (int) pduDecoder.getValue32();
2144            pduDecoder.decodeXWapApplicationId(index);
2145            String wapAppId = pduDecoder.getValueString();
2146            if (wapAppId == null) {
2147                wapAppId = Integer.toString((int) pduDecoder.getValue32());
2148            }
2149
2150            String contentType = ((mimeType == null) ?
2151                    Long.toString(binaryContentType) : mimeType);
2152            if (false) Log.v(LOG_TAG, "appid found: " + wapAppId + ":" + contentType);
2153
2154            try {
2155                boolean processFurther = true;
2156                // IWapPushManager wapPushMan = mWapConn.getWapPushManager();
2157                if (wapPushMan == null) {
2158                    if (false) Log.w(LOG_TAG, "wap push manager not found!");
2159                } else {
2160                    Intent intent = new Intent();
2161                    intent.putExtra("transactionId", transactionId);
2162                    intent.putExtra("pduType", pduType);
2163                    intent.putExtra("header", header);
2164                    intent.putExtra("data", intentData);
2165                    intent.putExtra("contentTypeParameters",
2166                            pduDecoder.getContentParameters());
2167
2168                    int procRet = wapPushMan.processMessage(wapAppId, contentType, intent);
2169                    if (false) Log.v(LOG_TAG, "procRet:" + procRet);
2170                    if ((procRet & WapPushManagerParams.MESSAGE_HANDLED) > 0
2171                            && (procRet & WapPushManagerParams.FURTHER_PROCESSING) == 0) {
2172                        processFurther = false;
2173                    }
2174                }
2175                if (!processFurther) {
2176                    return Intents.RESULT_SMS_HANDLED;
2177                }
2178            } catch (RemoteException e) {
2179                if (false) Log.w(LOG_TAG, "remote func failed...");
2180            }
2181        }
2182        if (false) Log.v(LOG_TAG, "fall back to existing handler");
2183
2184        return Activity.RESULT_OK;
2185    }
2186
2187    protected byte[] retrieveWspBody() {
2188        byte[] array = new byte[mWspHeader.length + mMessageBody.length];
2189
2190        System.arraycopy(mWspHeader, 0, array, 0, mWspHeader.length);
2191        System.arraycopy(mMessageBody, 0, array, mWspHeader.length, mMessageBody.length);
2192        return array;
2193    }
2194
2195    protected String getContentTypeName(int ctypeVal) {
2196        int i;
2197
2198        for (i = 0; i < OMA_CONTENT_TYPE_VALUES.length; i++) {
2199            if (ctypeVal == OMA_CONTENT_TYPE_VALUES[i]) {
2200                return OMA_CONTENT_TYPE_NAMES[i];
2201            }
2202        }
2203        return null;
2204    }
2205
2206    protected boolean isContentTypeMapped(int ctypeVal) {
2207        int i;
2208
2209        for (i = 0; i < OMA_CONTENT_TYPE_VALUES.length; i++) {
2210            if (ctypeVal == OMA_CONTENT_TYPE_VALUES[i]) return true;
2211        }
2212        return false;
2213    }
2214
2215    /**
2216     * Integration test 1, simple case
2217     */
2218    public void testIntegration1() {
2219        boolean res;
2220        int originalAppIdValue = mAppIdValue;
2221        int originalContentTypeValue  = mContentTypeValue;
2222        String originalAppIdName = mAppIdName;
2223        String originalContentTypeName = mContentTypeName;
2224        String originalClassName = mClassName;
2225        byte[] originalMessageBody = mMessageBody;
2226        Random rd = new Random();
2227
2228        mMessageBody = new byte[100 + rd.nextInt(100)];
2229        rd.nextBytes(mMessageBody);
2230
2231        byte[] pdu = createPDU(1);
2232        byte[] wappushPdu = retrieveWspBody();
2233
2234
2235        mClassName = "com.android.smspush.unitTests.ReceiverActivity";
2236        // Phone dummy = new DummyPhone(getContext());
2237        // Phone gsm = PhoneFactory.getGsmPhone();
2238        // GSMPhone gsm = new GSMPhone(getContext(), new SimulatedCommands(), null, true);
2239        // WapPushOverSms dispatcher = new WapPushOverSms(dummy, null);
2240
2241        try {
2242            // set up data
2243            IWapPushManager iwapman = getInterface();
2244            IDataVerify dataverify = getVerifyInterface();
2245
2246            dataverify.resetData();
2247
2248            if (isContentTypeMapped(mContentTypeValue)) {
2249                // content type is mapped
2250                mContentTypeName = getContentTypeName(mContentTypeValue);
2251                Log.d(LOG_TAG, "mContentTypeValue mapping "
2252                        + mContentTypeName + ":" + mContentTypeValue);
2253            } else {
2254                mContentTypeName = Integer.toString(mContentTypeValue);
2255            }
2256            iwapman.addPackage(Integer.toString(mAppIdValue),
2257                    mContentTypeName, mPackageName, mClassName,
2258                    WapPushManagerParams.APP_TYPE_ACTIVITY, false, false);
2259
2260            dispatchWapPdu(wappushPdu, iwapman);
2261
2262            // clean up data
2263            iwapman.deletePackage(Integer.toString(mAppIdValue),
2264                    mContentTypeName, mPackageName, mClassName);
2265
2266            assertTrue(dataverify.verifyData(mMessageBody));
2267        } catch (RemoteException e) {
2268        }
2269
2270
2271        mClassName = originalClassName;
2272        mAppIdName = originalAppIdName;
2273        mContentTypeName = originalContentTypeName;
2274        mAppIdValue = originalAppIdValue;
2275        mContentTypeValue = originalContentTypeValue;
2276        mMessageBody = originalMessageBody;
2277    }
2278
2279    /**
2280     * Integration test 2, random mAppIdValue(int), all OMA content type
2281     */
2282    public void testIntegration2() {
2283        boolean res;
2284        int originalAppIdValue = mAppIdValue;
2285        int originalContentTypeValue  = mContentTypeValue;
2286        String originalAppIdName = mAppIdName;
2287        String originalContentTypeName = mContentTypeName;
2288        String originalClassName = mClassName;
2289        byte[] originalMessageBody = mMessageBody;
2290        Random rd = new Random();
2291
2292        IWapPushManager iwapman = getInterface();
2293        IDataVerify dataverify = getVerifyInterface();
2294        mClassName = "com.android.smspush.unitTests.ReceiverActivity";
2295
2296        for (int i = 0; i < OMA_CONTENT_TYPE_NAMES.length; i++) {
2297            mContentTypeName = OMA_CONTENT_TYPE_NAMES[i];
2298            mAppIdValue = rd.nextInt(0x0FFFFFFF);
2299
2300            mMessageBody = new byte[100 + rd.nextInt(100)];
2301            rd.nextBytes(mMessageBody);
2302
2303            byte[] pdu = createPDU(7);
2304            byte[] wappushPdu = retrieveWspBody();
2305
2306            try {
2307                dataverify.resetData();
2308                // set up data
2309                iwapman.addPackage(Integer.toString(mAppIdValue),
2310                        mContentTypeName, mPackageName, mClassName,
2311                        WapPushManagerParams.APP_TYPE_ACTIVITY, false, false);
2312
2313                dispatchWapPdu(wappushPdu, iwapman);
2314
2315                // clean up data
2316                iwapman.deletePackage(Integer.toString(mAppIdValue),
2317                        mContentTypeName, mPackageName, mClassName);
2318
2319                if (mContentTypeName.equals(WspTypeDecoder.CONTENT_TYPE_B_PUSH_CO)) {
2320                    assertTrue(dataverify.verifyData(wappushPdu));
2321                } else {
2322                    assertTrue(dataverify.verifyData(mMessageBody));
2323                }
2324            } catch (RemoteException e) {
2325            }
2326        }
2327
2328
2329        mClassName = originalClassName;
2330        mAppIdName = originalAppIdName;
2331        mContentTypeName = originalContentTypeName;
2332        mAppIdValue = originalAppIdValue;
2333        mContentTypeValue = originalContentTypeValue;
2334        mMessageBody = originalMessageBody;
2335    }
2336
2337    /**
2338     * Integration test 3, iterate OmaApplication ID, random binary content type
2339     */
2340    public void testIntegration3() {
2341        boolean res;
2342        int originalAppIdValue = mAppIdValue;
2343        int originalContentTypeValue  = mContentTypeValue;
2344        String originalAppIdName = mAppIdName;
2345        String originalContentTypeName = mContentTypeName;
2346        String originalClassName = mClassName;
2347        byte[] originalMessageBody = mMessageBody;
2348        Random rd = new Random();
2349
2350        IWapPushManager iwapman = getInterface();
2351        IDataVerify dataverify = getVerifyInterface();
2352        mClassName = "com.android.smspush.unitTests.ReceiverService";
2353
2354        for (int i = 0; i < OMA_APPLICATION_ID_NAMES.length; i++) {
2355            mAppIdName = OMA_APPLICATION_ID_NAMES[i];
2356            mContentTypeValue = rd.nextInt(0x0FFF);
2357
2358            mMessageBody = new byte[100 + rd.nextInt(100)];
2359            rd.nextBytes(mMessageBody);
2360
2361            byte[] pdu = createPDU(6);
2362            byte[] wappushPdu = retrieveWspBody();
2363
2364            try {
2365                dataverify.resetData();
2366                // set up data
2367                if (isContentTypeMapped(mContentTypeValue)) {
2368                    // content type is mapped to integer value
2369                    mContentTypeName = getContentTypeName(mContentTypeValue);
2370                    Log.d(LOG_TAG, "mContentTypeValue mapping "
2371                            + mContentTypeValue + ":" + mContentTypeName);
2372                } else {
2373                    mContentTypeName = Integer.toString(mContentTypeValue);
2374                }
2375
2376                iwapman.addPackage(mAppIdName,
2377                        mContentTypeName, mPackageName, mClassName,
2378                        WapPushManagerParams.APP_TYPE_SERVICE, false, false);
2379
2380                dispatchWapPdu(wappushPdu, iwapman);
2381
2382                // clean up data
2383                iwapman.deletePackage(mAppIdName,
2384                        mContentTypeName, mPackageName, mClassName);
2385
2386                if (mContentTypeName.equals(WspTypeDecoder.CONTENT_TYPE_B_PUSH_CO)) {
2387                    assertTrue(dataverify.verifyData(wappushPdu));
2388                } else {
2389                    assertTrue(dataverify.verifyData(mMessageBody));
2390                }
2391            } catch (RemoteException e) {
2392            }
2393        }
2394
2395        mClassName = originalClassName;
2396        mAppIdName = originalAppIdName;
2397        mContentTypeName = originalContentTypeName;
2398        mAppIdValue = originalAppIdValue;
2399        mContentTypeValue = originalContentTypeValue;
2400        mMessageBody = originalMessageBody;
2401    }
2402
2403    /**
2404     * Integration test 4, iterate OmaApplication ID, Oma content type
2405     */
2406    public void testIntegration4() {
2407        boolean res;
2408        int originalAppIdValue = mAppIdValue;
2409        int originalContentTypeValue  = mContentTypeValue;
2410        String originalAppIdName = mAppIdName;
2411        String originalContentTypeName = mContentTypeName;
2412        String originalClassName = mClassName;
2413        byte[] originalMessageBody = mMessageBody;
2414        Random rd = new Random();
2415
2416        IWapPushManager iwapman = getInterface();
2417        IDataVerify dataverify = getVerifyInterface();
2418        mClassName = "com.android.smspush.unitTests.ReceiverService";
2419
2420        for (int i = 0; i < OMA_APPLICATION_ID_NAMES.length
2421                + OMA_CONTENT_TYPE_NAMES.length; i++) {
2422            mAppIdName = OMA_APPLICATION_ID_NAMES[rd.nextInt(OMA_APPLICATION_ID_NAMES.length)];
2423            int contIndex = rd.nextInt(OMA_CONTENT_TYPE_NAMES.length);
2424            mContentTypeName = OMA_CONTENT_TYPE_NAMES[contIndex];
2425
2426            mMessageBody = new byte[100 + rd.nextInt(100)];
2427            rd.nextBytes(mMessageBody);
2428
2429            byte[] pdu = createPDU(8);
2430            byte[] wappushPdu = retrieveWspBody();
2431
2432            try {
2433                dataverify.resetData();
2434                // set up data
2435                iwapman.addPackage(mAppIdName,
2436                        mContentTypeName, mPackageName, mClassName,
2437                        WapPushManagerParams.APP_TYPE_SERVICE, false, false);
2438
2439                dispatchWapPdu(wappushPdu, iwapman);
2440
2441                // clean up data
2442                iwapman.deletePackage(mAppIdName,
2443                        mContentTypeName, mPackageName, mClassName);
2444
2445                if (mContentTypeName.equals(WspTypeDecoder.CONTENT_TYPE_B_PUSH_CO)) {
2446                    assertTrue(dataverify.verifyData(wappushPdu));
2447                } else {
2448                    assertTrue(dataverify.verifyData(mMessageBody));
2449                }
2450            } catch (RemoteException e) {
2451            }
2452        }
2453
2454        mClassName = originalClassName;
2455        mAppIdName = originalAppIdName;
2456        mContentTypeName = originalContentTypeName;
2457        mAppIdValue = originalAppIdValue;
2458        mContentTypeValue = originalContentTypeValue;
2459        mMessageBody = originalMessageBody;
2460    }
2461
2462    /**
2463     * Integration test 5, iterate binary OmaApplication ID, Oma binary content type
2464     */
2465    public void testIntegration5() {
2466        boolean res;
2467        int originalAppIdValue = mAppIdValue;
2468        int originalContentTypeValue  = mContentTypeValue;
2469        String originalAppIdName = mAppIdName;
2470        String originalContentTypeName = mContentTypeName;
2471        String originalClassName = mClassName;
2472        byte[] originalMessageBody = mMessageBody;
2473        Random rd = new Random();
2474
2475        IWapPushManager iwapman = getInterface();
2476        IDataVerify dataverify = getVerifyInterface();
2477        mClassName = "com.android.smspush.unitTests.ReceiverService";
2478
2479        for (int i = 0; i < OMA_APPLICATION_ID_VALUES.length +
2480                    OMA_CONTENT_TYPE_VALUES.length; i++) {
2481            mAppIdValue = OMA_APPLICATION_ID_VALUES[rd.nextInt(
2482                    OMA_APPLICATION_ID_VALUES.length)];
2483            mContentTypeValue =
2484                    OMA_CONTENT_TYPE_VALUES[rd.nextInt(OMA_CONTENT_TYPE_VALUES.length)];
2485
2486            mMessageBody = new byte[100 + rd.nextInt(100)];
2487            rd.nextBytes(mMessageBody);
2488
2489            byte[] pdu = createPDU(3);
2490            byte[] wappushPdu = retrieveWspBody();
2491
2492            try {
2493                dataverify.resetData();
2494                // set up data
2495                if (isContentTypeMapped(mContentTypeValue)) {
2496                    // content type is mapped to integer value
2497                    mContentTypeName = getContentTypeName(mContentTypeValue);
2498                    Log.d(LOG_TAG, "mContentTypeValue mapping "
2499                            + mContentTypeValue + ":" + mContentTypeName);
2500                } else {
2501                    mContentTypeName = Integer.toString(mContentTypeValue);
2502                }
2503
2504                iwapman.addPackage(Integer.toString(mAppIdValue),
2505                        mContentTypeName, mPackageName, mClassName,
2506                        WapPushManagerParams.APP_TYPE_SERVICE, false, false);
2507
2508                dispatchWapPdu(wappushPdu, iwapman);
2509
2510                // clean up data
2511                iwapman.deletePackage(Integer.toString(mAppIdValue),
2512                        mContentTypeName, mPackageName, mClassName);
2513
2514                if (mContentTypeName.equals(WspTypeDecoder.CONTENT_TYPE_B_PUSH_CO)) {
2515                    assertTrue(dataverify.verifyData(wappushPdu));
2516                } else {
2517                    assertTrue(dataverify.verifyData(mMessageBody));
2518                }
2519            } catch (RemoteException e) {
2520            }
2521        }
2522
2523        mClassName = originalClassName;
2524        mAppIdName = originalAppIdName;
2525        mContentTypeName = originalContentTypeName;
2526        mAppIdValue = originalAppIdValue;
2527        mContentTypeValue = originalContentTypeValue;
2528        mMessageBody = originalMessageBody;
2529    }
2530
2531}
2532