CdmaInboundSmsHandlerTest.java revision 27f471647b2da3ff50620a766c048ebef8d45ae1
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.SmallTest;
31
32import com.android.internal.telephony.InboundSmsHandler;
33import com.android.internal.telephony.SmsStorageMonitor;
34import com.android.internal.telephony.TelephonyTest;
35import com.android.internal.telephony.cdma.sms.SmsEnvelope;
36import com.android.internal.telephony.gsm.GsmInboundSmsHandlerTest;
37import com.android.internal.util.IState;
38import com.android.internal.util.StateMachine;
39
40import org.junit.After;
41import org.junit.Before;
42import org.junit.Test;
43import org.mockito.ArgumentCaptor;
44import org.mockito.Mock;
45
46import java.lang.reflect.Field;
47import java.lang.reflect.Method;
48
49import static com.android.internal.telephony.TelephonyTestUtils.waitForMs;
50import static org.junit.Assert.assertEquals;
51import static org.junit.Assert.assertFalse;
52import static org.junit.Assert.fail;
53import static org.mockito.Mockito.anyBoolean;
54import static org.mockito.Mockito.anyInt;
55import static org.mockito.Mockito.doReturn;
56import static org.mockito.Mockito.times;
57import static org.mockito.Mockito.verify;
58
59public class CdmaInboundSmsHandlerTest extends TelephonyTest {
60    @Mock
61    private SmsStorageMonitor mSmsStorageMonitor;
62    @Mock
63    private android.telephony.SmsMessage mSmsMessage;
64    @Mock
65    private SmsMessage mCdmaSmsMessage;
66
67    private CdmaInboundSmsHandler mCdmaInboundSmsHandler;
68    private TelephonyManager mTelephonyManager;
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        mTelephonyManager = TelephonyManager.from(mContext);
120        doReturn(true).when(mTelephonyManager).getSmsReceiveCapableForPhone(anyInt(), anyBoolean());
121        doReturn(true).when(mSmsStorageMonitor).isStorageAvailable();
122        doReturn(1).when(mInboundSmsTracker).getMessageCount();
123        doReturn(-1).when(mInboundSmsTracker).getDestPort();
124        doReturn(mInboundSmsTrackerCV).when(mInboundSmsTracker).getContentValues();
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        if (mCdmaInboundSmsHandler.getWakeLock().isHeld()) {
138            waitForMs(mCdmaInboundSmsHandler.getWakeLockTimeout() + 50);
139        }
140        assertFalse(mCdmaInboundSmsHandler.getWakeLock().isHeld());
141        mCdmaInboundSmsHandler = null;
142        super.tearDown();
143    }
144
145    private void transitionFromStartupToIdle() {
146        // verify initially in StartupState
147        assertEquals("StartupState", getCurrentState().getName());
148
149        // trigger transition to IdleState
150        mCdmaInboundSmsHandler.sendMessage(InboundSmsHandler.EVENT_START_ACCEPTING_SMS);
151        waitForMs(50);
152
153        assertEquals("IdleState", getCurrentState().getName());
154    }
155
156    @Test
157    @SmallTest
158    public void testNewSms() {
159        transitionFromStartupToIdle();
160
161        // send new SMS to state machine and verify that triggers SMS_DELIVER_ACTION
162        doReturn(SmsEnvelope.TELESERVICE_WMT).when(mCdmaSmsMessage).getTeleService();
163        mCdmaInboundSmsHandler.sendMessage(InboundSmsHandler.EVENT_NEW_SMS,
164                new AsyncResult(null, mSmsMessage, null));
165        waitForMs(100);
166
167        ArgumentCaptor<Intent> intentArgumentCaptor = ArgumentCaptor.forClass(Intent.class);
168        verify(mContext).sendBroadcast(intentArgumentCaptor.capture());
169        assertEquals(Telephony.Sms.Intents.SMS_DELIVER_ACTION,
170                intentArgumentCaptor.getValue().getAction());
171        assertEquals("WaitingState", getCurrentState().getName());
172
173        mContextFixture.sendBroadcastToOrderedBroadcastReceivers();
174
175        intentArgumentCaptor = ArgumentCaptor.forClass(Intent.class);
176        verify(mContext, times(2)).sendBroadcast(intentArgumentCaptor.capture());
177        assertEquals(Telephony.Sms.Intents.SMS_RECEIVED_ACTION,
178                intentArgumentCaptor.getAllValues().get(1).getAction());
179        assertEquals("WaitingState", getCurrentState().getName());
180
181        mContextFixture.sendBroadcastToOrderedBroadcastReceivers();
182        waitForMs(50);
183
184        assertEquals("IdleState", getCurrentState().getName());
185    }
186}
187