aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/java/com/android/internal/telephony/InboundSmsHandler.java22
-rw-r--r--src/java/com/android/internal/telephony/cdma/SmsMessage.java10
-rw-r--r--tests/telephonytests/src/com/android/internal/telephony/cdma/CdmaInboundSmsHandlerTest.java218
3 files changed, 234 insertions, 16 deletions
diff --git a/src/java/com/android/internal/telephony/InboundSmsHandler.java b/src/java/com/android/internal/telephony/InboundSmsHandler.java
index d40b1b142..bfe30b29d 100644
--- a/src/java/com/android/internal/telephony/InboundSmsHandler.java
+++ b/src/java/com/android/internal/telephony/InboundSmsHandler.java
@@ -270,7 +270,7 @@ public abstract class InboundSmsHandler extends StateMachine {
* This parent state throws an exception (for debug builds) or prints an error for unhandled
* message types.
*/
- class DefaultState extends State {
+ private class DefaultState extends State {
@Override
public boolean processMessage(Message msg) {
switch (msg.what) {
@@ -304,7 +304,7 @@ public abstract class InboundSmsHandler extends StateMachine {
* The Startup state waits for {@link SmsBroadcastUndelivered} to process the raw table and
* notify the state machine to broadcast any complete PDUs that might not have been broadcast.
*/
- class StartupState extends State {
+ private class StartupState extends State {
@Override
public boolean processMessage(Message msg) {
log("StartupState.processMessage:" + msg.what);
@@ -333,7 +333,7 @@ public abstract class InboundSmsHandler extends StateMachine {
* In the idle state the wakelock is released until a new SM arrives, then we transition
* to Delivering mode to handle it, acquiring the wakelock on exit.
*/
- class IdleState extends State {
+ private class IdleState extends State {
@Override
public void enter() {
if (DBG) log("entering Idle state");
@@ -389,7 +389,7 @@ public abstract class InboundSmsHandler extends StateMachine {
* transition to {@link WaitingState} state to send the ordered broadcast and wait for the
* results. When all messages have been processed, the halting state will release the wakelock.
*/
- class DeliveringState extends State {
+ private class DeliveringState extends State {
@Override
public void enter() {
if (DBG) log("entering Delivering state");
@@ -462,7 +462,7 @@ public abstract class InboundSmsHandler extends StateMachine {
* {@link DeliveringState}, {@link #EVENT_RETURN_TO_IDLE} is sent to transition to
* {@link IdleState} after any deferred {@link #EVENT_BROADCAST_SMS} messages are handled.
*/
- class WaitingState extends State {
+ private class WaitingState extends State {
@Override
public boolean processMessage(Message msg) {
log("WaitingState.processMessage:" + msg.what);
@@ -516,7 +516,7 @@ public abstract class InboundSmsHandler extends StateMachine {
* This method is called when a new SMS PDU is injected into application framework.
* @param ar is the AsyncResult that has the SMS PDU to be injected.
*/
- void handleInjectSms(AsyncResult ar) {
+ private void handleInjectSms(AsyncResult ar) {
int result;
PendingIntent receivedIntent = null;
try {
@@ -604,7 +604,7 @@ public abstract class InboundSmsHandler extends StateMachine {
* @param result result code indicating any error
* @param response callback message sent when operation completes.
*/
- void notifyAndAcknowledgeLastIncomingSms(boolean success,
+ private void notifyAndAcknowledgeLastIncomingSms(boolean success,
int result, Message response) {
if (!success) {
// broadcast SMS_REJECTED_ACTION intent
@@ -689,7 +689,7 @@ public abstract class InboundSmsHandler extends StateMachine {
* @param tracker the tracker containing the message segment to process
* @return true if an ordered broadcast was sent; false if waiting for more message segments
*/
- boolean processMessagePart(InboundSmsTracker tracker) {
+ private boolean processMessagePart(InboundSmsTracker tracker) {
int messageCount = tracker.getMessageCount();
byte[][] pdus;
int destPort = tracker.getDestPort();
@@ -954,7 +954,7 @@ public abstract class InboundSmsHandler extends StateMachine {
/**
* Helper for {@link SmsBroadcastUndelivered} to delete an old message in the raw table.
*/
- void deleteFromRawTable(String deleteWhere, String[] deleteWhereArgs) {
+ private void deleteFromRawTable(String deleteWhere, String[] deleteWhereArgs) {
int rows = mResolver.delete(sRawUri, deleteWhere, deleteWhereArgs);
if (rows == 0) {
loge("No rows were deleted from raw table!");
@@ -963,7 +963,7 @@ public abstract class InboundSmsHandler extends StateMachine {
}
}
- Bundle handleSmsWhitelisting(ComponentName target) {
+ private Bundle handleSmsWhitelisting(ComponentName target) {
String pkgName;
String reason;
if (target != null) {
@@ -993,7 +993,7 @@ public abstract class InboundSmsHandler extends StateMachine {
* @param destPort the destination port
* @param resultReceiver the receiver handling the delivery result
*/
- void dispatchSmsDeliveryIntent(byte[][] pdus, String format, int destPort,
+ private void dispatchSmsDeliveryIntent(byte[][] pdus, String format, int destPort,
BroadcastReceiver resultReceiver) {
Intent intent = new Intent();
intent.putExtra("pdus", pdus);
diff --git a/src/java/com/android/internal/telephony/cdma/SmsMessage.java b/src/java/com/android/internal/telephony/cdma/SmsMessage.java
index 66b404473..19622dc72 100644
--- a/src/java/com/android/internal/telephony/cdma/SmsMessage.java
+++ b/src/java/com/android/internal/telephony/cdma/SmsMessage.java
@@ -483,7 +483,7 @@ public class SmsMessage extends SmsMessageBase {
* {@link com.android.internal.telephony.cdma.sms.SmsEnvelope#TELESERVICE_VMN},
* {@link com.android.internal.telephony.cdma.sms.SmsEnvelope#TELESERVICE_WAP}
*/
- /* package */ int getTeleService() {
+ public int getTeleService() {
return mEnvelope.teleService;
}
@@ -494,7 +494,7 @@ public class SmsMessage extends SmsMessageBase {
* {@link com.android.internal.telephony.cdma.sms.SmsEnvelope#MESSAGE_TYPE_BROADCAST},
* {@link com.android.internal.telephony.cdma.sms.SmsEnvelope#MESSAGE_TYPE_ACKNOWLEDGE},
*/
- /* package */ int getMessageType() {
+ public int getMessageType() {
// NOTE: mEnvelope.messageType is not set correctly for cell broadcasts with some RILs.
// Use the service category parameter to detect CMAS and other cell broadcast messages.
if (mEnvelope.serviceCategory != 0) {
@@ -830,7 +830,7 @@ public class SmsMessage extends SmsMessageBase {
* binder-call, and hence should be thread-safe, it has been
* synchronized.
*/
- synchronized static int getNextMessageId() {
+ public synchronized static int getNextMessageId() {
// Testing and dialog with partners has indicated that
// msgId==0 is (sometimes?) treated specially by lower levels.
// Specifically, the ID is not preserved for delivery ACKs.
@@ -1019,7 +1019,7 @@ public class SmsMessage extends SmsMessageBase {
/** This function shall be called to get the number of voicemails.
* @hide
*/
- /*package*/ int getNumOfVoicemails() {
+ public int getNumOfVoicemails() {
return mBearerData.numberOfMessages;
}
@@ -1030,7 +1030,7 @@ public class SmsMessage extends SmsMessageBase {
* @return byte array uniquely identifying the message.
* @hide
*/
- /* package */ byte[] getIncomingSmsFingerprint() {
+ public byte[] getIncomingSmsFingerprint() {
ByteArrayOutputStream output = new ByteArrayOutputStream();
output.write(mEnvelope.serviceCategory);
diff --git a/tests/telephonytests/src/com/android/internal/telephony/cdma/CdmaInboundSmsHandlerTest.java b/tests/telephonytests/src/com/android/internal/telephony/cdma/CdmaInboundSmsHandlerTest.java
new file mode 100644
index 000000000..7417a1cf0
--- /dev/null
+++ b/tests/telephonytests/src/com/android/internal/telephony/cdma/CdmaInboundSmsHandlerTest.java
@@ -0,0 +1,218 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.internal.telephony.cdma;
+
+import android.content.BroadcastReceiver;
+import android.content.Context;
+import android.content.Intent;
+import android.os.AsyncResult;
+import android.os.Bundle;
+import android.os.Handler;
+import android.os.HandlerThread;
+import android.os.IBinder;
+import android.os.IDeviceIdleController;
+import android.os.ServiceManager;
+import android.os.UserHandle;
+import android.provider.Telephony;
+import android.telephony.*;
+import android.test.suitebuilder.annotation.SmallTest;
+import android.util.Log;
+
+import com.android.internal.telephony.CommandsInterface;
+import com.android.internal.telephony.ContextFixture;
+import com.android.internal.telephony.GsmCdmaPhone;
+import com.android.internal.telephony.InboundSmsHandler;
+import com.android.internal.telephony.Phone;
+import com.android.internal.telephony.SmsBroadcastUndelivered;
+import com.android.internal.telephony.SmsMessageBase;
+import com.android.internal.telephony.SmsStorageMonitor;
+import com.android.internal.telephony.TelephonyComponentFactory;
+import com.android.internal.telephony.TelephonyTestUtils;
+import com.android.internal.telephony.cdma.sms.SmsEnvelope;
+import com.android.internal.telephony.test.SimulatedCommands;
+import com.android.internal.telephony.uicc.UiccController;
+import com.android.internal.util.IState;
+import com.android.internal.util.StateMachine;
+
+import static org.junit.Assert.*;
+import static org.mockito.Mockito.*;
+
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+import org.mockito.ArgumentCaptor;
+import org.mockito.InjectMocks;
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
+import org.mockito.Spy;
+
+import java.lang.reflect.Field;
+import java.lang.reflect.Method;
+import java.util.List;
+
+public class CdmaInboundSmsHandlerTest {
+ private static final String TAG = "CdmaInboundSmsHandlerTest";
+
+ @Mock
+ private SmsStorageMonitor mSmsStorageMonitor;
+ @Mock
+ private Phone mPhone;
+ @Mock
+ private android.telephony.SmsMessage mSmsMessage;
+ @Mock
+ private SmsMessage mCdmaSmsMessage;
+ @Mock
+ private UiccController mUiccController;
+ @Mock
+ private IDeviceIdleController mIDeviceIdleController;
+ @Mock
+ private TelephonyComponentFactory mTelephonyComponentFactory;
+
+ private CdmaInboundSmsHandler mCdmaInboundSmsHandler;
+ private ContextFixture mContextFixture;
+ private SimulatedCommands mSimulatedCommands;
+ private TelephonyManager mTelephonyManager;
+ private SmsEnvelope mSmsEnvelope = new SmsEnvelope();
+
+ private Object mLock = new Object();
+ private boolean mReady;
+
+ private class CdmaInboundSmsHandlerTestHandler extends HandlerThread {
+
+ private CdmaInboundSmsHandlerTestHandler(String name) {
+ super(name);
+ }
+
+ @Override
+ public void onLooperPrepared() {
+ synchronized (mLock) {
+ mCdmaInboundSmsHandler = CdmaInboundSmsHandler.makeInboundSmsHandler(
+ mContextFixture.getTestDouble(), mSmsStorageMonitor, mPhone, null);
+ mReady = true;
+ }
+ }
+ }
+
+ private void waitUntilReady() {
+ while(true) {
+ synchronized (mLock) {
+ if (mReady) {
+ break;
+ }
+ }
+ }
+ }
+
+ private IState getCurrentState() {
+ try {
+ Method method = StateMachine.class.getDeclaredMethod("getCurrentState");
+ method.setAccessible(true);
+ return (IState) method.invoke(mCdmaInboundSmsHandler);
+ } catch (Exception e) {
+ fail(e.toString());
+ return null;
+ }
+ }
+
+ @Before
+ public void setUp() throws Exception {
+ MockitoAnnotations.initMocks(this);
+
+ //Use reflection to mock singletons
+ Field field = UiccController.class.getDeclaredField("mInstance");
+ field.setAccessible(true);
+ field.set(null, mUiccController);
+
+ field = TelephonyComponentFactory.class.getDeclaredField("sInstance");
+ field.setAccessible(true);
+ field.set(null, mTelephonyComponentFactory);
+
+ field = SmsMessage.class.getDeclaredField("mEnvelope");
+ field.setAccessible(true);
+ field.set(mCdmaSmsMessage, mSmsEnvelope);
+
+ mContextFixture = new ContextFixture();
+ mSimulatedCommands = new SimulatedCommands();
+ mPhone.mCi = mSimulatedCommands;
+
+ mTelephonyManager = TelephonyManager.from(mContextFixture.getTestDouble());
+ doReturn(true).when(mTelephonyManager).getSmsReceiveCapableForPhone(anyInt(), anyBoolean());
+ doReturn(true).when(mSmsStorageMonitor).isStorageAvailable();
+ doReturn(mIDeviceIdleController).when(mTelephonyComponentFactory).
+ getIDeviceIdleController();
+
+ mReady = false;
+ new CdmaInboundSmsHandlerTestHandler(TAG).start();
+ waitUntilReady();
+ }
+
+ @After
+ public void tearDown() throws Exception {
+ mCdmaInboundSmsHandler = null;
+ }
+
+ @Test @SmallTest
+ public void testNewSms() {
+ // verify initially in StartupState
+ assertEquals("StartupState", getCurrentState().getName());
+
+ // start SmsBroadcastUndelivered thread to trigger transition to IdleState
+ Thread broadcastThread = new Thread(new SmsBroadcastUndelivered(
+ mContextFixture.getTestDouble(), null, mCdmaInboundSmsHandler));
+ broadcastThread.start();
+ TelephonyTestUtils.waitForMs(50);
+
+ assertEquals("IdleState", getCurrentState().getName());
+
+ // send new SMS to state machine and verify that triggers SMS_DELIVER_ACTION
+ byte[] smsPdu = new byte[]{(byte)0xFF, (byte)0xFF, (byte)0xFF};
+ mSmsMessage.mWrappedSmsMessage = mCdmaSmsMessage;
+ doReturn(smsPdu).when(mCdmaSmsMessage).getPdu();
+ doReturn(SmsEnvelope.TELESERVICE_WMT).when(mCdmaSmsMessage).getTeleService();
+ mCdmaInboundSmsHandler.sendMessage(InboundSmsHandler.EVENT_NEW_SMS,
+ new AsyncResult(null, mSmsMessage, null));
+ TelephonyTestUtils.waitForMs(100);
+
+ ArgumentCaptor<Intent> intentArgumentCaptor = ArgumentCaptor.forClass(Intent.class);
+ verify(mContextFixture.getTestDouble(), times(2)).
+ sendBroadcast(intentArgumentCaptor.capture());
+
+ List<Intent> list = intentArgumentCaptor.getAllValues();
+ /* logd("list.size() " + list.size());
+ for (int i = 0; i < list.size(); i++) {
+ logd("list.get(i) " + list.get(i));
+ } */
+ //todo: seems to be some issue with ArgumentCaptor. Both DELIVER and RECEIVED broadcasts
+ //can be seen in logs but according to list both are RECEIVED
+ //assertEquals(Telephony.Sms.Intents.SMS_DELIVER_ACTION,
+ // list.get(0).getAction());
+ boolean smsReceivedAction = false;
+ for (Intent i : list) {
+ if (Telephony.Sms.Intents.SMS_RECEIVED_ACTION.equals(i.getAction())) {
+ smsReceivedAction = true;
+ break;
+ }
+ }
+ assertTrue(smsReceivedAction);
+
+ assertEquals("IdleState", getCurrentState().getName());
+ }
+
+ private static void logd(String s) {
+ Log.d(TAG, s);
+ }
+}