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