• 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.permission2.cts;
18 
19 import android.app.Activity;
20 import android.app.PendingIntent;
21 import android.content.BroadcastReceiver;
22 import android.content.Context;
23 import android.content.Intent;
24 import android.content.IntentFilter;
25 import android.content.pm.PackageManager;
26 import android.telephony.SmsManager;
27 import android.telephony.TelephonyManager;
28 import android.test.AndroidTestCase;
29 import android.text.TextUtils;
30 import android.util.Log;
31 
32 /**
33  * Verify Sms and Mms cannot be received without required permissions.
34  * Uses {@link android.telephony.SmsManager}.
35  */
36 public class NoReceiveSmsPermissionTest extends AndroidTestCase {
37 
38     // time to wait for sms to get delivered - currently 2 minutes
39     private static final int WAIT_TIME = 2*60*1000;
40     private static final String TELEPHONY_SMS_RECEIVED = "android.provider.Telephony.SMS_RECEIVED";
41     private static final String MESSAGE_STATUS_RECEIVED_ACTION =
42         "com.android.cts.permission.sms.MESSAGE_STATUS_RECEIVED_ACTION";
43     private static final String MESSAGE_SENT_ACTION =
44         "com.android.cts.permission.sms.MESSAGE_SENT";
45 
46     private static final String LOG_TAG = "NoReceiveSmsPermissionTest";
47 
48     /**
49      * Verify that SmsManager.sendTextMessage requires permissions.
50      * <p>Tests Permission:
51      *   {@link android.Manifest.permission#SEND_SMS}.
52      *
53      * Note: this test requires that the device under test reports a valid phone number
54      */
testReceiveTextMessage()55     public void testReceiveTextMessage() {
56         PackageManager packageManager = mContext.getPackageManager();
57         if (!packageManager.hasSystemFeature(PackageManager.FEATURE_TELEPHONY)) {
58             return;
59         }
60 
61         // register our test receiver to receive SMSs. This won't throw a SecurityException,
62         // so test needs to wait to determine if it actual receives an SMS
63         // admittedly, this is a weak verification
64         // this test should be used in conjunction with a test that verifies an SMS can be
65         // received successfully using the same logic if all permissions are in place
66         IllegalSmsReceiver receiver = new IllegalSmsReceiver();
67         IntentFilter filter = new IntentFilter();
68         filter.addAction(TELEPHONY_SMS_RECEIVED);
69         filter.addAction(MESSAGE_SENT_ACTION);
70         filter.addAction(MESSAGE_STATUS_RECEIVED_ACTION);
71 
72         getContext().registerReceiver(receiver, filter);
73         sendSMSToSelf();
74         synchronized(receiver) {
75             try {
76                 receiver.wait(WAIT_TIME);
77             } catch (InterruptedException e) {
78                 Log.w(LOG_TAG, "wait for sms interrupted");
79             }
80         }
81 
82         assertTrue("[RERUN] Sms not sent successfully. Check signal.",
83                 receiver.isMessageSent());
84         assertFalse("Sms received without proper permissions", receiver.isSmsReceived());
85     }
86 
sendSMSToSelf()87     private void sendSMSToSelf() {
88         PendingIntent sentIntent = PendingIntent.getBroadcast(getContext(), 0,
89                 new Intent(MESSAGE_SENT_ACTION), PendingIntent.FLAG_ONE_SHOT);
90         PendingIntent deliveryIntent = PendingIntent.getBroadcast(getContext(), 0,
91                 new Intent(MESSAGE_STATUS_RECEIVED_ACTION), PendingIntent.FLAG_ONE_SHOT);
92 
93         TelephonyManager telephony = (TelephonyManager)
94                  getContext().getSystemService(Context.TELEPHONY_SERVICE);
95         // get current phone number
96         String currentNumber = telephony.getLine1Number();
97         assertFalse("[RERUN] SIM card does not provide phone number. Use a suitable SIM Card.",
98                 TextUtils.isEmpty(currentNumber));
99 
100         Log.i(LOG_TAG, String.format("Sending SMS to self: %s", currentNumber));
101         sendSms(currentNumber, "test message", sentIntent, deliveryIntent);
102     }
103 
sendSms(String currentNumber, String text, PendingIntent sentIntent, PendingIntent deliveryIntent)104     protected void sendSms(String currentNumber, String text, PendingIntent sentIntent,
105             PendingIntent deliveryIntent) {
106         SmsManager.getDefault().sendTextMessage(currentNumber, null, text, sentIntent,
107                 deliveryIntent);
108     }
109 
110     /**
111      * A receiver that tracks if message was sent and received
112      */
113     public class IllegalSmsReceiver extends BroadcastReceiver {
114 
115         private boolean mIsSmsReceived = false;
116         private boolean mIsMessageSent = false;
117 
onReceive(Context context, Intent intent)118         public void onReceive(Context context, Intent intent) {
119             if (TELEPHONY_SMS_RECEIVED.equals(intent.getAction())) {
120                 // this is bad, received sms without having SMS permission
121                 setSmsReceived();
122             } else if (MESSAGE_STATUS_RECEIVED_ACTION.equals(intent.getAction())) {
123                 handleResultCode(getResultCode(), "delivery");
124             } else if (MESSAGE_SENT_ACTION.equals(intent.getAction())) {
125                 handleResultCode(getResultCode(), "sent");
126             } else {
127                 Log.w(LOG_TAG, String.format("unknown intent received: %s", intent.getAction()));
128             }
129 
130         }
131 
isSmsReceived()132         public boolean isSmsReceived() {
133             return mIsSmsReceived;
134         }
135 
setSmsReceived()136         private synchronized void setSmsReceived() {
137             mIsSmsReceived = true;
138             notify();
139         }
140 
isMessageSent()141         public boolean isMessageSent() {
142             return mIsMessageSent;
143         }
144 
handleResultCode(int resultCode, String action)145         private void handleResultCode(int resultCode, String action) {
146             if (resultCode == Activity.RESULT_OK) {
147                 Log.i(LOG_TAG, String.format("message %1$s successful", action));
148                 setMessageSentSuccess();
149             } else {
150                 setMessageSentFailure();
151                 String reason = getErrorReason(resultCode);
152                 Log.e(LOG_TAG, String.format("message %1$s failed: %2$s", action, reason));
153             }
154         }
155 
setMessageSentSuccess()156         private synchronized void setMessageSentSuccess() {
157             mIsMessageSent = true;
158             // set this to true, but don't notify receiver since we don't know if message received
159             // yet
160         }
161 
setMessageSentFailure()162         private synchronized void setMessageSentFailure() {
163             mIsMessageSent = false;
164             // test environment failure, notify observer so it can stop listening
165             // TODO: should test retry?
166             notify();
167         }
168 
getErrorReason(int resultCode)169         private String getErrorReason(int resultCode) {
170             switch (resultCode) {
171                 case SmsManager.RESULT_ERROR_GENERIC_FAILURE:
172                     return "generic failure";
173                 case SmsManager.RESULT_ERROR_NO_SERVICE:
174                     return "no service";
175                 case SmsManager.RESULT_ERROR_NULL_PDU:
176                     return "null pdu";
177                 case SmsManager.RESULT_ERROR_RADIO_OFF:
178                     return "Radio off";
179             }
180             return "unknown";
181         }
182     }
183 }
184