diff options
25 files changed, 420 insertions, 59 deletions
diff --git a/Android.bp b/Android.bp index 4097571eb5..5b684d2362 100644 --- a/Android.bp +++ b/Android.bp @@ -107,16 +107,10 @@ java_library { "net-utils-framework-common", "telephony-protos", "modules-utils-build_system", + "modules-utils-fastxmlserializer", "modules-utils-statemachine", ], - product_variables: { - pdk: { - // enable this build only when platform library is available - enabled: false, - }, - }, - optimize: { enabled: true, shrink: true, @@ -2,8 +2,8 @@ amagup@google.com amallampati@google.com amruthr@google.com breadley@google.com -chinmayd@google.com fionaxu@google.com +grantmenke@google.com huiwang@google.com jackyu@google.com jayachandranc@google.com @@ -17,6 +17,5 @@ tjstuart@google.com tnd@google.com xiaotonj@google.com - - - +# Domain Selection code is co-owned, adding additional owners for this code +per-file EmergencyStateTracker*=hwangoo@google.com,forestchoi@google.com,avinashmp@google.com,mkoon@google.com,seheele@google.com diff --git a/src/java/com/android/internal/telephony/CarrierKeyDownloadManager.java b/src/java/com/android/internal/telephony/CarrierKeyDownloadManager.java index beb6b2653d..195ef16165 100644 --- a/src/java/com/android/internal/telephony/CarrierKeyDownloadManager.java +++ b/src/java/com/android/internal/telephony/CarrierKeyDownloadManager.java @@ -30,6 +30,7 @@ import android.net.Uri; import android.os.Handler; import android.os.Message; import android.os.PersistableBundle; +import android.os.UserManager; import android.telephony.CarrierConfigManager; import android.telephony.ImsiEncryptionInfo; import android.telephony.SubscriptionManager; @@ -108,6 +109,7 @@ public class CarrierKeyDownloadManager extends Handler { private boolean mAllowedOverMeteredNetwork = false; private boolean mDeleteOldKeyAfterDownload = false; private TelephonyManager mTelephonyManager; + private UserManager mUserManager; @VisibleForTesting public String mMccMncForDownload; @@ -125,18 +127,35 @@ public class CarrierKeyDownloadManager extends Handler { mDownloadManager = (DownloadManager) mContext.getSystemService(Context.DOWNLOAD_SERVICE); mTelephonyManager = mContext.getSystemService(TelephonyManager.class) .createForSubscriptionId(mPhone.getSubId()); + mUserManager = mContext.getSystemService(UserManager.class); CarrierConfigManager carrierConfigManager = mContext.getSystemService( CarrierConfigManager.class); // Callback which directly handle config change should be executed on handler thread carrierConfigManager.registerCarrierConfigChangeListener(this::post, (slotIndex, subId, carrierId, specificCarrierId) -> { - if (slotIndex == mPhone.getPhoneId()) { + boolean isUserUnlocked = mUserManager.isUserUnlocked(); + + if (isUserUnlocked && slotIndex == mPhone.getPhoneId()) { Log.d(LOG_TAG, "Carrier Config changed: slotIndex=" + slotIndex); handleAlarmOrConfigChange(); + } else { + Log.d(LOG_TAG, "User is locked"); + mContext.registerReceiver(mUserUnlockedReceiver, new IntentFilter( + Intent.ACTION_USER_UNLOCKED)); } }); } + private final BroadcastReceiver mUserUnlockedReceiver = new BroadcastReceiver() { + @Override + public void onReceive(Context context, Intent intent) { + if (Intent.ACTION_USER_UNLOCKED.equals(intent.getAction())) { + Log.d(LOG_TAG, "Received UserUnlockedReceiver"); + handleAlarmOrConfigChange(); + } + } + }; + private final BroadcastReceiver mDownloadReceiver = new BroadcastReceiver() { @Override public void onReceive(Context context, Intent intent) { diff --git a/src/java/com/android/internal/telephony/FdnUtils.java b/src/java/com/android/internal/telephony/FdnUtils.java index aa2bcfd128..23cab44570 100644 --- a/src/java/com/android/internal/telephony/FdnUtils.java +++ b/src/java/com/android/internal/telephony/FdnUtils.java @@ -33,6 +33,7 @@ import com.android.internal.telephony.uicc.UiccProfile; import com.android.telephony.Rlog; import java.util.ArrayList; +import java.util.regex.PatternSyntaxException; /** * This is a basic utility class for common functions related to Fixed Dialing Numbers @@ -123,6 +124,7 @@ public class FdnUtils { dialStrNational = String.valueOf(phoneNumber.getNationalNumber()); } catch (NumberParseException ignored) { Rlog.w(LOG_TAG, "isFDN: could not parse dialStr"); + dialStr = extractSMSC(dialStr); } /** @@ -187,4 +189,37 @@ public class FdnUtils { return uiccProfile.getApplication(UiccController.APP_FAM_3GPP); } + + private static String extractSMSC(String dialStr) { + try { + String[] dialStrParts = null; + if (dialStr.contains(",")) { + // SMSC can be in the format of ""+123456789123",123" + // Split into two parts using comma as delimiter + // and first part of the string is used as smsc address + dialStrParts = dialStr.split(","); + } else if (dialStr.contains("@")) { + // SMSC can be in the format of "+123456789123@ims.mnc.org" + // Split into two parts using @ as delimiter + // and first part of the string is used as smsc address + dialStrParts = dialStr.split("@"); + } + + if (dialStrParts != null && dialStrParts.length >= 1) { + if (dialStrParts[0].contains("\"")) { + // If SMSC is in this format: ""+123456789123",123", after performing above + // split we get string with double-quotation marks in it + // dialStrParts[0] = ""+123456789123"". + // Here, we remove double-quotation marks from the string. + dialStrParts[0] = dialStrParts[0].replaceAll("\"", ""); + } + return dialStrParts[0]; + } + } catch (PatternSyntaxException ex) { + Rlog.w(LOG_TAG, "extractSMSC: Could not extract number from dialStr " + ex); + } + + // Return original dialStr if it is not in any of the formats mentions above. + return dialStr; + } }
\ No newline at end of file diff --git a/src/java/com/android/internal/telephony/SignalStrengthController.java b/src/java/com/android/internal/telephony/SignalStrengthController.java index 705dab4c0d..8c35e571f5 100644 --- a/src/java/com/android/internal/telephony/SignalStrengthController.java +++ b/src/java/com/android/internal/telephony/SignalStrengthController.java @@ -294,31 +294,38 @@ public class SignalStrengthController extends Handler { } /** - * send signal-strength-changed notification if changed Called both for - * solicited and unsolicited signal strength updates - * - * @return true if the signal strength changed and a notification was sent. + * Send signal-strength-changed notification if changed. Called for both solicited and + * unsolicited signal strength updates. */ - private boolean onSignalStrengthResult(@NonNull AsyncResult ar) { - - // This signal is used for both voice and data radio signal so parse - // all fields + private void onSignalStrengthResult(@NonNull AsyncResult ar) { + // This signal is used for both voice and data radio signal so parse all fields. + SignalStrength signalStrength; if ((ar.exception == null) && (ar.result != null)) { - mSignalStrength = (SignalStrength) ar.result; + signalStrength = (SignalStrength) ar.result; + } else { + loge("onSignalStrengthResult() Exception from RIL : " + ar.exception); + signalStrength = new SignalStrength(); + } + updateSignalStrength(signalStrength); + } - if (mPhone.getServiceStateTracker() != null) { - mSignalStrength.updateLevel(mCarrierConfig, mPhone.getServiceStateTracker().mSS); - } + /** + * Set {@code mSignalStrength} to the input argument {@code signalStrength}, update its level, + * and send signal-strength-changed notification if changed. + * + * @param signalStrength The new SignalStrength used for updating {@code mSignalStrength}. + */ + private void updateSignalStrength(@NonNull SignalStrength signalStrength) { + mSignalStrength = signalStrength; + ServiceStateTracker serviceStateTracker = mPhone.getServiceStateTracker(); + if (serviceStateTracker != null) { + mSignalStrength.updateLevel(mCarrierConfig, serviceStateTracker.mSS); } else { - log("onSignalStrengthResult() Exception from RIL : " + ar.exception); - mSignalStrength = new SignalStrength(); + loge("updateSignalStrength: serviceStateTracker is null"); } mSignalStrengthUpdatedTime = System.currentTimeMillis(); - - boolean ssChanged = notifySignalStrength(); - - return ssChanged; + notifySignalStrength(); } /** @@ -720,20 +727,17 @@ public class SignalStrengthController extends Handler { mSignalStrengthUpdatedTime = System.currentTimeMillis(); } - boolean notifySignalStrength() { - boolean notified = false; + void notifySignalStrength() { if (!mSignalStrength.equals(mLastSignalStrength)) { try { mSignalStrengthChangedRegistrants.notifyRegistrants(); mPhone.notifySignalStrength(); - notified = true; mLastSignalStrength = mSignalStrength; } catch (NullPointerException ex) { - log("updateSignalStrength() Phone already destroyed: " + ex + loge("updateSignalStrength() Phone already destroyed: " + ex + "SignalStrength not notified"); } } - return notified; } /** @@ -1132,6 +1136,7 @@ public class SignalStrengthController extends Handler { updateArfcnLists(); updateReportingCriteria(); + updateSignalStrength(new SignalStrength(mSignalStrength)); } private static SignalThresholdInfo createSignalThresholdsInfo( diff --git a/src/java/com/android/internal/telephony/data/DataNetworkController.java b/src/java/com/android/internal/telephony/data/DataNetworkController.java index 57a0f5af43..f9e7510612 100644 --- a/src/java/com/android/internal/telephony/data/DataNetworkController.java +++ b/src/java/com/android/internal/telephony/data/DataNetworkController.java @@ -614,6 +614,13 @@ public class DataNetworkController extends Handler { * @param transport The transport of the data service. */ public void onDataServiceBound(@TransportType int transport) {} + + /** + * Called when SIM load state changed. + * + * @param simState The current SIM state + */ + public void onSimStateChanged(@SimState int simState) {} } /** @@ -2203,7 +2210,8 @@ public class DataNetworkController extends Handler { @Nullable public DataNetwork getDataNetworkByInterface(@NonNull String interfaceName) { return mDataNetworkList.stream() - .filter(dataNetwork -> !dataNetwork.isDisconnecting()) + .filter(dataNetwork -> !(dataNetwork.isDisconnecting() + || dataNetwork.isDisconnected())) .filter(dataNetwork -> interfaceName.equals( dataNetwork.getLinkProperties().getInterfaceName())) .findFirst() @@ -3124,6 +3132,8 @@ public class DataNetworkController extends Handler { sendMessage(obtainMessage(EVENT_REEVALUATE_UNSATISFIED_NETWORK_REQUESTS, DataEvaluationReason.SIM_LOADED)); } + mDataNetworkControllerCallbacks.forEach(callback -> callback.invokeFromExecutor( + () -> callback.onSimStateChanged(mSimState))); } } diff --git a/src/java/com/android/internal/telephony/data/DataProfileManager.java b/src/java/com/android/internal/telephony/data/DataProfileManager.java index e7e92042e9..0878ccf48a 100644 --- a/src/java/com/android/internal/telephony/data/DataProfileManager.java +++ b/src/java/com/android/internal/telephony/data/DataProfileManager.java @@ -36,6 +36,7 @@ import android.telephony.AnomalyReporter; import android.telephony.CarrierConfigManager; import android.telephony.SubscriptionManager; import android.telephony.TelephonyManager; +import android.telephony.TelephonyManager.SimState; import android.telephony.data.ApnSetting; import android.telephony.data.DataProfile; import android.telephony.data.TrafficDescriptor; @@ -109,6 +110,9 @@ public class DataProfileManager extends Handler { private final @NonNull Set<DataProfileManagerCallback> mDataProfileManagerCallbacks = new ArraySet<>(); + /** SIM state. */ + private @SimState int mSimState = TelephonyManager.SIM_STATE_UNKNOWN; + /** * Data profile manager callback. This should be only used by {@link DataNetworkController}. */ @@ -163,6 +167,11 @@ public class DataProfileManager extends Handler { @NonNull List<DataNetwork> internetNetworks) { DataProfileManager.this.onInternetDataNetworkConnected(internetNetworks); } + + @Override + public void onSimStateChanged(@SimState int simState) { + DataProfileManager.this.mSimState = simState; + } }); mDataConfigManager.registerCallback(new DataConfigManagerCallback(this::post) { @Override @@ -285,7 +294,7 @@ public class DataProfileManager extends Handler { DataProfile dataProfile; - if (!profiles.isEmpty()) { // APN database has been read successfully after SIM loaded + if (mSimState == TelephonyManager.SIM_STATE_LOADED) { // Check if any of the profile already supports IMS, if not, add the default one. dataProfile = profiles.stream() .filter(dp -> dp.canSatisfy(NetworkCapabilities.NET_CAPABILITY_IMS)) @@ -992,6 +1001,16 @@ public class DataProfileManager extends Handler { } /** + * Called by {@link DataRetryManager} to clear all permanent failures upon reset. + */ + public void clearAllDataProfilePermanentFailures() { + mAllDataProfiles.stream() + .map(DataProfile::getApnSetting) + .filter(Objects::nonNull) + .forEach(apnSetting -> apnSetting.setPermanentFailed(false)); + } + + /** * Check if the provided data profile is still compatible with the current environment. Note * this method ignores APN id check and traffic descriptor check. A data profile with traffic * descriptor only can always be used in any condition. diff --git a/src/java/com/android/internal/telephony/data/DataRetryManager.java b/src/java/com/android/internal/telephony/data/DataRetryManager.java index e4e6e26f9c..314668973b 100644 --- a/src/java/com/android/internal/telephony/data/DataRetryManager.java +++ b/src/java/com/android/internal/telephony/data/DataRetryManager.java @@ -1357,6 +1357,9 @@ public class DataRetryManager extends Handler { logl("Remove all retry and throttling entries, reason=" + resetReasonToString(reason)); removeMessages(EVENT_DATA_SETUP_RETRY); removeMessages(EVENT_DATA_HANDOVER_RETRY); + + mDataProfileManager.clearAllDataProfilePermanentFailures(); + mDataRetryEntries.stream() .filter(entry -> entry.getState() == DataRetryEntry.RETRY_STATE_NOT_RETRIED) .forEach(entry -> entry.setState(DataRetryEntry.RETRY_STATE_CANCELLED)); diff --git a/src/java/com/android/internal/telephony/data/PhoneSwitcher.java b/src/java/com/android/internal/telephony/data/PhoneSwitcher.java index a5b3da25ab..cf1a47d3f6 100644 --- a/src/java/com/android/internal/telephony/data/PhoneSwitcher.java +++ b/src/java/com/android/internal/telephony/data/PhoneSwitcher.java @@ -1545,7 +1545,7 @@ public class PhoneSwitcher extends Handler { // If validation feature is not supported, set it directly. Otherwise, // start validation on the subscription first. if (!mValidator.isValidationFeatureSupported()) { - setAutoSelectedDataSubIdInternal(subIdToValidate); + setAutoSelectedDataSubIdInternal(subId); sendSetOpptCallbackHelper(callback, SET_OPPORTUNISTIC_SUB_SUCCESS); return; } diff --git a/src/java/com/android/internal/telephony/domainselection/OWNERS b/src/java/com/android/internal/telephony/domainselection/OWNERS new file mode 100644 index 0000000000..b9112be19b --- /dev/null +++ b/src/java/com/android/internal/telephony/domainselection/OWNERS @@ -0,0 +1,8 @@ +# automatically inherit owners from fw/opt/telephony + +hwangoo@google.com +forestchoi@google.com +avinashmp@google.com +mkoon@google.com +seheele@google.com +radhikaagrawal@google.com diff --git a/src/java/com/android/internal/telephony/ims/ImsServiceControllerCompat.java b/src/java/com/android/internal/telephony/ims/ImsServiceControllerCompat.java index 13ec750819..778bd0e149 100644 --- a/src/java/com/android/internal/telephony/ims/ImsServiceControllerCompat.java +++ b/src/java/com/android/internal/telephony/ims/ImsServiceControllerCompat.java @@ -118,13 +118,13 @@ public class ImsServiceControllerCompat extends ImsServiceController { public final void disableIms(int slotId, int subId) { MmTelFeatureCompatAdapter adapter = mMmTelCompatAdapters.get(slotId); if (adapter == null) { - Log.w(TAG, "enableIms: adapter null for slot :" + slotId); + Log.w(TAG, "disableIms: adapter null for slot :" + slotId); return; } try { adapter.disableIms(); } catch (RemoteException e) { - Log.w(TAG, "Couldn't enable IMS: " + e.getMessage()); + Log.w(TAG, "Couldn't disableIms IMS: " + e.getMessage()); } } diff --git a/src/java/com/android/internal/telephony/subscription/SubscriptionManagerService.java b/src/java/com/android/internal/telephony/subscription/SubscriptionManagerService.java index b462daf041..ba69d8a7c0 100644 --- a/src/java/com/android/internal/telephony/subscription/SubscriptionManagerService.java +++ b/src/java/com/android/internal/telephony/subscription/SubscriptionManagerService.java @@ -89,6 +89,7 @@ import com.android.internal.telephony.MccTable; import com.android.internal.telephony.MultiSimSettingController; import com.android.internal.telephony.Phone; import com.android.internal.telephony.PhoneFactory; +import com.android.internal.telephony.ProxyController; import com.android.internal.telephony.RILConstants; import com.android.internal.telephony.TelephonyIntents; import com.android.internal.telephony.TelephonyPermissions; @@ -486,7 +487,7 @@ public class SubscriptionManagerService extends ISub.Stub { @Override public void onInitialized() { log("Subscription database has been initialized."); - for (int phoneId = 0; phoneId < mTelephonyManager.getActiveModemCount() + for (int phoneId = 0; phoneId < mTelephonyManager.getSupportedModemCount() ; phoneId++) { markSubscriptionsInactive(phoneId); } @@ -2800,6 +2801,8 @@ public class SubscriptionManagerService extends ISub.Stub { final long token = Binder.clearCallingIdentity(); try { if (mDefaultDataSubId.set(subId)) { + remapRafIfApplicable(); + MultiSimSettingController.getInstance().notifyDefaultDataSubChanged(); broadcastSubId(TelephonyIntents.ACTION_DEFAULT_DATA_SUBSCRIPTION_CHANGED, @@ -2813,6 +2816,23 @@ public class SubscriptionManagerService extends ISub.Stub { } /** + * Remap Radio Access Family if needed. + */ + private void remapRafIfApplicable() { + boolean applicable = mSlotIndexToSubId.containsValue(getDefaultDataSubId()); + if (!applicable) return; + ProxyController proxyController = ProxyController.getInstance(); + RadioAccessFamily[] rafs = new RadioAccessFamily[mTelephonyManager.getActiveModemCount()]; + for (int phoneId = 0; phoneId < rafs.length; phoneId++) { + int raf = mSlotIndexToSubId.getOrDefault(phoneId, + SubscriptionManager.INVALID_SUBSCRIPTION_ID) == getDefaultDataSubId() + ? proxyController.getMaxRafSupported() : proxyController.getMinRafSupported(); + rafs[phoneId] = new RadioAccessFamily(phoneId, raf); + } + proxyController.setRadioCapability(rafs); + } + + /** * @return The default subscription id for voice. */ @Override diff --git a/src/java/com/android/internal/telephony/uicc/SimPhonebookRecordCache.java b/src/java/com/android/internal/telephony/uicc/SimPhonebookRecordCache.java index 149e6059b6..b1fc47367b 100644 --- a/src/java/com/android/internal/telephony/uicc/SimPhonebookRecordCache.java +++ b/src/java/com/android/internal/telephony/uicc/SimPhonebookRecordCache.java @@ -446,6 +446,7 @@ public class SimPhonebookRecordCache extends Handler { notifyAdnLoadingWaiters(); tryFireUpdatePendingList(); } else { + notifyAdnLoadingWaiters(); logd("ADN capacity is invalid"); } mIsInitialized.set(true); // Let's say the whole process is ready @@ -455,6 +456,9 @@ public class SimPhonebookRecordCache extends Handler { mIsCacheInvalidated.set(false); notifyAdnLoadingWaiters(); tryFireUpdatePendingList(); + } else if (!newCapacity.isSimValid()) { + mIsCacheInvalidated.set(false); + notifyAdnLoadingWaiters(); } else if (!mIsUpdateDone && !newCapacity.isSimEmpty()) { invalidateSimPbCache(); fillCacheWithoutWaiting(); diff --git a/src/java/com/android/internal/telephony/uicc/UiccController.java b/src/java/com/android/internal/telephony/uicc/UiccController.java index 566bec24c4..9456467355 100644 --- a/src/java/com/android/internal/telephony/uicc/UiccController.java +++ b/src/java/com/android/internal/telephony/uicc/UiccController.java @@ -804,12 +804,14 @@ public class UiccController extends Handler { UiccSlot slot = UiccController.getInstance().getUiccSlotForPhone(phoneId); int slotId = UiccController.getInstance().getSlotIdFromPhoneId(phoneId); intent.putExtra(PhoneConstants.SLOT_KEY, slotId); + int portIndex = -1; if (slot != null) { - intent.putExtra(PhoneConstants.PORT_KEY, slot.getPortIndexFromPhoneId(phoneId)); + portIndex = slot.getPortIndexFromPhoneId(phoneId); + intent.putExtra(PhoneConstants.PORT_KEY, portIndex); } Rlog.d(LOG_TAG, "Broadcasting intent ACTION_SIM_CARD_STATE_CHANGED " + TelephonyManager.simStateToString(state) + " for phone: " + phoneId - + " slot: " + slotId + " port: " + slot.getPortIndexFromPhoneId(phoneId)); + + " slot: " + slotId + " port: " + portIndex); mContext.sendBroadcast(intent, Manifest.permission.READ_PRIVILEGED_PHONE_STATE); TelephonyMetrics.getInstance().updateSimState(phoneId, state); } diff --git a/testing/Android.bp b/testing/Android.bp index 3c100d857c..903b98e7aa 100644 --- a/testing/Android.bp +++ b/testing/Android.bp @@ -16,7 +16,7 @@ android_library { "guava", "junit", "mockito-target-minus-junit4", - "truth-prebuilt", + "truth", ], sdk_version: "test_current", diff --git a/tests/telephonytests/Android.bp b/tests/telephonytests/Android.bp index 2aa446d8ab..9fb4fe642d 100644 --- a/tests/telephonytests/Android.bp +++ b/tests/telephonytests/Android.bp @@ -38,9 +38,9 @@ android_test { "platform-test-annotations", "services.core", "services.net", - "truth-prebuilt", + "truth", "testables", - "platform-compat-test-rules" + "platform-compat-test-rules", ], jarjar_rules: ":jarjar-rules-telephony-tests", diff --git a/tests/telephonytests/src/com/android/internal/telephony/CarrierKeyDownloadMgrTest.java b/tests/telephonytests/src/com/android/internal/telephony/CarrierKeyDownloadMgrTest.java index 40e1821dba..9fd89ffcb1 100644 --- a/tests/telephonytests/src/com/android/internal/telephony/CarrierKeyDownloadMgrTest.java +++ b/tests/telephonytests/src/com/android/internal/telephony/CarrierKeyDownloadMgrTest.java @@ -94,7 +94,7 @@ public class CarrierKeyDownloadMgrTest extends TelephonyTest { super.setUp(getClass().getSimpleName()); mBundle = mContextFixture.getCarrierConfigBundle(); when(mCarrierConfigManager.getConfigForSubId(anyInt(), any())).thenReturn(mBundle); - + when(mUserManager.isUserUnlocked()).thenReturn(true); // Capture listener to emulate the carrier config change notification used later ArgumentCaptor<CarrierConfigManager.CarrierConfigChangeListener> listenerArgumentCaptor = ArgumentCaptor.forClass(CarrierConfigManager.CarrierConfigChangeListener.class); @@ -342,7 +342,50 @@ public class CarrierKeyDownloadMgrTest extends TelephonyTest { **/ @Test @SmallTest - public void testCarrierConfigChanged() { + public void testCarrierConfigChangedWithUserUnlocked() { + CarrierConfigManager carrierConfigManager = (CarrierConfigManager) + mContext.getSystemService(Context.CARRIER_CONFIG_SERVICE); + int slotId = mPhone.getPhoneId(); + PersistableBundle bundle = carrierConfigManager.getConfigForSubId(slotId); + bundle.putInt(CarrierConfigManager.IMSI_KEY_AVAILABILITY_INT, 3); + bundle.putString(CarrierConfigManager.IMSI_KEY_DOWNLOAD_URL_STRING, mURL); + + when(mTelephonyManager.getSimOperator(anyInt())).thenReturn("310260"); + when(mTelephonyManager.getSimCarrierId()).thenReturn(1); + mCarrierConfigChangeListener.onCarrierConfigChanged(0 /* slotIndex */, + SubscriptionManager.INVALID_SUBSCRIPTION_ID, + TelephonyManager.UNKNOWN_CARRIER_ID, TelephonyManager.UNKNOWN_CARRIER_ID); + processAllMessages(); + assertEquals("310260", mCarrierKeyDM.mMccMncForDownload); + assertEquals(1, mCarrierKeyDM.mCarrierId); + } + + @Test + @SmallTest + public void testCarrierConfigChangedWithUserLocked() { + when(mUserManager.isUserUnlocked()).thenReturn(false); + CarrierConfigManager carrierConfigManager = (CarrierConfigManager) + mContext.getSystemService(Context.CARRIER_CONFIG_SERVICE); + int slotId = mPhone.getPhoneId(); + PersistableBundle bundle = carrierConfigManager.getConfigForSubId(slotId); + bundle.putInt(CarrierConfigManager.IMSI_KEY_AVAILABILITY_INT, 3); + bundle.putString(CarrierConfigManager.IMSI_KEY_DOWNLOAD_URL_STRING, mURL); + + when(mTelephonyManager.getSimOperator(anyInt())).thenReturn("310260"); + when(mTelephonyManager.getSimCarrierId()).thenReturn(1); + mCarrierConfigChangeListener.onCarrierConfigChanged(0 /* slotIndex */, + SubscriptionManager.INVALID_SUBSCRIPTION_ID, + TelephonyManager.UNKNOWN_CARRIER_ID, TelephonyManager.UNKNOWN_CARRIER_ID); + processAllMessages(); + assertNull(mCarrierKeyDM.mMccMncForDownload); + assertEquals(0, mCarrierKeyDM.mCarrierId); + } + + @Test + @SmallTest + public void testUserLockedAfterCarrierConfigChanged() { + // User is locked at beginning + when(mUserManager.isUserUnlocked()).thenReturn(false); CarrierConfigManager carrierConfigManager = (CarrierConfigManager) mContext.getSystemService(Context.CARRIER_CONFIG_SERVICE); int slotId = mPhone.getPhoneId(); @@ -350,12 +393,20 @@ public class CarrierKeyDownloadMgrTest extends TelephonyTest { bundle.putInt(CarrierConfigManager.IMSI_KEY_AVAILABILITY_INT, 3); bundle.putString(CarrierConfigManager.IMSI_KEY_DOWNLOAD_URL_STRING, mURL); + // Carrier config change received when(mTelephonyManager.getSimOperator(anyInt())).thenReturn("310260"); when(mTelephonyManager.getSimCarrierId()).thenReturn(1); mCarrierConfigChangeListener.onCarrierConfigChanged(0 /* slotIndex */, SubscriptionManager.INVALID_SUBSCRIPTION_ID, TelephonyManager.UNKNOWN_CARRIER_ID, TelephonyManager.UNKNOWN_CARRIER_ID); processAllMessages(); + + // User unlocked event received + Intent mIntent = new Intent(Intent.ACTION_USER_UNLOCKED); + mContext.sendBroadcast(mIntent); + when(mUserManager.isUserUnlocked()).thenReturn(true); + processAllMessages(); + assertEquals("310260", mCarrierKeyDM.mMccMncForDownload); assertEquals(1, mCarrierKeyDM.mCarrierId); } diff --git a/tests/telephonytests/src/com/android/internal/telephony/FdnUtilsTest.java b/tests/telephonytests/src/com/android/internal/telephony/FdnUtilsTest.java index 2c481584e9..9da19bc487 100644 --- a/tests/telephonytests/src/com/android/internal/telephony/FdnUtilsTest.java +++ b/tests/telephonytests/src/com/android/internal/telephony/FdnUtilsTest.java @@ -163,4 +163,22 @@ public class FdnUtilsTest { assertFalse(FdnUtils.isFDN("6502910000", "", fdnList)); } + + @Test + public void smscAddrInTwoStringsFormat_returnsTrue() { + ArrayList<AdnRecord> fdnList = initializeFdnList(); + AdnRecord adnRecord = new AdnRecord(null, "1234560000"); + fdnList.add(7, adnRecord); + + assertTrue(FdnUtils.isFDN("\"1234560000\",124", "US", fdnList)); + } + + @Test + public void smscAddrInEmailIdFormat_returnsTrue() { + ArrayList<AdnRecord> fdnList = initializeFdnList(); + AdnRecord adnRecord = new AdnRecord(null, "1234560000"); + fdnList.add(8, adnRecord); + + assertTrue(FdnUtils.isFDN("1234560000@ims.mnc.org", "US", fdnList)); + } }
\ No newline at end of file diff --git a/tests/telephonytests/src/com/android/internal/telephony/SignalStrengthControllerTest.java b/tests/telephonytests/src/com/android/internal/telephony/SignalStrengthControllerTest.java index 01f06ea129..e4617feaa8 100644 --- a/tests/telephonytests/src/com/android/internal/telephony/SignalStrengthControllerTest.java +++ b/tests/telephonytests/src/com/android/internal/telephony/SignalStrengthControllerTest.java @@ -959,6 +959,59 @@ public class SignalStrengthControllerTest extends TelephonyTest { assertThat(msgCaptor.getValue().what).isEqualTo(ssChangedEvent); } + @Test + public void testSignalStrengthLevelUpdatedDueToCarrierConfigChanged() { + Handler mockRegistrant = Mockito.mock(Handler.class); + ArgumentCaptor<Message> msgCaptor = ArgumentCaptor.forClass(Message.class); + int ssChangedEvent = 0; + mSsc.registerForSignalStrengthChanged(mockRegistrant, ssChangedEvent, null); + + SignalStrength ss = new SignalStrength( + new CellSignalStrengthCdma(), + new CellSignalStrengthGsm(), + new CellSignalStrengthWcdma(), + new CellSignalStrengthTdscdma(), + new CellSignalStrengthLte( + -110, /* rssi */ + -114, /* rsrp */ + -5, /* rsrq */ + 0, /* rssnr */ + SignalStrength.INVALID, /* cqi */ + SignalStrength.INVALID /* ta */), + new CellSignalStrengthNr()); + + mBundle.putBoolean(CarrierConfigManager.KEY_USE_ONLY_RSRP_FOR_LTE_SIGNAL_BAR_BOOL, true); + + sendCarrierConfigUpdate(); + verify(mockRegistrant).sendMessageDelayed(msgCaptor.capture(), Mockito.anyLong()); + assertThat(msgCaptor.getValue().what).isEqualTo(ssChangedEvent); + assertEquals(CellSignalStrength.SIGNAL_STRENGTH_NONE_OR_UNKNOWN, + mSsc.getSignalStrength().getLevel()); + + Mockito.clearInvocations(mockRegistrant); + mSimulatedCommands.setSignalStrength(ss); + mSimulatedCommands.notifySignalStrength(); + processAllMessages(); + // Default thresholds are POOR=-115 MODERATE=-105 GOOD=-95 GREAT=-85 + assertEquals(CellSignalStrength.SIGNAL_STRENGTH_POOR, mSsc.getSignalStrength().getLevel()); + verify(mockRegistrant).sendMessageDelayed(msgCaptor.capture(), Mockito.anyLong()); + assertThat(msgCaptor.getValue().what).isEqualTo(ssChangedEvent); + + Mockito.clearInvocations(mockRegistrant); + int[] lteThresholds = { + -130, // SIGNAL_STRENGTH_POOR + -120, // SIGNAL_STRENGTH_MODERATE + -110, // SIGNAL_STRENGTH_GOOD + -100, // SIGNAL_STRENGTH_GREAT + }; + mBundle.putIntArray(CarrierConfigManager.KEY_LTE_RSRP_THRESHOLDS_INT_ARRAY, lteThresholds); + sendCarrierConfigUpdate(); + assertEquals(CellSignalStrength.SIGNAL_STRENGTH_MODERATE, + mSsc.getSignalStrength().getLevel()); + verify(mockRegistrant).sendMessageDelayed(msgCaptor.capture(), Mockito.anyLong()); + assertThat(msgCaptor.getValue().what).isEqualTo(ssChangedEvent); + } + private void verifyAllEmptyThresholdAreDisabledWhenSetSignalStrengthReportingCriteria( int expectedNonEmptyThreshold) { ArgumentCaptor<List<SignalThresholdInfo>> signalThresholdInfoCaptor = diff --git a/tests/telephonytests/src/com/android/internal/telephony/data/DataProfileManagerTest.java b/tests/telephonytests/src/com/android/internal/telephony/data/DataProfileManagerTest.java index feb51d0ca9..27271dfe56 100644 --- a/tests/telephonytests/src/com/android/internal/telephony/data/DataProfileManagerTest.java +++ b/tests/telephonytests/src/com/android/internal/telephony/data/DataProfileManagerTest.java @@ -922,7 +922,7 @@ public class DataProfileManagerTest extends TelephonyTest { // SIM removed Mockito.clearInvocations(mDataProfileManagerCallback); - mSimInserted = false; + changeSimStateTo(TelephonyManager.SIM_STATE_ABSENT); mDataProfileManagerUT.obtainMessage(2 /*EVENT_APN_DATABASE_CHANGED*/).sendToTarget(); processAllMessages(); @@ -1016,7 +1016,7 @@ public class DataProfileManagerTest extends TelephonyTest { doReturn(List.of(ApnSetting.TYPE_IMS)) .when(mDataConfigManager).getAllowedInitialAttachApnTypes(); - mSimInserted = true; + changeSimStateTo(TelephonyManager.SIM_STATE_LOADED); mDataProfileManagerUT.obtainMessage(2 /*EVENT_APN_DATABASE_CHANGED*/).sendToTarget(); processAllMessages(); @@ -1189,7 +1189,7 @@ public class DataProfileManagerTest extends TelephonyTest { @Test public void testResetApn() { - mSimInserted = true; + changeSimStateTo(TelephonyManager.SIM_STATE_LOADED); mDataProfileManagerUT.obtainMessage(2 /*EVENT_APN_DATABASE_CHANGED*/).sendToTarget(); processAllMessages(); @@ -1258,7 +1258,7 @@ public class DataProfileManagerTest extends TelephonyTest { new NetworkRequest.Builder() .addCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET) .build(), mPhone); - mSimInserted = true; + changeSimStateTo(TelephonyManager.SIM_STATE_LOADED); mDataProfileManagerUT.obtainMessage(2 /*EVENT_APN_DATABASE_CHANGED*/).sendToTarget(); processAllMessages(); @@ -1369,7 +1369,7 @@ public class DataProfileManagerTest extends TelephonyTest { @Test public void testDataProfileCompatibility_FilteringWithPreferredApnSetIdAsDefault() { mApnSettingContentProvider.setPreferredApn(GENERAL_PURPOSE_APN); - mSimInserted = true; + changeSimStateTo(TelephonyManager.SIM_STATE_LOADED); mDataProfileManagerUT.obtainMessage(2 /*EVENT_APN_DATABASE_CHANGED*/).sendToTarget(); processAllMessages(); @@ -1460,7 +1460,7 @@ public class DataProfileManagerTest extends TelephonyTest { @Test public void testDataProfileCompatibility_FilteringWithPreferredApnSetIdAs1() { mApnSettingContentProvider.setPreferredApn(APN_SET_ID_1_APN); - mSimInserted = true; + changeSimStateTo(TelephonyManager.SIM_STATE_LOADED); mDataProfileManagerUT.obtainMessage(2 /*EVENT_APN_DATABASE_CHANGED*/).sendToTarget(); processAllMessages(); @@ -1590,4 +1590,25 @@ public class DataProfileManagerTest extends TelephonyTest { assertThat(mDataProfileManagerUT.getDataProfileForNetworkRequest(tnr, TelephonyManager.NETWORK_TYPE_LTE, false)).isNull(); } + + private void changeSimStateTo(@TelephonyManager.SimState int simState) { + mSimInserted = simState == TelephonyManager.SIM_STATE_LOADED; + mDataNetworkControllerCallback.onSimStateChanged(simState); + } + + @Test + public void testClearAllDataProfilePermanentFailures() { + testPermanentFailureWithPreferredDataProfile(); + + // Reset all data profiles + mDataProfileManagerUT.clearAllDataProfilePermanentFailures(); + + NetworkRequest request = new NetworkRequest.Builder() + .addCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET).build(); + + // Verify the we can get the previously permanent failed data profile again. + assertThat(mDataProfileManagerUT.getDataProfileForNetworkRequest( + new TelephonyNetworkRequest(request, mPhone), + TelephonyManager.NETWORK_TYPE_LTE, false)).isNotNull(); + } } diff --git a/tests/telephonytests/src/com/android/internal/telephony/data/DataRetryManagerTest.java b/tests/telephonytests/src/com/android/internal/telephony/data/DataRetryManagerTest.java index 5113af8b28..103b189f7e 100644 --- a/tests/telephonytests/src/com/android/internal/telephony/data/DataRetryManagerTest.java +++ b/tests/telephonytests/src/com/android/internal/telephony/data/DataRetryManagerTest.java @@ -850,7 +850,7 @@ public class DataRetryManagerTest extends TelephonyTest { @Test public void testRilCrashedReset() { testDataSetupRetryNetworkSuggestedNeverRetry(); - Mockito.clearInvocations(mDataRetryManagerCallbackMock); + Mockito.clearInvocations(mDataRetryManagerCallbackMock, mDataProfileManager); // RIL crashed and came back online. mDataRetryManagerUT.obtainMessage(8/*EVENT_RADIO_ON*/, @@ -870,12 +870,13 @@ public class DataRetryManagerTest extends TelephonyTest { assertThat(throttleStatus.getThrottleExpiryTimeMillis()).isEqualTo(-1); assertThat(throttleStatus.getTransportType()) .isEqualTo(AccessNetworkConstants.TRANSPORT_TYPE_WWAN); + verify(mDataProfileManager).clearAllDataProfilePermanentFailures(); } @Test public void testModemCrashedReset() { testDataSetupRetryNetworkSuggestedNeverRetry(); - Mockito.clearInvocations(mDataRetryManagerCallbackMock); + Mockito.clearInvocations(mDataRetryManagerCallbackMock, mDataProfileManager); // RIL crashed and came back online. mDataRetryManagerUT.obtainMessage(10 /*EVENT_TAC_CHANGED*/, @@ -895,6 +896,7 @@ public class DataRetryManagerTest extends TelephonyTest { assertThat(throttleStatus.getThrottleExpiryTimeMillis()).isEqualTo(-1); assertThat(throttleStatus.getTransportType()) .isEqualTo(AccessNetworkConstants.TRANSPORT_TYPE_WWAN); + verify(mDataProfileManager).clearAllDataProfilePermanentFailures(); } @Test @@ -902,7 +904,7 @@ public class DataRetryManagerTest extends TelephonyTest { doReturn(true).when(mDataConfigManager).shouldResetDataThrottlingWhenTacChanges(); testDataSetupRetryNetworkSuggestedNeverRetry(); - Mockito.clearInvocations(mDataRetryManagerCallbackMock); + Mockito.clearInvocations(mDataRetryManagerCallbackMock, mDataProfileManager); // RIL crashed and came back online. mDataRetryManagerUT.obtainMessage(9/*EVENT_MODEM_RESET*/, @@ -922,5 +924,6 @@ public class DataRetryManagerTest extends TelephonyTest { assertThat(throttleStatus.getThrottleExpiryTimeMillis()).isEqualTo(-1); assertThat(throttleStatus.getTransportType()) .isEqualTo(AccessNetworkConstants.TRANSPORT_TYPE_WWAN); + verify(mDataProfileManager).clearAllDataProfilePermanentFailures(); } } diff --git a/tests/telephonytests/src/com/android/internal/telephony/data/PhoneSwitcherTest.java b/tests/telephonytests/src/com/android/internal/telephony/data/PhoneSwitcherTest.java index 807f44c66b..c215483b63 100644 --- a/tests/telephonytests/src/com/android/internal/telephony/data/PhoneSwitcherTest.java +++ b/tests/telephonytests/src/com/android/internal/telephony/data/PhoneSwitcherTest.java @@ -679,6 +679,37 @@ public class PhoneSwitcherTest extends TelephonyTest { } @Test + public void testSetAutoSelectedValidationFeatureNotSupported() throws Exception { + doReturn(false).when(mCellularNetworkValidator).isValidationFeatureSupported(); + initialize(); + + // Phone 0 has sub 1, phone 1 has sub 2. + // Sub 1 is default data sub. + // Both are active subscriptions are active sub, as they are in both active slots. + setSlotIndexToSubId(0, 1); + setSlotIndexToSubId(1, 2); + setDefaultDataSubId(1); + + doReturn(new SubscriptionInfoInternal.Builder(mSubscriptionManagerService + .getSubscriptionInfoInternal(2)).setOpportunistic(1).build()) + .when(mSubscriptionManagerService).getSubscriptionInfoInternal(2); + + mPhoneSwitcherUT.trySetOpportunisticDataSubscription(2, false, mSetOpptDataCallback1); + processAllMessages(); + mPhoneSwitcherUT.mValidationCallback.onNetworkAvailable(null, 2); + processAllMessages(); + assertEquals(2, mPhoneSwitcherUT.getAutoSelectedDataSubId()); + + // Switch to the default sub, verify AutoSelectedDataSubId is the default value. + clearInvocations(mSetOpptDataCallback1); + mPhoneSwitcherUT.trySetOpportunisticDataSubscription(SubscriptionManager + .DEFAULT_SUBSCRIPTION_ID, true, mSetOpptDataCallback1); + processAllMessages(); + assertEquals(SubscriptionManager.DEFAULT_SUBSCRIPTION_ID, + mPhoneSwitcherUT.getAutoSelectedDataSubId()); + } + + @Test @SmallTest public void testSetPreferredDataModemCommand() throws Exception { doReturn(true).when(mMockRadioConfig).isSetPreferredDataCommandSupported(); @@ -1357,7 +1388,7 @@ public class PhoneSwitcherTest extends TelephonyTest { .when(mSubscriptionManagerService).getSubscriptionInfoInternal(2); // Switch to primary before a primary is selected/inactive. - setDefaultDataSubId(-1); + setDefaultDataSubId(SubscriptionManager.INVALID_SUBSCRIPTION_ID); mPhoneSwitcherUT.trySetOpportunisticDataSubscription( SubscriptionManager.DEFAULT_SUBSCRIPTION_ID, false, mSetOpptDataCallback1); processAllMessages(); @@ -1991,7 +2022,7 @@ public class PhoneSwitcherTest extends TelephonyTest { doReturn(true).when(mDataConfigManager).isPingTestBeforeAutoDataSwitchRequired(); } - private void setDefaultDataSubId(int defaultDataSub) throws Exception { + private void setDefaultDataSubId(int defaultDataSub) { mDefaultDataSub = defaultDataSub; doReturn(mDefaultDataSub).when(mSubscriptionManagerService).getDefaultDataSubId(); for (Phone phone : mPhones) { diff --git a/tests/telephonytests/src/com/android/internal/telephony/domainselection/OWNERS b/tests/telephonytests/src/com/android/internal/telephony/domainselection/OWNERS new file mode 100644 index 0000000000..b9112be19b --- /dev/null +++ b/tests/telephonytests/src/com/android/internal/telephony/domainselection/OWNERS @@ -0,0 +1,8 @@ +# automatically inherit owners from fw/opt/telephony + +hwangoo@google.com +forestchoi@google.com +avinashmp@google.com +mkoon@google.com +seheele@google.com +radhikaagrawal@google.com diff --git a/tests/telephonytests/src/com/android/internal/telephony/imsphone/ImsCallTest.java b/tests/telephonytests/src/com/android/internal/telephony/imsphone/ImsCallTest.java index aa071255d4..b869c9bc14 100644 --- a/tests/telephonytests/src/com/android/internal/telephony/imsphone/ImsCallTest.java +++ b/tests/telephonytests/src/com/android/internal/telephony/imsphone/ImsCallTest.java @@ -17,6 +17,7 @@ package com.android.internal.telephony.imsphone; import static junit.framework.Assert.assertNotNull; +import static junit.framework.Assert.assertNull; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; @@ -237,4 +238,40 @@ public class ImsCallTest extends TelephonyTest { assertFalse(mTestImsCall.isWifiCall()); assertEquals(mTestImsCall.getNetworkType(), TelephonyManager.NETWORK_TYPE_LTE); } + + @Test + @SmallTest + public void testListenerCalledAfterCallClosed() throws Exception { + ImsCallSession mockSession = mock(ImsCallSession.class); + ImsCall testImsCall = new ImsCall(mContext, mTestCallProfile); + ImsCallProfile profile = new ImsCallProfile(); + when(mockSession.getCallProfile()).thenReturn(profile); + testImsCall.attachSession(mockSession); + + ArgumentCaptor<ImsCallSession.Listener> listenerCaptor = + ArgumentCaptor.forClass(ImsCallSession.Listener.class); + verify(mockSession).setListener(listenerCaptor.capture(), any()); + ImsCallSession.Listener listener = listenerCaptor.getValue(); + assertNotNull(listener); + + // Call closed + testImsCall.close(); + // Set CallProfile value to null because ImsCallSession was closed + when(mockSession.getCallProfile()).thenReturn(null); + + // Set new profile with direction of none + ImsStreamMediaProfile newProfile = new ImsStreamMediaProfile( + ImsStreamMediaProfile.AUDIO_QUALITY_AMR_WB, + ImsStreamMediaProfile.DIRECTION_INACTIVE, + ImsStreamMediaProfile.VIDEO_QUALITY_NONE, + ImsStreamMediaProfile.DIRECTION_INACTIVE, + ImsStreamMediaProfile.RTT_MODE_DISABLED); + try { + listener.callSessionProgressing(mockSession, newProfile); + } catch (Exception e) { + throw new AssertionError("not expected exception", e); + } + + assertNull(testImsCall.getCallProfile()); + } } diff --git a/tests/telephonytests/src/com/android/internal/telephony/subscription/SubscriptionManagerServiceTest.java b/tests/telephonytests/src/com/android/internal/telephony/subscription/SubscriptionManagerServiceTest.java index ddc9171e47..aea79656c1 100644 --- a/tests/telephonytests/src/com/android/internal/telephony/subscription/SubscriptionManagerServiceTest.java +++ b/tests/telephonytests/src/com/android/internal/telephony/subscription/SubscriptionManagerServiceTest.java @@ -648,6 +648,7 @@ public class SubscriptionManagerServiceTest extends TelephonyTest { mSubscriptionManagerServiceUT.setDefaultDataSubId(1); assertThat(mSubscriptionManagerServiceUT.getDefaultDataSubId()).isEqualTo(1); + verify(mProxyController).setRadioCapability(any()); assertThat(Settings.Global.getInt(mContext.getContentResolver(), Settings.Global.MULTI_SIM_DATA_CALL_SUBSCRIPTION)).isEqualTo(1); @@ -675,6 +676,26 @@ public class SubscriptionManagerServiceTest extends TelephonyTest { } @Test + public void testSingleSimSetDefaultDataSubId() { + mContextFixture.addCallingOrSelfPermission(Manifest.permission.READ_PRIVILEGED_PHONE_STATE); + mContextFixture.addCallingOrSelfPermission(Manifest.permission.MODIFY_PHONE_STATE); + doReturn(1).when(mProxyController).getMinRafSupported(); + doReturn(2).when(mProxyController).getMaxRafSupported(); + insertSubscription(FAKE_SUBSCRIPTION_INFO2); + + mContextFixture.addCallingOrSelfPermission(Manifest.permission.MODIFY_PHONE_STATE); + + mSubscriptionManagerServiceUT.setDefaultDataSubId(1); + assertThat(mSubscriptionManagerServiceUT.getDefaultDataSubId()).isEqualTo(1); + ArgumentCaptor<RadioAccessFamily[]> rafsCaptor = ArgumentCaptor.forClass( + RadioAccessFamily[].class); + verify(mProxyController).setRadioCapability(rafsCaptor.capture()); + RadioAccessFamily[] rafs = (RadioAccessFamily[]) rafsCaptor.getValue(); + assertThat(rafs[0].getRadioAccessFamily()).isEqualTo(1); + assertThat(rafs[1].getRadioAccessFamily()).isEqualTo(2); + } + + @Test public void testSetDefaultSmsSubId() throws Exception { clearInvocations(mContext); insertSubscription(FAKE_SUBSCRIPTION_INFO1); |