• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2009 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 
17 package android.telephony.cts;
18 
19 import static androidx.test.InstrumentationRegistry.getContext;
20 
21 import static org.junit.Assert.assertEquals;
22 import static org.junit.Assert.assertFalse;
23 import static org.junit.Assert.assertNotNull;
24 import static org.junit.Assert.assertNull;
25 import static org.junit.Assert.assertTrue;
26 import static org.junit.Assert.fail;
27 
28 import android.content.Context;
29 import android.content.pm.PackageManager;
30 import android.telephony.SmsMessage;
31 import android.telephony.TelephonyManager;
32 
33 import org.junit.Before;
34 import org.junit.Test;
35 
36 public class SmsMessageTest {
37 
38     private TelephonyManager mTelephonyManager;
39     private PackageManager mPackageManager;
40 
41     private static final String DISPLAY_MESSAGE_BODY = "test subject /test body";
42     private static final String DMB = "{ testBody[^~\\] }";
43     private static final String EMAIL_ADD = "foo@example.com";
44     private static final String EMAIL_FROM = "foo@example.com";
45     private static final String MB = DMB;
46     private static final String MESSAGE_BODY1 = "Test";
47     private static final String MESSAGE_BODY2 = "(Subject)Test";
48     private static final String MESSAGE_BODY3 = "\u2122\u00a9\u00aehello";
49     private static final String MESSAGE_BODY4 = " ";
50     private static final String MESSAGE_BODY5 = " ";
51     private static final String OA = "foo@example.com";
52     private static final String OA1 = "+14154255486";
53     private static final String OA2 = "+15122977683";
54     private static final String OA3 = "_@";
55     private static final String OA4 = "\u0394@";
56     // pseudo subject will always be empty
57     private static final String PSEUDO_SUBJECT = "";
58     private static final String SCA1 = "+16466220020";
59     private static final String SCA2 = "+12063130012";
60     private static final String SCA3 = "+14155551212";
61     private static final String SCA4 = "+14155551212";
62     private static final int NOT_CREATE_FROM_SIM = -1;
63     private static final int NOT_CREATE_FROM_ICC = -1;
64     private static final int PROTOCOL_IDENTIFIER = 0;
65     private static final int SMS_NUMBER1 = 1;
66     private static final int SMS_NUMBER2 = 1;
67     private static final int SMS_NUMBER3 = 1;
68     private static final int STATUS = 0;
69     private static final int STATUS_ON_SIM_DEF = -1;
70     private static final int STATUS_ON_ICC_DEF = -1;
71     private static final int TPLAYER_LENGTH_FOR_PDU = 23;
72     private static final long TIMESTAMP_MILLIS = 1149631383000l;
73     private static final int SEPTETS_SKT = 80;
74     private static final int SEPTETS_KT = 90;
75     private static final String LONG_TEXT_WITH_32BIT_CHARS =
76         "Long dkkshsh jdjsusj kbsksbdf jfkhcu hhdiwoqiwyrygrvn?*?*!\";:'/,."
77         + "__?9#9292736&4;\"$+$+((]\\[\\℅©℅™^®°¥°¥=¢£}}£∆~¶~÷|√×."
78         + " ������������������������������⛪⛲ ";
79     private static final String LONG_TEXT_WITH_FLAGS =
80         "��������������������������������������������������������"
81         + "������������������������������������������������������������";
82 
83     @Before
setUp()84     public void setUp() throws Exception {
85         mTelephonyManager =
86             (TelephonyManager) getContext().getSystemService(Context.TELEPHONY_SERVICE);
87         mPackageManager = getContext().getPackageManager();
88     }
89 
90     @Test
testCreateFromPdu()91     public void testCreateFromPdu() throws Exception {
92         if (!mPackageManager.hasSystemFeature(PackageManager.FEATURE_TELEPHONY)
93                 || mPackageManager.hasSystemFeature(PackageManager.FEATURE_TELEPHONY_CDMA)) {
94             // TODO: temp workaround, need to adjust test to use CDMA pdus
95             return;
96         }
97 
98         String pdu = "07916164260220F0040B914151245584F600006060605130308A04D4F29C0E";
99         SmsMessage sms = SmsMessage.createFromPdu(hexStringToByteArray(pdu),
100                 SmsMessage.FORMAT_3GPP);
101         assertEquals(SCA1, sms.getServiceCenterAddress());
102         assertEquals(OA1, sms.getOriginatingAddress());
103         assertEquals(MESSAGE_BODY1, sms.getMessageBody());
104         assertEquals(TPLAYER_LENGTH_FOR_PDU, SmsMessage.getTPLayerLengthForPDU(pdu));
105         int[] result = SmsMessage.calculateLength(sms.getMessageBody(), true);
106         assertEquals(SMS_NUMBER1, result[0]);
107         assertEquals(sms.getMessageBody().length(), result[1]);
108         assertRemaining(sms.getMessageBody().length(), result[2], SmsMessage.MAX_USER_DATA_SEPTETS);
109         assertEquals(SmsMessage.ENCODING_7BIT, result[3]);
110         assertEquals(pdu, toHexString(sms.getPdu()));
111 
112         assertEquals(NOT_CREATE_FROM_SIM, sms.getIndexOnSim());
113         assertEquals(NOT_CREATE_FROM_ICC, sms.getIndexOnIcc());
114         assertEquals(PROTOCOL_IDENTIFIER, sms.getProtocolIdentifier());
115         assertFalse(sms.isEmail());
116         assertFalse(sms.isReplyPathPresent());
117         assertFalse(sms.isStatusReportMessage());
118         assertFalse(sms.isCphsMwiMessage());
119         assertEquals(SmsMessage.MessageClass.UNKNOWN, sms.getMessageClass());
120         assertEquals(STATUS, sms.getStatus());
121         assertEquals(STATUS_ON_SIM_DEF, sms.getStatusOnSim());
122         assertEquals(STATUS_ON_ICC_DEF, sms.getStatusOnIcc());
123         assertEquals(TIMESTAMP_MILLIS, sms.getTimestampMillis());
124 
125         // Test create from null Pdu
126         sms = SmsMessage.createFromPdu(null, SmsMessage.FORMAT_3GPP);
127         assertNull(sms);
128 
129         // Test create from long Pdu
130         pdu = "07912160130310F2040B915121927786F300036060924180008A0DA"
131             + "8695DAC2E8FE9296A794E07";
132         sms = SmsMessage.createFromPdu(hexStringToByteArray(pdu), SmsMessage.FORMAT_3GPP);
133         assertEquals(SCA2, sms.getServiceCenterAddress());
134         assertEquals(OA2, sms.getOriginatingAddress());
135         assertEquals(MESSAGE_BODY2, sms.getMessageBody());
136         CharSequence msgBody = sms.getMessageBody();
137         result = SmsMessage.calculateLength(msgBody, false);
138         assertEquals(SMS_NUMBER2, result[0]);
139         assertEquals(sms.getMessageBody().length(), result[1]);
140         assertRemaining(sms.getMessageBody().length(), result[2], SmsMessage.MAX_USER_DATA_SEPTETS);
141         assertEquals(SmsMessage.ENCODING_7BIT, result[3]);
142 
143         // Test createFromPdu Ucs to Sms
144         pdu = "07912160130300F4040B914151245584"
145             + "F600087010807121352B10212200A900AE00680065006C006C006F";
146         sms = SmsMessage.createFromPdu(hexStringToByteArray(pdu), SmsMessage.FORMAT_3GPP);
147         assertEquals(MESSAGE_BODY3, sms.getMessageBody());
148         result = SmsMessage.calculateLength(sms.getMessageBody(), true);
149         assertEquals(SMS_NUMBER3, result[0]);
150         assertEquals(sms.getMessageBody().length(), result[1]);
151         assertRemaining(sms.getMessageBody().length(), result[2], SmsMessage.MAX_USER_DATA_SEPTETS);
152         assertEquals(SmsMessage.ENCODING_7BIT, result[3]);
153     }
154 
assertRemaining(int messageLength, int remaining, int maxChars)155     private void assertRemaining(int messageLength, int remaining, int maxChars) {
156         if (TelephonyUtils.isSkt(mTelephonyManager)) {
157             assertTrue(checkRemaining(SEPTETS_SKT, messageLength, remaining)
158                     || checkRemaining(maxChars, messageLength, remaining));
159         } else if (TelephonyUtils.isKt(mTelephonyManager)) {
160             assertTrue(checkRemaining(SEPTETS_KT, messageLength, remaining)
161                     || checkRemaining(maxChars, messageLength, remaining));
162         } else {
163             assertTrue(checkRemaining(maxChars, messageLength, remaining));
164         }
165     }
166 
checkRemaining(int total, int messageLength, int remaining)167     private boolean checkRemaining(int total, int messageLength, int remaining) {
168         return total - messageLength == remaining;
169     }
170 
171     @Test
testCPHSVoiceMail()172     public void testCPHSVoiceMail() throws Exception {
173         if (!mPackageManager.hasSystemFeature(PackageManager.FEATURE_TELEPHONY)
174                 || mPackageManager.hasSystemFeature(PackageManager.FEATURE_TELEPHONY_CDMA)) {
175             // TODO: temp workaround, need to adjust test to use CDMA pdus
176             return;
177         }
178 
179         // "set MWI flag"
180         String pdu = "07912160130310F20404D0110041006060627171118A0120";
181         SmsMessage sms = SmsMessage.createFromPdu(hexStringToByteArray(pdu),
182                 SmsMessage.FORMAT_3GPP);
183         assertTrue(sms.isReplace());
184         assertEquals(OA3, sms.getOriginatingAddress());
185         assertEquals(MESSAGE_BODY4, sms.getMessageBody());
186         assertTrue(sms.isMWISetMessage());
187 
188         // "clear mwi flag"
189         pdu = "07912160130310F20404D0100041006021924193352B0120";
190         sms = SmsMessage.createFromPdu(hexStringToByteArray(pdu), SmsMessage.FORMAT_3GPP);
191         assertTrue(sms.isMWIClearMessage());
192 
193         // "clear MWI flag"
194         pdu = "07912160130310F20404D0100041006060627161058A0120";
195         sms = SmsMessage.createFromPdu(hexStringToByteArray(pdu), SmsMessage.FORMAT_3GPP);
196         assertTrue(sms.isReplace());
197         assertEquals(OA4, sms.getOriginatingAddress());
198         assertEquals(MESSAGE_BODY5, sms.getMessageBody());
199         assertTrue(sms.isMWIClearMessage());
200 
201         // "set MWI flag"
202         pdu = "07912180958750F84401800500C87020026195702B06040102000200";
203         sms = SmsMessage.createFromPdu(hexStringToByteArray(pdu), SmsMessage.FORMAT_3GPP);
204         assertTrue(sms.isMWISetMessage());
205         assertTrue(sms.isMwiDontStore());
206 
207         // "clear mwi flag"
208         pdu = "07912180958750F84401800500C07020027160112B06040102000000";
209         sms = SmsMessage.createFromPdu(hexStringToByteArray(pdu), SmsMessage.FORMAT_3GPP);
210 
211         assertTrue(sms.isMWIClearMessage());
212         assertTrue(sms.isMwiDontStore());
213     }
214 
215     @Test
testGetUserData()216     public void testGetUserData() throws Exception {
217         if (!mPackageManager.hasSystemFeature(PackageManager.FEATURE_TELEPHONY)
218                 || mPackageManager.hasSystemFeature(PackageManager.FEATURE_TELEPHONY_CDMA)) {
219             // TODO: temp workaround, need to adjust test to use CDMA pdus
220             return;
221         }
222 
223         String pdu = "07914140279510F6440A8111110301003BF56080207130138A8C0B05040B8423F"
224             + "000032A02010106276170706C69636174696F6E2F766E642E7761702E6D6D732D"
225             + "6D65737361676500AF848D0185B4848C8298524E453955304A6D7135514141426"
226             + "66C414141414D7741414236514141414141008D908918802B3135313232393737"
227             + "3638332F545950453D504C4D4E008A808E022B918805810306977F83687474703"
228             + "A2F2F36";
229         SmsMessage sms = SmsMessage.createFromPdu(hexStringToByteArray(pdu),
230                 SmsMessage.FORMAT_3GPP);
231         byte[] userData = sms.getUserData();
232         assertNotNull(userData);
233     }
234 
235     @Test
testGetSubmitPdu()236     public void testGetSubmitPdu() throws Exception {
237         if (!mPackageManager.hasSystemFeature(PackageManager.FEATURE_TELEPHONY)) {
238             return;
239         }
240 
241         String scAddress = null, destinationAddress = null;
242         String message = null;
243         boolean statusReportRequested = false;
244 
245         try {
246             // null message, null destination
247             SmsMessage.getSubmitPdu(scAddress, destinationAddress, message, statusReportRequested);
248             fail("Should throw NullPointerException");
249         } catch (NullPointerException expected) {
250             // expected
251         }
252 
253         message = "This is a test message";
254         try {
255             // non-null message
256             SmsMessage.getSubmitPdu(scAddress, destinationAddress, message, statusReportRequested);
257             fail("Should throw NullPointerException");
258         } catch (NullPointerException expected) {
259             // expected
260         }
261 
262         if (mTelephonyManager.getPhoneType() == TelephonyManager.PHONE_TYPE_CDMA) {
263             // TODO: temp workaround, OCTET encoding for EMS not properly supported
264             return;
265         }
266 
267         scAddress = "1650253000";
268         destinationAddress = "18004664411";
269         message = "This is a test message";
270         statusReportRequested = false;
271         SmsMessage.SubmitPdu smsPdu =
272             SmsMessage.getSubmitPdu(scAddress, destinationAddress, message, statusReportRequested);
273         assertNotNull(smsPdu);
274 
275         smsPdu = SmsMessage.getSubmitPdu(scAddress, destinationAddress, (short)80,
276                 message.getBytes(), statusReportRequested);
277         assertNotNull(smsPdu);
278     }
279 
280     @Test
testEmailGateway()281     public void testEmailGateway() throws Exception {
282         if (!mPackageManager.hasSystemFeature(PackageManager.FEATURE_TELEPHONY)
283                 || mPackageManager.hasSystemFeature(PackageManager.FEATURE_TELEPHONY_CDMA)) {
284             // TODO: temp workaround, need to adjust test to use CDMA pdus
285             return;
286         }
287 
288         String pdu = "07914151551512f204038105f300007011103164638a28e6f71b50c687db" +
289                          "7076d9357eb7412f7a794e07cdeb6275794c07bde8e5391d247e93f3";
290 
291         SmsMessage sms = SmsMessage.createFromPdu(hexStringToByteArray(pdu),
292                 SmsMessage.FORMAT_3GPP);
293         assertEquals(SCA4, sms.getServiceCenterAddress());
294         assertTrue(sms.isEmail());
295         assertEquals(EMAIL_ADD, sms.getEmailFrom());
296         assertEquals(EMAIL_ADD, sms.getDisplayOriginatingAddress());
297         assertEquals(PSEUDO_SUBJECT, sms.getPseudoSubject());
298 
299         assertEquals(DISPLAY_MESSAGE_BODY, sms.getDisplayMessageBody());
300         assertEquals(DISPLAY_MESSAGE_BODY, sms.getEmailBody());
301 
302         pdu = "07914151551512f204038105f400007011103105458a29e6f71b50c687db" +
303                         "7076d9357eb741af0d0a442fcfe9c23739bfe16d289bdee6b5f1813629";
304         sms = SmsMessage.createFromPdu(hexStringToByteArray(pdu), SmsMessage.FORMAT_3GPP);
305         assertEquals(SCA3, sms.getServiceCenterAddress());
306         assertTrue(sms.isEmail());
307         assertEquals(OA, sms.getDisplayOriginatingAddress());
308         assertEquals(EMAIL_FROM, sms.getEmailFrom());
309         assertEquals(DMB, sms.getDisplayMessageBody());
310         assertEquals(MB, sms.getEmailBody());
311     }
312 
313     @Test
testCalculateLength()314     public void testCalculateLength() throws Exception {
315         if (!mPackageManager.hasSystemFeature(PackageManager.FEATURE_TELEPHONY)) {
316             return;
317         }
318 
319         int[] result = SmsMessage.calculateLength(LONG_TEXT_WITH_32BIT_CHARS, false);
320         assertEquals(3, result[0]);
321         assertEquals(LONG_TEXT_WITH_32BIT_CHARS.length(), result[1]);
322         // 3 parts, each with (SmsMessage.MAX_USER_DATA_BYTES_WITH_HEADER / 2) 16-bit
323         // characters. We need to subtract one because a 32-bit character crosses the
324         // boundary of 2 parts.
325         int preMaxChars = 3 * SmsMessage.MAX_USER_DATA_BYTES_WITH_HEADER / 2 - 1;
326         // If EMS is not supported, break down EMS into single segment SMS
327         // and add page info "x/y".
328         // In the case of UCS2 encoding type, we need 8 bytes for this
329         // but we only have 6 bytes from UDH, so truncate the limit for
330         // each segment by 2 bytes (1 char). This log sms has three segments,
331         // so truncate the limit by 3 char in total
332         int maxChars = SmsMessage.hasEmsSupport() ? preMaxChars : preMaxChars - 3;
333         assertRemaining(LONG_TEXT_WITH_32BIT_CHARS.length(), result[2],
334                 maxChars);
335         assertEquals(SmsMessage.ENCODING_16BIT, result[3]);
336     }
337 
338     @Test
testCalculateLengthFlags()339     public void testCalculateLengthFlags() throws Exception {
340         if (!mPackageManager.hasSystemFeature(PackageManager.FEATURE_TELEPHONY)) {
341             return;
342         }
343         int[] result = SmsMessage.calculateLength(LONG_TEXT_WITH_FLAGS, false);
344         assertEquals(2, result[0]);
345     }
346 
347     private final static char[] HEX_DIGITS = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
348             'A', 'B', 'C', 'D', 'E', 'F' };
349 
toHexString(byte[] array)350     public static String toHexString(byte[] array) {
351         int length = array.length;
352         char[] buf = new char[length * 2];
353 
354         int bufIndex = 0;
355         for (int i = 0 ; i < length; i++)
356         {
357             byte b = array[i];
358             buf[bufIndex++] = HEX_DIGITS[(b >>> 4) & 0x0F];
359             buf[bufIndex++] = HEX_DIGITS[b & 0x0F];
360         }
361 
362         return new String(buf);
363     }
364 
toByte(char c)365     private static int toByte(char c) {
366         if (c >= '0' && c <= '9') return (c - '0');
367         if (c >= 'A' && c <= 'F') return (c - 'A' + 10);
368         if (c >= 'a' && c <= 'f') return (c - 'a' + 10);
369 
370         throw new RuntimeException ("Invalid hex char '" + c + "'");
371     }
372 
hexStringToByteArray(String hexString)373     private static byte[] hexStringToByteArray(String hexString) {
374         int length = hexString.length();
375         byte[] buffer = new byte[length / 2];
376 
377         for (int i = 0 ; i < length ; i += 2) {
378             buffer[i / 2] =
379                 (byte)((toByte(hexString.charAt(i)) << 4) | toByte(hexString.charAt(i+1)));
380         }
381 
382         return buffer;
383     }
384 }
385