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