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