CdmaInboundSmsHandlerTest.java revision 578df6250b7ca57ba044753b4bc62ad002cd8d40
1/*
2 * Copyright (C) 2016 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.internal.telephony.cdma;
18
19import android.content.ContentValues;
20import android.content.Context;
21import android.content.Intent;
22import android.os.AsyncResult;
23import android.os.HandlerThread;
24import android.os.RemoteException;
25import android.os.UserHandle;
26import android.os.UserManager;
27import android.provider.Telephony;
28import android.test.mock.MockContentResolver;
29import android.test.suitebuilder.annotation.MediumTest;
30
31import com.android.internal.telephony.InboundSmsHandler;
32import com.android.internal.telephony.SmsStorageMonitor;
33import com.android.internal.telephony.TelephonyTest;
34import com.android.internal.telephony.cdma.sms.SmsEnvelope;
35import com.android.internal.telephony.gsm.GsmInboundSmsHandlerTest;
36import com.android.internal.util.IState;
37import com.android.internal.util.StateMachine;
38
39import org.junit.After;
40import org.junit.Before;
41import org.junit.Test;
42import org.mockito.ArgumentCaptor;
43import org.mockito.Mock;
44
45import java.lang.reflect.Field;
46import java.lang.reflect.Method;
47
48import static com.android.internal.telephony.TelephonyTestUtils.waitForMs;
49import static org.junit.Assert.assertEquals;
50import static org.junit.Assert.assertFalse;
51import static org.junit.Assert.fail;
52import static org.mockito.Matchers.any;
53import static org.mockito.Mockito.anyBoolean;
54import static org.mockito.Mockito.anyInt;
55import static org.mockito.Mockito.doReturn;
56import static org.mockito.Mockito.never;
57import static org.mockito.Mockito.times;
58import static org.mockito.Mockito.verify;
59
60public class CdmaInboundSmsHandlerTest extends TelephonyTest {
61    @Mock
62    private SmsStorageMonitor mSmsStorageMonitor;
63    @Mock
64    private android.telephony.SmsMessage mSmsMessage;
65    @Mock
66    private SmsMessage mCdmaSmsMessage;
67
68    private CdmaInboundSmsHandler mCdmaInboundSmsHandler;
69    private SmsEnvelope mSmsEnvelope = new SmsEnvelope();
70    private ContentValues mInboundSmsTrackerCV = new ContentValues();
71
72    private class CdmaInboundSmsHandlerTestHandler extends HandlerThread {
73
74        private CdmaInboundSmsHandlerTestHandler(String name) {
75            super(name);
76        }
77
78        @Override
79        public void onLooperPrepared() {
80            mCdmaInboundSmsHandler = CdmaInboundSmsHandler.makeInboundSmsHandler(mContext,
81                    mSmsStorageMonitor, mPhone, null);
82            setReady(true);
83        }
84    }
85
86    private IState getCurrentState() {
87        try {
88            Method method = StateMachine.class.getDeclaredMethod("getCurrentState");
89            method.setAccessible(true);
90            return (IState) method.invoke(mCdmaInboundSmsHandler);
91        } catch (Exception e) {
92            fail(e.toString());
93            return null;
94        }
95    }
96
97    @Before
98    public void setUp() throws Exception {
99        super.setUp("CdmaInboundSmsHandlerTest");
100
101        Field field = SmsMessage.class.getDeclaredField("mEnvelope");
102        field.setAccessible(true);
103        field.set(mCdmaSmsMessage, mSmsEnvelope);
104
105        UserManager userManager = (UserManager) mContextFixture.getTestDouble().
106                getSystemService(Context.USER_SERVICE);
107        doReturn(true).when(userManager).isUserUnlocked();
108
109        try {
110            doReturn(new int[]{UserHandle.USER_SYSTEM}).when(mIActivityManager).getRunningUserIds();
111        } catch (RemoteException re) {
112            fail("Unexpected RemoteException: " + re.getStackTrace());
113        }
114
115        byte[] smsPdu = new byte[]{(byte)0xFF, (byte)0xFF, (byte)0xFF};
116        mSmsMessage.mWrappedSmsMessage = mCdmaSmsMessage;
117        doReturn(smsPdu).when(mCdmaSmsMessage).getPdu();
118
119        doReturn(true).when(mTelephonyManager).getSmsReceiveCapableForPhone(anyInt(), anyBoolean());
120        doReturn(true).when(mSmsStorageMonitor).isStorageAvailable();
121        doReturn(1).when(mInboundSmsTracker).getMessageCount();
122        doReturn(-1).when(mInboundSmsTracker).getDestPort();
123        doReturn(mInboundSmsTrackerCV).when(mInboundSmsTracker).getContentValues();
124        doReturn(smsPdu).when(mInboundSmsTracker).getPdu();
125
126        GsmInboundSmsHandlerTest.FakeSmsContentProvider contentProvider =
127                new GsmInboundSmsHandlerTest.FakeSmsContentProvider();
128        ((MockContentResolver)mContext.getContentResolver()).addProvider(
129                Telephony.Sms.CONTENT_URI.getAuthority(), contentProvider);
130
131        new CdmaInboundSmsHandlerTestHandler(TAG).start();
132        waitUntilReady();
133    }
134
135    @After
136    public void tearDown() throws Exception {
137        // wait for wakelock to be released; timeout at 10s
138        int i = 0;
139        while (mCdmaInboundSmsHandler.getWakeLock().isHeld() && i < 100) {
140            waitForMs(100);
141            i++;
142        }
143        assertFalse(mCdmaInboundSmsHandler.getWakeLock().isHeld());
144        mCdmaInboundSmsHandler = null;
145        super.tearDown();
146    }
147
148    private void transitionFromStartupToIdle() {
149        // verify initially in StartupState
150        assertEquals("StartupState", getCurrentState().getName());
151
152        // trigger transition to IdleState
153        mCdmaInboundSmsHandler.sendMessage(InboundSmsHandler.EVENT_START_ACCEPTING_SMS);
154        waitForMs(50);
155
156        assertEquals("IdleState", getCurrentState().getName());
157    }
158
159    @Test
160    @MediumTest
161    public void testNewSms() {
162        transitionFromStartupToIdle();
163
164        // send new SMS to state machine and verify that triggers SMS_DELIVER_ACTION
165        doReturn(SmsEnvelope.TELESERVICE_WMT).when(mCdmaSmsMessage).getTeleService();
166        mCdmaInboundSmsHandler.sendMessage(InboundSmsHandler.EVENT_NEW_SMS,
167                new AsyncResult(null, mSmsMessage, null));
168        waitForMs(100);
169
170        ArgumentCaptor<Intent> intentArgumentCaptor = ArgumentCaptor.forClass(Intent.class);
171        verify(mContext).sendBroadcast(intentArgumentCaptor.capture());
172        assertEquals(Telephony.Sms.Intents.SMS_DELIVER_ACTION,
173                intentArgumentCaptor.getValue().getAction());
174        assertEquals("WaitingState", getCurrentState().getName());
175
176        mContextFixture.sendBroadcastToOrderedBroadcastReceivers();
177
178        intentArgumentCaptor = ArgumentCaptor.forClass(Intent.class);
179        verify(mContext, times(2)).sendBroadcast(intentArgumentCaptor.capture());
180        assertEquals(Telephony.Sms.Intents.SMS_RECEIVED_ACTION,
181                intentArgumentCaptor.getAllValues().get(1).getAction());
182        assertEquals("WaitingState", getCurrentState().getName());
183
184        mContextFixture.sendBroadcastToOrderedBroadcastReceivers();
185        waitForMs(50);
186
187        assertEquals("IdleState", getCurrentState().getName());
188    }
189
190    @Test
191    @MediumTest
192    public void testNewSmsFromBlockedNumber_noBroadcastsSent() {
193        String blockedNumber = "123456789";
194        doReturn(blockedNumber).when(mInboundSmsTracker).getAddress();
195        mFakeBlockedNumberContentProvider.mBlockedNumbers.add(blockedNumber);
196
197        transitionFromStartupToIdle();
198
199        doReturn(SmsEnvelope.TELESERVICE_WMT).when(mCdmaSmsMessage).getTeleService();
200        mCdmaInboundSmsHandler.sendMessage(InboundSmsHandler.EVENT_NEW_SMS,
201                new AsyncResult(null, mSmsMessage, null));
202        waitForMs(100);
203
204        verify(mContext, never()).sendBroadcast(any(Intent.class));
205        assertEquals("IdleState", getCurrentState().getName());
206    }
207}
208