CdmaInboundSmsHandlerTest.java revision a8857077b00d6c2856b3335a62ac43ae5403c142
1/*
2 * Copyright (C) 2015 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.BroadcastReceiver;
20import android.content.Context;
21import android.content.Intent;
22import android.os.AsyncResult;
23import android.os.Bundle;
24import android.os.Handler;
25import android.os.HandlerThread;
26import android.os.IBinder;
27import android.os.IDeviceIdleController;
28import android.os.ServiceManager;
29import android.os.UserHandle;
30import android.provider.Telephony;
31import android.telephony.*;
32import android.test.suitebuilder.annotation.SmallTest;
33import android.util.Log;
34
35import com.android.internal.telephony.CommandsInterface;
36import com.android.internal.telephony.ContextFixture;
37import com.android.internal.telephony.GsmCdmaPhone;
38import com.android.internal.telephony.InboundSmsHandler;
39import com.android.internal.telephony.Phone;
40import com.android.internal.telephony.SmsBroadcastUndelivered;
41import com.android.internal.telephony.SmsMessageBase;
42import com.android.internal.telephony.SmsStorageMonitor;
43import com.android.internal.telephony.TelephonyComponentFactory;
44import com.android.internal.telephony.TelephonyTestUtils;
45import com.android.internal.telephony.cdma.sms.SmsEnvelope;
46import com.android.internal.telephony.test.SimulatedCommands;
47import com.android.internal.telephony.uicc.UiccController;
48import com.android.internal.util.IState;
49import com.android.internal.util.StateMachine;
50
51import static org.junit.Assert.*;
52import static org.mockito.Mockito.*;
53
54import org.junit.After;
55import org.junit.Before;
56import org.junit.Test;
57import org.mockito.ArgumentCaptor;
58import org.mockito.InjectMocks;
59import org.mockito.Mock;
60import org.mockito.MockitoAnnotations;
61import org.mockito.Spy;
62
63import java.lang.reflect.Field;
64import java.lang.reflect.Method;
65import java.util.List;
66
67public class CdmaInboundSmsHandlerTest {
68    private static final String TAG = "CdmaInboundSmsHandlerTest";
69
70    @Mock
71    private SmsStorageMonitor mSmsStorageMonitor;
72    @Mock
73    private Phone mPhone;
74    @Mock
75    private android.telephony.SmsMessage mSmsMessage;
76    @Mock
77    private SmsMessage mCdmaSmsMessage;
78    @Mock
79    private UiccController mUiccController;
80    @Mock
81    private IDeviceIdleController mIDeviceIdleController;
82    @Mock
83    private TelephonyComponentFactory mTelephonyComponentFactory;
84
85    private CdmaInboundSmsHandler mCdmaInboundSmsHandler;
86    private ContextFixture mContextFixture;
87    private SimulatedCommands mSimulatedCommands;
88    private TelephonyManager mTelephonyManager;
89    private SmsEnvelope mSmsEnvelope = new SmsEnvelope();
90
91    private Object mLock = new Object();
92    private boolean mReady;
93
94    private class CdmaInboundSmsHandlerTestHandler extends HandlerThread {
95
96        private CdmaInboundSmsHandlerTestHandler(String name) {
97            super(name);
98        }
99
100        @Override
101        public void onLooperPrepared() {
102            synchronized (mLock) {
103                mCdmaInboundSmsHandler = CdmaInboundSmsHandler.makeInboundSmsHandler(
104                        mContextFixture.getTestDouble(), mSmsStorageMonitor, mPhone, null);
105                mReady = true;
106            }
107        }
108    }
109
110    private void waitUntilReady() {
111        while(true) {
112            synchronized (mLock) {
113                if (mReady) {
114                    break;
115                }
116            }
117        }
118    }
119
120    private IState getCurrentState() {
121        try {
122            Method method = StateMachine.class.getDeclaredMethod("getCurrentState");
123            method.setAccessible(true);
124            return (IState) method.invoke(mCdmaInboundSmsHandler);
125        } catch (Exception e) {
126            fail(e.toString());
127            return null;
128        }
129    }
130
131    @Before
132    public void setUp() throws Exception {
133        MockitoAnnotations.initMocks(this);
134
135        //Use reflection to mock singletons
136        Field field = UiccController.class.getDeclaredField("mInstance");
137        field.setAccessible(true);
138        field.set(null, mUiccController);
139
140        field = TelephonyComponentFactory.class.getDeclaredField("sInstance");
141        field.setAccessible(true);
142        field.set(null, mTelephonyComponentFactory);
143
144        field = SmsMessage.class.getDeclaredField("mEnvelope");
145        field.setAccessible(true);
146        field.set(mCdmaSmsMessage, mSmsEnvelope);
147
148        mContextFixture = new ContextFixture();
149        mSimulatedCommands = new SimulatedCommands();
150        mPhone.mCi = mSimulatedCommands;
151
152        mTelephonyManager = TelephonyManager.from(mContextFixture.getTestDouble());
153        doReturn(true).when(mTelephonyManager).getSmsReceiveCapableForPhone(anyInt(), anyBoolean());
154        doReturn(true).when(mSmsStorageMonitor).isStorageAvailable();
155        doReturn(mIDeviceIdleController).when(mTelephonyComponentFactory).
156                getIDeviceIdleController();
157
158        mReady = false;
159        new CdmaInboundSmsHandlerTestHandler(TAG).start();
160        waitUntilReady();
161    }
162
163    @After
164    public void tearDown() throws Exception {
165        mCdmaInboundSmsHandler = null;
166    }
167
168    @Test @SmallTest
169    public void testNewSms() {
170        // verify initially in StartupState
171        assertEquals("StartupState", getCurrentState().getName());
172
173        // start SmsBroadcastUndelivered thread to trigger transition to IdleState
174        SmsBroadcastUndelivered.initialize(mContextFixture.getTestDouble(), null,
175                mCdmaInboundSmsHandler);
176        TelephonyTestUtils.waitForMs(50);
177
178        assertEquals("IdleState", getCurrentState().getName());
179
180        // send new SMS to state machine and verify that triggers SMS_DELIVER_ACTION
181        byte[] smsPdu = new byte[]{(byte)0xFF, (byte)0xFF, (byte)0xFF};
182        mSmsMessage.mWrappedSmsMessage = mCdmaSmsMessage;
183        doReturn(smsPdu).when(mCdmaSmsMessage).getPdu();
184        doReturn(SmsEnvelope.TELESERVICE_WMT).when(mCdmaSmsMessage).getTeleService();
185        mCdmaInboundSmsHandler.sendMessage(InboundSmsHandler.EVENT_NEW_SMS,
186                new AsyncResult(null, mSmsMessage, null));
187        TelephonyTestUtils.waitForMs(100);
188
189        ArgumentCaptor<Intent> intentArgumentCaptor = ArgumentCaptor.forClass(Intent.class);
190        verify(mContextFixture.getTestDouble(), times(2)).
191                sendBroadcast(intentArgumentCaptor.capture());
192
193        List<Intent> list = intentArgumentCaptor.getAllValues();
194        /* logd("list.size() " + list.size());
195        for (int i = 0; i < list.size(); i++) {
196            logd("list.get(i) " + list.get(i));
197        } */
198        //todo: seems to be some issue with ArgumentCaptor. Both DELIVER and RECEIVED broadcasts
199        //can be seen in logs but according to list both are RECEIVED
200        //assertEquals(Telephony.Sms.Intents.SMS_DELIVER_ACTION,
201        //                list.get(0).getAction());
202        boolean smsReceivedAction = false;
203        for (Intent i : list) {
204            if (Telephony.Sms.Intents.SMS_RECEIVED_ACTION.equals(i.getAction())) {
205                smsReceivedAction = true;
206                break;
207            }
208        }
209        assertTrue(smsReceivedAction);
210
211        assertEquals("IdleState", getCurrentState().getName());
212    }
213
214    private static void logd(String s) {
215        Log.d(TAG, s);
216    }
217}
218