Loading src/java/com/android/internal/telephony/SmsController.java +75 −0 Original line number Diff line number Diff line Loading @@ -18,7 +18,9 @@ package com.android.internal.telephony; import static android.content.pm.PackageManager.FEATURE_TELEPHONY_MESSAGING; import static android.content.pm.PackageManager.PERMISSION_GRANTED; import static android.telephony.TelephonyManager.ENABLE_FEATURE_MAPPING; import static com.android.internal.telephony.util.TelephonyUtils.checkDumpPermission; Loading @@ -27,6 +29,7 @@ import android.annotation.Nullable; import android.app.ActivityManager; import android.app.AppOpsManager; import android.app.PendingIntent; import android.app.compat.CompatChanges; import android.compat.annotation.UnsupportedAppUsage; import android.content.Context; import android.content.pm.PackageManager; Loading Loading @@ -66,11 +69,14 @@ public class SmsController extends ISmsImplBase { static final String LOG_TAG = "SmsController"; private final Context mContext; private final PackageManager mPackageManager; @NonNull private final FeatureFlags mFlags; @VisibleForTesting public SmsController(Context context, @NonNull FeatureFlags flags) { mContext = context; mFlags = flags; mPackageManager = context.getPackageManager(); ServiceRegisterer smsServiceRegisterer = TelephonyFrameworkInitializer .getTelephonyServiceManager() .getSmsServiceRegisterer(); Loading Loading @@ -284,6 +290,8 @@ public class SmsController extends ISmsImplBase { return; } enforceTelephonyFeatureWithException(callingPackage, "sendTextForSubscriber"); long token = Binder.clearCallingIdentity(); SubscriptionInfo info; try { Loading Loading @@ -401,6 +409,8 @@ public class SmsController extends ISmsImplBase { return; } enforceTelephonyFeatureWithException(callingPackage, "sendMultipartTextForSubscriber"); // Perform FDN check if (isNumberBlockedByFDN(subId, destAddr, callingPackage)) { sendErrorInPendingIntents(sentIntents, SmsManager.RESULT_ERROR_FDN_CHECK_FAILURE); Loading Loading @@ -467,6 +477,9 @@ public class SmsController extends ISmsImplBase { @Override public boolean enableCellBroadcastRangeForSubscriber(int subId, int startMessageId, int endMessageId, int ranType) { enforceTelephonyFeatureWithException(getCallingPackage(), "enableCellBroadcastRangeForSubscriber"); IccSmsInterfaceManager iccSmsIntMgr = getIccSmsInterfaceManager(subId); if (iccSmsIntMgr != null) { return iccSmsIntMgr.enableCellBroadcastRange(startMessageId, endMessageId, ranType); Loading @@ -489,6 +502,9 @@ public class SmsController extends ISmsImplBase { @Override public boolean disableCellBroadcastRangeForSubscriber(int subId, int startMessageId, int endMessageId, int ranType) { enforceTelephonyFeatureWithException(getCallingPackage(), "disableCellBroadcastRangeForSubscriber"); IccSmsInterfaceManager iccSmsIntMgr = getIccSmsInterfaceManager(subId); if (iccSmsIntMgr != null) { return iccSmsIntMgr.disableCellBroadcastRange(startMessageId, endMessageId, ranType); Loading @@ -501,6 +517,8 @@ public class SmsController extends ISmsImplBase { @Override public int getPremiumSmsPermission(String packageName) { enforceTelephonyFeatureWithException(packageName, "getPremiumSmsPermission"); return getPremiumSmsPermissionForSubscriber(getPreferredSmsSubscription(), packageName); } Loading @@ -518,6 +536,8 @@ public class SmsController extends ISmsImplBase { @Override public void setPremiumSmsPermission(String packageName, int permission) { enforceTelephonyFeatureWithException(packageName, "setPremiumSmsPermission"); setPremiumSmsPermissionForSubscriber(getPreferredSmsSubscription(), packageName, permission); } Loading Loading @@ -558,6 +578,9 @@ public class SmsController extends ISmsImplBase { + "Suppressing activity."); return false; } enforceTelephonyFeatureWithException(getCallingPackage(), "isSmsSimPickActivityNeeded"); TelephonyManager telephonyManager = (TelephonyManager) context.getSystemService(Context.TELEPHONY_SERVICE); if (mFlags.enforceSubscriptionUserFilter()) { Loading Loading @@ -626,6 +649,8 @@ public class SmsController extends ISmsImplBase { @Override public void injectSmsPduForSubscriber( int subId, byte[] pdu, String format, PendingIntent receivedIntent) { enforceTelephonyFeatureWithException(getCallingPackage(), "injectSmsPduForSubscriber"); IccSmsInterfaceManager iccSmsIntMgr = getIccSmsInterfaceManager(subId); if (iccSmsIntMgr != null) { iccSmsIntMgr.injectSmsPdu(pdu, format, receivedIntent); Loading @@ -652,6 +677,9 @@ public class SmsController extends ISmsImplBase { if (SubscriptionManager.isValidSubscriptionId(defaultSubId)) { return defaultSubId; } enforceTelephonyFeatureWithException(getCallingPackage(), "getPreferredSmsSubscription"); // No default, if there is only one sub active, choose that as the "preferred" sub id. long token = Binder.clearCallingIdentity(); try { Loading Loading @@ -720,6 +748,9 @@ public class SmsController extends ISmsImplBase { @Override public Bundle getCarrierConfigValuesForSubscriber(int subId) { enforceTelephonyFeatureWithException(getCallingPackage(), "getCarrierConfigValuesForSubscriber"); final long identity = Binder.clearCallingIdentity(); try { final CarrierConfigManager configManager = Loading Loading @@ -848,6 +879,10 @@ public class SmsController extends ISmsImplBase { if (callingPkg == null) { callingPkg = getCallingPackage(); } enforceTelephonyFeatureWithException(callingPkg, "createAppSpecificSmsTokenWithPackageInfo"); return getPhone(subId).getAppSmsManager().createAppSpecificSmsTokenWithPackageInfo( subId, callingPkg, prefixes, intent); } Loading @@ -857,6 +892,9 @@ public class SmsController extends ISmsImplBase { if (callingPkg == null) { callingPkg = getCallingPackage(); } enforceTelephonyFeatureWithException(callingPkg, "createAppSpecificSmsToken"); return getPhone(subId).getAppSmsManager().createAppSpecificSmsToken(callingPkg, intent); } Loading Loading @@ -972,6 +1010,10 @@ public class SmsController extends ISmsImplBase { if (callingPackage == null) { callingPackage = getCallingPackage(); } enforceTelephonyFeatureWithException(callingPackage, "getSmscAddressFromIccEfForSubscriber"); IccSmsInterfaceManager iccSmsIntMgr = getIccSmsInterfaceManager(subId); if (iccSmsIntMgr != null) { return iccSmsIntMgr.getSmscAddressFromIccEf(callingPackage); Loading @@ -988,6 +1030,10 @@ public class SmsController extends ISmsImplBase { if (callingPackage == null) { callingPackage = getCallingPackage(); } enforceTelephonyFeatureWithException(callingPackage, "setSmscAddressOnIccEfForSubscriber"); IccSmsInterfaceManager iccSmsIntMgr = getIccSmsInterfaceManager(subId); if (iccSmsIntMgr != null) { return iccSmsIntMgr.setSmscAddressOnIccEf(callingPackage, smsc); Loading Loading @@ -1063,6 +1109,9 @@ public class SmsController extends ISmsImplBase { */ @Override public int getSmsCapacityOnIccForSubscriber(int subId) { enforceTelephonyFeatureWithException(getCallingPackage(), "getSmsCapacityOnIccForSubscriber"); IccSmsInterfaceManager iccSmsIntMgr = getIccSmsInterfaceManager(subId); if (iccSmsIntMgr != null ) { Loading @@ -1081,6 +1130,9 @@ public class SmsController extends ISmsImplBase { */ @Override public boolean resetAllCellBroadcastRanges(int subId) { enforceTelephonyFeatureWithException(getCallingPackage(), "resetAllCellBroadcastRanges"); IccSmsInterfaceManager iccSmsIntMgr = getIccSmsInterfaceManager(subId); if (iccSmsIntMgr != null) { iccSmsIntMgr.resetAllCellBroadcastRanges(); Loading Loading @@ -1158,4 +1210,27 @@ public class SmsController extends ISmsImplBase { byte[] bytes = locationUrl.getBytes(StandardCharsets.ISO_8859_1); return WapPushCache.getWapMessageSize(bytes); } /** * Make sure the device has required telephony feature * * @throws UnsupportedOperationException if the device does not have required telephony feature */ private void enforceTelephonyFeatureWithException(@Nullable String callingPackage, @NonNull String methodName) { if (callingPackage == null || mPackageManager == null) { return; } if (!mFlags.enforceTelephonyFeatureMappingForPublicApis() || !CompatChanges.isChangeEnabled(ENABLE_FEATURE_MAPPING, callingPackage, Binder.getCallingUserHandle())) { return; } if (!mPackageManager.hasSystemFeature(FEATURE_TELEPHONY_MESSAGING)) { throw new UnsupportedOperationException( methodName + " is unsupported without " + FEATURE_TELEPHONY_MESSAGING); } } } No newline at end of file tests/telephonytests/src/com/android/internal/telephony/SmsControllerTest.java +36 −0 Original line number Diff line number Diff line Loading @@ -29,7 +29,9 @@ import static org.mockito.Mockito.eq; import static org.mockito.Mockito.never; import static org.mockito.Mockito.verify; import android.compat.testing.PlatformCompatChangeRule; import android.content.pm.PackageManager; import android.telephony.TelephonyManager; import android.testing.AndroidTestingRunner; import android.testing.TestableLooper; Loading @@ -37,9 +39,13 @@ import com.android.internal.telephony.uicc.AdnRecord; import com.android.internal.telephony.uicc.AdnRecordCache; import com.android.internal.telephony.uicc.IccConstants; import libcore.junit.util.compat.CoreCompatChangeRule.EnableCompatChanges; import org.junit.After; import org.junit.Before; import org.junit.Rule; import org.junit.Test; import org.junit.rules.TestRule; import org.junit.runner.RunWith; import org.mockito.Mockito; Loading @@ -50,6 +56,8 @@ import java.util.NoSuchElementException; @RunWith(AndroidTestingRunner.class) @TestableLooper.RunWithLooper public class SmsControllerTest extends TelephonyTest { @Rule public TestRule compatChangeRule = new PlatformCompatChangeRule(); // Mocked classes private AdnRecordCache mAdnRecordCache; Loading @@ -65,6 +73,9 @@ public class SmsControllerTest extends TelephonyTest { mAdnRecordCache = Mockito.mock(AdnRecordCache.class); mSmsControllerUT = new SmsController(mContext, mFeatureFlags); mCallingPackage = mContext.getOpPackageName(); doReturn(true).when(mPackageManager).hasSystemFeature( PackageManager.FEATURE_TELEPHONY_MESSAGING); } @After Loading Loading @@ -281,4 +292,29 @@ public class SmsControllerTest extends TelephonyTest { mSmsControllerUT.getWapMessageSize("content://mms") ); } @Test @EnableCompatChanges({TelephonyManager.ENABLE_FEATURE_MAPPING}) public void sendTextForSubscriberTestEnabledTelephonyFeature() { int subId = 1; doReturn(true).when(mSubscriptionManager) .isSubscriptionAssociatedWithUser(eq(subId), any()); // Feature enabled, device does not have required telephony feature. doReturn(true).when(mFeatureFlags).enforceTelephonyFeatureMappingForPublicApis(); doReturn(false).when(mPackageManager).hasSystemFeature( PackageManager.FEATURE_TELEPHONY_MESSAGING); assertThrows(UnsupportedOperationException.class, () -> mSmsControllerUT.sendTextForSubscriber(subId, mCallingPackage, null, "1234", null, "text", null, null, false, 0L, true, true)); // Device has required telephony feature. doReturn(true).when(mPackageManager).hasSystemFeature( PackageManager.FEATURE_TELEPHONY_MESSAGING); mSmsControllerUT.sendTextForSubscriber(subId, mCallingPackage, null, "1234", null, "text", null, null, false, 0L, true, true); verify(mIccSmsInterfaceManager, Mockito.times(1)) .sendText(mCallingPackage, "1234", null, "text", null, null, false, 0L, true); } } No newline at end of file Loading
src/java/com/android/internal/telephony/SmsController.java +75 −0 Original line number Diff line number Diff line Loading @@ -18,7 +18,9 @@ package com.android.internal.telephony; import static android.content.pm.PackageManager.FEATURE_TELEPHONY_MESSAGING; import static android.content.pm.PackageManager.PERMISSION_GRANTED; import static android.telephony.TelephonyManager.ENABLE_FEATURE_MAPPING; import static com.android.internal.telephony.util.TelephonyUtils.checkDumpPermission; Loading @@ -27,6 +29,7 @@ import android.annotation.Nullable; import android.app.ActivityManager; import android.app.AppOpsManager; import android.app.PendingIntent; import android.app.compat.CompatChanges; import android.compat.annotation.UnsupportedAppUsage; import android.content.Context; import android.content.pm.PackageManager; Loading Loading @@ -66,11 +69,14 @@ public class SmsController extends ISmsImplBase { static final String LOG_TAG = "SmsController"; private final Context mContext; private final PackageManager mPackageManager; @NonNull private final FeatureFlags mFlags; @VisibleForTesting public SmsController(Context context, @NonNull FeatureFlags flags) { mContext = context; mFlags = flags; mPackageManager = context.getPackageManager(); ServiceRegisterer smsServiceRegisterer = TelephonyFrameworkInitializer .getTelephonyServiceManager() .getSmsServiceRegisterer(); Loading Loading @@ -284,6 +290,8 @@ public class SmsController extends ISmsImplBase { return; } enforceTelephonyFeatureWithException(callingPackage, "sendTextForSubscriber"); long token = Binder.clearCallingIdentity(); SubscriptionInfo info; try { Loading Loading @@ -401,6 +409,8 @@ public class SmsController extends ISmsImplBase { return; } enforceTelephonyFeatureWithException(callingPackage, "sendMultipartTextForSubscriber"); // Perform FDN check if (isNumberBlockedByFDN(subId, destAddr, callingPackage)) { sendErrorInPendingIntents(sentIntents, SmsManager.RESULT_ERROR_FDN_CHECK_FAILURE); Loading Loading @@ -467,6 +477,9 @@ public class SmsController extends ISmsImplBase { @Override public boolean enableCellBroadcastRangeForSubscriber(int subId, int startMessageId, int endMessageId, int ranType) { enforceTelephonyFeatureWithException(getCallingPackage(), "enableCellBroadcastRangeForSubscriber"); IccSmsInterfaceManager iccSmsIntMgr = getIccSmsInterfaceManager(subId); if (iccSmsIntMgr != null) { return iccSmsIntMgr.enableCellBroadcastRange(startMessageId, endMessageId, ranType); Loading @@ -489,6 +502,9 @@ public class SmsController extends ISmsImplBase { @Override public boolean disableCellBroadcastRangeForSubscriber(int subId, int startMessageId, int endMessageId, int ranType) { enforceTelephonyFeatureWithException(getCallingPackage(), "disableCellBroadcastRangeForSubscriber"); IccSmsInterfaceManager iccSmsIntMgr = getIccSmsInterfaceManager(subId); if (iccSmsIntMgr != null) { return iccSmsIntMgr.disableCellBroadcastRange(startMessageId, endMessageId, ranType); Loading @@ -501,6 +517,8 @@ public class SmsController extends ISmsImplBase { @Override public int getPremiumSmsPermission(String packageName) { enforceTelephonyFeatureWithException(packageName, "getPremiumSmsPermission"); return getPremiumSmsPermissionForSubscriber(getPreferredSmsSubscription(), packageName); } Loading @@ -518,6 +536,8 @@ public class SmsController extends ISmsImplBase { @Override public void setPremiumSmsPermission(String packageName, int permission) { enforceTelephonyFeatureWithException(packageName, "setPremiumSmsPermission"); setPremiumSmsPermissionForSubscriber(getPreferredSmsSubscription(), packageName, permission); } Loading Loading @@ -558,6 +578,9 @@ public class SmsController extends ISmsImplBase { + "Suppressing activity."); return false; } enforceTelephonyFeatureWithException(getCallingPackage(), "isSmsSimPickActivityNeeded"); TelephonyManager telephonyManager = (TelephonyManager) context.getSystemService(Context.TELEPHONY_SERVICE); if (mFlags.enforceSubscriptionUserFilter()) { Loading Loading @@ -626,6 +649,8 @@ public class SmsController extends ISmsImplBase { @Override public void injectSmsPduForSubscriber( int subId, byte[] pdu, String format, PendingIntent receivedIntent) { enforceTelephonyFeatureWithException(getCallingPackage(), "injectSmsPduForSubscriber"); IccSmsInterfaceManager iccSmsIntMgr = getIccSmsInterfaceManager(subId); if (iccSmsIntMgr != null) { iccSmsIntMgr.injectSmsPdu(pdu, format, receivedIntent); Loading @@ -652,6 +677,9 @@ public class SmsController extends ISmsImplBase { if (SubscriptionManager.isValidSubscriptionId(defaultSubId)) { return defaultSubId; } enforceTelephonyFeatureWithException(getCallingPackage(), "getPreferredSmsSubscription"); // No default, if there is only one sub active, choose that as the "preferred" sub id. long token = Binder.clearCallingIdentity(); try { Loading Loading @@ -720,6 +748,9 @@ public class SmsController extends ISmsImplBase { @Override public Bundle getCarrierConfigValuesForSubscriber(int subId) { enforceTelephonyFeatureWithException(getCallingPackage(), "getCarrierConfigValuesForSubscriber"); final long identity = Binder.clearCallingIdentity(); try { final CarrierConfigManager configManager = Loading Loading @@ -848,6 +879,10 @@ public class SmsController extends ISmsImplBase { if (callingPkg == null) { callingPkg = getCallingPackage(); } enforceTelephonyFeatureWithException(callingPkg, "createAppSpecificSmsTokenWithPackageInfo"); return getPhone(subId).getAppSmsManager().createAppSpecificSmsTokenWithPackageInfo( subId, callingPkg, prefixes, intent); } Loading @@ -857,6 +892,9 @@ public class SmsController extends ISmsImplBase { if (callingPkg == null) { callingPkg = getCallingPackage(); } enforceTelephonyFeatureWithException(callingPkg, "createAppSpecificSmsToken"); return getPhone(subId).getAppSmsManager().createAppSpecificSmsToken(callingPkg, intent); } Loading Loading @@ -972,6 +1010,10 @@ public class SmsController extends ISmsImplBase { if (callingPackage == null) { callingPackage = getCallingPackage(); } enforceTelephonyFeatureWithException(callingPackage, "getSmscAddressFromIccEfForSubscriber"); IccSmsInterfaceManager iccSmsIntMgr = getIccSmsInterfaceManager(subId); if (iccSmsIntMgr != null) { return iccSmsIntMgr.getSmscAddressFromIccEf(callingPackage); Loading @@ -988,6 +1030,10 @@ public class SmsController extends ISmsImplBase { if (callingPackage == null) { callingPackage = getCallingPackage(); } enforceTelephonyFeatureWithException(callingPackage, "setSmscAddressOnIccEfForSubscriber"); IccSmsInterfaceManager iccSmsIntMgr = getIccSmsInterfaceManager(subId); if (iccSmsIntMgr != null) { return iccSmsIntMgr.setSmscAddressOnIccEf(callingPackage, smsc); Loading Loading @@ -1063,6 +1109,9 @@ public class SmsController extends ISmsImplBase { */ @Override public int getSmsCapacityOnIccForSubscriber(int subId) { enforceTelephonyFeatureWithException(getCallingPackage(), "getSmsCapacityOnIccForSubscriber"); IccSmsInterfaceManager iccSmsIntMgr = getIccSmsInterfaceManager(subId); if (iccSmsIntMgr != null ) { Loading @@ -1081,6 +1130,9 @@ public class SmsController extends ISmsImplBase { */ @Override public boolean resetAllCellBroadcastRanges(int subId) { enforceTelephonyFeatureWithException(getCallingPackage(), "resetAllCellBroadcastRanges"); IccSmsInterfaceManager iccSmsIntMgr = getIccSmsInterfaceManager(subId); if (iccSmsIntMgr != null) { iccSmsIntMgr.resetAllCellBroadcastRanges(); Loading Loading @@ -1158,4 +1210,27 @@ public class SmsController extends ISmsImplBase { byte[] bytes = locationUrl.getBytes(StandardCharsets.ISO_8859_1); return WapPushCache.getWapMessageSize(bytes); } /** * Make sure the device has required telephony feature * * @throws UnsupportedOperationException if the device does not have required telephony feature */ private void enforceTelephonyFeatureWithException(@Nullable String callingPackage, @NonNull String methodName) { if (callingPackage == null || mPackageManager == null) { return; } if (!mFlags.enforceTelephonyFeatureMappingForPublicApis() || !CompatChanges.isChangeEnabled(ENABLE_FEATURE_MAPPING, callingPackage, Binder.getCallingUserHandle())) { return; } if (!mPackageManager.hasSystemFeature(FEATURE_TELEPHONY_MESSAGING)) { throw new UnsupportedOperationException( methodName + " is unsupported without " + FEATURE_TELEPHONY_MESSAGING); } } } No newline at end of file
tests/telephonytests/src/com/android/internal/telephony/SmsControllerTest.java +36 −0 Original line number Diff line number Diff line Loading @@ -29,7 +29,9 @@ import static org.mockito.Mockito.eq; import static org.mockito.Mockito.never; import static org.mockito.Mockito.verify; import android.compat.testing.PlatformCompatChangeRule; import android.content.pm.PackageManager; import android.telephony.TelephonyManager; import android.testing.AndroidTestingRunner; import android.testing.TestableLooper; Loading @@ -37,9 +39,13 @@ import com.android.internal.telephony.uicc.AdnRecord; import com.android.internal.telephony.uicc.AdnRecordCache; import com.android.internal.telephony.uicc.IccConstants; import libcore.junit.util.compat.CoreCompatChangeRule.EnableCompatChanges; import org.junit.After; import org.junit.Before; import org.junit.Rule; import org.junit.Test; import org.junit.rules.TestRule; import org.junit.runner.RunWith; import org.mockito.Mockito; Loading @@ -50,6 +56,8 @@ import java.util.NoSuchElementException; @RunWith(AndroidTestingRunner.class) @TestableLooper.RunWithLooper public class SmsControllerTest extends TelephonyTest { @Rule public TestRule compatChangeRule = new PlatformCompatChangeRule(); // Mocked classes private AdnRecordCache mAdnRecordCache; Loading @@ -65,6 +73,9 @@ public class SmsControllerTest extends TelephonyTest { mAdnRecordCache = Mockito.mock(AdnRecordCache.class); mSmsControllerUT = new SmsController(mContext, mFeatureFlags); mCallingPackage = mContext.getOpPackageName(); doReturn(true).when(mPackageManager).hasSystemFeature( PackageManager.FEATURE_TELEPHONY_MESSAGING); } @After Loading Loading @@ -281,4 +292,29 @@ public class SmsControllerTest extends TelephonyTest { mSmsControllerUT.getWapMessageSize("content://mms") ); } @Test @EnableCompatChanges({TelephonyManager.ENABLE_FEATURE_MAPPING}) public void sendTextForSubscriberTestEnabledTelephonyFeature() { int subId = 1; doReturn(true).when(mSubscriptionManager) .isSubscriptionAssociatedWithUser(eq(subId), any()); // Feature enabled, device does not have required telephony feature. doReturn(true).when(mFeatureFlags).enforceTelephonyFeatureMappingForPublicApis(); doReturn(false).when(mPackageManager).hasSystemFeature( PackageManager.FEATURE_TELEPHONY_MESSAGING); assertThrows(UnsupportedOperationException.class, () -> mSmsControllerUT.sendTextForSubscriber(subId, mCallingPackage, null, "1234", null, "text", null, null, false, 0L, true, true)); // Device has required telephony feature. doReturn(true).when(mPackageManager).hasSystemFeature( PackageManager.FEATURE_TELEPHONY_MESSAGING); mSmsControllerUT.sendTextForSubscriber(subId, mCallingPackage, null, "1234", null, "text", null, null, false, 0L, true, true); verify(mIccSmsInterfaceManager, Mockito.times(1)) .sendText(mCallingPackage, "1234", null, "text", null, null, false, 0L, true); } } No newline at end of file