Loading flags/messaging.aconfig +8 −1 Original line number Diff line number Diff line package: "com.android.internal.telephony.flags" flag { name: "reject_bad_sub_id_interaction" namespace: "telephony" description: "Previously, the DB allows insertion of a random sub Id, but doesn't allow query it. This change rejects such interaction." bug: "294125411" } No newline at end of file src/java/com/android/internal/telephony/ServiceStateTracker.java +2 −1 Original line number Diff line number Diff line Loading @@ -99,6 +99,7 @@ import com.android.internal.telephony.metrics.RadioPowerStateStats; import com.android.internal.telephony.metrics.ServiceStateStats; import com.android.internal.telephony.metrics.TelephonyMetrics; import com.android.internal.telephony.satellite.NtnCapabilityResolver; import com.android.internal.telephony.satellite.SatelliteController; import com.android.internal.telephony.subscription.SubscriptionInfoInternal; import com.android.internal.telephony.subscription.SubscriptionManagerService; import com.android.internal.telephony.uicc.IccCardApplicationStatus.AppState; Loading Loading @@ -4971,6 +4972,7 @@ public class ServiceStateTracker extends Handler { */ public void powerOffRadioSafely() { synchronized (this) { SatelliteController.getInstance().onCellularRadioPowerOffRequested(); if (!mPendingRadioPowerOffAfterDataOff) { // hang up all active voice calls first if (mPhone.isPhoneTypeGsm() && mPhone.isInCall()) { Loading Loading @@ -5056,7 +5058,6 @@ public class ServiceStateTracker extends Handler { } mCi.setRadioPower(false, obtainMessage(EVENT_RADIO_POWER_OFF_DONE)); } /** Cancel a pending (if any) pollState() operation */ Loading src/java/com/android/internal/telephony/satellite/SatelliteController.java +22 −23 Original line number Diff line number Diff line Loading @@ -1038,29 +1038,7 @@ public class SatelliteController extends Handler { } case EVENT_RADIO_STATE_CHANGED: { if (mCi.getRadioState() == TelephonyManager.RADIO_POWER_OFF || mCi.getRadioState() == TelephonyManager.RADIO_POWER_UNAVAILABLE) { mIsRadioOn = false; logd("Radio State Changed to " + mCi.getRadioState()); if (isSatelliteEnabled()) { IIntegerConsumer errorCallback = new IIntegerConsumer.Stub() { @Override public void accept(int result) { logd("RequestSatelliteEnabled: result=" + result); } }; Phone phone = SatelliteServiceUtils.getPhone(); Consumer<Integer> result = FunctionalUtils .ignoreRemoteException(errorCallback::accept); RequestSatelliteEnabledArgument message = new RequestSatelliteEnabledArgument(false, false, result); request = new SatelliteControllerHandlerRequest(message, phone); handleSatelliteEnabled(request); } else { logd("EVENT_RADIO_STATE_CHANGED: Satellite modem is currently disabled." + " Ignored the event"); } } else { if (mCi.getRadioState() == TelephonyManager.RADIO_POWER_ON) { mIsRadioOn = true; if (!mSatelliteModemInterface.isSatelliteServiceSupported()) { synchronized (mIsSatelliteSupportedLock) { Loading Loading @@ -2097,6 +2075,27 @@ public class SatelliteController extends Handler { } } /** * This function is used by {@link com.android.internal.telephony.ServiceStateTracker} to notify * {@link SatelliteController} that it has received a request to power off the cellular radio * modem. {@link SatelliteController} will then power off the satellite modem. */ public void onCellularRadioPowerOffRequested() { if (!mFeatureFlags.oemEnabledSatelliteFlag()) { return; } mIsRadioOn = false; requestSatelliteEnabled(SubscriptionManager.DEFAULT_SUBSCRIPTION_ID, false /* enableSatellite */, false /* enableDemoMode */, new IIntegerConsumer.Stub() { @Override public void accept(int result) { logd("onRadioPowerOffRequested: requestSatelliteEnabled result=" + result); } }); } /** * @return {@code true} is satellite is supported on the device, {@code false} otherwise. */ Loading src/java/com/android/internal/telephony/subscription/SubscriptionManagerService.java +14 −23 Original line number Diff line number Diff line Loading @@ -3646,7 +3646,7 @@ public class SubscriptionManagerService extends ISub.Stub { * else {@code false} if subscription is not associated with user. * * @throws SecurityException if the caller doesn't have permissions required. * * @throws IllegalArgumentException if the subscription has no records on device. */ @Override public boolean isSubscriptionAssociatedWithUser(int subscriptionId, Loading @@ -3656,18 +3656,11 @@ public class SubscriptionManagerService extends ISub.Stub { long token = Binder.clearCallingIdentity(); try { // Return true if there are no subscriptions on the device. List<SubscriptionInfo> subInfoList = getAllSubInfoList( mContext.getOpPackageName(), mContext.getAttributionTag()); if (subInfoList == null || subInfoList.isEmpty()) { return true; } List<Integer> subIdList = subInfoList.stream().map(SubscriptionInfo::getSubscriptionId) .collect(Collectors.toList()); if (!subIdList.contains(subscriptionId)) { // Return true as this subscription is not available on the device. return true; // Throw IAE if no record of the sub's association state. if (mSubscriptionDatabaseManager.getSubscriptionInfoInternal(subscriptionId) == null) { throw new IllegalArgumentException( "[isSubscriptionAssociatedWithUser]: Subscription doesn't exist: " + subscriptionId); } // Get list of subscriptions associated with this user. Loading Loading @@ -3709,23 +3702,21 @@ public class SubscriptionManagerService extends ISub.Stub { long token = Binder.clearCallingIdentity(); try { List<SubscriptionInfo> subInfoList = getAllSubInfoList( mContext.getOpPackageName(), mContext.getAttributionTag()); if (subInfoList == null || subInfoList.isEmpty()) { List<SubscriptionInfoInternal> subInfoList = mSubscriptionDatabaseManager .getAllSubscriptions(); if (subInfoList.isEmpty()) { return new ArrayList<>(); } List<SubscriptionInfo> subscriptionsAssociatedWithUser = new ArrayList<>(); List<SubscriptionInfo> subscriptionsWithNoAssociation = new ArrayList<>(); for (SubscriptionInfo subInfo : subInfoList) { int subId = subInfo.getSubscriptionId(); UserHandle subIdUserHandle = getSubscriptionUserHandle(subId); if (userHandle.equals(subIdUserHandle)) { for (SubscriptionInfoInternal subInfo : subInfoList) { if (subInfo.getUserId() == userHandle.getIdentifier()) { // Store subscriptions whose user handle matches with required user handle. subscriptionsAssociatedWithUser.add(subInfo); } else if (subIdUserHandle == null) { subscriptionsAssociatedWithUser.add(subInfo.toSubscriptionInfo()); } else if (subInfo.getUserId() == UserHandle.USER_NULL) { // Store subscriptions whose user handle is set to null. subscriptionsWithNoAssociation.add(subInfo); subscriptionsWithNoAssociation.add(subInfo.toSubscriptionInfo()); } } Loading tests/telephonytests/src/com/android/internal/telephony/ServiceStateTrackerTest.java +6 −0 Original line number Diff line number Diff line Loading @@ -32,6 +32,7 @@ import static org.mockito.Matchers.nullable; import static org.mockito.Mockito.anyInt; import static org.mockito.Mockito.anyString; import static org.mockito.Mockito.atLeast; import static org.mockito.Mockito.clearInvocations; import static org.mockito.Mockito.doReturn; import static org.mockito.Mockito.eq; import static org.mockito.Mockito.never; Loading Loading @@ -511,18 +512,22 @@ public class ServiceStateTrackerTest extends TelephonyTest { } private void testSetRadioPowerForReason(int reason) { clearInvocations(mSatelliteController); // Radio does not turn on if off for other reason and not emergency call. assertTrue(mSimulatedCommands.getRadioState() == TelephonyManager.RADIO_POWER_ON); assertTrue(sst.getRadioPowerOffReasons().isEmpty()); sst.setRadioPowerForReason(false, false, false, false, reason); assertTrue(sst.getRadioPowerOffReasons().contains(reason)); assertTrue(sst.getRadioPowerOffReasons().size() == 1); verify(mSatelliteController).onCellularRadioPowerOffRequested(); clearInvocations(mSatelliteController); waitForLastHandlerAction(mSSTTestHandler.getThreadHandler()); assertTrue(mSimulatedCommands.getRadioState() == TelephonyManager.RADIO_POWER_OFF); sst.setRadioPowerForReason(true, false, false, false, TelephonyManager.RADIO_POWER_REASON_USER); assertTrue(sst.getRadioPowerOffReasons().contains(reason)); assertTrue(sst.getRadioPowerOffReasons().size() == 1); verify(mSatelliteController, never()).onCellularRadioPowerOffRequested(); waitForLastHandlerAction(mSSTTestHandler.getThreadHandler()); assertTrue(mSimulatedCommands.getRadioState() == TelephonyManager.RADIO_POWER_OFF); Loading @@ -530,6 +535,7 @@ public class ServiceStateTrackerTest extends TelephonyTest { // had been turned off for. sst.setRadioPowerForReason(true, false, false, false, reason); assertTrue(sst.getRadioPowerOffReasons().isEmpty()); verify(mSatelliteController, never()).onCellularRadioPowerOffRequested(); waitForLastHandlerAction(mSSTTestHandler.getThreadHandler()); assertTrue(mSimulatedCommands.getRadioState() == TelephonyManager.RADIO_POWER_ON); Loading Loading
flags/messaging.aconfig +8 −1 Original line number Diff line number Diff line package: "com.android.internal.telephony.flags" flag { name: "reject_bad_sub_id_interaction" namespace: "telephony" description: "Previously, the DB allows insertion of a random sub Id, but doesn't allow query it. This change rejects such interaction." bug: "294125411" } No newline at end of file
src/java/com/android/internal/telephony/ServiceStateTracker.java +2 −1 Original line number Diff line number Diff line Loading @@ -99,6 +99,7 @@ import com.android.internal.telephony.metrics.RadioPowerStateStats; import com.android.internal.telephony.metrics.ServiceStateStats; import com.android.internal.telephony.metrics.TelephonyMetrics; import com.android.internal.telephony.satellite.NtnCapabilityResolver; import com.android.internal.telephony.satellite.SatelliteController; import com.android.internal.telephony.subscription.SubscriptionInfoInternal; import com.android.internal.telephony.subscription.SubscriptionManagerService; import com.android.internal.telephony.uicc.IccCardApplicationStatus.AppState; Loading Loading @@ -4971,6 +4972,7 @@ public class ServiceStateTracker extends Handler { */ public void powerOffRadioSafely() { synchronized (this) { SatelliteController.getInstance().onCellularRadioPowerOffRequested(); if (!mPendingRadioPowerOffAfterDataOff) { // hang up all active voice calls first if (mPhone.isPhoneTypeGsm() && mPhone.isInCall()) { Loading Loading @@ -5056,7 +5058,6 @@ public class ServiceStateTracker extends Handler { } mCi.setRadioPower(false, obtainMessage(EVENT_RADIO_POWER_OFF_DONE)); } /** Cancel a pending (if any) pollState() operation */ Loading
src/java/com/android/internal/telephony/satellite/SatelliteController.java +22 −23 Original line number Diff line number Diff line Loading @@ -1038,29 +1038,7 @@ public class SatelliteController extends Handler { } case EVENT_RADIO_STATE_CHANGED: { if (mCi.getRadioState() == TelephonyManager.RADIO_POWER_OFF || mCi.getRadioState() == TelephonyManager.RADIO_POWER_UNAVAILABLE) { mIsRadioOn = false; logd("Radio State Changed to " + mCi.getRadioState()); if (isSatelliteEnabled()) { IIntegerConsumer errorCallback = new IIntegerConsumer.Stub() { @Override public void accept(int result) { logd("RequestSatelliteEnabled: result=" + result); } }; Phone phone = SatelliteServiceUtils.getPhone(); Consumer<Integer> result = FunctionalUtils .ignoreRemoteException(errorCallback::accept); RequestSatelliteEnabledArgument message = new RequestSatelliteEnabledArgument(false, false, result); request = new SatelliteControllerHandlerRequest(message, phone); handleSatelliteEnabled(request); } else { logd("EVENT_RADIO_STATE_CHANGED: Satellite modem is currently disabled." + " Ignored the event"); } } else { if (mCi.getRadioState() == TelephonyManager.RADIO_POWER_ON) { mIsRadioOn = true; if (!mSatelliteModemInterface.isSatelliteServiceSupported()) { synchronized (mIsSatelliteSupportedLock) { Loading Loading @@ -2097,6 +2075,27 @@ public class SatelliteController extends Handler { } } /** * This function is used by {@link com.android.internal.telephony.ServiceStateTracker} to notify * {@link SatelliteController} that it has received a request to power off the cellular radio * modem. {@link SatelliteController} will then power off the satellite modem. */ public void onCellularRadioPowerOffRequested() { if (!mFeatureFlags.oemEnabledSatelliteFlag()) { return; } mIsRadioOn = false; requestSatelliteEnabled(SubscriptionManager.DEFAULT_SUBSCRIPTION_ID, false /* enableSatellite */, false /* enableDemoMode */, new IIntegerConsumer.Stub() { @Override public void accept(int result) { logd("onRadioPowerOffRequested: requestSatelliteEnabled result=" + result); } }); } /** * @return {@code true} is satellite is supported on the device, {@code false} otherwise. */ Loading
src/java/com/android/internal/telephony/subscription/SubscriptionManagerService.java +14 −23 Original line number Diff line number Diff line Loading @@ -3646,7 +3646,7 @@ public class SubscriptionManagerService extends ISub.Stub { * else {@code false} if subscription is not associated with user. * * @throws SecurityException if the caller doesn't have permissions required. * * @throws IllegalArgumentException if the subscription has no records on device. */ @Override public boolean isSubscriptionAssociatedWithUser(int subscriptionId, Loading @@ -3656,18 +3656,11 @@ public class SubscriptionManagerService extends ISub.Stub { long token = Binder.clearCallingIdentity(); try { // Return true if there are no subscriptions on the device. List<SubscriptionInfo> subInfoList = getAllSubInfoList( mContext.getOpPackageName(), mContext.getAttributionTag()); if (subInfoList == null || subInfoList.isEmpty()) { return true; } List<Integer> subIdList = subInfoList.stream().map(SubscriptionInfo::getSubscriptionId) .collect(Collectors.toList()); if (!subIdList.contains(subscriptionId)) { // Return true as this subscription is not available on the device. return true; // Throw IAE if no record of the sub's association state. if (mSubscriptionDatabaseManager.getSubscriptionInfoInternal(subscriptionId) == null) { throw new IllegalArgumentException( "[isSubscriptionAssociatedWithUser]: Subscription doesn't exist: " + subscriptionId); } // Get list of subscriptions associated with this user. Loading Loading @@ -3709,23 +3702,21 @@ public class SubscriptionManagerService extends ISub.Stub { long token = Binder.clearCallingIdentity(); try { List<SubscriptionInfo> subInfoList = getAllSubInfoList( mContext.getOpPackageName(), mContext.getAttributionTag()); if (subInfoList == null || subInfoList.isEmpty()) { List<SubscriptionInfoInternal> subInfoList = mSubscriptionDatabaseManager .getAllSubscriptions(); if (subInfoList.isEmpty()) { return new ArrayList<>(); } List<SubscriptionInfo> subscriptionsAssociatedWithUser = new ArrayList<>(); List<SubscriptionInfo> subscriptionsWithNoAssociation = new ArrayList<>(); for (SubscriptionInfo subInfo : subInfoList) { int subId = subInfo.getSubscriptionId(); UserHandle subIdUserHandle = getSubscriptionUserHandle(subId); if (userHandle.equals(subIdUserHandle)) { for (SubscriptionInfoInternal subInfo : subInfoList) { if (subInfo.getUserId() == userHandle.getIdentifier()) { // Store subscriptions whose user handle matches with required user handle. subscriptionsAssociatedWithUser.add(subInfo); } else if (subIdUserHandle == null) { subscriptionsAssociatedWithUser.add(subInfo.toSubscriptionInfo()); } else if (subInfo.getUserId() == UserHandle.USER_NULL) { // Store subscriptions whose user handle is set to null. subscriptionsWithNoAssociation.add(subInfo); subscriptionsWithNoAssociation.add(subInfo.toSubscriptionInfo()); } } Loading
tests/telephonytests/src/com/android/internal/telephony/ServiceStateTrackerTest.java +6 −0 Original line number Diff line number Diff line Loading @@ -32,6 +32,7 @@ import static org.mockito.Matchers.nullable; import static org.mockito.Mockito.anyInt; import static org.mockito.Mockito.anyString; import static org.mockito.Mockito.atLeast; import static org.mockito.Mockito.clearInvocations; import static org.mockito.Mockito.doReturn; import static org.mockito.Mockito.eq; import static org.mockito.Mockito.never; Loading Loading @@ -511,18 +512,22 @@ public class ServiceStateTrackerTest extends TelephonyTest { } private void testSetRadioPowerForReason(int reason) { clearInvocations(mSatelliteController); // Radio does not turn on if off for other reason and not emergency call. assertTrue(mSimulatedCommands.getRadioState() == TelephonyManager.RADIO_POWER_ON); assertTrue(sst.getRadioPowerOffReasons().isEmpty()); sst.setRadioPowerForReason(false, false, false, false, reason); assertTrue(sst.getRadioPowerOffReasons().contains(reason)); assertTrue(sst.getRadioPowerOffReasons().size() == 1); verify(mSatelliteController).onCellularRadioPowerOffRequested(); clearInvocations(mSatelliteController); waitForLastHandlerAction(mSSTTestHandler.getThreadHandler()); assertTrue(mSimulatedCommands.getRadioState() == TelephonyManager.RADIO_POWER_OFF); sst.setRadioPowerForReason(true, false, false, false, TelephonyManager.RADIO_POWER_REASON_USER); assertTrue(sst.getRadioPowerOffReasons().contains(reason)); assertTrue(sst.getRadioPowerOffReasons().size() == 1); verify(mSatelliteController, never()).onCellularRadioPowerOffRequested(); waitForLastHandlerAction(mSSTTestHandler.getThreadHandler()); assertTrue(mSimulatedCommands.getRadioState() == TelephonyManager.RADIO_POWER_OFF); Loading @@ -530,6 +535,7 @@ public class ServiceStateTrackerTest extends TelephonyTest { // had been turned off for. sst.setRadioPowerForReason(true, false, false, false, reason); assertTrue(sst.getRadioPowerOffReasons().isEmpty()); verify(mSatelliteController, never()).onCellularRadioPowerOffRequested(); waitForLastHandlerAction(mSSTTestHandler.getThreadHandler()); assertTrue(mSimulatedCommands.getRadioState() == TelephonyManager.RADIO_POWER_ON); Loading