Merge "Gate default with explicit flag" into main
diff --git a/flags/data.aconfig b/flags/data.aconfig
index e65f8e4..152660b 100644
--- a/flags/data.aconfig
+++ b/flags/data.aconfig
@@ -1,6 +1,20 @@
package: "com.android.internal.telephony.flags"
flag {
+ name: "auto_switch_allow_roaming"
+ namespace: "telephony"
+ description: "Allow using roaming network as target if user allows it from settings."
+ bug: "306488039"
+}
+
+flag {
+ name: "auto_data_switch_rat_ss"
+ namespace: "telephony"
+ description: "Whether switch for better rat and signal strength"
+ bug:"260928808"
+}
+
+flag {
name: "use_alarm_callback"
namespace: "telephony"
description: "Use alarm callback instead of broadcast."
@@ -69,4 +83,3 @@
description: "notify data activity changed for slot id"
bug: "309896936"
}
-
diff --git a/flags/ims.aconfig b/flags/ims.aconfig
index 0fa1f1e..94c933c 100644
--- a/flags/ims.aconfig
+++ b/flags/ims.aconfig
@@ -27,3 +27,10 @@
description: "This flag is created to prevent unnecessary updates when multiple provisioning items to update ims service are changed."
bug:"302281114"
}
+
+flag {
+ name: "add_rat_related_suggested_action_to_ims_registration"
+ namespace: "telephony"
+ description: "This flag is for adding suggested actions related to RAT to ims registration"
+ bug:"290573256"
+}
diff --git a/flags/misc.aconfig b/flags/misc.aconfig
index 159d462..c7140f5 100644
--- a/flags/misc.aconfig
+++ b/flags/misc.aconfig
@@ -63,3 +63,10 @@
description: "Enable Telephony Analytics information of Service State , Sms and Call scenarios"
bug: "309896524"
}
+
+flag {
+ name: "show_call_id_and_call_waiting_in_additional_settings_menu"
+ namespace: "telephony"
+ description: "Expose carrier config KEY_ADDITIONAL_SETTINGS_CALLER_ID_VISIBILITY_BOOL and KEY_ADDITIONAL_SETTINGS_CALL_WAITING_VISIBILITY_BOOL."
+ bug: "310264981"
+}
diff --git a/flags/network.aconfig b/flags/network.aconfig
index 299a2a0..27489f4 100644
--- a/flags/network.aconfig
+++ b/flags/network.aconfig
@@ -13,3 +13,10 @@
description: "Allow carriers to hide the roaming (R) icon when roaming."
bug: "301467052"
}
+
+flag {
+ name: "enable_identifier_disclosure_transparency"
+ namespace: "telephony"
+ description: "Allows the framework to register for CellularIdentifierDisclosure events and emit notifications to the user about them"
+ bug: "276752426"
+}
diff --git a/src/java/com/android/internal/telephony/BaseCommands.java b/src/java/com/android/internal/telephony/BaseCommands.java
index 3f3d297..b33b732 100644
--- a/src/java/com/android/internal/telephony/BaseCommands.java
+++ b/src/java/com/android/internal/telephony/BaseCommands.java
@@ -119,6 +119,7 @@
protected RegistrantList mNotifyAnbrRegistrants = new RegistrantList();
protected RegistrantList mTriggerImsDeregistrationRegistrants = new RegistrantList();
protected RegistrantList mImeiInfoRegistrants = new RegistrantList();
+ protected RegistrantList mCellularIdentifierDisclosedRegistrants = new RegistrantList();
@UnsupportedAppUsage
protected Registrant mGsmSmsRegistrant;
@@ -1183,4 +1184,14 @@
public void registerForImeiMappingChanged(Handler h, int what, Object obj) {
mImeiInfoRegistrants.add(h, what, obj);
}
+
+ @Override
+ public void registerForCellularIdentifierDisclosures(Handler h, int what, Object obj) {
+ mCellularIdentifierDisclosedRegistrants.add(h, what, obj);
+ }
+
+ @Override
+ public void unregisterForCellularIdentifierDisclosures(Handler h) {
+ mCellularIdentifierDisclosedRegistrants.remove(h);
+ }
}
diff --git a/src/java/com/android/internal/telephony/CommandsInterface.java b/src/java/com/android/internal/telephony/CommandsInterface.java
index 6b40040..91e6fab 100644
--- a/src/java/com/android/internal/telephony/CommandsInterface.java
+++ b/src/java/com/android/internal/telephony/CommandsInterface.java
@@ -2927,4 +2927,17 @@
* @param result Callback message to receive the result.
*/
default void isSecurityAlgorithmsUpdatedEnabled(Message result) {}
+
+ /**
+ * Registers for cellular identifier disclosure events.
+ */
+ default void registerForCellularIdentifierDisclosures(
+ @NonNull Handler h, int what, @Nullable Object obj) {}
+
+ /**
+ * Unregisters for cellular identifier disclosure events.
+ *
+ * @param h Handler to be removed from the registrant list.
+ */
+ default void unregisterForCellularIdentifierDisclosures(@NonNull Handler h) {}
}
diff --git a/src/java/com/android/internal/telephony/GsmCdmaPhone.java b/src/java/com/android/internal/telephony/GsmCdmaPhone.java
index d912187..3ef7164 100644
--- a/src/java/com/android/internal/telephony/GsmCdmaPhone.java
+++ b/src/java/com/android/internal/telephony/GsmCdmaPhone.java
@@ -80,6 +80,7 @@
import android.telephony.CarrierConfigManager;
import android.telephony.CellBroadcastIdRange;
import android.telephony.CellIdentity;
+import android.telephony.CellularIdentifierDisclosure;
import android.telephony.ImsiEncryptionInfo;
import android.telephony.LinkCapacityEstimate;
import android.telephony.NetworkScanRequest;
@@ -116,6 +117,7 @@
import com.android.internal.telephony.imsphone.ImsPhoneMmiCode;
import com.android.internal.telephony.metrics.TelephonyMetrics;
import com.android.internal.telephony.metrics.VoiceCallSessionStats;
+import com.android.internal.telephony.security.CellularIdentifierDisclosureNotifier;
import com.android.internal.telephony.subscription.SubscriptionInfoInternal;
import com.android.internal.telephony.subscription.SubscriptionManagerService.SubscriptionManagerServiceCallback;
import com.android.internal.telephony.test.SimulatedRadioControl;
@@ -298,6 +300,8 @@
private final SubscriptionManager.OnSubscriptionsChangedListener mSubscriptionsChangedListener;
private final CallWaitingController mCallWaitingController;
+ private CellularIdentifierDisclosureNotifier mIdentifierDisclosureNotifier;
+
// Set via Carrier Config
private boolean mIsN1ModeAllowedByCarrier = true;
// Set via a call to the method on Phone; the only caller is IMS, and all of this code will
@@ -515,6 +519,20 @@
mCIM = new CarrierInfoManager();
mCi.registerForImeiMappingChanged(this, EVENT_IMEI_MAPPING_CHANGED, null);
+
+ if (mFeatureFlags.enableIdentifierDisclosureTransparency()) {
+ logi(
+ "enable_identifier_disclosure_transparency is on. Registering for cellular "
+ + "identifier disclosures from phone "
+ + getPhoneId());
+ mIdentifierDisclosureNotifier =
+ mTelephonyComponentFactory
+ .inject(CellularIdentifierDisclosureNotifier.class.getName())
+ .makeIdentifierDisclosureNotifier();
+ mCi.registerForCellularIdentifierDisclosures(
+ this, EVENT_CELL_IDENTIFIER_DISCLOSURE, null);
+ }
+
initializeCarrierApps();
}
@@ -3663,6 +3681,26 @@
parseImeiInfo(msg);
break;
+ case EVENT_CELL_IDENTIFIER_DISCLOSURE:
+ logd("EVENT_CELL_IDENTIFIER_DISCLOSURE phoneId = " + getPhoneId());
+
+ ar = (AsyncResult) msg.obj;
+ if (ar == null || ar.result == null || ar.exception != null) {
+ Rlog.e(
+ LOG_TAG,
+ "Failed to process cellular identifier disclosure",
+ ar.exception);
+ break;
+ }
+
+ CellularIdentifierDisclosure disclosure = (CellularIdentifierDisclosure) ar.result;
+ if (mFeatureFlags.enableIdentifierDisclosureTransparency()
+ && mIdentifierDisclosureNotifier != null
+ && disclosure != null) {
+ mIdentifierDisclosureNotifier.addDisclosure(disclosure);
+ }
+ break;
+
default:
super.handleMessage(msg);
}
diff --git a/src/java/com/android/internal/telephony/NetworkIndication.java b/src/java/com/android/internal/telephony/NetworkIndication.java
index 3f345e0..d86c090 100644
--- a/src/java/com/android/internal/telephony/NetworkIndication.java
+++ b/src/java/com/android/internal/telephony/NetworkIndication.java
@@ -44,6 +44,7 @@
import android.telephony.BarringInfo;
import android.telephony.CellIdentity;
import android.telephony.CellInfo;
+import android.telephony.CellularIdentifierDisclosure;
import android.telephony.EmergencyRegResult;
import android.telephony.LinkCapacityEstimate;
import android.telephony.NetworkRegistrationInfo;
@@ -436,7 +437,11 @@
mRil.unsljLogRet(RIL_UNSOL_CELLULAR_IDENTIFIER_DISCLOSED, identifierDisclsoure);
}
- // TODO (b/276752426) notify registrants of identifier disclosure
+ CellularIdentifierDisclosure disclosure =
+ RILUtils.convertCellularIdentifierDisclosure(identifierDisclsoure);
+
+ mRil.mCellularIdentifierDisclosedRegistrants.notifyRegistrants(
+ new AsyncResult(null, disclosure, null));
}
/**
diff --git a/src/java/com/android/internal/telephony/Phone.java b/src/java/com/android/internal/telephony/Phone.java
index b991b8e..cc1d4a4 100644
--- a/src/java/com/android/internal/telephony/Phone.java
+++ b/src/java/com/android/internal/telephony/Phone.java
@@ -254,7 +254,8 @@
protected static final int EVENT_GET_N1_MODE_ENABLED_DONE = 69;
protected static final int EVENT_SET_N1_MODE_ENABLED_DONE = 70;
protected static final int EVENT_IMEI_MAPPING_CHANGED = 71;
- protected static final int EVENT_LAST = EVENT_IMEI_MAPPING_CHANGED;
+ protected static final int EVENT_CELL_IDENTIFIER_DISCLOSURE = 72;
+ protected static final int EVENT_LAST = EVENT_CELL_IDENTIFIER_DISCLOSURE;
// For shared prefs.
private static final String GSM_ROAMING_LIST_OVERRIDE_PREFIX = "gsm_roaming_list_";
diff --git a/src/java/com/android/internal/telephony/PhoneFactory.java b/src/java/com/android/internal/telephony/PhoneFactory.java
index 3560048..0cbc035 100644
--- a/src/java/com/android/internal/telephony/PhoneFactory.java
+++ b/src/java/com/android/internal/telephony/PhoneFactory.java
@@ -265,7 +265,8 @@
sPhoneSwitcher = TelephonyComponentFactory.getInstance().inject(
PhoneSwitcher.class.getName()).
- makePhoneSwitcher(maxActivePhones, sContext, Looper.myLooper());
+ makePhoneSwitcher(maxActivePhones, sContext, Looper.myLooper(),
+ featureFlags);
sProxyController = ProxyController.getInstance(context);
diff --git a/src/java/com/android/internal/telephony/RIL.java b/src/java/com/android/internal/telephony/RIL.java
index 998d572..e608e4d 100644
--- a/src/java/com/android/internal/telephony/RIL.java
+++ b/src/java/com/android/internal/telephony/RIL.java
@@ -5087,7 +5087,7 @@
public void setCellularIdentifierTransparencyEnabled(boolean enable, Message result) {
RadioNetworkProxy networkProxy = getRadioServiceProxy(RadioNetworkProxy.class);
if (!canMakeRequest(
- "setCellularIdentifierDisclosedEnabled",
+ "setCellularIdentifierTransparencyEnabled",
networkProxy,
result,
RADIO_HAL_VERSION_2_2)) {
@@ -5103,9 +5103,12 @@
}
radioServiceInvokeHelper(
- HAL_SERVICE_NETWORK, rr, "setCellularIdentifierDisclosedEnabled", () -> {
- networkProxy.setCellularIdentifierTransparencyEnabled(rr.mSerial, enable);
- });
+ HAL_SERVICE_NETWORK,
+ rr,
+ "setCellularIdentifierTransparencyEnabled",
+ () -> {
+ networkProxy.setCellularIdentifierTransparencyEnabled(rr.mSerial, enable);
+ });
}
/**
@@ -5115,7 +5118,7 @@
public void isCellularIdentifierTransparencyEnabled(Message result) {
RadioNetworkProxy networkProxy = getRadioServiceProxy(RadioNetworkProxy.class);
if (!canMakeRequest(
- "isCellularIdentifierDisclosedEnabled",
+ "isCellularIdentifierTransparencyEnabled",
networkProxy,
result,
RADIO_HAL_VERSION_2_2)) {
@@ -5130,9 +5133,12 @@
}
radioServiceInvokeHelper(
- HAL_SERVICE_NETWORK, rr, "isCellularIdentifierDisclosedEnabled", () -> {
- networkProxy.isCellularIdentifierTransparencyEnabled(rr.mSerial);
- });
+ HAL_SERVICE_NETWORK,
+ rr,
+ "isCellularIdentifierTransparencyEnabled",
+ () -> {
+ networkProxy.isCellularIdentifierTransparencyEnabled(rr.mSerial);
+ });
}
/**
diff --git a/src/java/com/android/internal/telephony/RILUtils.java b/src/java/com/android/internal/telephony/RILUtils.java
index cb5684f..94f2e96 100644
--- a/src/java/com/android/internal/telephony/RILUtils.java
+++ b/src/java/com/android/internal/telephony/RILUtils.java
@@ -323,6 +323,7 @@
import android.telephony.CellSignalStrengthNr;
import android.telephony.CellSignalStrengthTdscdma;
import android.telephony.CellSignalStrengthWcdma;
+import android.telephony.CellularIdentifierDisclosure;
import android.telephony.ClosedSubscriberGroupInfo;
import android.telephony.DomainSelectionService;
import android.telephony.EmergencyRegResult;
@@ -5675,6 +5676,20 @@
}
}
+ /** Convert an AIDL-based CellularIdentifierDisclosure to its Java wrapper. */
+ public static CellularIdentifierDisclosure convertCellularIdentifierDisclosure(
+ android.hardware.radio.network.CellularIdentifierDisclosure identifierDisclsoure) {
+ if (identifierDisclsoure == null) {
+ return null;
+ }
+
+ return new CellularIdentifierDisclosure(
+ identifierDisclsoure.protocolMessage,
+ identifierDisclsoure.identifier,
+ identifierDisclsoure.plmn,
+ identifierDisclsoure.isEmergency);
+ }
+
private static void logd(String log) {
Rlog.d("RILUtils", log);
}
diff --git a/src/java/com/android/internal/telephony/TelephonyComponentFactory.java b/src/java/com/android/internal/telephony/TelephonyComponentFactory.java
index 74d1786..74094a3 100644
--- a/src/java/com/android/internal/telephony/TelephonyComponentFactory.java
+++ b/src/java/com/android/internal/telephony/TelephonyComponentFactory.java
@@ -47,6 +47,7 @@
import com.android.internal.telephony.imsphone.ImsPhone;
import com.android.internal.telephony.imsphone.ImsPhoneCallTracker;
import com.android.internal.telephony.nitz.NitzStateMachineImpl;
+import com.android.internal.telephony.security.CellularIdentifierDisclosureNotifier;
import com.android.internal.telephony.uicc.IccCardStatus;
import com.android.internal.telephony.uicc.UiccCard;
import com.android.internal.telephony.uicc.UiccProfile;
@@ -480,8 +481,8 @@
}
public PhoneSwitcher makePhoneSwitcher(int maxDataAttachModemCount, Context context,
- Looper looper) {
- return PhoneSwitcher.make(maxDataAttachModemCount, context, looper);
+ Looper looper, @NonNull FeatureFlags featureFlags) {
+ return PhoneSwitcher.make(maxDataAttachModemCount, context, looper, featureFlags);
}
/**
@@ -565,4 +566,9 @@
@NonNull DataSettingsManager.DataSettingsManagerCallback callback) {
return new DataSettingsManager(phone, dataNetworkController, looper, callback);
}
+
+ /** Create CellularIdentifierDisclosureNotifier. */
+ public CellularIdentifierDisclosureNotifier makeIdentifierDisclosureNotifier() {
+ return CellularIdentifierDisclosureNotifier.getInstance();
+ }
}
diff --git a/src/java/com/android/internal/telephony/data/AutoDataSwitchController.java b/src/java/com/android/internal/telephony/data/AutoDataSwitchController.java
index 0ea0598..e8cd8f0 100644
--- a/src/java/com/android/internal/telephony/data/AutoDataSwitchController.java
+++ b/src/java/com/android/internal/telephony/data/AutoDataSwitchController.java
@@ -47,6 +47,7 @@
import com.android.internal.telephony.Phone;
import com.android.internal.telephony.PhoneFactory;
+import com.android.internal.telephony.flags.FeatureFlags;
import com.android.internal.telephony.subscription.SubscriptionInfoInternal;
import com.android.internal.telephony.subscription.SubscriptionManagerService;
import com.android.internal.telephony.util.NotificationChannelController;
@@ -125,6 +126,7 @@
private final @NonNull LocalLog mLocalLog = new LocalLog(128);
private final @NonNull Context mContext;
+ private final @NonNull FeatureFlags mFlags;
private final @NonNull SubscriptionManagerService mSubscriptionManagerService;
private final @NonNull PhoneSwitcher mPhoneSwitcher;
private final @NonNull AutoDataSwitchControllerCallback mPhoneSwitcherCallback;
@@ -167,15 +169,29 @@
* switch to.
*/
private static class PhoneSignalStatus {
+ /**
+ * How preferred the current phone is.
+ */
+ enum UsableState {
+ HOME(1), ROAMING_ENABLED(0), NOT_USABLE(-1);
+ /**
+ * The higher the score, the more preferred.
+ * HOME is preferred over ROAMING assuming roaming is metered.
+ */
+ final int mScore;
+ UsableState(int score) {
+ this.mScore = score;
+ }
+ }
/** The phone */
- private final @NonNull Phone mPhone;
+ @NonNull private final Phone mPhone;
/** Data registration state of the phone */
- private @RegistrationState int mDataRegState = NetworkRegistrationInfo
+ @RegistrationState private int mDataRegState = NetworkRegistrationInfo
.REGISTRATION_STATE_NOT_REGISTERED_OR_SEARCHING;
/** Current Telephony display info of the phone */
- private @NonNull TelephonyDisplayInfo mDisplayInfo;
+ @NonNull private TelephonyDisplayInfo mDisplayInfo;
/** Signal strength of the phone */
- private @NonNull SignalStrength mSignalStrength;
+ @NonNull private SignalStrength mSignalStrength;
/** {@code true} if this slot is listening for events. */
private boolean mListeningForEvents;
private PhoneSignalStatus(@NonNull Phone phone) {
@@ -193,11 +209,28 @@
? mPhone.getDataNetworkController().getDataConfigManager()
.getAutoDataSwitchScore(mDisplayInfo, mSignalStrength) : 0;
}
+
+ /**
+ * @return The current usable state of the phone.
+ */
+ private UsableState getUsableState() {
+ switch (mDataRegState) {
+ case NetworkRegistrationInfo.REGISTRATION_STATE_HOME:
+ return UsableState.HOME;
+ case NetworkRegistrationInfo.REGISTRATION_STATE_ROAMING:
+ return mPhone.getDataRoamingEnabled()
+ ? UsableState.ROAMING_ENABLED : UsableState.NOT_USABLE;
+ default:
+ return UsableState.NOT_USABLE;
+ }
+ }
+
@Override
public String toString() {
return "{phone " + mPhone.getPhoneId()
+ " score=" + getRatSignalScore() + " dataRegState="
+ NetworkRegistrationInfo.registrationStateToString(mDataRegState)
+ + " " + getUsableState()
+ " display=" + mDisplayInfo + " signalStrength=" + mSignalStrength.getLevel()
+ " listeningForEvents=" + mListeningForEvents
+ "}";
@@ -238,10 +271,11 @@
* @param phoneSwitcherCallback Callback for phone switcher to execute.
*/
public AutoDataSwitchController(@NonNull Context context, @NonNull Looper looper,
- @NonNull PhoneSwitcher phoneSwitcher,
+ @NonNull PhoneSwitcher phoneSwitcher, @NonNull FeatureFlags featureFlags,
@NonNull AutoDataSwitchControllerCallback phoneSwitcherCallback) {
super(looper);
mContext = context;
+ mFlags = featureFlags;
mSubscriptionManagerService = SubscriptionManagerService.getInstance();
mPhoneSwitcher = phoneSwitcher;
mPhoneSwitcherCallback = phoneSwitcherCallback;
@@ -275,7 +309,7 @@
}
/** Notify subscriptions changed. */
- public void notifySubscriptionsChanged() {
+ public void notifySubscriptionsMappingChanged() {
sendEmptyMessage(EVENT_SUBSCRIPTIONS_CHANGED);
}
@@ -291,16 +325,19 @@
.collect(Collectors.toSet());
// Track events only if there are at least two active visible subscriptions.
if (activePhoneIds.size() < 2) activePhoneIds.clear();
+ boolean changed = false;
for (int phoneId = 0; phoneId < mPhonesSignalStatus.length; phoneId++) {
if (activePhoneIds.contains(phoneId)
&& !mPhonesSignalStatus[phoneId].mListeningForEvents) {
registerAllEventsForPhone(phoneId);
+ changed = true;
} else if (!activePhoneIds.contains(phoneId)
&& mPhonesSignalStatus[phoneId].mListeningForEvents) {
unregisterAllEventsForPhone(phoneId);
+ changed = true;
}
}
- logl("onSubscriptionChanged: " + Arrays.toString(mPhonesSignalStatus));
+ if (changed) logl("onSubscriptionChanged: " + Arrays.toString(mPhonesSignalStatus));
}
/**
@@ -362,7 +399,7 @@
case EVENT_SERVICE_STATE_CHANGED:
ar = (AsyncResult) msg.obj;
phoneId = (int) ar.userObj;
- onRegistrationStateChanged(phoneId);
+ onServiceStateChanged(phoneId);
break;
case EVENT_DISPLAY_INFO_CHANGED:
ar = (AsyncResult) msg.obj;
@@ -396,7 +433,7 @@
/**
* Called when registration state changed.
*/
- private void onRegistrationStateChanged(int phoneId) {
+ private void onServiceStateChanged(int phoneId) {
Phone phone = PhoneFactory.getPhone(phoneId);
if (phone != null && isActiveModemPhone(phoneId)) {
int oldRegState = mPhonesSignalStatus[phoneId].mDataRegState;
@@ -409,7 +446,7 @@
mPhonesSignalStatus[phoneId].mDataRegState = newRegState;
if (isInService(oldRegState) != isInService(newRegState)
|| isHomeService(oldRegState) != isHomeService(newRegState)) {
- log("onRegistrationStateChanged: phone " + phoneId + " "
+ log("onServiceStateChanged: phone " + phoneId + " "
+ NetworkRegistrationInfo.registrationStateToString(oldRegState)
+ " -> "
+ NetworkRegistrationInfo.registrationStateToString(newRegState));
@@ -562,35 +599,92 @@
boolean backToDefault = false;
boolean needValidation = true;
- if (mDefaultNetworkIsOnNonCellular) {
- log(debugMessage.append(", back to default as default network")
- .append(" is active on nonCellular transport").toString());
- backToDefault = true;
- needValidation = false;
- } else if (!isHomeService(mPhonesSignalStatus[preferredPhoneId].mDataRegState)) {
- log(debugMessage.append(", back to default as backup phone lost HOME registration")
- .toString());
- backToDefault = true;
- needValidation = false;
- } else if (isRatSignalStrengthBasedSwitchEnabled()) {
- int defaultScore = mPhonesSignalStatus[defaultDataPhoneId].getRatSignalScore();
- int currentScore = mPhonesSignalStatus[preferredPhoneId].getRatSignalScore();
- if ((defaultScore - currentScore) > mScoreTolerance) {
- log(debugMessage
- .append(", back to default as default phone has higher score ")
- .append(defaultScore).append(" versus current ")
- .append(currentScore).toString());
+ if (mFlags.autoSwitchAllowRoaming()) {
+ if (mDefaultNetworkIsOnNonCellular) {
+ debugMessage.append(", back to default as default network")
+ .append(" is active on nonCellular transport");
+ backToDefault = true;
+ needValidation = false;
+ } else {
+ PhoneSignalStatus.UsableState defaultUsableState =
+ mPhonesSignalStatus[defaultDataPhoneId].getUsableState();
+ PhoneSignalStatus.UsableState currentUsableState =
+ mPhonesSignalStatus[preferredPhoneId].getUsableState();
+
+ boolean isCurrentUsable = currentUsableState.mScore
+ > PhoneSignalStatus.UsableState.NOT_USABLE.mScore;
+
+ if (currentUsableState.mScore < defaultUsableState.mScore) {
+ debugMessage.append(", back to default phone ").append(preferredPhoneId)
+ .append(" : ").append(defaultUsableState)
+ .append(" , backup phone: ").append(currentUsableState);
+
+ backToDefault = true;
+ // Require validation if the current preferred phone is usable.
+ needValidation = isCurrentUsable && mRequirePingTestBeforeSwitch;
+ } else if (defaultUsableState.mScore == currentUsableState.mScore) {
+ debugMessage.append(", default phone ").append(preferredPhoneId)
+ .append(" : ").append(defaultUsableState)
+ .append(" , backup phone: ").append(currentUsableState);
+
+ if (isCurrentUsable) {
+ // Both phones are usable.
+ if (isRatSignalStrengthBasedSwitchEnabled()) {
+ int defaultScore = mPhonesSignalStatus[defaultDataPhoneId]
+ .getRatSignalScore();
+ int currentScore = mPhonesSignalStatus[preferredPhoneId]
+ .getRatSignalScore();
+ if ((defaultScore - currentScore) > mScoreTolerance) {
+ debugMessage
+ .append(", back to default for higher score ")
+ .append(defaultScore).append(" versus current ")
+ .append(currentScore);
+ backToDefault = true;
+ needValidation = mRequirePingTestBeforeSwitch;
+ }
+ } else {
+ // Only OOS/in service switch is enabled, switch back.
+ debugMessage.append(", back to default as it's usable. ");
+ backToDefault = true;
+ needValidation = mRequirePingTestBeforeSwitch;
+ }
+ } else {
+ debugMessage.append(", back to default as both phones are unusable.");
+ backToDefault = true;
+ needValidation = false;
+ }
+ }
+ }
+ } else {
+ if (mDefaultNetworkIsOnNonCellular) {
+ debugMessage.append(", back to default as default network")
+ .append(" is active on nonCellular transport");
+ backToDefault = true;
+ needValidation = false;
+ } else if (!isHomeService(mPhonesSignalStatus[preferredPhoneId].mDataRegState)) {
+ debugMessage.append(", back to default as backup phone lost HOME registration");
+ backToDefault = true;
+ needValidation = false;
+ } else if (isRatSignalStrengthBasedSwitchEnabled()) {
+ int defaultScore = mPhonesSignalStatus[defaultDataPhoneId].getRatSignalScore();
+ int currentScore = mPhonesSignalStatus[preferredPhoneId].getRatSignalScore();
+ if ((defaultScore - currentScore) > mScoreTolerance) {
+ debugMessage
+ .append(", back to default as default phone has higher score ")
+ .append(defaultScore).append(" versus current ")
+ .append(currentScore);
+ backToDefault = true;
+ needValidation = mRequirePingTestBeforeSwitch;
+ }
+ } else if (isInService(mPhonesSignalStatus[defaultDataPhoneId].mDataRegState)) {
+ debugMessage.append(", back to default as the default is back to service ");
backToDefault = true;
needValidation = mRequirePingTestBeforeSwitch;
}
- } else if (isInService(mPhonesSignalStatus[defaultDataPhoneId].mDataRegState)) {
- log(debugMessage.append(", back to default as the default is back to service ")
- .toString());
- backToDefault = true;
- needValidation = mRequirePingTestBeforeSwitch;
}
if (backToDefault) {
+ log(debugMessage.toString());
mSelectedTargetPhoneId = defaultDataPhoneId;
startStabilityCheck(DEFAULT_PHONE_INDEX, needValidation);
} else {
@@ -625,20 +719,60 @@
return INVALID_PHONE_INDEX;
}
- // check whether primary and secondary signal status are worth switching
- if (!isRatSignalStrengthBasedSwitchEnabled()
- && isInService(mPhonesSignalStatus[defaultPhoneId].mDataRegState)) {
- debugMessage.append(", no candidate as default phone is in service");
- return INVALID_PHONE_INDEX;
+ if (mFlags.autoSwitchAllowRoaming()) {
+ // check whether primary and secondary signal status are worth switching
+ if (!isRatSignalStrengthBasedSwitchEnabled()
+ && isHomeService(mPhonesSignalStatus[defaultPhoneId].mDataRegState)) {
+ debugMessage.append(", no candidate as default phone is in HOME service");
+ return INVALID_PHONE_INDEX;
+ }
+ } else {
+ // check whether primary and secondary signal status are worth switching
+ if (!isRatSignalStrengthBasedSwitchEnabled()
+ && isInService(mPhonesSignalStatus[defaultPhoneId].mDataRegState)) {
+ debugMessage.append(", no candidate as default phone is in service");
+ return INVALID_PHONE_INDEX;
+ }
}
- for (int phoneId = 0; phoneId < mPhonesSignalStatus.length; phoneId++) {
- if (phoneId != defaultPhoneId
- // the alternative phone must have HOME availability
- && isHomeService(mPhonesSignalStatus[phoneId].mDataRegState)) {
- Phone secondaryDataPhone = null;
- debugMessage.append(", found phone ").append(phoneId).append(" in HOME reg");
- if (isInService(mPhonesSignalStatus[defaultPhoneId].mDataRegState)) {
+ PhoneSignalStatus defaultPhoneStatus = mPhonesSignalStatus[defaultPhoneId];
+ for (int phoneId = 0; phoneId < mPhonesSignalStatus.length; phoneId++) {
+ if (phoneId == defaultPhoneId) continue;
+
+ Phone secondaryDataPhone = null;
+ PhoneSignalStatus candidatePhoneStatus = mPhonesSignalStatus[phoneId];
+ if (mFlags.autoSwitchAllowRoaming()) {
+ PhoneSignalStatus.UsableState currentUsableState =
+ mPhonesSignalStatus[defaultPhoneId].getUsableState();
+ PhoneSignalStatus.UsableState candidatePhoneUsableRank =
+ mPhonesSignalStatus[phoneId].getUsableState();
+ debugMessage.append(", found phone ").append(phoneId).append(" is ").append(
+ candidatePhoneUsableRank)
+ .append(", current is ").append(currentUsableState);
+ if (candidatePhoneUsableRank.mScore > currentUsableState.mScore) {
+ secondaryDataPhone = PhoneFactory.getPhone(phoneId);
+ } else if (isRatSignalStrengthBasedSwitchEnabled()
+ && currentUsableState.mScore == candidatePhoneUsableRank.mScore) {
+ // Both phones are home or both roaming enabled, so compare RAT/signal score.
+
+ int defaultScore = defaultPhoneStatus.getRatSignalScore();
+ int candidateScore = candidatePhoneStatus.getRatSignalScore();
+ if ((candidateScore - defaultScore) > mScoreTolerance) {
+ debugMessage.append(" with higher score ").append(
+ candidateScore)
+ .append(" versus current ").append(defaultScore);
+ secondaryDataPhone = PhoneFactory.getPhone(phoneId);
+ } else {
+ debugMessage.append(", but its score ").append(candidateScore)
+ .append(" doesn't meet the bar to switch given the current ")
+ .append(defaultScore);
+ }
+ }
+ } else if (isHomeService(candidatePhoneStatus.mDataRegState)) {
+ // the alternative phone must have HOME availability
+ debugMessage.append(", found phone ").append(phoneId).append(" in HOME service");
+
+ if (isInService(defaultPhoneStatus.mDataRegState)) {
// Use score if RAT/signal strength based switch is enabled and both phone are
// in service.
if (isRatSignalStrengthBasedSwitchEnabled()) {
@@ -658,13 +792,14 @@
// Only OOS/in service switch is enabled.
secondaryDataPhone = PhoneFactory.getPhone(phoneId);
}
- if (secondaryDataPhone != null) {
- // check auto switch feature enabled
- if (secondaryDataPhone.isDataAllowed()) {
- return phoneId;
- } else {
- debugMessage.append(", but its data is not allowed");
- }
+ }
+
+ if (secondaryDataPhone != null) {
+ // check auto switch feature enabled
+ if (secondaryDataPhone.isDataAllowed()) {
+ return phoneId;
+ } else {
+ debugMessage.append(", but its data is not allowed");
}
}
}
@@ -676,7 +811,7 @@
* @return {@code true} If the feature of switching base on RAT and signal strength is enabled.
*/
private boolean isRatSignalStrengthBasedSwitchEnabled() {
- return mScoreTolerance >= 0;
+ return mFlags.autoDataSwitchRatSs() && mScoreTolerance >= 0;
}
/**
diff --git a/src/java/com/android/internal/telephony/data/PhoneSwitcher.java b/src/java/com/android/internal/telephony/data/PhoneSwitcher.java
index 36e6587..2c84f5e 100644
--- a/src/java/com/android/internal/telephony/data/PhoneSwitcher.java
+++ b/src/java/com/android/internal/telephony/data/PhoneSwitcher.java
@@ -28,6 +28,7 @@
import static android.telephony.ims.stub.ImsRegistrationImplBase.REGISTRATION_TECH_CROSS_SIM;
import static android.telephony.ims.stub.ImsRegistrationImplBase.REGISTRATION_TECH_IWLAN;
import static android.telephony.ims.stub.ImsRegistrationImplBase.REGISTRATION_TECH_NONE;
+
import static java.util.Arrays.copyOf;
import android.annotation.NonNull;
@@ -83,6 +84,7 @@
import com.android.internal.telephony.TelephonyIntents;
import com.android.internal.telephony.data.DataNetworkController.NetworkRequestList;
import com.android.internal.telephony.data.DataSettingsManager.DataSettingsManagerCallback;
+import com.android.internal.telephony.flags.FeatureFlags;
import com.android.internal.telephony.metrics.TelephonyMetrics;
import com.android.internal.telephony.nano.TelephonyProto.TelephonyEvent;
import com.android.internal.telephony.nano.TelephonyProto.TelephonyEvent.DataSwitch;
@@ -184,6 +186,7 @@
private final @NonNull NetworkRequestList mNetworkRequestList = new NetworkRequestList();
protected final RegistrantList mActivePhoneRegistrants;
private final SubscriptionManagerService mSubscriptionManagerService;
+ private final @NonNull FeatureFlags mFlags;
protected final Context mContext;
private final LocalLog mLocalLog;
protected PhoneState[] mPhoneStates;
@@ -397,9 +400,10 @@
/**
* Method to create singleton instance.
*/
- public static PhoneSwitcher make(int maxDataAttachModemCount, Context context, Looper looper) {
+ public static PhoneSwitcher make(int maxDataAttachModemCount, Context context, Looper looper,
+ @NonNull FeatureFlags flags) {
if (sPhoneSwitcher == null) {
- sPhoneSwitcher = new PhoneSwitcher(maxDataAttachModemCount, context, looper);
+ sPhoneSwitcher = new PhoneSwitcher(maxDataAttachModemCount, context, looper, flags);
}
return sPhoneSwitcher;
@@ -457,9 +461,11 @@
}
@VisibleForTesting
- public PhoneSwitcher(int maxActivePhones, Context context, Looper looper) {
+ public PhoneSwitcher(int maxActivePhones, Context context, Looper looper,
+ @NonNull FeatureFlags featureFlags) {
super(looper);
mContext = context;
+ mFlags = featureFlags;
mActiveModemCount = getTm().getActiveModemCount();
mPhoneSubscriptions = new int[mActiveModemCount];
mPhoneStates = new PhoneState[mActiveModemCount];
@@ -497,6 +503,12 @@
@TelephonyManager.DataEnabledChangedReason int reason,
@NonNull String callingPackage) {
PhoneSwitcher.this.onDataEnabledChanged();
+ }
+ @Override
+ public void onDataRoamingEnabledChanged(boolean enabled) {
+ PhoneSwitcher.this.mAutoDataSwitchController.evaluateAutoDataSwitch(
+ AutoDataSwitchController
+ .EVALUATION_REASON_DATA_SETTINGS_CHANGED);
}});
phone.getDataSettingsManager().registerCallback(
mDataSettingsManagerCallbacks.get(phoneId));
@@ -546,7 +558,7 @@
}
};
mAutoDataSwitchController = new AutoDataSwitchController(context, looper, this,
- mAutoDataSwitchCallback);
+ mFlags, mAutoDataSwitchCallback);
mContext.registerReceiver(mDefaultDataChangedReceiver,
new IntentFilter(TelephonyIntents.ACTION_DEFAULT_DATA_SUBSCRIPTION_CHANGED));
@@ -647,7 +659,6 @@
public void handleMessage(Message msg) {
switch (msg.what) {
case EVENT_SUBSCRIPTION_CHANGED: {
- mAutoDataSwitchController.notifySubscriptionsChanged();
onEvaluate(REQUESTS_UNCHANGED, "subscription changed");
break;
}
@@ -902,6 +913,12 @@
@NonNull String callingPackage) {
PhoneSwitcher.this.onDataEnabledChanged();
}
+ @Override
+ public void onDataRoamingEnabledChanged(boolean enabled) {
+ PhoneSwitcher.this.mAutoDataSwitchController.evaluateAutoDataSwitch(
+ AutoDataSwitchController
+ .EVALUATION_REASON_DATA_SETTINGS_CHANGED);
+ }
});
phone.getDataSettingsManager().registerCallback(
mDataSettingsManagerCallbacks.get(phone.getPhoneId()));
@@ -1080,6 +1097,7 @@
registerForImsRadioTechChange(mContext, i);
}
diffDetected = true;
+ mAutoDataSwitchController.notifySubscriptionsMappingChanged();
}
}
diff --git a/src/java/com/android/internal/telephony/imsphone/ImsPhone.java b/src/java/com/android/internal/telephony/imsphone/ImsPhone.java
index 4943ba3..b21d45d 100644
--- a/src/java/com/android/internal/telephony/imsphone/ImsPhone.java
+++ b/src/java/com/android/internal/telephony/imsphone/ImsPhone.java
@@ -23,6 +23,8 @@
import static android.telephony.ims.RegistrationManager.SUGGESTED_ACTION_NONE;
import static android.telephony.ims.RegistrationManager.SUGGESTED_ACTION_TRIGGER_PLMN_BLOCK;
import static android.telephony.ims.RegistrationManager.SUGGESTED_ACTION_TRIGGER_PLMN_BLOCK_WITH_TIMEOUT;
+import static android.telephony.ims.RegistrationManager.SUGGESTED_ACTION_TRIGGER_RAT_BLOCK;
+import static android.telephony.ims.RegistrationManager.SUGGESTED_ACTION_TRIGGER_CLEAR_RAT_BLOCK;
import static android.telephony.ims.stub.ImsRegistrationImplBase.REGISTRATION_TECH_NONE;
import static com.android.internal.telephony.CommandsInterface.CB_FACILITY_BAIC;
@@ -2527,6 +2529,11 @@
if ((suggestedAction == SUGGESTED_ACTION_TRIGGER_PLMN_BLOCK)
|| (suggestedAction == SUGGESTED_ACTION_TRIGGER_PLMN_BLOCK_WITH_TIMEOUT)) {
suggestedModemAction = suggestedAction;
+ } else if (mFeatureFlags.addRatRelatedSuggestedActionToImsRegistration()) {
+ if ((suggestedAction == SUGGESTED_ACTION_TRIGGER_RAT_BLOCK)
+ || (suggestedAction == SUGGESTED_ACTION_TRIGGER_CLEAR_RAT_BLOCK)) {
+ suggestedModemAction = suggestedAction;
+ }
}
}
updateImsRegistrationInfo(REGISTRATION_STATE_NOT_REGISTERED,
diff --git a/src/java/com/android/internal/telephony/security/CellularIdentifierDisclosureNotifier.java b/src/java/com/android/internal/telephony/security/CellularIdentifierDisclosureNotifier.java
new file mode 100644
index 0000000..46e6a28
--- /dev/null
+++ b/src/java/com/android/internal/telephony/security/CellularIdentifierDisclosureNotifier.java
@@ -0,0 +1,62 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.internal.telephony.security;
+
+import android.telephony.CellularIdentifierDisclosure;
+
+import com.android.internal.annotations.VisibleForTesting;
+import com.android.telephony.Rlog;
+
+/**
+ * Encapsulates logic to emit notifications to the user that their cellular identifiers were
+ * disclosed in the clear.
+ *
+ * <p>This class will either emit notifications through SafetyCenterManager if SafetyCenter exists
+ * on a device, or it will emit system notifications otherwise.
+ *
+ * @hide
+ */
+public class CellularIdentifierDisclosureNotifier {
+
+ private static final String TAG = "CellularIdentifierDisclosureNotifier";
+ private static CellularIdentifierDisclosureNotifier sInstance = null;
+
+ @VisibleForTesting
+ public CellularIdentifierDisclosureNotifier() {}
+
+ /**
+ * Add a CellularIdentifierDisclosure to be tracked by this instance.
+ * If appropriate, this will trigger a user notification.
+ */
+ public void addDisclosure(CellularIdentifierDisclosure disclosure) {
+ // TODO (b/308985417) this is a stub method for now. Logic
+ // for tracking disclosures and emitting notifications will flow
+ // from here.
+ Rlog.d(TAG, "Identifier disclosure reported: " + disclosure);
+ }
+
+ /**
+ * Get a singleton CellularIdentifierDisclosureNotifier.
+ */
+ public static synchronized CellularIdentifierDisclosureNotifier getInstance() {
+ if (sInstance == null) {
+ sInstance = new CellularIdentifierDisclosureNotifier();
+ }
+
+ return sInstance;
+ }
+}
diff --git a/tests/telephonytests/src/com/android/internal/telephony/ContextFixture.java b/tests/telephonytests/src/com/android/internal/telephony/ContextFixture.java
index 2dac867..da3920e 100644
--- a/tests/telephonytests/src/com/android/internal/telephony/ContextFixture.java
+++ b/tests/telephonytests/src/com/android/internal/telephony/ContextFixture.java
@@ -779,7 +779,7 @@
doReturn(mBundle).when(mCarrierConfigManager).getConfigForSubId(anyInt(), anyString());
doAnswer(invocation -> mNetworkId++).when(mNetwork).getNetId();
doReturn(mNetwork).when(mConnectivityManager).registerNetworkAgent(
- any(), any(), any(), any(), any(), any(), any(), anyInt());
+ any(), any(), any(), any(), any(), any(), anyInt());
doReturn(true).when(mEuiccManager).isEnabled();
diff --git a/tests/telephonytests/src/com/android/internal/telephony/GsmCdmaPhoneTest.java b/tests/telephonytests/src/com/android/internal/telephony/GsmCdmaPhoneTest.java
index 2563fdf..34087b6 100644
--- a/tests/telephonytests/src/com/android/internal/telephony/GsmCdmaPhoneTest.java
+++ b/tests/telephonytests/src/com/android/internal/telephony/GsmCdmaPhoneTest.java
@@ -72,6 +72,7 @@
import android.telephony.CellIdentity;
import android.telephony.CellIdentityCdma;
import android.telephony.CellIdentityGsm;
+import android.telephony.CellularIdentifierDisclosure;
import android.telephony.LinkCapacityEstimate;
import android.telephony.NetworkRegistrationInfo;
import android.telephony.RadioAccessFamily;
@@ -2761,4 +2762,105 @@
assertEquals(Phone.IMEI_TYPE_SECONDARY, mPhoneUT.getImeiType());
assertEquals(FAKE_IMEI, mPhoneUT.getImei());
}
+
+ @Test
+ public void testCellularIdentifierDisclosureFlagOff() {
+ when(mFeatureFlags.enableIdentifierDisclosureTransparency()).thenReturn(false);
+
+ GsmCdmaPhone phoneUT =
+ new GsmCdmaPhone(
+ mContext,
+ mSimulatedCommands,
+ mNotifier,
+ true,
+ 0,
+ PhoneConstants.PHONE_TYPE_GSM,
+ mTelephonyComponentFactory,
+ (c, p) -> mImsManager,
+ mFeatureFlags);
+ phoneUT.mCi = mMockCi;
+
+ verify(mMockCi, never())
+ .registerForCellularIdentifierDisclosures(
+ any(Handler.class), anyInt(), any(Object.class));
+ }
+
+ @Test
+ public void testCellularIdentifierDisclosureFlagOn() {
+ when(mFeatureFlags.enableIdentifierDisclosureTransparency()).thenReturn(true);
+
+ Phone phoneUT =
+ new GsmCdmaPhone(
+ mContext,
+ mMockCi,
+ mNotifier,
+ true,
+ 0,
+ PhoneConstants.PHONE_TYPE_GSM,
+ mTelephonyComponentFactory,
+ (c, p) -> mImsManager,
+ mFeatureFlags);
+
+ verify(mMockCi, times(1))
+ .registerForCellularIdentifierDisclosures(
+ eq(phoneUT),
+ eq(Phone.EVENT_CELL_IDENTIFIER_DISCLOSURE),
+ nullable(Object.class));
+ }
+
+ @Test
+ public void testCellularIdentifierDisclosure_disclosureEventAddedToNotifier() {
+ when(mFeatureFlags.enableIdentifierDisclosureTransparency()).thenReturn(true);
+
+ Phone phoneUT =
+ new GsmCdmaPhone(
+ mContext,
+ mMockCi,
+ mNotifier,
+ true,
+ 0,
+ PhoneConstants.PHONE_TYPE_GSM,
+ mTelephonyComponentFactory,
+ (c, p) -> mImsManager,
+ mFeatureFlags);
+
+ CellularIdentifierDisclosure disclosure =
+ new CellularIdentifierDisclosure(
+ CellularIdentifierDisclosure.NAS_PROTOCOL_MESSAGE_ATTACH_REQUEST,
+ CellularIdentifierDisclosure.CELLULAR_IDENTIFIER_IMSI,
+ "001001",
+ false);
+ phoneUT.sendMessage(
+ mPhoneUT.obtainMessage(
+ Phone.EVENT_CELL_IDENTIFIER_DISCLOSURE,
+ new AsyncResult(null, disclosure, null)));
+ processAllMessages();
+
+ verify(mIdentifierDisclosureNotifier, times(1)).addDisclosure(eq(disclosure));
+ }
+
+ @Test
+ public void testCellularIdentifierDisclosure_disclosureEventNull() {
+ when(mFeatureFlags.enableIdentifierDisclosureTransparency()).thenReturn(true);
+
+ Phone phoneUT =
+ new GsmCdmaPhone(
+ mContext,
+ mMockCi,
+ mNotifier,
+ true,
+ 0,
+ PhoneConstants.PHONE_TYPE_GSM,
+ mTelephonyComponentFactory,
+ (c, p) -> mImsManager,
+ mFeatureFlags);
+
+ phoneUT.sendMessage(
+ mPhoneUT.obtainMessage(
+ Phone.EVENT_CELL_IDENTIFIER_DISCLOSURE, new AsyncResult(null, null, null)));
+ processAllMessages();
+
+ verify(mIdentifierDisclosureNotifier, never())
+ .addDisclosure(any(CellularIdentifierDisclosure.class));
+ }
}
diff --git a/tests/telephonytests/src/com/android/internal/telephony/TelephonyTest.java b/tests/telephonytests/src/com/android/internal/telephony/TelephonyTest.java
index b8d875c..1ebe96d 100644
--- a/tests/telephonytests/src/com/android/internal/telephony/TelephonyTest.java
+++ b/tests/telephonytests/src/com/android/internal/telephony/TelephonyTest.java
@@ -122,6 +122,7 @@
import com.android.internal.telephony.metrics.SmsStats;
import com.android.internal.telephony.metrics.VoiceCallSessionStats;
import com.android.internal.telephony.satellite.SatelliteController;
+import com.android.internal.telephony.security.CellularIdentifierDisclosureNotifier;
import com.android.internal.telephony.subscription.SubscriptionManagerService;
import com.android.internal.telephony.test.SimulatedCommands;
import com.android.internal.telephony.test.SimulatedCommandsVerifier;
@@ -279,6 +280,7 @@
protected ServiceStateStats mServiceStateStats;
protected SatelliteController mSatelliteController;
protected DeviceStateHelper mDeviceStateHelper;
+ protected CellularIdentifierDisclosureNotifier mIdentifierDisclosureNotifier;
// Initialized classes
protected ActivityManager mActivityManager;
@@ -549,6 +551,7 @@
mServiceStateStats = Mockito.mock(ServiceStateStats.class);
mSatelliteController = Mockito.mock(SatelliteController.class);
mDeviceStateHelper = Mockito.mock(DeviceStateHelper.class);
+ mIdentifierDisclosureNotifier = Mockito.mock(CellularIdentifierDisclosureNotifier.class);
TelephonyManager.disableServiceHandleCaching();
PropertyInvalidatedCache.disableForTestMode();
@@ -662,6 +665,9 @@
any(DataServiceManager.class), any(Looper.class),
any(FeatureFlags.class),
any(DataProfileManager.DataProfileManagerCallback.class));
+ doReturn(mIdentifierDisclosureNotifier)
+ .when(mTelephonyComponentFactory)
+ .makeIdentifierDisclosureNotifier();
//mPhone
doReturn(mContext).when(mPhone).getContext();
diff --git a/tests/telephonytests/src/com/android/internal/telephony/data/AutoDataSwitchControllerTest.java b/tests/telephonytests/src/com/android/internal/telephony/data/AutoDataSwitchControllerTest.java
index 4b88f0a..6462d73 100644
--- a/tests/telephonytests/src/com/android/internal/telephony/data/AutoDataSwitchControllerTest.java
+++ b/tests/telephonytests/src/com/android/internal/telephony/data/AutoDataSwitchControllerTest.java
@@ -152,12 +152,16 @@
doReturn(PHONE_1).when(mPhoneSwitcher).getPreferredDataPhoneId();
mAutoDataSwitchControllerUT = new AutoDataSwitchController(mContext, Looper.myLooper(),
- mPhoneSwitcher, mMockedPhoneSwitcherCallback);
+ mPhoneSwitcher, mFeatureFlags, mMockedPhoneSwitcherCallback);
+
+ doReturn(true).when(mFeatureFlags).autoSwitchAllowRoaming();
}
@After
public void tearDown() throws Exception {
mAutoDataSwitchControllerUT = null;
+ mGoodTelephonyDisplayInfo = null;
+ mBadTelephonyDisplayInfo = null;
super.tearDown();
}
@@ -222,6 +226,97 @@
}
@Test
+ public void testRoaming_prefer_home_over_roam() {
+ // DDS -> nDDS: Prefer Home over Roaming
+ prepareIdealUsesNonDdsCondition();
+ serviceStateChanged(PHONE_1, NetworkRegistrationInfo.REGISTRATION_STATE_ROAMING);
+ serviceStateChanged(PHONE_2, NetworkRegistrationInfo.REGISTRATION_STATE_HOME);
+ processAllFutureMessages();
+
+ verify(mMockedPhoneSwitcherCallback).onRequireValidation(PHONE_2, true/*needValidation*/);
+
+ // nDDS -> DDS: Prefer Home over Roaming
+ doReturn(PHONE_2).when(mPhoneSwitcher).getPreferredDataPhoneId();
+ serviceStateChanged(PHONE_1, NetworkRegistrationInfo.REGISTRATION_STATE_HOME);
+ serviceStateChanged(PHONE_2, NetworkRegistrationInfo.REGISTRATION_STATE_ROAMING);
+ processAllFutureMessages();
+
+ verify(mMockedPhoneSwitcherCallback).onRequireValidation(DEFAULT_PHONE_INDEX,
+ true/*needValidation*/);
+ }
+
+ @Test
+ public void testRoaming_roaming_but_roam_disabled() {
+ // Disable RAT + signalStrength base switching.
+ doReturn(-1).when(mDataConfigManager).getAutoDataSwitchScoreTolerance();
+ mAutoDataSwitchControllerUT = new AutoDataSwitchController(mContext, Looper.myLooper(),
+ mPhoneSwitcher, mFeatureFlags, mMockedPhoneSwitcherCallback);
+
+ // On primary phone
+ // 1.1 Both roaming, user allow roaming on both phone, no need to switch.
+ prepareIdealUsesNonDdsCondition();
+ serviceStateChanged(PHONE_1, NetworkRegistrationInfo.REGISTRATION_STATE_ROAMING);
+ serviceStateChanged(PHONE_2, NetworkRegistrationInfo.REGISTRATION_STATE_ROAMING);
+ processAllFutureMessages();
+ clearInvocations(mMockedPhoneSwitcherCallback);
+
+ mAutoDataSwitchControllerUT.evaluateAutoDataSwitch(EVALUATION_REASON_DATA_SETTINGS_CHANGED);
+ processAllFutureMessages();
+ verify(mMockedPhoneSwitcherCallback, never()).onRequireValidation(anyInt(),
+ anyBoolean()/*needValidation*/);
+
+ // 1.2 Both roaming, but roaming is only allowed on the backup phone.
+ doReturn(false).when(mPhone).getDataRoamingEnabled();
+ mAutoDataSwitchControllerUT.evaluateAutoDataSwitch(EVALUATION_REASON_DATA_SETTINGS_CHANGED);
+ processAllFutureMessages();
+
+ verify(mMockedPhoneSwitcherCallback).onRequireValidation(PHONE_2, true/*needValidation*/);
+
+ // On backup phone
+ doReturn(PHONE_2).when(mPhoneSwitcher).getPreferredDataPhoneId();
+ // 2.1 Both roaming, user allow roaming on both phone, prefer default.
+ doReturn(true).when(mPhone).getDataRoamingEnabled();
+ mAutoDataSwitchControllerUT.evaluateAutoDataSwitch(EVALUATION_REASON_DATA_SETTINGS_CHANGED);
+ processAllFutureMessages();
+
+ verify(mMockedPhoneSwitcherCallback).onRequireValidation(DEFAULT_PHONE_INDEX,
+ true/*needValidation*/);
+
+ // 2.1 Both roaming, but roaming is only allowed on the default phone.
+ doReturn(false).when(mPhone2).getDataRoamingEnabled();
+ mAutoDataSwitchControllerUT.evaluateAutoDataSwitch(EVALUATION_REASON_DATA_SETTINGS_CHANGED);
+ processAllFutureMessages();
+
+ verify(mMockedPhoneSwitcherCallback).onRequireValidation(DEFAULT_PHONE_INDEX,
+ false/*needValidation*/);
+ }
+
+ @Test
+ public void testRoaming_same_roaming_condition_uses_rat_signalStrength() {
+ doReturn(true).when(mFeatureFlags).autoDataSwitchRatSs();
+ // On primary phone
+ // 1. Both roaming, user allow roaming on both phone, uses RAT score to decide switch.
+ prepareIdealUsesNonDdsCondition();
+ serviceStateChanged(PHONE_1, NetworkRegistrationInfo.REGISTRATION_STATE_ROAMING);
+ serviceStateChanged(PHONE_2, NetworkRegistrationInfo.REGISTRATION_STATE_ROAMING);
+ processAllFutureMessages();
+
+ verify(mMockedPhoneSwitcherCallback).onRequireValidation(PHONE_2, true/*needValidation*/);
+
+ // On backup phone
+ doReturn(PHONE_2).when(mPhoneSwitcher).getPreferredDataPhoneId();
+ // 2. Both roaming, user allow roaming on both phone, uses RAT score to decide switch.
+ signalStrengthChanged(PHONE_1, SignalStrength.SIGNAL_STRENGTH_GREAT);
+ signalStrengthChanged(PHONE_2, SignalStrength.SIGNAL_STRENGTH_POOR);
+ displayInfoChanged(PHONE_1, mGoodTelephonyDisplayInfo);
+ displayInfoChanged(PHONE_2, mBadTelephonyDisplayInfo);
+ processAllFutureMessages();
+
+ verify(mMockedPhoneSwitcherCallback).onRequireValidation(DEFAULT_PHONE_INDEX,
+ true/*needValidation*/);
+ }
+
+ @Test
public void testCancelSwitch_onPrimary_rat_signalStrength() {
// 4.1.1 Display info and signal strength on secondary phone became bad,
// but primary is still OOS, so still switch to the secondary.
@@ -269,13 +364,13 @@
// Disable Rat/SignalStrength based switch to test primary OOS based switch
doReturn(-1).when(mDataConfigManager).getAutoDataSwitchScoreTolerance();
mAutoDataSwitchControllerUT = new AutoDataSwitchController(mContext, Looper.myLooper(),
- mPhoneSwitcher, mMockedPhoneSwitcherCallback);
+ mPhoneSwitcher, mFeatureFlags, mMockedPhoneSwitcherCallback);
doReturn(PHONE_2).when(mPhoneSwitcher).getPreferredDataPhoneId();
prepareIdealUsesNonDdsCondition();
// 1.1 service state changes - primary becomes available again, require validation
serviceStateChanged(PHONE_1,
- NetworkRegistrationInfo.REGISTRATION_STATE_ROAMING/*need validate*/);
+ NetworkRegistrationInfo.REGISTRATION_STATE_HOME/*need validate*/);
processAllFutureMessages();
verify(mMockedPhoneSwitcherCallback).onRequireValidation(DEFAULT_PHONE_INDEX,
true/*needValidation*/);
@@ -285,7 +380,7 @@
// 1.2 service state changes - secondary becomes unavailable, NO need validation
serviceStateChanged(PHONE_1,
NetworkRegistrationInfo.REGISTRATION_STATE_HOME/*need validate*/);
- serviceStateChanged(PHONE_2, NetworkRegistrationInfo.REGISTRATION_STATE_ROAMING/*no need*/);
+ serviceStateChanged(PHONE_2, NetworkRegistrationInfo.REGISTRATION_STATE_DENIED/*no need*/);
processAllFutureMessages();
// The later validation requirement overrides the previous
verify(mMockedPhoneSwitcherCallback).onRequireValidation(DEFAULT_PHONE_INDEX,
@@ -325,6 +420,7 @@
@Test
public void testOnNonDdsSwitchBackToPrimary_rat_signalStrength() {
+ doReturn(true).when(mFeatureFlags).autoDataSwitchRatSs();
doReturn(PHONE_2).when(mPhoneSwitcher).getPreferredDataPhoneId();
prepareIdealUsesNonDdsCondition();
@@ -354,8 +450,8 @@
doReturn(PHONE_2).when(mPhoneSwitcher).getPreferredDataPhoneId();
prepareIdealUsesNonDdsCondition();
- // attempts the switch back due to secondary becomes ROAMING
- serviceStateChanged(PHONE_2, NetworkRegistrationInfo.REGISTRATION_STATE_ROAMING);
+ // attempts the switch back due to secondary not usable
+ serviceStateChanged(PHONE_2, NetworkRegistrationInfo.REGISTRATION_STATE_DENIED);
processAllFutureMessages();
verify(mMockedPhoneSwitcherCallback).onRequireValidation(DEFAULT_PHONE_INDEX,
@@ -413,7 +509,7 @@
doReturn(-1 /*Disable signal based switch for easy mock*/).when(mDataConfigManager)
.getAutoDataSwitchScoreTolerance();
mAutoDataSwitchControllerUT = new AutoDataSwitchController(mContext, Looper.myLooper(),
- mPhoneSwitcher, mMockedPhoneSwitcherCallback);
+ mPhoneSwitcher, mFeatureFlags, mMockedPhoneSwitcherCallback);
//1. DDS -> nDDS, verify callback doesn't require validation
prepareIdealUsesNonDdsCondition();
@@ -423,7 +519,7 @@
//2. nDDS -> DDS, verify callback doesn't require validation
doReturn(PHONE_2).when(mPhoneSwitcher).getPreferredDataPhoneId();
- serviceStateChanged(PHONE_1, NetworkRegistrationInfo.REGISTRATION_STATE_ROAMING);
+ serviceStateChanged(PHONE_1, NetworkRegistrationInfo.REGISTRATION_STATE_HOME);
processAllFutureMessages();
verify(mMockedPhoneSwitcherCallback).onRequireValidation(DEFAULT_PHONE_INDEX,
false/*needValidation*/);
@@ -478,7 +574,7 @@
int modemCount = 2;
doReturn(new int[]{SUB_2}).when(mSubscriptionManagerService)
.getActiveSubIdList(true);
- mAutoDataSwitchControllerUT.notifySubscriptionsChanged();
+ mAutoDataSwitchControllerUT.notifySubscriptionsMappingChanged();
processAllMessages();
// Verify unregister from both slots since only 1 visible SIM is insufficient for switching
@@ -492,7 +588,7 @@
clearInvocations(mDisplayInfoController, mSignalStrengthController, mSST);
doReturn(new int[]{SUB_1, SUB_2}).when(mSubscriptionManagerService)
.getActiveSubIdList(true);
- mAutoDataSwitchControllerUT.notifySubscriptionsChanged();
+ mAutoDataSwitchControllerUT.notifySubscriptionsMappingChanged();
processAllMessages();
// Verify register on both slots
@@ -544,8 +640,10 @@
// 4.1 User data enabled on primary SIM
doReturn(true).when(mPhone).isUserDataEnabled();
+ doReturn(true).when(mPhone).getDataRoamingEnabled();
// 4.2 Auto switch feature is enabled
+ doReturn(true).when(mPhone2).getDataRoamingEnabled();
doReturn(true).when(mPhone2).isDataAllowed();
// 5. No default network
diff --git a/tests/telephonytests/src/com/android/internal/telephony/data/DataNetworkTest.java b/tests/telephonytests/src/com/android/internal/telephony/data/DataNetworkTest.java
index ffaf8fc..5dd83bf 100644
--- a/tests/telephonytests/src/com/android/internal/telephony/data/DataNetworkTest.java
+++ b/tests/telephonytests/src/com/android/internal/telephony/data/DataNetworkTest.java
@@ -445,7 +445,7 @@
verify(mConnectivityManager).registerNetworkAgent(any(), any(NetworkInfo.class),
linkPropertiesCaptor.capture(), networkCapabilitiesCaptor.capture(), any(), any(),
- any(), anyInt());
+ anyInt());
// The very first link properties from telephony is an empty link properties. It will be
// updated later.
assertThat(linkPropertiesCaptor.getValue()).isEqualTo(new LinkProperties());
@@ -552,7 +552,7 @@
verify(mConnectivityManager).registerNetworkAgent(any(), any(NetworkInfo.class),
any(LinkProperties.class), networkCapabilitiesCaptor.capture(), any(), any(),
- any(), anyInt());
+ anyInt());
// Make sure the initial network capability has NOT_SUSPENDED
assertThat(networkCapabilitiesCaptor.getValue().hasCapability(
@@ -616,7 +616,7 @@
// Agent re-created, so register should be called twice.
verify(mConnectivityManager, times(2)).registerNetworkAgent(any(), any(NetworkInfo.class),
any(LinkProperties.class), networkCapabilitiesCaptor.capture(), any(), any(),
- any(), anyInt());
+ anyInt());
// Make sure the 2nd network agent was created with NOT_SUSPENDED.
assertThat(networkCapabilitiesCaptor.getValue().hasCapability(
@@ -663,7 +663,7 @@
verify(mConnectivityManager).registerNetworkAgent(any(), any(NetworkInfo.class),
linkPropertiesCaptor.capture(), networkCapabilitiesCaptor.capture(), any(), any(),
- any(), anyInt());
+ anyInt());
// The very first link properties from telephony is an empty link properties. It will be
// updated later.
assertThat(linkPropertiesCaptor.getValue()).isEqualTo(new LinkProperties());
@@ -1424,8 +1424,8 @@
.forClass(NetworkAgentConfig.class);
verify(mConnectivityManager).registerNetworkAgent(any(), any(NetworkInfo.class),
- any(LinkProperties.class), any(NetworkCapabilities.class), any(), any(),
- captor.capture(), anyInt());
+ any(LinkProperties.class), any(NetworkCapabilities.class), any(), captor.capture(),
+ anyInt());
NetworkAgentConfig networkAgentConfig = captor.getValue();
@@ -1508,7 +1508,7 @@
// Agent re-created, so register should be called twice.
verify(mConnectivityManager, times(2)).registerNetworkAgent(any(), any(NetworkInfo.class),
any(LinkProperties.class), any(NetworkCapabilities.class), any(), any(),
- any(), anyInt());
+ anyInt());
assertThat(mDataNetworkUT.getNetworkCapabilities().hasCapability(
NetworkCapabilities.NET_CAPABILITY_ENTERPRISE)).isTrue();
@@ -1530,7 +1530,7 @@
// Agent not re-created, so register should be called once.
verify(mConnectivityManager, times(1)).registerNetworkAgent(any(), any(NetworkInfo.class),
any(LinkProperties.class), any(NetworkCapabilities.class), any(), any(),
- any(), anyInt());
+ anyInt());
assertThat(mDataNetworkUT.getNetworkCapabilities().hasCapability(
NetworkCapabilities.NET_CAPABILITY_TEMPORARILY_NOT_METERED)).isTrue();
@@ -1730,7 +1730,7 @@
// Agent re-created, so register should be called twice.
verify(mConnectivityManager, times(2)).registerNetworkAgent(any(), any(NetworkInfo.class),
linkPropertiesCaptor.capture(), any(NetworkCapabilities.class), any(), any(),
- any(), anyInt());
+ anyInt());
// The new agent should have the new IP address.
assertThat(linkPropertiesCaptor.getValue().getAllAddresses()).containsExactly(
InetAddresses.parseNumericAddress(IPV4_ADDRESS1),
@@ -1779,7 +1779,7 @@
// Agent re-created, so register should be called twice.
verify(mConnectivityManager, times(2)).registerNetworkAgent(any(), any(NetworkInfo.class),
linkPropertiesCaptor.capture(), any(NetworkCapabilities.class), any(), any(),
- any(), anyInt());
+ anyInt());
// The new agent should have the new IP address.
assertThat(linkPropertiesCaptor.getValue().getAllAddresses()).containsExactly(
InetAddresses.parseNumericAddress(IPV6_ADDRESS1));
@@ -1870,7 +1870,7 @@
// Agent should not be re-created, so register should be called ony once.
verify(mConnectivityManager, times(1)).registerNetworkAgent(any(), any(NetworkInfo.class),
any(LinkProperties.class), any(NetworkCapabilities.class), any(), any(),
- any(), anyInt());
+ anyInt());
// The network should have IPv6 address now
assertThat(mDataNetworkUT.getLinkProperties().getAllAddresses()).containsExactly(
@@ -1914,7 +1914,7 @@
// Agent should not be re-created, so register should be called ony once.
verify(mConnectivityManager, times(1)).registerNetworkAgent(any(), any(NetworkInfo.class),
any(LinkProperties.class), any(NetworkCapabilities.class), any(), any(),
- any(), anyInt());
+ anyInt());
// The network should have IPv6 address now
assertThat(mDataNetworkUT.getLinkProperties().getAllAddresses()).containsExactly(
@@ -1959,7 +1959,7 @@
// Agent should not be re-created, so register should be called ony once.
verify(mConnectivityManager, times(1)).registerNetworkAgent(any(), any(NetworkInfo.class),
any(LinkProperties.class), any(NetworkCapabilities.class), any(), any(),
- any(), anyInt());
+ anyInt());
// The network should have IPv6 address now
assertThat(mDataNetworkUT.getLinkProperties().getAllAddresses()).containsExactly(
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 94fd934..13ab611 100644
--- a/tests/telephonytests/src/com/android/internal/telephony/data/PhoneSwitcherTest.java
+++ b/tests/telephonytests/src/com/android/internal/telephony/data/PhoneSwitcherTest.java
@@ -26,8 +26,10 @@
import static android.telephony.ims.stub.ImsRegistrationImplBase.REGISTRATION_TECH_CROSS_SIM;
import static android.telephony.ims.stub.ImsRegistrationImplBase.REGISTRATION_TECH_IWLAN;
import static android.telephony.ims.stub.ImsRegistrationImplBase.REGISTRATION_TECH_LTE;
+
import static com.android.internal.telephony.data.AutoDataSwitchController.EVALUATION_REASON_VOICE_CALL_END;
import static com.android.internal.telephony.data.PhoneSwitcher.ECBM_DEFAULT_DATA_SWITCH_BASE_TIME_MS;
+
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNotNull;
@@ -267,12 +269,14 @@
assertFalse("data allowed", mDataAllowed[0]);
setSlotIndexToSubId(1, 1);
+ clearInvocations(mAutoDataSwitchController);
mSubChangedListener.onSubscriptionsChanged();
processAllMessages();
Message.obtain(mPhoneSwitcherUT, EVENT_MODEM_COMMAND_DONE, res).sendToTarget();
processAllMessages();
verify(mActivePhoneSwitchHandler, times(1)).sendMessageAtTime(any(), anyLong());
+ verify(mAutoDataSwitchController).notifySubscriptionsMappingChanged();
clearInvocations(mActivePhoneSwitchHandler);
assertFalse("data allowed", mDataAllowed[0]);
assertTrue("data not allowed", mDataAllowed[1]);
@@ -289,8 +293,10 @@
// 3 lose default via sub->phone change
setSlotIndexToSubId(0, 2);
+ clearInvocations(mAutoDataSwitchController);
mSubChangedListener.onSubscriptionsChanged();
processAllMessages();
+ verify(mAutoDataSwitchController).notifySubscriptionsMappingChanged();
Message.obtain(mPhoneSwitcherUT, EVENT_MODEM_COMMAND_DONE, res).sendToTarget();
processAllMessages();
@@ -1097,7 +1103,6 @@
}
@Test
- @SmallTest
public void testDataEnabledChangedDuringVoiceCall() throws Exception {
doReturn(true).when(mMockRadioConfig).isSetPreferredDataCommandSupported();
initialize();
@@ -1135,6 +1140,18 @@
}
@Test
+ public void testRoamingToggle() throws Exception {
+ initialize();
+ setSlotIndexToSubId(0, 1);
+
+ mDataSettingsManagerCallbacks.get(0).onDataRoamingEnabledChanged(true);
+ processAllMessages();
+
+ verify(mAutoDataSwitchController).evaluateAutoDataSwitch(AutoDataSwitchController
+ .EVALUATION_REASON_DATA_SETTINGS_CHANGED);
+ }
+
+ @Test
@SmallTest
public void testNetworkRequestOnNonDefaultData() throws Exception {
doReturn(true).when(mMockRadioConfig).isSetPreferredDataCommandSupported();
@@ -1858,7 +1875,8 @@
initializeConnManagerMock();
initializeConfigMock();
- mPhoneSwitcherUT = new PhoneSwitcher(mMaxDataAttachModemCount, mContext, Looper.myLooper());
+ mPhoneSwitcherUT = new PhoneSwitcher(mMaxDataAttachModemCount, mContext, Looper.myLooper(),
+ mFeatureFlags);
Field field = PhoneSwitcher.class.getDeclaredField("mDataSettingsManagerCallbacks");
field.setAccessible(true);
diff --git a/tests/telephonytests/src/com/android/internal/telephony/imsphone/ImsPhoneTest.java b/tests/telephonytests/src/com/android/internal/telephony/imsphone/ImsPhoneTest.java
index 4e61c67..fbb30ff 100644
--- a/tests/telephonytests/src/com/android/internal/telephony/imsphone/ImsPhoneTest.java
+++ b/tests/telephonytests/src/com/android/internal/telephony/imsphone/ImsPhoneTest.java
@@ -24,6 +24,8 @@
import static android.telephony.ims.RegistrationManager.SUGGESTED_ACTION_NONE;
import static android.telephony.ims.RegistrationManager.SUGGESTED_ACTION_TRIGGER_PLMN_BLOCK;
import static android.telephony.ims.RegistrationManager.SUGGESTED_ACTION_TRIGGER_PLMN_BLOCK_WITH_TIMEOUT;
+import static android.telephony.ims.RegistrationManager.SUGGESTED_ACTION_TRIGGER_RAT_BLOCK;
+import static android.telephony.ims.RegistrationManager.SUGGESTED_ACTION_TRIGGER_CLEAR_RAT_BLOCK;
import static android.telephony.ims.stub.ImsRegistrationImplBase.REGISTRATION_TECH_3G;
import static android.telephony.ims.stub.ImsRegistrationImplBase.REGISTRATION_TECH_IWLAN;
import static android.telephony.ims.stub.ImsRegistrationImplBase.REGISTRATION_TECH_LTE;
@@ -1484,6 +1486,81 @@
assertTrue(regInfo[0] == 1 && regInfo[1] == 1 && regInfo[2] == 1);
}
+ /**
+ * Verifies that valid state and reason is passed to RIL with RAT suggested actions
+ * when IMS registration state changes to unregistered.
+ */
+ @Test
+ @SmallTest
+ public void testUpdateImsRegistrationInfoWithRatSuggestedAction() {
+ doReturn(true).when(mFeatureFlags)
+ .addRatRelatedSuggestedActionToImsRegistration();
+
+ mSimulatedCommands.updateImsRegistrationInfo(0, 0, 0, 0, null);
+
+ int[] regInfo = mSimulatedCommands.getImsRegistrationInfo();
+ assertNotNull(regInfo);
+ assertTrue(regInfo[0] == 0 && regInfo[1] == 0 && regInfo[2] == 0);
+
+ RegistrationManager.RegistrationCallback registrationCallback =
+ mImsPhoneUT.getImsMmTelRegistrationCallback();
+
+ ImsReasonInfo reasonInfo = new ImsReasonInfo(ImsReasonInfo.CODE_REGISTRATION_ERROR,
+ ImsReasonInfo.CODE_UNSPECIFIED, "");
+
+ // unregistered with rat block
+ registrationCallback.onUnregistered(reasonInfo,
+ SUGGESTED_ACTION_TRIGGER_RAT_BLOCK,
+ REGISTRATION_TECH_LTE);
+ regInfo = mSimulatedCommands.getImsRegistrationInfo();
+
+ assertTrue(regInfo[0] == RegistrationManager.REGISTRATION_STATE_NOT_REGISTERED
+ && regInfo[1] == REGISTRATION_TECH_LTE
+ && regInfo[2] == SUGGESTED_ACTION_TRIGGER_RAT_BLOCK);
+
+ // reset the registration info saved in the SimulatedCommands
+ mSimulatedCommands.updateImsRegistrationInfo(0, 0, 0, 0, null);
+ regInfo = mSimulatedCommands.getImsRegistrationInfo();
+
+ assertTrue(regInfo[0] == 0 && regInfo[1] == 0 && regInfo[2] == 0);
+
+ // verfies that duplicated notification with the same suggested action is invoked
+ registrationCallback.onUnregistered(reasonInfo,
+ SUGGESTED_ACTION_TRIGGER_RAT_BLOCK,
+ REGISTRATION_TECH_LTE);
+ regInfo = mSimulatedCommands.getImsRegistrationInfo();
+
+ assertTrue(regInfo[0] == RegistrationManager.REGISTRATION_STATE_NOT_REGISTERED
+ && regInfo[1] == REGISTRATION_TECH_LTE
+ && regInfo[2] == SUGGESTED_ACTION_TRIGGER_RAT_BLOCK);
+
+ // unregistered with rat block clear
+ registrationCallback.onUnregistered(reasonInfo,
+ SUGGESTED_ACTION_TRIGGER_CLEAR_RAT_BLOCK,
+ REGISTRATION_TECH_LTE);
+ regInfo = mSimulatedCommands.getImsRegistrationInfo();
+
+ assertTrue(regInfo[0] == RegistrationManager.REGISTRATION_STATE_NOT_REGISTERED
+ && regInfo[1] == REGISTRATION_TECH_LTE
+ && regInfo[2] == SUGGESTED_ACTION_TRIGGER_CLEAR_RAT_BLOCK);
+
+ // reset the registration info saved in the SimulatedCommands
+ mSimulatedCommands.updateImsRegistrationInfo(0, 0, 0, 0, null);
+ regInfo = mSimulatedCommands.getImsRegistrationInfo();
+
+ assertTrue(regInfo[0] == 0 && regInfo[1] == 0 && regInfo[2] == 0);
+
+ // verfies that duplicated notification with the same suggested action is invoked
+ registrationCallback.onUnregistered(reasonInfo,
+ SUGGESTED_ACTION_TRIGGER_CLEAR_RAT_BLOCK,
+ REGISTRATION_TECH_LTE);
+ regInfo = mSimulatedCommands.getImsRegistrationInfo();
+
+ assertTrue(regInfo[0] == RegistrationManager.REGISTRATION_STATE_NOT_REGISTERED
+ && regInfo[1] == REGISTRATION_TECH_LTE
+ && regInfo[2] == SUGGESTED_ACTION_TRIGGER_CLEAR_RAT_BLOCK);
+ }
+
@Test
@SmallTest
public void testImsDialArgsBuilderFromForAlternateService() {
diff --git a/tests/telephonytests/src/com/android/internal/telephony/security/CellularIdentifierDisclosureTest.java b/tests/telephonytests/src/com/android/internal/telephony/security/CellularIdentifierDisclosureTest.java
index 7d2a6a6..327a1cb 100644
--- a/tests/telephonytests/src/com/android/internal/telephony/security/CellularIdentifierDisclosureTest.java
+++ b/tests/telephonytests/src/com/android/internal/telephony/security/CellularIdentifierDisclosureTest.java
@@ -19,12 +19,16 @@
import static android.telephony.CellularIdentifierDisclosure.CELLULAR_IDENTIFIER_IMEI;
import static android.telephony.CellularIdentifierDisclosure.CELLULAR_IDENTIFIER_IMSI;
import static android.telephony.CellularIdentifierDisclosure.NAS_PROTOCOL_MESSAGE_ATTACH_REQUEST;
+import static android.telephony.CellularIdentifierDisclosure.NAS_PROTOCOL_MESSAGE_IDENTITY_RESPONSE;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotEquals;
+import android.hardware.radio.network.CellularIdentifier;
+import android.hardware.radio.network.NasProtocolMessage;
import android.os.Parcel;
-import android.telephony.CellularIdentifierDisclosure;
+
+import com.android.internal.telephony.RILUtils;
import org.junit.Test;
@@ -32,22 +36,38 @@
@Test
public void testEqualsAndHash() {
- CellularIdentifierDisclosure disclosure = new CellularIdentifierDisclosure(
- NAS_PROTOCOL_MESSAGE_ATTACH_REQUEST, CELLULAR_IDENTIFIER_IMSI, "001001", false);
+ android.telephony.CellularIdentifierDisclosure disclosure =
+ new android.telephony.CellularIdentifierDisclosure(
+ NAS_PROTOCOL_MESSAGE_ATTACH_REQUEST,
+ CELLULAR_IDENTIFIER_IMSI,
+ "001001",
+ false);
- CellularIdentifierDisclosure anotherDislcosure = new CellularIdentifierDisclosure(
- NAS_PROTOCOL_MESSAGE_ATTACH_REQUEST, CELLULAR_IDENTIFIER_IMSI, "001001", false);
+ android.telephony.CellularIdentifierDisclosure anotherDislcosure =
+ new android.telephony.CellularIdentifierDisclosure(
+ NAS_PROTOCOL_MESSAGE_ATTACH_REQUEST,
+ CELLULAR_IDENTIFIER_IMSI,
+ "001001",
+ false);
assertEquals(disclosure, anotherDislcosure);
assertEquals(disclosure.hashCode(), anotherDislcosure.hashCode());
}
@Test
public void testNotEqualsAndHash() {
- CellularIdentifierDisclosure imsiDisclosure = new CellularIdentifierDisclosure(
- NAS_PROTOCOL_MESSAGE_ATTACH_REQUEST, CELLULAR_IDENTIFIER_IMSI, "001001", false);
+ android.telephony.CellularIdentifierDisclosure imsiDisclosure =
+ new android.telephony.CellularIdentifierDisclosure(
+ NAS_PROTOCOL_MESSAGE_ATTACH_REQUEST,
+ CELLULAR_IDENTIFIER_IMSI,
+ "001001",
+ false);
- CellularIdentifierDisclosure imeiDisclosure = new CellularIdentifierDisclosure(
- NAS_PROTOCOL_MESSAGE_ATTACH_REQUEST, CELLULAR_IDENTIFIER_IMEI, "001001", false);
+ android.telephony.CellularIdentifierDisclosure imeiDisclosure =
+ new android.telephony.CellularIdentifierDisclosure(
+ NAS_PROTOCOL_MESSAGE_ATTACH_REQUEST,
+ CELLULAR_IDENTIFIER_IMEI,
+ "001001",
+ false);
assertNotEquals(imsiDisclosure, imeiDisclosure);
assertNotEquals(imsiDisclosure.hashCode(), imeiDisclosure.hashCode());
@@ -55,8 +75,12 @@
@Test
public void testGetters() {
- CellularIdentifierDisclosure disclosure = new CellularIdentifierDisclosure(
- NAS_PROTOCOL_MESSAGE_ATTACH_REQUEST, CELLULAR_IDENTIFIER_IMSI, "001001", false);
+ android.telephony.CellularIdentifierDisclosure disclosure =
+ new android.telephony.CellularIdentifierDisclosure(
+ NAS_PROTOCOL_MESSAGE_ATTACH_REQUEST,
+ CELLULAR_IDENTIFIER_IMSI,
+ "001001",
+ false);
assertEquals(NAS_PROTOCOL_MESSAGE_ATTACH_REQUEST, disclosure.getNasProtocolMessage());
assertEquals(CELLULAR_IDENTIFIER_IMSI, disclosure.getCellularIdentifier());
@@ -66,15 +90,39 @@
@Test
public void testParcel() {
- CellularIdentifierDisclosure disclosure = new CellularIdentifierDisclosure(
- NAS_PROTOCOL_MESSAGE_ATTACH_REQUEST, CELLULAR_IDENTIFIER_IMSI, "001001", false);
+ android.telephony.CellularIdentifierDisclosure disclosure =
+ new android.telephony.CellularIdentifierDisclosure(
+ NAS_PROTOCOL_MESSAGE_ATTACH_REQUEST,
+ CELLULAR_IDENTIFIER_IMSI,
+ "001001",
+ false);
Parcel p = Parcel.obtain();
disclosure.writeToParcel(p, 0);
p.setDataPosition(0);
- CellularIdentifierDisclosure fromParcel =
- CellularIdentifierDisclosure.CREATOR.createFromParcel(p);
+ android.telephony.CellularIdentifierDisclosure fromParcel =
+ android.telephony.CellularIdentifierDisclosure.CREATOR.createFromParcel(p);
assertEquals(disclosure, fromParcel);
}
+
+ @Test
+ public void testConvertCellularIdentifierDisclosure() {
+ android.hardware.radio.network.CellularIdentifierDisclosure aidlDisclsoure =
+ new android.hardware.radio.network.CellularIdentifierDisclosure();
+ aidlDisclsoure.plmn = "001001";
+ aidlDisclsoure.identifier = NasProtocolMessage.IDENTITY_RESPONSE;
+ aidlDisclsoure.protocolMessage = CellularIdentifier.IMEI;
+ aidlDisclsoure.isEmergency = true;
+
+ android.telephony.CellularIdentifierDisclosure expectedDisclosure =
+ new android.telephony.CellularIdentifierDisclosure(
+ NAS_PROTOCOL_MESSAGE_IDENTITY_RESPONSE,
+ CELLULAR_IDENTIFIER_IMEI,
+ "001001",
+ true);
+
+ assertEquals(
+ expectedDisclosure, RILUtils.convertCellularIdentifierDisclosure(aidlDisclsoure));
+ }
}