Loading src/java/com/android/internal/telephony/SMSDispatcher.java +54 −3 Original line number Diff line number Diff line Loading @@ -43,6 +43,7 @@ import android.os.AsyncResult; import android.os.Binder; import android.os.Build; import android.os.Handler; import android.os.Looper; import android.os.Message; import android.os.PersistableBundle; import android.os.Process; Loading @@ -63,6 +64,8 @@ import android.text.Html; import android.text.Spanned; import android.text.TextUtils; import android.util.EventLog; import android.util.IndentingPrintWriter; import android.util.LocalLog; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; Loading @@ -80,6 +83,8 @@ import com.android.internal.telephony.uicc.UiccCard; import com.android.internal.telephony.uicc.UiccController; import com.android.telephony.Rlog; import java.io.FileDescriptor; import java.io.PrintWriter; import java.util.ArrayList; import java.util.HashMap; import java.util.List; Loading Loading @@ -149,6 +154,7 @@ public abstract class SMSDispatcher extends Handler { protected final CommandsInterface mCi; @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) protected final TelephonyManager mTelephonyManager; protected final LocalLog mLocalLog = new LocalLog(16); /** Maximum number of times to retry sending a failed SMS. */ private static final int MAX_SEND_RETRIES = 3; Loading @@ -174,6 +180,9 @@ public abstract class SMSDispatcher extends Handler { protected boolean mSmsCapable = true; protected boolean mSmsSendDisabled; @VisibleForTesting public int mCarrierMessagingTimeout = 10 * 60 * 1000; //10 minutes @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) protected static int getNextConcatenatedRef() { sConcatenatedRef += 1; Loading Loading @@ -344,19 +353,23 @@ public abstract class SMSDispatcher extends Handler { /** * Use the carrier messaging service to send a data or text SMS. */ protected abstract class SmsSender { protected abstract class SmsSender extends Handler { private static final int EVENT_TIMEOUT = 1; protected final SmsTracker mTracker; // Initialized in sendSmsByCarrierApp protected volatile SmsSenderCallback mSenderCallback; protected final CarrierMessagingServiceWrapper mCarrierMessagingServiceWrapper = new CarrierMessagingServiceWrapper(); private String mCarrierPackageName; protected SmsSender(SmsTracker tracker) { super(Looper.getMainLooper()); mTracker = tracker; } public void sendSmsByCarrierApp(String carrierPackageName, SmsSenderCallback senderCallback) { mCarrierPackageName = carrierPackageName; mSenderCallback = senderCallback; if (!mCarrierMessagingServiceWrapper.bindToCarrierMessagingService( mContext, carrierPackageName, runnable -> runnable.run(), Loading @@ -367,10 +380,33 @@ public abstract class SMSDispatcher extends Handler { 0 /* messageRef */); } else { Rlog.d(TAG, "bindService() for carrier messaging service succeeded"); sendMessageDelayed(obtainMessage(EVENT_TIMEOUT), mCarrierMessagingTimeout); } } public abstract void onServiceReady(); @Override public void handleMessage(Message msg) { if (msg.what == EVENT_TIMEOUT) { logWithLocalLog("handleMessage: did not receive response from " + mCarrierPackageName + " for " + mCarrierMessagingTimeout + " ms"); mSenderCallback.onSendSmsComplete( CarrierMessagingService.SEND_STATUS_RETRY_ON_CARRIER_NETWORK, 0 /* messageRef */); } else { logWithLocalLog("handleMessage: received unexpected message " + msg.what); } } public void removeTimeout() { removeMessages(EVENT_TIMEOUT); } } private void logWithLocalLog(String logStr) { mLocalLog.log(logStr); Rlog.d(TAG, logStr); } /** Loading Loading @@ -398,7 +434,7 @@ public abstract class SMSDispatcher extends Handler { runnable -> runnable.run(), mSenderCallback); } catch (RuntimeException e) { Rlog.e(TAG, "Exception sending the SMS: " + e); Rlog.e(TAG, "Exception sending the SMS: " + e.getMessage()); mSenderCallback.onSendSmsComplete( CarrierMessagingService.SEND_STATUS_RETRY_ON_CARRIER_NETWORK, 0 /* messageRef */); Loading Loading @@ -472,6 +508,7 @@ public abstract class SMSDispatcher extends Handler { try { mSmsSender.mCarrierMessagingServiceWrapper.disconnect(); processSendSmsResponse(mSmsSender.mTracker, result, messageRef); mSmsSender.removeTimeout(); } finally { Binder.restoreCallingIdentity(identity); } Loading Loading @@ -2476,4 +2513,18 @@ public abstract class SMSDispatcher extends Handler { Binder.restoreCallingIdentity(token); } } /** * Dump local logs */ public void dump(FileDescriptor fd, PrintWriter printWriter, String[] args) { IndentingPrintWriter pw = new IndentingPrintWriter(printWriter, " "); pw.println(TAG); pw.increaseIndent(); pw.println("mLocalLog:"); pw.increaseIndent(); mLocalLog.dump(fd, pw, args); pw.decreaseIndent(); pw.decreaseIndent(); } } src/java/com/android/internal/telephony/SmsDispatchersController.java +3 −0 Original line number Diff line number Diff line Loading @@ -1051,6 +1051,9 @@ public class SmsDispatchersController extends Handler { public void dump(FileDescriptor fd, PrintWriter pw, String[] args) { mGsmInboundSmsHandler.dump(fd, pw, args); mCdmaInboundSmsHandler.dump(fd, pw, args); mGsmDispatcher.dump(fd, pw, args); mCdmaDispatcher.dump(fd, pw, args); mImsSmsDispatcher.dump(fd, pw, args); } private void logd(String msg) { Loading tests/telephonytests/src/com/android/internal/telephony/ContextFixture.java +13 −3 Original line number Diff line number Diff line Loading @@ -101,6 +101,7 @@ import java.util.HashSet; import java.util.List; import java.util.Locale; import java.util.Map; import java.util.Set; /** * Controls a test {@link Context} as would be provided by the Android framework to an Loading Loading @@ -197,6 +198,9 @@ public class ContextFixture implements TestFixture<Context> { Intent serviceIntent, ServiceConnection connection, int flags) { if (mMockBindingFailureForPackage.contains(serviceIntent.getPackage())) { return false; } if (mServiceByServiceConnection.containsKey(connection)) { throw new RuntimeException("ServiceConnection already bound: " + connection); } Loading @@ -218,10 +222,11 @@ public class ContextFixture implements TestFixture<Context> { public void unbindService( ServiceConnection connection) { IInterface service = mServiceByServiceConnection.remove(connection); if (service == null) { throw new RuntimeException("ServiceConnection not found: " + connection); } if (service != null) { connection.onServiceDisconnected(mComponentNameByService.get(service)); } else { logd("unbindService: ServiceConnection not found: " + connection); } } @Override Loading Loading @@ -624,6 +629,7 @@ public class ContextFixture implements TestFixture<Context> { private final Map<ComponentName, IntentFilter> mIntentFilterByComponentName = new HashMap<>(); private final Map<IInterface, ComponentName> mComponentNameByService = new HashMap<IInterface, ComponentName>(); private final Set<String> mMockBindingFailureForPackage = new HashSet(); private final Map<ServiceConnection, IInterface> mServiceByServiceConnection = new HashMap<ServiceConnection, IInterface>(); private final Multimap<String, BroadcastReceiver> mBroadcastReceiversByAction = Loading Loading @@ -791,6 +797,10 @@ public class ContextFixture implements TestFixture<Context> { mComponentNameByService.put(service, name); } public void mockBindingFailureForPackage(String packageName) { mMockBindingFailureForPackage.add(packageName); } private List<ResolveInfo> doQueryIntentServices(Intent intent, int flags) { List<ResolveInfo> result = new ArrayList<ResolveInfo>(); for (ComponentName componentName : mComponentNamesByAction.get(intent.getAction())) { Loading tests/telephonytests/src/com/android/internal/telephony/TelephonyTest.java +1 −0 Original line number Diff line number Diff line Loading @@ -589,6 +589,7 @@ public abstract class TelephonyTest { eq(UiccController.APP_FAM_3GPP2)); doReturn(mUiccCardApplicationIms).when(mUiccController).getUiccCardApplication(anyInt(), eq(UiccController.APP_FAM_IMS)); doReturn(mUiccCard).when(mUiccController).getUiccCard(anyInt()); doAnswer(new Answer<IccRecords>() { public IccRecords answer(InvocationOnMock invocation) { Loading tests/telephonytests/src/com/android/internal/telephony/gsm/GsmSmsDispatcherTest.java +139 −18 Original line number Diff line number Diff line Loading @@ -23,32 +23,44 @@ import static com.android.internal.telephony.SmsUsageMonitor.PREMIUM_SMS_PERMISS import static com.android.internal.telephony.TelephonyTestUtils.waitForMs; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertTrue; import static org.mockito.Matchers.any; import static org.mockito.Matchers.anyInt; import static org.mockito.Matchers.anyString; import static org.mockito.Mockito.doAnswer; import static org.mockito.Mockito.doReturn; import static org.mockito.Mockito.times; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; import android.app.Activity; import android.app.ActivityManager; import android.app.PendingIntent; import android.content.BroadcastReceiver; import android.content.ComponentName; import android.content.Context; import android.content.Intent; import android.content.IntentFilter; import android.content.pm.PackageManager; import android.content.pm.ServiceInfo; import android.location.Country; import android.location.CountryDetector; import android.os.HandlerThread; import android.os.Message; import android.os.RemoteException; import android.os.SystemProperties; import android.provider.Settings; import android.service.carrier.CarrierMessagingService; import android.service.carrier.ICarrierMessagingCallback; import android.service.carrier.ICarrierMessagingService; import android.telephony.SmsManager; import android.test.suitebuilder.annotation.MediumTest; import android.test.suitebuilder.annotation.SmallTest; import android.testing.AndroidTestingRunner; import android.testing.TestableLooper; import android.util.Singleton; import androidx.test.filters.FlakyTest; import androidx.test.filters.MediumTest; import androidx.test.filters.SmallTest; import com.android.internal.telephony.ContextFixture; import com.android.internal.telephony.ISub; Loading @@ -62,15 +74,22 @@ import org.junit.After; import org.junit.Before; import org.junit.Ignore; import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.ArgumentCaptor; import org.mockito.Mock; import org.mockito.invocation.InvocationOnMock; import org.mockito.stubbing.Answer; import java.util.ArrayList; import java.util.HashMap; import java.util.List; @RunWith(AndroidTestingRunner.class) @TestableLooper.RunWithLooper public class GsmSmsDispatcherTest extends TelephonyTest { private static final long TIMEOUT_MS = 500; private static final String CARRIER_APP_PACKAGE_NAME = "com.android.carrier"; @Mock private android.telephony.SmsMessage mSmsMessage; Loading @@ -86,6 +105,9 @@ public class GsmSmsDispatcherTest extends TelephonyTest { private SMSDispatcher.SmsTracker mSmsTracker; @Mock private ISub.Stub mISubStub; @Mock private ICarrierMessagingService.Stub mICarrierAppMessagingService; private Object mLock = new Object(); private boolean mReceivedTestIntent; private static final String TEST_INTENT = "com.android.internal.telephony.TEST_INTENT"; Loading @@ -95,6 +117,7 @@ public class GsmSmsDispatcherTest extends TelephonyTest { logd("onReceive"); synchronized (mLock) { mReceivedTestIntent = true; mLock.notifyAll(); } } }; Loading Loading @@ -129,6 +152,9 @@ public class GsmSmsDispatcherTest extends TelephonyTest { mGsmSmsDispatcherTestHandler = new GsmSmsDispatcherTestHandler(getClass().getSimpleName()); mGsmSmsDispatcherTestHandler.start(); waitUntilReady(); mGsmSmsDispatcher = new GsmSMSDispatcher(mPhone, mSmsDispatchersController, mGsmInboundSmsHandler); processAllMessages(); } @After Loading @@ -142,7 +168,7 @@ public class GsmSmsDispatcherTest extends TelephonyTest { @Test @SmallTest public void testSmsStatus() { mSimulatedCommands.notifySmsStatus(new byte[]{(byte)0xFF, (byte)0xFF, (byte)0xFF}); TelephonyTestUtils.waitForMs(50); processAllMessages(); verify(mSimulatedCommandsVerifier).acknowledgeLastIncomingGsmSms(true, 0, null); } Loading Loading @@ -202,18 +228,22 @@ public class GsmSmsDispatcherTest extends TelephonyTest { } } @Test @SmallTest @FlakyTest @Ignore public void testSendTextWithInvalidDestAddr() throws Exception { private void registerTestIntentReceiver() throws Exception { // unmock ActivityManager to be able to register receiver, create real PendingIntent and // receive TEST_INTENT restoreInstance(Singleton.class, "mInstance", mIActivityManagerSingleton); restoreInstance(ActivityManager.class, "IActivityManagerSingleton", null); Context realContext = TestApplication.getAppContext(); realContext.registerReceiver(mTestReceiver, new IntentFilter(TEST_INTENT)); PendingIntent pendingIntent = PendingIntent.getBroadcast(realContext, 0, } @Test @SmallTest @FlakyTest @Ignore public void testSendTextWithInvalidDestAddr() throws Exception { registerTestIntentReceiver(); PendingIntent pendingIntent = PendingIntent.getBroadcast(TestApplication.getAppContext(), 0, new Intent(TEST_INTENT), 0); // send invalid dest address: + mReceivedTestIntent = false; Loading Loading @@ -250,7 +280,8 @@ public class GsmSmsDispatcherTest extends TelephonyTest { Settings.Global.DEVICE_PROVISIONED, 1); mGsmSmsDispatcher.sendRawPdu(new SMSDispatcher.SmsTracker[] {mSmsTracker}); waitForHandlerAction(mGsmSmsDispatcher, TIMEOUT_MS); //waitForHandlerAction(mGsmSmsDispatcher, TIMEOUT_MS); processAllMessages(); verify(mSmsUsageMonitor, times(1)).checkDestination(any(), any()); verify(mSmsUsageMonitor, times(1)).getPremiumSmsPermission(any()); Loading @@ -264,13 +295,7 @@ public class GsmSmsDispatcherTest extends TelephonyTest { @FlakyTest @Ignore public void testSendMultipartTextWithInvalidText() throws Exception { // unmock ActivityManager to be able to register receiver, create real PendingIntent and // receive TEST_INTENT restoreInstance(Singleton.class, "mInstance", mIActivityManagerSingleton); restoreInstance(ActivityManager.class, "IActivityManagerSingleton", null); Context realContext = TestApplication.getAppContext(); realContext.registerReceiver(mTestReceiver, new IntentFilter(TEST_INTENT)); registerTestIntentReceiver(); // initiate parameters for an invalid text MO SMS (the 2nd segmeant has 161 characters) ArrayList<String> parts = new ArrayList<>(); Loading @@ -280,7 +305,7 @@ public class GsmSmsDispatcherTest extends TelephonyTest { + "8"); ArrayList<PendingIntent> sentIntents = new ArrayList<>(); PendingIntent sentIntent = PendingIntent.getBroadcast(realContext, 0, PendingIntent sentIntent = PendingIntent.getBroadcast(TestApplication.getAppContext(), 0, new Intent(TEST_INTENT), PendingIntent.FLAG_IMMUTABLE); sentIntents.add(sentIntent); sentIntents.add(sentIntent); Loading @@ -296,4 +321,100 @@ public class GsmSmsDispatcherTest extends TelephonyTest { assertEquals(SmsManager.RESULT_ERROR_GENERIC_FAILURE, mTestReceiver.getResultCode()); } } private void mockCarrierApp() throws RemoteException { mContextFixture.addService( CarrierMessagingService.SERVICE_INTERFACE, new ComponentName(CARRIER_APP_PACKAGE_NAME, "CarrierAppFilterClass"), CARRIER_APP_PACKAGE_NAME, mICarrierAppMessagingService, new ServiceInfo()); when(mICarrierAppMessagingService.asBinder()).thenReturn(mICarrierAppMessagingService); mockUiccWithCarrierApp(); } private void mockUiccWithCarrierApp() { when(mUiccController.getUiccCard(mPhone.getPhoneId())).thenReturn(mUiccCard); List<String> carrierPackages = new ArrayList<>(); carrierPackages.add(CARRIER_APP_PACKAGE_NAME); when(mUiccCard.getCarrierPackageNamesForIntent( any(PackageManager.class), any(Intent.class))).thenReturn(carrierPackages); } private void mockCarrierAppStubResults(final int result, ICarrierMessagingService.Stub stub, boolean callOnFilterComplete) throws RemoteException { when(stub.queryLocalInterface(anyString())).thenReturn(stub); when(stub.asBinder()).thenReturn(stub); doAnswer(new Answer<Void>() { @Override public Void answer(InvocationOnMock invocation) throws Throwable { Object[] args = invocation.getArguments(); ICarrierMessagingCallback callback = (ICarrierMessagingCallback) args[4]; if (callOnFilterComplete) { callback.onSendSmsComplete(result, 0); } return null; } }).when(stub).sendTextSms( anyString(), anyInt(), anyString(), anyInt(), any(ICarrierMessagingCallback.class)); } @Test @SmallTest public void testSendSmsByCarrierApp() throws Exception { mockCarrierApp(); mockCarrierAppStubResults(CarrierMessagingService.SEND_STATUS_OK, mICarrierAppMessagingService, true); registerTestIntentReceiver(); PendingIntent pendingIntent = PendingIntent.getBroadcast(TestApplication.getAppContext(), 0, new Intent(TEST_INTENT), PendingIntent.FLAG_MUTABLE); mReceivedTestIntent = false; mGsmSmsDispatcher.sendText("6501002000", "121" /*scAddr*/, "test sms", pendingIntent, null, null, null, false, -1, false, -1, false, 0L); processAllMessages(); synchronized (mLock) { if (!mReceivedTestIntent) { // long wait since sometimes broadcasts can take a long time if the system is loaded mLock.wait(60000); } assertEquals(true, mReceivedTestIntent); int resultCode = mTestReceiver.getResultCode(); assertTrue("Unexpected result code: " + resultCode, resultCode == SmsManager.RESULT_ERROR_NONE || resultCode == Activity.RESULT_OK); verify(mSimulatedCommandsVerifier, times(0)).sendSMS(anyString(), anyString(), any(Message.class)); } } @Test @SmallTest public void testSendSmsByCarrierAppNoResponse() throws Exception { mockCarrierApp(); // do not mock result, instead reduce the timeout for test mGsmSmsDispatcher.mCarrierMessagingTimeout = 100; mGsmSmsDispatcher.sendText("6501002000", "121" /*scAddr*/, "test sms", null, null, null, null, false, -1, false, -1, false, 0L); // wait for timeout waitForMs(150); verify(mSimulatedCommandsVerifier).sendSMS(anyString(), anyString(), any(Message.class)); } @Test @SmallTest public void testSendSmsByCarrierAppBindingFailed() throws Exception { mContextFixture.mockBindingFailureForPackage(CARRIER_APP_PACKAGE_NAME); // mock presence of carrier app, but do not create a mock service to make binding fail mockUiccWithCarrierApp(); mGsmSmsDispatcher.sendText("6501002000", "121" /*scAddr*/, "test sms", null, null, null, null, false, -1, false, -1, false, 0L); processAllMessages(); verify(mSimulatedCommandsVerifier).sendSMS(anyString(), anyString(), any(Message.class)); } } Loading
src/java/com/android/internal/telephony/SMSDispatcher.java +54 −3 Original line number Diff line number Diff line Loading @@ -43,6 +43,7 @@ import android.os.AsyncResult; import android.os.Binder; import android.os.Build; import android.os.Handler; import android.os.Looper; import android.os.Message; import android.os.PersistableBundle; import android.os.Process; Loading @@ -63,6 +64,8 @@ import android.text.Html; import android.text.Spanned; import android.text.TextUtils; import android.util.EventLog; import android.util.IndentingPrintWriter; import android.util.LocalLog; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; Loading @@ -80,6 +83,8 @@ import com.android.internal.telephony.uicc.UiccCard; import com.android.internal.telephony.uicc.UiccController; import com.android.telephony.Rlog; import java.io.FileDescriptor; import java.io.PrintWriter; import java.util.ArrayList; import java.util.HashMap; import java.util.List; Loading Loading @@ -149,6 +154,7 @@ public abstract class SMSDispatcher extends Handler { protected final CommandsInterface mCi; @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) protected final TelephonyManager mTelephonyManager; protected final LocalLog mLocalLog = new LocalLog(16); /** Maximum number of times to retry sending a failed SMS. */ private static final int MAX_SEND_RETRIES = 3; Loading @@ -174,6 +180,9 @@ public abstract class SMSDispatcher extends Handler { protected boolean mSmsCapable = true; protected boolean mSmsSendDisabled; @VisibleForTesting public int mCarrierMessagingTimeout = 10 * 60 * 1000; //10 minutes @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) protected static int getNextConcatenatedRef() { sConcatenatedRef += 1; Loading Loading @@ -344,19 +353,23 @@ public abstract class SMSDispatcher extends Handler { /** * Use the carrier messaging service to send a data or text SMS. */ protected abstract class SmsSender { protected abstract class SmsSender extends Handler { private static final int EVENT_TIMEOUT = 1; protected final SmsTracker mTracker; // Initialized in sendSmsByCarrierApp protected volatile SmsSenderCallback mSenderCallback; protected final CarrierMessagingServiceWrapper mCarrierMessagingServiceWrapper = new CarrierMessagingServiceWrapper(); private String mCarrierPackageName; protected SmsSender(SmsTracker tracker) { super(Looper.getMainLooper()); mTracker = tracker; } public void sendSmsByCarrierApp(String carrierPackageName, SmsSenderCallback senderCallback) { mCarrierPackageName = carrierPackageName; mSenderCallback = senderCallback; if (!mCarrierMessagingServiceWrapper.bindToCarrierMessagingService( mContext, carrierPackageName, runnable -> runnable.run(), Loading @@ -367,10 +380,33 @@ public abstract class SMSDispatcher extends Handler { 0 /* messageRef */); } else { Rlog.d(TAG, "bindService() for carrier messaging service succeeded"); sendMessageDelayed(obtainMessage(EVENT_TIMEOUT), mCarrierMessagingTimeout); } } public abstract void onServiceReady(); @Override public void handleMessage(Message msg) { if (msg.what == EVENT_TIMEOUT) { logWithLocalLog("handleMessage: did not receive response from " + mCarrierPackageName + " for " + mCarrierMessagingTimeout + " ms"); mSenderCallback.onSendSmsComplete( CarrierMessagingService.SEND_STATUS_RETRY_ON_CARRIER_NETWORK, 0 /* messageRef */); } else { logWithLocalLog("handleMessage: received unexpected message " + msg.what); } } public void removeTimeout() { removeMessages(EVENT_TIMEOUT); } } private void logWithLocalLog(String logStr) { mLocalLog.log(logStr); Rlog.d(TAG, logStr); } /** Loading Loading @@ -398,7 +434,7 @@ public abstract class SMSDispatcher extends Handler { runnable -> runnable.run(), mSenderCallback); } catch (RuntimeException e) { Rlog.e(TAG, "Exception sending the SMS: " + e); Rlog.e(TAG, "Exception sending the SMS: " + e.getMessage()); mSenderCallback.onSendSmsComplete( CarrierMessagingService.SEND_STATUS_RETRY_ON_CARRIER_NETWORK, 0 /* messageRef */); Loading Loading @@ -472,6 +508,7 @@ public abstract class SMSDispatcher extends Handler { try { mSmsSender.mCarrierMessagingServiceWrapper.disconnect(); processSendSmsResponse(mSmsSender.mTracker, result, messageRef); mSmsSender.removeTimeout(); } finally { Binder.restoreCallingIdentity(identity); } Loading Loading @@ -2476,4 +2513,18 @@ public abstract class SMSDispatcher extends Handler { Binder.restoreCallingIdentity(token); } } /** * Dump local logs */ public void dump(FileDescriptor fd, PrintWriter printWriter, String[] args) { IndentingPrintWriter pw = new IndentingPrintWriter(printWriter, " "); pw.println(TAG); pw.increaseIndent(); pw.println("mLocalLog:"); pw.increaseIndent(); mLocalLog.dump(fd, pw, args); pw.decreaseIndent(); pw.decreaseIndent(); } }
src/java/com/android/internal/telephony/SmsDispatchersController.java +3 −0 Original line number Diff line number Diff line Loading @@ -1051,6 +1051,9 @@ public class SmsDispatchersController extends Handler { public void dump(FileDescriptor fd, PrintWriter pw, String[] args) { mGsmInboundSmsHandler.dump(fd, pw, args); mCdmaInboundSmsHandler.dump(fd, pw, args); mGsmDispatcher.dump(fd, pw, args); mCdmaDispatcher.dump(fd, pw, args); mImsSmsDispatcher.dump(fd, pw, args); } private void logd(String msg) { Loading
tests/telephonytests/src/com/android/internal/telephony/ContextFixture.java +13 −3 Original line number Diff line number Diff line Loading @@ -101,6 +101,7 @@ import java.util.HashSet; import java.util.List; import java.util.Locale; import java.util.Map; import java.util.Set; /** * Controls a test {@link Context} as would be provided by the Android framework to an Loading Loading @@ -197,6 +198,9 @@ public class ContextFixture implements TestFixture<Context> { Intent serviceIntent, ServiceConnection connection, int flags) { if (mMockBindingFailureForPackage.contains(serviceIntent.getPackage())) { return false; } if (mServiceByServiceConnection.containsKey(connection)) { throw new RuntimeException("ServiceConnection already bound: " + connection); } Loading @@ -218,10 +222,11 @@ public class ContextFixture implements TestFixture<Context> { public void unbindService( ServiceConnection connection) { IInterface service = mServiceByServiceConnection.remove(connection); if (service == null) { throw new RuntimeException("ServiceConnection not found: " + connection); } if (service != null) { connection.onServiceDisconnected(mComponentNameByService.get(service)); } else { logd("unbindService: ServiceConnection not found: " + connection); } } @Override Loading Loading @@ -624,6 +629,7 @@ public class ContextFixture implements TestFixture<Context> { private final Map<ComponentName, IntentFilter> mIntentFilterByComponentName = new HashMap<>(); private final Map<IInterface, ComponentName> mComponentNameByService = new HashMap<IInterface, ComponentName>(); private final Set<String> mMockBindingFailureForPackage = new HashSet(); private final Map<ServiceConnection, IInterface> mServiceByServiceConnection = new HashMap<ServiceConnection, IInterface>(); private final Multimap<String, BroadcastReceiver> mBroadcastReceiversByAction = Loading Loading @@ -791,6 +797,10 @@ public class ContextFixture implements TestFixture<Context> { mComponentNameByService.put(service, name); } public void mockBindingFailureForPackage(String packageName) { mMockBindingFailureForPackage.add(packageName); } private List<ResolveInfo> doQueryIntentServices(Intent intent, int flags) { List<ResolveInfo> result = new ArrayList<ResolveInfo>(); for (ComponentName componentName : mComponentNamesByAction.get(intent.getAction())) { Loading
tests/telephonytests/src/com/android/internal/telephony/TelephonyTest.java +1 −0 Original line number Diff line number Diff line Loading @@ -589,6 +589,7 @@ public abstract class TelephonyTest { eq(UiccController.APP_FAM_3GPP2)); doReturn(mUiccCardApplicationIms).when(mUiccController).getUiccCardApplication(anyInt(), eq(UiccController.APP_FAM_IMS)); doReturn(mUiccCard).when(mUiccController).getUiccCard(anyInt()); doAnswer(new Answer<IccRecords>() { public IccRecords answer(InvocationOnMock invocation) { Loading
tests/telephonytests/src/com/android/internal/telephony/gsm/GsmSmsDispatcherTest.java +139 −18 Original line number Diff line number Diff line Loading @@ -23,32 +23,44 @@ import static com.android.internal.telephony.SmsUsageMonitor.PREMIUM_SMS_PERMISS import static com.android.internal.telephony.TelephonyTestUtils.waitForMs; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertTrue; import static org.mockito.Matchers.any; import static org.mockito.Matchers.anyInt; import static org.mockito.Matchers.anyString; import static org.mockito.Mockito.doAnswer; import static org.mockito.Mockito.doReturn; import static org.mockito.Mockito.times; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; import android.app.Activity; import android.app.ActivityManager; import android.app.PendingIntent; import android.content.BroadcastReceiver; import android.content.ComponentName; import android.content.Context; import android.content.Intent; import android.content.IntentFilter; import android.content.pm.PackageManager; import android.content.pm.ServiceInfo; import android.location.Country; import android.location.CountryDetector; import android.os.HandlerThread; import android.os.Message; import android.os.RemoteException; import android.os.SystemProperties; import android.provider.Settings; import android.service.carrier.CarrierMessagingService; import android.service.carrier.ICarrierMessagingCallback; import android.service.carrier.ICarrierMessagingService; import android.telephony.SmsManager; import android.test.suitebuilder.annotation.MediumTest; import android.test.suitebuilder.annotation.SmallTest; import android.testing.AndroidTestingRunner; import android.testing.TestableLooper; import android.util.Singleton; import androidx.test.filters.FlakyTest; import androidx.test.filters.MediumTest; import androidx.test.filters.SmallTest; import com.android.internal.telephony.ContextFixture; import com.android.internal.telephony.ISub; Loading @@ -62,15 +74,22 @@ import org.junit.After; import org.junit.Before; import org.junit.Ignore; import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.ArgumentCaptor; import org.mockito.Mock; import org.mockito.invocation.InvocationOnMock; import org.mockito.stubbing.Answer; import java.util.ArrayList; import java.util.HashMap; import java.util.List; @RunWith(AndroidTestingRunner.class) @TestableLooper.RunWithLooper public class GsmSmsDispatcherTest extends TelephonyTest { private static final long TIMEOUT_MS = 500; private static final String CARRIER_APP_PACKAGE_NAME = "com.android.carrier"; @Mock private android.telephony.SmsMessage mSmsMessage; Loading @@ -86,6 +105,9 @@ public class GsmSmsDispatcherTest extends TelephonyTest { private SMSDispatcher.SmsTracker mSmsTracker; @Mock private ISub.Stub mISubStub; @Mock private ICarrierMessagingService.Stub mICarrierAppMessagingService; private Object mLock = new Object(); private boolean mReceivedTestIntent; private static final String TEST_INTENT = "com.android.internal.telephony.TEST_INTENT"; Loading @@ -95,6 +117,7 @@ public class GsmSmsDispatcherTest extends TelephonyTest { logd("onReceive"); synchronized (mLock) { mReceivedTestIntent = true; mLock.notifyAll(); } } }; Loading Loading @@ -129,6 +152,9 @@ public class GsmSmsDispatcherTest extends TelephonyTest { mGsmSmsDispatcherTestHandler = new GsmSmsDispatcherTestHandler(getClass().getSimpleName()); mGsmSmsDispatcherTestHandler.start(); waitUntilReady(); mGsmSmsDispatcher = new GsmSMSDispatcher(mPhone, mSmsDispatchersController, mGsmInboundSmsHandler); processAllMessages(); } @After Loading @@ -142,7 +168,7 @@ public class GsmSmsDispatcherTest extends TelephonyTest { @Test @SmallTest public void testSmsStatus() { mSimulatedCommands.notifySmsStatus(new byte[]{(byte)0xFF, (byte)0xFF, (byte)0xFF}); TelephonyTestUtils.waitForMs(50); processAllMessages(); verify(mSimulatedCommandsVerifier).acknowledgeLastIncomingGsmSms(true, 0, null); } Loading Loading @@ -202,18 +228,22 @@ public class GsmSmsDispatcherTest extends TelephonyTest { } } @Test @SmallTest @FlakyTest @Ignore public void testSendTextWithInvalidDestAddr() throws Exception { private void registerTestIntentReceiver() throws Exception { // unmock ActivityManager to be able to register receiver, create real PendingIntent and // receive TEST_INTENT restoreInstance(Singleton.class, "mInstance", mIActivityManagerSingleton); restoreInstance(ActivityManager.class, "IActivityManagerSingleton", null); Context realContext = TestApplication.getAppContext(); realContext.registerReceiver(mTestReceiver, new IntentFilter(TEST_INTENT)); PendingIntent pendingIntent = PendingIntent.getBroadcast(realContext, 0, } @Test @SmallTest @FlakyTest @Ignore public void testSendTextWithInvalidDestAddr() throws Exception { registerTestIntentReceiver(); PendingIntent pendingIntent = PendingIntent.getBroadcast(TestApplication.getAppContext(), 0, new Intent(TEST_INTENT), 0); // send invalid dest address: + mReceivedTestIntent = false; Loading Loading @@ -250,7 +280,8 @@ public class GsmSmsDispatcherTest extends TelephonyTest { Settings.Global.DEVICE_PROVISIONED, 1); mGsmSmsDispatcher.sendRawPdu(new SMSDispatcher.SmsTracker[] {mSmsTracker}); waitForHandlerAction(mGsmSmsDispatcher, TIMEOUT_MS); //waitForHandlerAction(mGsmSmsDispatcher, TIMEOUT_MS); processAllMessages(); verify(mSmsUsageMonitor, times(1)).checkDestination(any(), any()); verify(mSmsUsageMonitor, times(1)).getPremiumSmsPermission(any()); Loading @@ -264,13 +295,7 @@ public class GsmSmsDispatcherTest extends TelephonyTest { @FlakyTest @Ignore public void testSendMultipartTextWithInvalidText() throws Exception { // unmock ActivityManager to be able to register receiver, create real PendingIntent and // receive TEST_INTENT restoreInstance(Singleton.class, "mInstance", mIActivityManagerSingleton); restoreInstance(ActivityManager.class, "IActivityManagerSingleton", null); Context realContext = TestApplication.getAppContext(); realContext.registerReceiver(mTestReceiver, new IntentFilter(TEST_INTENT)); registerTestIntentReceiver(); // initiate parameters for an invalid text MO SMS (the 2nd segmeant has 161 characters) ArrayList<String> parts = new ArrayList<>(); Loading @@ -280,7 +305,7 @@ public class GsmSmsDispatcherTest extends TelephonyTest { + "8"); ArrayList<PendingIntent> sentIntents = new ArrayList<>(); PendingIntent sentIntent = PendingIntent.getBroadcast(realContext, 0, PendingIntent sentIntent = PendingIntent.getBroadcast(TestApplication.getAppContext(), 0, new Intent(TEST_INTENT), PendingIntent.FLAG_IMMUTABLE); sentIntents.add(sentIntent); sentIntents.add(sentIntent); Loading @@ -296,4 +321,100 @@ public class GsmSmsDispatcherTest extends TelephonyTest { assertEquals(SmsManager.RESULT_ERROR_GENERIC_FAILURE, mTestReceiver.getResultCode()); } } private void mockCarrierApp() throws RemoteException { mContextFixture.addService( CarrierMessagingService.SERVICE_INTERFACE, new ComponentName(CARRIER_APP_PACKAGE_NAME, "CarrierAppFilterClass"), CARRIER_APP_PACKAGE_NAME, mICarrierAppMessagingService, new ServiceInfo()); when(mICarrierAppMessagingService.asBinder()).thenReturn(mICarrierAppMessagingService); mockUiccWithCarrierApp(); } private void mockUiccWithCarrierApp() { when(mUiccController.getUiccCard(mPhone.getPhoneId())).thenReturn(mUiccCard); List<String> carrierPackages = new ArrayList<>(); carrierPackages.add(CARRIER_APP_PACKAGE_NAME); when(mUiccCard.getCarrierPackageNamesForIntent( any(PackageManager.class), any(Intent.class))).thenReturn(carrierPackages); } private void mockCarrierAppStubResults(final int result, ICarrierMessagingService.Stub stub, boolean callOnFilterComplete) throws RemoteException { when(stub.queryLocalInterface(anyString())).thenReturn(stub); when(stub.asBinder()).thenReturn(stub); doAnswer(new Answer<Void>() { @Override public Void answer(InvocationOnMock invocation) throws Throwable { Object[] args = invocation.getArguments(); ICarrierMessagingCallback callback = (ICarrierMessagingCallback) args[4]; if (callOnFilterComplete) { callback.onSendSmsComplete(result, 0); } return null; } }).when(stub).sendTextSms( anyString(), anyInt(), anyString(), anyInt(), any(ICarrierMessagingCallback.class)); } @Test @SmallTest public void testSendSmsByCarrierApp() throws Exception { mockCarrierApp(); mockCarrierAppStubResults(CarrierMessagingService.SEND_STATUS_OK, mICarrierAppMessagingService, true); registerTestIntentReceiver(); PendingIntent pendingIntent = PendingIntent.getBroadcast(TestApplication.getAppContext(), 0, new Intent(TEST_INTENT), PendingIntent.FLAG_MUTABLE); mReceivedTestIntent = false; mGsmSmsDispatcher.sendText("6501002000", "121" /*scAddr*/, "test sms", pendingIntent, null, null, null, false, -1, false, -1, false, 0L); processAllMessages(); synchronized (mLock) { if (!mReceivedTestIntent) { // long wait since sometimes broadcasts can take a long time if the system is loaded mLock.wait(60000); } assertEquals(true, mReceivedTestIntent); int resultCode = mTestReceiver.getResultCode(); assertTrue("Unexpected result code: " + resultCode, resultCode == SmsManager.RESULT_ERROR_NONE || resultCode == Activity.RESULT_OK); verify(mSimulatedCommandsVerifier, times(0)).sendSMS(anyString(), anyString(), any(Message.class)); } } @Test @SmallTest public void testSendSmsByCarrierAppNoResponse() throws Exception { mockCarrierApp(); // do not mock result, instead reduce the timeout for test mGsmSmsDispatcher.mCarrierMessagingTimeout = 100; mGsmSmsDispatcher.sendText("6501002000", "121" /*scAddr*/, "test sms", null, null, null, null, false, -1, false, -1, false, 0L); // wait for timeout waitForMs(150); verify(mSimulatedCommandsVerifier).sendSMS(anyString(), anyString(), any(Message.class)); } @Test @SmallTest public void testSendSmsByCarrierAppBindingFailed() throws Exception { mContextFixture.mockBindingFailureForPackage(CARRIER_APP_PACKAGE_NAME); // mock presence of carrier app, but do not create a mock service to make binding fail mockUiccWithCarrierApp(); mGsmSmsDispatcher.sendText("6501002000", "121" /*scAddr*/, "test sms", null, null, null, null, false, -1, false, -1, false, 0L); processAllMessages(); verify(mSimulatedCommandsVerifier).sendSMS(anyString(), anyString(), any(Message.class)); } }