Merge "Save call disconnect info for error propagation" into main
diff --git a/flags/Android.bp b/flags/Android.bp
index 99c99c5..3c0deee 100644
--- a/flags/Android.bp
+++ b/flags/Android.bp
@@ -23,6 +23,7 @@
package: "com.android.internal.telephony.flags",
srcs: [
"data.aconfig",
+ "domainselection.aconfig",
"ims.aconfig",
"messaging.aconfig",
"misc.aconfig",
diff --git a/flags/data.aconfig b/flags/data.aconfig
index befb38d..152660b 100644
--- a/flags/data.aconfig
+++ b/flags/data.aconfig
@@ -1,6 +1,34 @@
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."
+ bug: "311476875"
+}
+
+flag {
+ name: "refine_preferred_data_profile_selection"
+ namespace: "telephony"
+ description: "Upon internet network connect, refine selection of preferred data profile."
+ bug: "311476883"
+}
+
+flag {
name: "unthrottle_check_transport"
namespace: "telephony"
description: "Check transport when unthrottle."
@@ -49,3 +77,9 @@
bug:"286171724"
}
+flag {
+ name: "notify_data_activity_changed_with_slot"
+ namespace: "telephony"
+ description: "notify data activity changed for slot id"
+ bug: "309896936"
+}
diff --git a/flags/domainselection.aconfig b/flags/domainselection.aconfig
new file mode 100644
index 0000000..2e1dfc8
--- /dev/null
+++ b/flags/domainselection.aconfig
@@ -0,0 +1,29 @@
+package: "com.android.internal.telephony.flags"
+
+flag {
+ name: "ap_domain_selection_enabled"
+ namespace: "telephony"
+ description: "This flag controls AP domain selection feature."
+ bug:"258112541"
+}
+
+flag {
+ name: "use_aosp_domain_selection_service"
+ namespace: "telephony"
+ description: "This flag controls AOSP's domain selection service supported."
+ bug:"258112541"
+}
+
+flag {
+ name: "use_oem_domain_selection_service"
+ namespace: "telephony"
+ description: "This flag controls OEMs' domain selection service supported."
+ bug:"258112541"
+}
+
+flag {
+ name: "domain_selection_metrics_enabled"
+ namespace: "telephony"
+ description: "This flag controls domain selection metrics."
+ bug:"258112541"
+}
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/iwlan.aconfig b/flags/iwlan.aconfig
index efd43e4..0dc9f8d 100644
--- a/flags/iwlan.aconfig
+++ b/flags/iwlan.aconfig
@@ -6,3 +6,9 @@
description: "Add AEAD algorithms AES-GCM-8, AES-GCM-12 and AES-GCM-16 to IWLAN"
bug:"306119890"
}
+flag {
+ name: "enable_multiple_sa_proposals"
+ namespace: "telephony"
+ description: "Add multiple proposals of cipher suites in IKE SA and Child SA"
+ bug:"287296642"
+}
diff --git a/flags/misc.aconfig b/flags/misc.aconfig
index 159d462..7f40596 100644
--- a/flags/misc.aconfig
+++ b/flags/misc.aconfig
@@ -63,3 +63,17 @@
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"
+}
+
+flag {
+ name: "radio_info_is_radio_on"
+ namespace: "telephony"
+ description: "change method to show mobile radio power from service state to radio power"
+ bug: "306084899"
+}
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/proto/src/persist_atoms.proto b/proto/src/persist_atoms.proto
index 537f824..6d1008b 100644
--- a/proto/src/persist_atoms.proto
+++ b/proto/src/persist_atoms.proto
@@ -277,6 +277,9 @@
optional int32 fold_state = 34;
optional int64 rat_switch_count_after_connected = 35;
optional bool handover_in_progress = 36;
+ optional bool is_iwlan_cross_sim_at_start = 37;
+ optional bool is_iwlan_cross_sim_at_end = 38;
+ optional bool is_iwlan_cross_sim_at_connected = 39;
// Internal use only
optional int64 setup_begin_millis = 10001;
@@ -365,6 +368,7 @@
repeated int32 handover_failure_causes = 20;
repeated int32 handover_failure_rat = 21;
optional bool is_non_dds = 22;
+ optional bool is_iwlan_cross_sim = 23;
}
message CellularServiceState {
@@ -382,6 +386,7 @@
optional int32 fold_state = 12;
optional bool override_voice_service = 13;
optional bool isDataEnabled = 14;
+ optional bool is_iwlan_cross_sim = 15;
// Internal use only
optional int64 last_used_millis = 10001;
@@ -408,6 +413,7 @@
optional int32 extra_code = 6;
optional string extra_message = 7;
optional int32 count = 8;
+ optional bool is_iwlan_cross_sim = 9;
// Internal use only
optional int64 last_used_millis = 10001;
@@ -429,6 +435,7 @@
optional int64 ut_available_millis = 12;
optional int64 registering_millis = 13;
optional int64 unregistered_millis = 14;
+ optional bool is_iwlan_cross_sim = 15;
// Internal use only
optional int64 last_used_millis = 10001;
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/CarrierPrivilegesTracker.java b/src/java/com/android/internal/telephony/CarrierPrivilegesTracker.java
index ab7ebc4..67be1b6 100644
--- a/src/java/com/android/internal/telephony/CarrierPrivilegesTracker.java
+++ b/src/java/com/android/internal/telephony/CarrierPrivilegesTracker.java
@@ -560,7 +560,7 @@
}
private void updateCertsForPackage(@NonNull PackageInfo pkg) {
- Set<String> certs = new ArraySet<>();
+ Set<String> certs = new ArraySet<>(1);
List<Signature> signatures = UiccAccessRule.getSignatures(pkg);
for (Signature signature : signatures) {
byte[] sha1 = UiccAccessRule.getCertHash(signature, SHA_1);
@@ -773,7 +773,7 @@
return mCachedUids.get(pkgName);
}
- Set<Integer> uids = new ArraySet<>();
+ Set<Integer> uids = new ArraySet<>(1);
List<UserInfo> users = mUserManager.getUsers();
for (UserInfo user : users) {
int userId = user.getUserHandle().getIdentifier();
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/DefaultPhoneNotifier.java b/src/java/com/android/internal/telephony/DefaultPhoneNotifier.java
index c9db985..c035329 100644
--- a/src/java/com/android/internal/telephony/DefaultPhoneNotifier.java
+++ b/src/java/com/android/internal/telephony/DefaultPhoneNotifier.java
@@ -41,6 +41,7 @@
import android.telephony.ims.ImsReasonInfo;
import android.telephony.ims.MediaQualityStatus;
+import com.android.internal.telephony.flags.FeatureFlags;
import com.android.telephony.Rlog;
import java.util.List;
@@ -55,10 +56,15 @@
private TelephonyRegistryManager mTelephonyRegistryMgr;
+ /** Feature flags */
+ @NonNull
+ private final FeatureFlags mFeatureFlags;
- public DefaultPhoneNotifier(Context context) {
+
+ public DefaultPhoneNotifier(Context context, @NonNull FeatureFlags featureFlags) {
mTelephonyRegistryMgr = (TelephonyRegistryManager) context.getSystemService(
Context.TELEPHONY_REGISTRY_SERVICE);
+ mFeatureFlags = featureFlags;
}
@Override
@@ -125,10 +131,16 @@
@Override
public void notifyDataActivity(Phone sender) {
- int phoneId = sender.getPhoneId();
+
int subId = sender.getSubId();
- mTelephonyRegistryMgr.notifyDataActivityChanged(phoneId, subId,
- sender.getDataActivityState());
+
+ if (mFeatureFlags.notifyDataActivityChangedWithSlot()) {
+ int phoneId = sender.getPhoneId();
+ mTelephonyRegistryMgr.notifyDataActivityChanged(phoneId, subId,
+ sender.getDataActivityState());
+ } else {
+ mTelephonyRegistryMgr.notifyDataActivityChanged(subId, sender.getDataActivityState());
+ }
}
@Override
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/MultiSimSettingController.java b/src/java/com/android/internal/telephony/MultiSimSettingController.java
index d6b0930..d07e731 100644
--- a/src/java/com/android/internal/telephony/MultiSimSettingController.java
+++ b/src/java/com/android/internal/telephony/MultiSimSettingController.java
@@ -541,7 +541,7 @@
boolean setDefaultData = true;
List<SubscriptionInfo> activeSubList = mSubscriptionManagerService
.getActiveSubscriptionInfoList(mContext.getOpPackageName(),
- mContext.getAttributionTag());
+ mContext.getAttributionTag(), true/*isForAllProfile*/);
for (SubscriptionInfo activeInfo : activeSubList) {
if (!(groupUuid.equals(activeInfo.getGroupUuid()))) {
// Do not set refSubId as defaultDataSubId if there are other active
@@ -588,7 +588,7 @@
List<SubscriptionInfo> activeSubInfos = mSubscriptionManagerService
.getActiveSubscriptionInfoList(mContext.getOpPackageName(),
- mContext.getAttributionTag());
+ mContext.getAttributionTag(), true/*isForAllProfile*/);
if (ArrayUtils.isEmpty(activeSubInfos)) {
mPrimarySubList.clear();
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/NetworkTypeController.java b/src/java/com/android/internal/telephony/NetworkTypeController.java
index d1c8359..e6fb84e 100644
--- a/src/java/com/android/internal/telephony/NetworkTypeController.java
+++ b/src/java/com/android/internal/telephony/NetworkTypeController.java
@@ -594,9 +594,6 @@
log("Reset timers since physical channel config indications are off.");
}
resetAllTimers();
- mRatchetedNrBands.clear();
- mRatchetedNrBandwidths = 0;
- mLastAnchorNrCellId = PhysicalChannelConfig.PHYSICAL_CELL_ID_UNKNOWN;
}
transitionToCurrentState();
break;
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/PhoneConfigurationManager.java b/src/java/com/android/internal/telephony/PhoneConfigurationManager.java
index 06ab584..78d1387 100644
--- a/src/java/com/android/internal/telephony/PhoneConfigurationManager.java
+++ b/src/java/com/android/internal/telephony/PhoneConfigurationManager.java
@@ -19,6 +19,7 @@
import static android.telephony.TelephonyManager.ACTION_MULTI_SIM_CONFIG_CHANGED;
import static android.telephony.TelephonyManager.EXTRA_ACTIVE_SIM_SUPPORTED_COUNT;
+import android.annotation.NonNull;
import android.content.Context;
import android.content.Intent;
import android.os.AsyncResult;
@@ -37,6 +38,7 @@
import android.util.Log;
import com.android.internal.annotations.VisibleForTesting;
+import com.android.internal.telephony.flags.FeatureFlags;
import com.android.internal.telephony.subscription.SubscriptionManagerService;
import com.android.telephony.Rlog;
@@ -75,6 +77,10 @@
private final Map<Integer, Boolean> mPhoneStatusMap;
private MockableInterface mMi = new MockableInterface();
private TelephonyManager mTelephonyManager;
+
+ /** Feature flags */
+ @NonNull
+ private final FeatureFlags mFeatureFlags;
/**
* True if 'Virtual DSDA' i.e., in-call IMS connectivity on both subs with only single logical
* modem, is enabled.
@@ -88,10 +94,11 @@
* Init method to instantiate the object
* Should only be called once.
*/
- public static PhoneConfigurationManager init(Context context) {
+ public static PhoneConfigurationManager init(Context context,
+ @NonNull FeatureFlags featureFlags) {
synchronized (PhoneConfigurationManager.class) {
if (sInstance == null) {
- sInstance = new PhoneConfigurationManager(context);
+ sInstance = new PhoneConfigurationManager(context, featureFlags);
} else {
Log.wtf(LOG_TAG, "init() called multiple times! sInstance = " + sInstance);
}
@@ -103,8 +110,9 @@
* Constructor.
* @param context context needed to send broadcast.
*/
- private PhoneConfigurationManager(Context context) {
+ private PhoneConfigurationManager(Context context, @NonNull FeatureFlags featureFlags) {
mContext = context;
+ mFeatureFlags = featureFlags;
// TODO: send commands to modem once interface is ready.
mTelephonyManager = (TelephonyManager) context.getSystemService(Context.TELEPHONY_SERVICE);
//initialize with default, it'll get updated when RADIO is ON/AVAILABLE
@@ -360,7 +368,7 @@
}
private void notifyCapabilityChanged() {
- PhoneNotifier notifier = new DefaultPhoneNotifier(mContext);
+ PhoneNotifier notifier = new DefaultPhoneNotifier(mContext, mFeatureFlags);
notifier.notifyPhoneCapabilityChanged(mStaticCapability);
}
diff --git a/src/java/com/android/internal/telephony/PhoneFactory.java b/src/java/com/android/internal/telephony/PhoneFactory.java
index 625a937..0cbc035 100644
--- a/src/java/com/android/internal/telephony/PhoneFactory.java
+++ b/src/java/com/android/internal/telephony/PhoneFactory.java
@@ -163,7 +163,7 @@
// register statsd pullers.
sMetricsCollector = new MetricsCollector(context);
- sPhoneNotifier = new DefaultPhoneNotifier(context);
+ sPhoneNotifier = new DefaultPhoneNotifier(context, featureFlags);
int cdmaSubscription = CdmaSubscriptionSourceManager.getDefault(context);
Rlog.i(LOG_TAG, "Cdma Subscription set to " + cdmaSubscription);
@@ -256,7 +256,7 @@
Rlog.i(LOG_TAG, "IMS is not supported on this device, skipping ImsResolver.");
}
- sPhoneConfigurationManager = PhoneConfigurationManager.init(sContext);
+ sPhoneConfigurationManager = PhoneConfigurationManager.init(sContext, featureFlags);
sCellularNetworkValidator = CellularNetworkValidator.make(sContext);
@@ -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 7ed7dcb..e608e4d 100644
--- a/src/java/com/android/internal/telephony/RIL.java
+++ b/src/java/com/android/internal/telephony/RIL.java
@@ -1179,7 +1179,8 @@
private void addRequest(RILRequest rr) {
acquireWakeLock(rr, FOR_WAKELOCK);
Trace.asyncTraceForTrackBegin(
- Trace.TRACE_TAG_NETWORK, "RIL", RILUtils.requestToString(rr.mRequest), rr.mSerial);
+ Trace.TRACE_TAG_NETWORK, "RIL", rr.mSerial + "> "
+ + RILUtils.requestToString(rr.mRequest), rr.mSerial);
synchronized (mRequestList) {
rr.mStartTimeMs = SystemClock.elapsedRealtime();
mRequestList.append(rr.mSerial, rr);
@@ -5086,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)) {
@@ -5102,9 +5103,12 @@
}
radioServiceInvokeHelper(
- HAL_SERVICE_NETWORK, rr, "setCellularIdentifierDisclosedEnabled", () -> {
- networkProxy.setCellularIdentifierTransparencyEnabled(rr.mSerial, enable);
- });
+ HAL_SERVICE_NETWORK,
+ rr,
+ "setCellularIdentifierTransparencyEnabled",
+ () -> {
+ networkProxy.setCellularIdentifierTransparencyEnabled(rr.mSerial, enable);
+ });
}
/**
@@ -5114,7 +5118,7 @@
public void isCellularIdentifierTransparencyEnabled(Message result) {
RadioNetworkProxy networkProxy = getRadioServiceProxy(RadioNetworkProxy.class);
if (!canMakeRequest(
- "isCellularIdentifierDisclosedEnabled",
+ "isCellularIdentifierTransparencyEnabled",
networkProxy,
result,
RADIO_HAL_VERSION_2_2)) {
@@ -5129,9 +5133,12 @@
}
radioServiceInvokeHelper(
- HAL_SERVICE_NETWORK, rr, "isCellularIdentifierDisclosedEnabled", () -> {
- networkProxy.isCellularIdentifierTransparencyEnabled(rr.mSerial);
- });
+ HAL_SERVICE_NETWORK,
+ rr,
+ "isCellularIdentifierTransparencyEnabled",
+ () -> {
+ networkProxy.isCellularIdentifierTransparencyEnabled(rr.mSerial);
+ });
}
/**
@@ -5404,14 +5411,22 @@
private void processResponseDoneInternal(RILRequest rr, int rilError, int responseType,
Object ret) {
if (rilError == 0) {
- if (RILJ_LOGD) {
- riljLog(rr.serialString() + "< " + RILUtils.requestToString(rr.mRequest)
- + " " + retToString(rr.mRequest, ret));
+ if (isLogOrTrace()) {
+ String logStr = rr.serialString() + "< " + RILUtils.requestToString(rr.mRequest)
+ + " " + retToString(rr.mRequest, ret);
+ if (RILJ_LOGD) {
+ riljLog(logStr);
+ }
+ Trace.instantForTrack(Trace.TRACE_TAG_NETWORK, "RIL", logStr);
}
} else {
- if (RILJ_LOGD) {
- riljLog(rr.serialString() + "< " + RILUtils.requestToString(rr.mRequest)
- + " error " + rilError);
+ if (isLogOrTrace()) {
+ String logStr = rr.serialString() + "< " + RILUtils.requestToString(rr.mRequest)
+ + " error " + rilError;
+ if (RILJ_LOGD) {
+ riljLog(logStr);
+ }
+ Trace.instantForTrack(Trace.TRACE_TAG_NETWORK, "RIL", logStr);
}
rr.onError(rilError, ret);
}
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/ServiceStateTracker.java b/src/java/com/android/internal/telephony/ServiceStateTracker.java
index 01d6e4c..d19e4cb 100644
--- a/src/java/com/android/internal/telephony/ServiceStateTracker.java
+++ b/src/java/com/android/internal/telephony/ServiceStateTracker.java
@@ -94,6 +94,8 @@
import com.android.internal.telephony.data.AccessNetworksManager.AccessNetworksManagerCallback;
import com.android.internal.telephony.data.DataNetwork;
import com.android.internal.telephony.data.DataNetworkController.DataNetworkControllerCallback;
+import com.android.internal.telephony.domainselection.DomainSelectionResolver;
+import com.android.internal.telephony.emergency.EmergencyStateTracker;
import com.android.internal.telephony.flags.FeatureFlags;
import com.android.internal.telephony.imsphone.ImsPhone;
import com.android.internal.telephony.metrics.RadioPowerStateStats;
@@ -4969,6 +4971,9 @@
public void powerOffRadioSafely() {
synchronized (this) {
SatelliteController.getInstance().onCellularRadioPowerOffRequested();
+ if (DomainSelectionResolver.getInstance().isDomainSelectionSupported()) {
+ EmergencyStateTracker.getInstance().onCellularRadioPowerOffRequested();
+ }
if (!mPendingRadioPowerOffAfterDataOff) {
// hang up all active voice calls first
if (mPhone.isPhoneTypeGsm() && mPhone.isInCall()) {
diff --git a/src/java/com/android/internal/telephony/SignalStrengthController.java b/src/java/com/android/internal/telephony/SignalStrengthController.java
index 383ffcd..387c501 100644
--- a/src/java/com/android/internal/telephony/SignalStrengthController.java
+++ b/src/java/com/android/internal/telephony/SignalStrengthController.java
@@ -353,7 +353,7 @@
List<SubscriptionInfo> subInfoList = SubscriptionManagerService.getInstance()
.getActiveSubscriptionInfoList(mPhone.getContext().getOpPackageName(),
- mPhone.getContext().getAttributionTag());
+ mPhone.getContext().getAttributionTag(), true/*isForAllProfile*/);
if (!ArrayUtils.isEmpty(subInfoList)) {
for (SubscriptionInfo info : subInfoList) {
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/DataNetwork.java b/src/java/com/android/internal/telephony/data/DataNetwork.java
index 48a18ee..bba0f19 100644
--- a/src/java/com/android/internal/telephony/data/DataNetwork.java
+++ b/src/java/com/android/internal/telephony/data/DataNetwork.java
@@ -406,6 +406,10 @@
/** Data network tear down due to preferred data switched to another phone. */
public static final int TEAR_DOWN_REASON_PREFERRED_DATA_SWITCHED = 30;
+ //********************************************************************************************//
+ // WHENEVER ADD A NEW TEAR DOWN REASON, PLEASE UPDATE DataDeactivateReasonEnum in enums.proto //
+ //********************************************************************************************//
+
@IntDef(prefix = {"BANDWIDTH_SOURCE_"},
value = {
BANDWIDTH_SOURCE_UNKNOWN,
diff --git a/src/java/com/android/internal/telephony/data/DataProfileManager.java b/src/java/com/android/internal/telephony/data/DataProfileManager.java
index df1fc92..b4055a3 100644
--- a/src/java/com/android/internal/telephony/data/DataProfileManager.java
+++ b/src/java/com/android/internal/telephony/data/DataProfileManager.java
@@ -419,18 +419,36 @@
* @param internetNetworks The connected internet data networks.
*/
private void onInternetDataNetworkConnected(@NonNull Set<DataNetwork> internetNetworks) {
- // Most of the cases there should be only one.
- // but in case there are multiple, find the default internet network, and choose the
- // one which has longest life cycle.
- DataProfile defaultProfile = internetNetworks.stream()
- .filter(network -> mPreferredDataProfile == null
- // Find the one most resembles the current preferred profile,
- // avoiding e.g. DUN default network.
- || canPreferredDataProfileSatisfy(
- network.getAttachedNetworkRequestList()))
- .map(DataNetwork::getDataProfile)
- .min(Comparator.comparingLong(DataProfile::getLastSetupTimestamp))
- .orElse(null);
+ DataProfile defaultProfile = null;
+ if (mFeatureFlags.refinePreferredDataProfileSelection()) {
+ // Most of the cases there should be only one.
+ // but in case there are multiple, find the default internet network, and choose the
+ // one which has longest life cycle.
+ defaultProfile = internetNetworks.stream()
+ .filter(network -> mPreferredDataProfile == null
+ // Find the one most resembles the current preferred profile,
+ // avoiding e.g. DUN default network.
+ || canPreferredDataProfileSatisfy(
+ network.getAttachedNetworkRequestList()))
+ .map(DataNetwork::getDataProfile)
+ .min(Comparator.comparingLong(DataProfile::getLastSetupTimestamp))
+ .orElse(null);
+ } else {
+ if (internetNetworks.size() == 1) {
+ // Most of the cases there should be only one.
+ defaultProfile = internetNetworks.stream().findFirst().get().getDataProfile();
+ } else if (internetNetworks.size() > 1) {
+ // but in case there are multiple, find the default internet network, and choose the
+ // one which has longest life cycle.
+ defaultProfile = internetNetworks.stream()
+ .filter(network -> mPreferredDataProfile == null
+ || canPreferredDataProfileSatisfy(
+ network.getAttachedNetworkRequestList()))
+ .map(DataNetwork::getDataProfile)
+ .min(Comparator.comparingLong(DataProfile::getLastSetupTimestamp))
+ .orElse(null);
+ }
+ }
// Update a working internet data profile as a future candidate for preferred data profile
// after APNs are reset to default
diff --git a/src/java/com/android/internal/telephony/data/DataRetryManager.java b/src/java/com/android/internal/telephony/data/DataRetryManager.java
index 754400e..5933463 100644
--- a/src/java/com/android/internal/telephony/data/DataRetryManager.java
+++ b/src/java/com/android/internal/telephony/data/DataRetryManager.java
@@ -22,6 +22,11 @@
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.app.AlarmManager;
+import android.app.PendingIntent;
+import android.content.BroadcastReceiver;
+import android.content.Context;
+import android.content.Intent;
+import android.content.IntentFilter;
import android.net.NetworkCapabilities;
import android.os.AsyncResult;
import android.os.Handler;
@@ -74,6 +79,11 @@
public class DataRetryManager extends Handler {
private static final boolean VDBG = false;
+ /** Intent of Alarm Manager for long retry timer. */
+ private static final String ACTION_RETRY = "com.android.internal.telephony.data.ACTION_RETRY";
+ /** The extra key for the hashcode of the retry entry for Alarm Manager. */
+ private static final String ACTION_RETRY_EXTRA_HASHCODE = "extra_retry_hashcode";
+
/** Event for data setup retry. */
private static final int EVENT_DATA_SETUP_RETRY = 3;
@@ -1014,6 +1024,22 @@
mRil.registerForOn(this, EVENT_RADIO_ON, null);
mRil.registerForModemReset(this, EVENT_MODEM_RESET, null);
+ if (!mFlags.useAlarmCallback()) {
+ // Register intent of alarm manager for long retry timer
+ IntentFilter intentFilter = new IntentFilter();
+ intentFilter.addAction(ACTION_RETRY);
+ mPhone.getContext().registerReceiver(new BroadcastReceiver() {
+ @Override
+ public void onReceive(Context context, Intent intent) {
+ if (ACTION_RETRY.equals(intent.getAction())) {
+ DataRetryManager.this.onAlarmIntentRetry(
+ intent.getIntExtra(ACTION_RETRY_EXTRA_HASHCODE,
+ -1 /*Bad hashcode*/));
+ }
+ }
+ }, intentFilter);
+ }
+
if (mDataConfigManager.shouldResetDataThrottlingWhenTacChanges()) {
mPhone.getServiceStateTracker().registerForAreaCodeChanged(this, EVENT_TAC_CHANGED,
null);
@@ -1449,19 +1475,48 @@
? EVENT_DATA_SETUP_RETRY : EVENT_DATA_HANDOVER_RETRY, dataRetryEntry),
dataRetryEntry.retryDelayMillis);
} else {
- // No need to wake up the device, the retry can wait util next time the device wake up
- // to save power.
- mAlarmManager.setExactAndAllowWhileIdle(AlarmManager.ELAPSED_REALTIME,
- dataRetryEntry.retryElapsedTime,
- "dataRetryHash-" + dataRetryEntry.hashCode() /*debug tag*/,
- Runnable::run,
- null /*worksource*/,
- () -> {
- logl("onAlarm retry " + dataRetryEntry);
- sendMessage(obtainMessage(dataRetryEntry instanceof DataSetupRetryEntry
- ? EVENT_DATA_SETUP_RETRY : EVENT_DATA_HANDOVER_RETRY,
- dataRetryEntry));
- });
+ if (mFlags.useAlarmCallback()) {
+ // No need to wake up the device, the retry can wait util next time the device wake
+ // up to save power.
+ mAlarmManager.setExactAndAllowWhileIdle(AlarmManager.ELAPSED_REALTIME,
+ dataRetryEntry.retryElapsedTime,
+ "dataRetryHash-" + dataRetryEntry.hashCode() /*debug tag*/,
+ Runnable::run,
+ null /*worksource*/,
+ () -> {
+ logl("onAlarm retry " + dataRetryEntry);
+ sendMessage(obtainMessage(dataRetryEntry instanceof DataSetupRetryEntry
+ ? EVENT_DATA_SETUP_RETRY : EVENT_DATA_HANDOVER_RETRY,
+ dataRetryEntry));
+ });
+ } else {
+ Intent intent = new Intent(ACTION_RETRY);
+ intent.putExtra(ACTION_RETRY_EXTRA_HASHCODE, dataRetryEntry.hashCode());
+ // No need to wake up the device, the retry can wait util next time the device wake
+ // up to save power.
+ mAlarmManager.setAndAllowWhileIdle(AlarmManager.ELAPSED_REALTIME,
+ dataRetryEntry.retryElapsedTime,
+ PendingIntent.getBroadcast(mPhone.getContext(),
+ dataRetryEntry.hashCode()/*Unique identifier of the retry attempt*/,
+ intent,
+ PendingIntent.FLAG_IMMUTABLE));
+ }
+ }
+ }
+
+ /**
+ * Called when it's time to retry scheduled by Alarm Manager.
+ * @param retryHashcode The hashcode is the unique identifier of which retry entry to retry.
+ */
+ private void onAlarmIntentRetry(int retryHashcode) {
+ DataRetryEntry dataRetryEntry = mDataRetryEntries.stream()
+ .filter(entry -> entry.hashCode() == retryHashcode)
+ .findAny()
+ .orElse(null);
+ logl("onAlarmIntentRetry: found " + dataRetryEntry + " with hashcode " + retryHashcode);
+ if (dataRetryEntry != null) {
+ sendMessage(obtainMessage(dataRetryEntry instanceof DataSetupRetryEntry
+ ? EVENT_DATA_SETUP_RETRY : EVENT_DATA_HANDOVER_RETRY, dataRetryEntry));
}
}
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/domainselection/OWNERS b/src/java/com/android/internal/telephony/domainselection/OWNERS
new file mode 100644
index 0000000..b9112be
--- /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/emergency/EmergencyStateTracker.java b/src/java/com/android/internal/telephony/emergency/EmergencyStateTracker.java
index 3023501..0692f7d 100644
--- a/src/java/com/android/internal/telephony/emergency/EmergencyStateTracker.java
+++ b/src/java/com/android/internal/telephony/emergency/EmergencyStateTracker.java
@@ -892,6 +892,18 @@
}
}
+ /**
+ * Handles the radio power off request.
+ */
+ public void onCellularRadioPowerOffRequested() {
+ synchronized (mLock) {
+ if (isInEcm()) {
+ exitEmergencyCallbackMode(null);
+ }
+ exitEmergencyModeIfDelayed();
+ }
+ }
+
private static boolean isVoWiFi(int properties) {
return (properties & android.telecom.Connection.PROPERTY_WIFI) > 0
|| (properties & android.telecom.Connection.PROPERTY_CROSS_SIM) > 0;
diff --git a/src/java/com/android/internal/telephony/imsphone/ImsPhone.java b/src/java/com/android/internal/telephony/imsphone/ImsPhone.java
index 1ee8447..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;
@@ -2481,7 +2483,7 @@
setServiceState(ServiceState.STATE_IN_SERVICE);
getDefaultPhone().setImsRegistrationState(true);
mMetrics.writeOnImsConnectionState(mPhoneId, ImsConnectionState.State.CONNECTED, null);
- mImsStats.onImsRegistered(imsRadioTech);
+ mImsStats.onImsRegistered(attributes);
mImsNrSaModeHandler.onImsRegistered(
attributes.getRegistrationTechnology(), attributes.getFeatureTags());
updateImsRegistrationInfo(REGISTRATION_STATE_REGISTERED,
@@ -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/metrics/ImsStats.java b/src/java/com/android/internal/telephony/metrics/ImsStats.java
index 2420602..04c9677 100644
--- a/src/java/com/android/internal/telephony/metrics/ImsStats.java
+++ b/src/java/com/android/internal/telephony/metrics/ImsStats.java
@@ -23,6 +23,7 @@
import static android.telephony.ims.feature.MmTelFeature.MmTelCapabilities.CAPABILITY_TYPE_UT;
import static android.telephony.ims.feature.MmTelFeature.MmTelCapabilities.CAPABILITY_TYPE_VIDEO;
import static android.telephony.ims.feature.MmTelFeature.MmTelCapabilities.CAPABILITY_TYPE_VOICE;
+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 android.telephony.ims.stub.ImsRegistrationImplBase.REGISTRATION_TECH_NONE;
@@ -39,6 +40,7 @@
import android.telephony.ServiceState;
import android.telephony.TelephonyManager;
import android.telephony.ims.ImsReasonInfo;
+import android.telephony.ims.ImsRegistrationAttributes;
import android.telephony.ims.ProvisioningManager;
import android.telephony.ims.RegistrationManager.ImsRegistrationState;
import android.telephony.ims.feature.MmTelFeature.MmTelCapabilities;
@@ -231,6 +233,12 @@
} else {
ImsRegistrationStats stats = copyOfDimensionsOnly(mLastRegistrationStats);
+ if (stats.rat == TelephonyManager.NETWORK_TYPE_UNKNOWN) {
+ logw("conclude: discarding UNKNOWN RAT, duration=%d", duration);
+ mLastTimestamp = now;
+ return;
+ }
+
switch (mLastRegistrationState) {
case REGISTRATION_STATE_REGISTERED:
stats.registeredMillis = duration;
@@ -285,6 +293,7 @@
mLastRegistrationStats.rat = newRat;
ratChanged = true;
}
+ mLastRegistrationStats.isIwlanCrossSim = radioTech == REGISTRATION_TECH_CROSS_SIM;
boolean voiceAvailableNow = capabilities.isCapable(CAPABILITY_TYPE_VOICE);
boolean voiceAvailabilityChanged =
@@ -324,15 +333,18 @@
}
/** Updates the stats when IMS registration succeeds. */
- public synchronized void onImsRegistered(@TransportType int imsRadioTech) {
+ public synchronized void onImsRegistered(ImsRegistrationAttributes attributes) {
conclude();
- mLastTransportType = imsRadioTech;
+ mLastTransportType = attributes.getTransportType();
// NOTE: status can be unregistered (no registering phase)
if (mLastRegistrationState == REGISTRATION_STATE_NOT_REGISTERED) {
updateImsRegistrationStats();
}
- mLastRegistrationStats.rat = convertTransportTypeToNetworkType(imsRadioTech);
+ mLastRegistrationStats.rat =
+ convertTransportTypeToNetworkType(attributes.getTransportType());
+ mLastRegistrationStats.isIwlanCrossSim = attributes.getRegistrationTechnology()
+ == REGISTRATION_TECH_CROSS_SIM;
mLastRegistrationState = REGISTRATION_STATE_REGISTERED;
}
@@ -344,6 +356,8 @@
ImsRegistrationTermination termination = new ImsRegistrationTermination();
if (mLastRegistrationState != REGISTRATION_STATE_NOT_REGISTERED) {
termination.carrierId = mLastRegistrationStats.carrierId;
+ termination.ratAtEnd = getRatAtEnd(mLastRegistrationStats.rat);
+ termination.isIwlanCrossSim = mLastRegistrationStats.isIwlanCrossSim;
} else {
// if the registration state is from unregistered to unregistered.
termination.carrierId = mPhone.getDefaultPhone().getCarrierId();
@@ -359,16 +373,20 @@
// Reset state to unregistered.
mLastRegistrationState = REGISTRATION_STATE_NOT_REGISTERED;
- mLastRegistrationStats.rat = TelephonyManager.NETWORK_TYPE_UNKNOWN;
mLastAvailableFeatures = new MmTelCapabilities();
}
/** Updates the RAT when service state changes. */
public synchronized void onServiceStateChanged(ServiceState state) {
- if (mLastTransportType == AccessNetworkConstants.TRANSPORT_TYPE_WWAN
- && mLastRegistrationState != REGISTRATION_STATE_NOT_REGISTERED) {
- mLastRegistrationStats.rat =
- ServiceStateStats.getRat(state, NetworkRegistrationInfo.DOMAIN_PS);
+ conclude();
+
+ @NetworkType int newRat = state.getDataNetworkType();
+ MmTelCapabilities lastCapableFeatures = getLastCapableFeaturesForNetworkType(newRat);
+
+ if (lastCapableFeatures != null) {
+ mLastRegistrationStats.rat = newRat;
+ } else {
+ mLastRegistrationStats.rat = TelephonyManager.NETWORK_TYPE_UNKNOWN;
}
}
@@ -428,6 +446,19 @@
case REGISTRATION_TECH_NONE:
return null;
case REGISTRATION_TECH_IWLAN:
+ case REGISTRATION_TECH_CROSS_SIM:
+ return mLastWlanCapableFeatures;
+ default:
+ return mLastWwanCapableFeatures;
+ }
+ }
+
+ @Nullable
+ private MmTelCapabilities getLastCapableFeaturesForNetworkType(@NetworkType int netType) {
+ switch (netType) {
+ case TelephonyManager.NETWORK_TYPE_UNKNOWN:
+ return null;
+ case TelephonyManager.NETWORK_TYPE_IWLAN:
return mLastWlanCapableFeatures;
default:
return mLastWwanCapableFeatures;
@@ -442,6 +473,7 @@
case REGISTRATION_TECH_LTE:
return TelephonyManager.NETWORK_TYPE_LTE;
case REGISTRATION_TECH_IWLAN:
+ case REGISTRATION_TECH_CROSS_SIM:
return TelephonyManager.NETWORK_TYPE_IWLAN;
case REGISTRATION_TECH_NR:
return TelephonyManager.NETWORK_TYPE_NR;
@@ -457,6 +489,7 @@
dest.carrierId = source.carrierId;
dest.simSlotIndex = source.simSlotIndex;
dest.rat = source.rat;
+ dest.isIwlanCrossSim = source.isIwlanCrossSim;
return dest;
}
diff --git a/src/java/com/android/internal/telephony/metrics/MetricsCollector.java b/src/java/com/android/internal/telephony/metrics/MetricsCollector.java
index 8c1aae3..e27d14b 100644
--- a/src/java/com/android/internal/telephony/metrics/MetricsCollector.java
+++ b/src/java/com/android/internal/telephony/metrics/MetricsCollector.java
@@ -53,6 +53,7 @@
import static com.android.internal.telephony.TelephonyStatsLog.VOICE_CALL_RAT_USAGE;
import static com.android.internal.telephony.TelephonyStatsLog.VOICE_CALL_SESSION;
import static com.android.internal.telephony.TelephonyStatsLog.VOICE_CALL_SESSION__CALL_DURATION__CALL_DURATION_UNKNOWN;
+import static com.android.internal.telephony.util.TelephonyUtils.IS_DEBUGGABLE;
import android.app.StatsManager;
import android.content.Context;
@@ -136,16 +137,33 @@
DBG ? 10L * MILLIS_PER_SECOND : 23L * MILLIS_PER_HOUR;
/**
+ * Sets atom pull cool down to 4 minutes for userdebug build.
+ *
+ * <p>Applies to certain atoms: CellularServiceState.
+ */
+ private static final long CELL_SERVICE_MIN_COOLDOWN_MILLIS =
+ DBG ? 10L * MILLIS_PER_SECOND :
+ IS_DEBUGGABLE ? 4L * MILLIS_PER_MINUTE : 23L * MILLIS_PER_HOUR;
+
+ /**
* Buckets with less than these many calls will be dropped.
*
* <p>Applies to metrics with duration fields. Currently used by voice call RAT usages.
*/
private static final long MIN_CALLS_PER_BUCKET = DBG ? 0L : 5L;
- /** Bucket size in milliseconds to round call durations into. */
+ /** Bucket size in milliseconds to round call durations info. */
private static final long DURATION_BUCKET_MILLIS =
DBG ? 2L * MILLIS_PER_SECOND : 5L * MILLIS_PER_MINUTE;
+ /**
+ * Sets smaller bucket size to round call durations for userdebug build.
+ *
+ * <p>Applies to certain atoms: CellularServiceState.
+ */
+ private static final long CELL_SERVICE_DURATION_BUCKET_MILLIS =
+ DBG || IS_DEBUGGABLE ? 2L * MILLIS_PER_SECOND : 5L * MILLIS_PER_MINUTE;
+
private final PersistAtomsStorage mStorage;
private final DeviceStateHelper mDeviceStateHelper;
private final StatsManager mStatsManager;
@@ -510,7 +528,7 @@
// Include the latest durations
concludeServiceStateStats();
CellularServiceState[] persistAtoms =
- mStorage.getCellularServiceStates(MIN_COOLDOWN_MILLIS);
+ mStorage.getCellularServiceStates(CELL_SERVICE_MIN_COOLDOWN_MILLIS);
if (persistAtoms != null) {
// list is already shuffled when instances were inserted
Arrays.stream(persistAtoms)
@@ -786,7 +804,8 @@
perSimStatus.minimumVoltageClass, // simVoltageClass
perSimStatus.userModifiedApnTypes, // userModifiedApnTypeBitmask
perSimStatus.unmeteredNetworks, // unmeteredNetworks
- perSimStatus.vonrEnabled); // vonrEnabled
+ perSimStatus.vonrEnabled, // vonrEnabled
+ perSimStatus.crossSimCallingEnabled); // crossSimCallingEnabled
data.add(statsEvent);
result = StatsManager.PULL_SUCCESS;
}
@@ -929,12 +948,14 @@
state.simSlotIndex,
state.isMultiSim,
state.carrierId,
- roundAndConvertMillisToSeconds(state.totalTimeMillis),
+ roundAndConvertMillisToSeconds(state.totalTimeMillis,
+ CELL_SERVICE_DURATION_BUCKET_MILLIS),
state.isEmergencyOnly,
state.isInternetPdnUp,
state.foldState,
state.overrideVoiceService,
- state.isDataEnabled);
+ state.isDataEnabled,
+ state.isIwlanCrossSim);
}
private static StatsEvent buildStatsEvent(VoiceCallRatUsage usage) {
@@ -988,7 +1009,10 @@
session.lastKnownRat,
session.foldState,
session.ratSwitchCountAfterConnected,
- session.handoverInProgress);
+ session.handoverInProgress,
+ session.isIwlanCrossSimAtStart,
+ session.isIwlanCrossSimAtEnd,
+ session.isIwlanCrossSimAtConnected);
}
private static StatsEvent buildStatsEvent(IncomingSms sms) {
@@ -1060,7 +1084,8 @@
dataCallSession.bandAtEnd,
dataCallSession.handoverFailureCauses,
dataCallSession.handoverFailureRat,
- dataCallSession.isNonDds);
+ dataCallSession.isNonDds,
+ dataCallSession.isIwlanCrossSim);
}
private static StatsEvent buildStatsEvent(ImsRegistrationStats stats) {
@@ -1079,7 +1104,8 @@
roundAndConvertMillisToSeconds(stats.utCapableMillis),
roundAndConvertMillisToSeconds(stats.utAvailableMillis),
roundAndConvertMillisToSeconds(stats.registeringMillis),
- roundAndConvertMillisToSeconds(stats.unregisteredMillis));
+ roundAndConvertMillisToSeconds(stats.unregisteredMillis),
+ stats.isIwlanCrossSim);
}
private static StatsEvent buildStatsEvent(ImsRegistrationTermination termination) {
@@ -1092,7 +1118,8 @@
termination.reasonCode,
termination.extraCode,
termination.extraMessage,
- termination.count);
+ termination.count,
+ termination.isIwlanCrossSim);
}
private static StatsEvent buildStatsEvent(NetworkRequestsV2 networkRequests) {
@@ -1356,8 +1383,15 @@
* Rounds the duration and converts it from milliseconds to seconds.
*/
private static int roundAndConvertMillisToSeconds(long valueMillis) {
- long roundedValueMillis = Math.round((double) valueMillis / DURATION_BUCKET_MILLIS)
- * DURATION_BUCKET_MILLIS;
+ return roundAndConvertMillisToSeconds(valueMillis, DURATION_BUCKET_MILLIS);
+ }
+
+ /**
+ * Rounds the duration and converts it from milliseconds to seconds.
+ */
+ private static int roundAndConvertMillisToSeconds(long valueMillis, long durationBucketSize) {
+ long roundedValueMillis = Math.round((double) valueMillis / durationBucketSize)
+ * durationBucketSize;
return (int) (roundedValueMillis / MILLIS_PER_SECOND);
}
diff --git a/src/java/com/android/internal/telephony/metrics/PerSimStatus.java b/src/java/com/android/internal/telephony/metrics/PerSimStatus.java
index bc1edc3..a8c7421 100644
--- a/src/java/com/android/internal/telephony/metrics/PerSimStatus.java
+++ b/src/java/com/android/internal/telephony/metrics/PerSimStatus.java
@@ -32,6 +32,7 @@
import android.database.Cursor;
import android.net.Uri;
import android.provider.Telephony;
+import android.telephony.AnomalyReporter;
import android.telephony.SubscriptionManager;
import android.telephony.TelephonyManager;
import android.telephony.data.ApnSetting;
@@ -46,9 +47,14 @@
import com.android.internal.telephony.subscription.SubscriptionManagerService;
import com.android.internal.telephony.uicc.UiccController;
import com.android.internal.telephony.uicc.UiccSlot;
+import com.android.telephony.Rlog;
+
+import java.util.UUID;
/** Stores the per SIM status. */
public class PerSimStatus {
+ private static final String TAG = "PerSimStatus";
+
private static final long BITMASK_2G =
TelephonyManager.NETWORK_TYPE_BITMASK_GSM
| TelephonyManager.NETWORK_TYPE_BITMASK_GPRS
@@ -56,6 +62,9 @@
| TelephonyManager.NETWORK_TYPE_BITMASK_CDMA
| TelephonyManager.NETWORK_TYPE_BITMASK_1xRTT;
+ private static final UUID CROSS_SIM_CALLING_STATUS_ANOMALY_UUID =
+ UUID.fromString("377e1a33-d4ac-4039-9cc0-f0d8396757f3");
+
public final int carrierId;
public final int phoneNumberSourceUicc;
public final int phoneNumberSourceCarrier;
@@ -74,6 +83,8 @@
public final long unmeteredNetworks;
public final boolean vonrEnabled;
+ public final boolean crossSimCallingEnabled;
+
/** Returns the current sim status of the given {@link Phone}. */
@Nullable
public static PerSimStatus getCurrentState(Phone phone) {
@@ -105,7 +116,8 @@
getMinimumVoltageClass(phone),
getUserModifiedApnTypes(phone),
persistAtomsStorage.getUnmeteredNetworks(phone.getPhoneId(), carrierId),
- isVonrEnabled(phone));
+ isVonrEnabled(phone),
+ isCrossSimCallingEnabled(imsMmTelManager));
}
private PerSimStatus(
@@ -125,7 +137,8 @@
int minimumVoltageClass,
int userModifiedApnTypes,
long unmeteredNetworks,
- boolean vonrEnabled) {
+ boolean vonrEnabled,
+ boolean crossSimCallingEnabled) {
this.carrierId = carrierId;
this.phoneNumberSourceUicc = phoneNumberSourceUicc;
this.phoneNumberSourceCarrier = phoneNumberSourceCarrier;
@@ -143,6 +156,18 @@
this.userModifiedApnTypes = userModifiedApnTypes;
this.unmeteredNetworks = unmeteredNetworks;
this.vonrEnabled = vonrEnabled;
+ this.crossSimCallingEnabled = crossSimCallingEnabled;
+ }
+
+ private static boolean isCrossSimCallingEnabled(ImsMmTelManager imsMmTelManager) {
+ try {
+ return imsMmTelManager != null && imsMmTelManager.isCrossSimCallingEnabled();
+ } catch (Exception e) {
+ AnomalyReporter.reportAnomaly(CROSS_SIM_CALLING_STATUS_ANOMALY_UUID,
+ "Failed to query ImsMmTelManager for cross-SIM calling status!");
+ Rlog.e(TAG, e.getMessage());
+ }
+ return false;
}
@Nullable
diff --git a/src/java/com/android/internal/telephony/metrics/PersistAtomsStorage.java b/src/java/com/android/internal/telephony/metrics/PersistAtomsStorage.java
index d5d041a..101df0d 100644
--- a/src/java/com/android/internal/telephony/metrics/PersistAtomsStorage.java
+++ b/src/java/com/android/internal/telephony/metrics/PersistAtomsStorage.java
@@ -1713,7 +1713,8 @@
&& state.isInternetPdnUp == key.isInternetPdnUp
&& state.foldState == key.foldState
&& state.overrideVoiceService == key.overrideVoiceService
- && state.isDataEnabled == key.isDataEnabled) {
+ && state.isDataEnabled == key.isDataEnabled
+ && state.isIwlanCrossSim == key.isIwlanCrossSim) {
return state;
}
}
@@ -1761,7 +1762,8 @@
for (ImsRegistrationStats stats : mAtoms.imsRegistrationStats) {
if (stats.carrierId == key.carrierId
&& stats.simSlotIndex == key.simSlotIndex
- && stats.rat == key.rat) {
+ && stats.rat == key.rat
+ && stats.isIwlanCrossSim == key.isIwlanCrossSim) {
return stats;
}
}
@@ -1777,6 +1779,7 @@
if (termination.carrierId == key.carrierId
&& termination.isMultiSim == key.isMultiSim
&& termination.ratAtEnd == key.ratAtEnd
+ && termination.isIwlanCrossSim == key.isIwlanCrossSim
&& termination.setupFailed == key.setupFailed
&& termination.reasonCode == key.reasonCode
&& termination.extraCode == key.extraCode
diff --git a/src/java/com/android/internal/telephony/metrics/ServiceStateStats.java b/src/java/com/android/internal/telephony/metrics/ServiceStateStats.java
index 14ce2cc..d400c22 100644
--- a/src/java/com/android/internal/telephony/metrics/ServiceStateStats.java
+++ b/src/java/com/android/internal/telephony/metrics/ServiceStateStats.java
@@ -32,6 +32,7 @@
import android.telephony.ServiceState;
import android.telephony.ServiceState.RoamingType;
import android.telephony.TelephonyManager;
+import android.telephony.ims.stub.ImsRegistrationImplBase;
import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.telephony.Phone;
@@ -89,6 +90,7 @@
CellularServiceState newServiceState = copyOf(state.mServiceState);
newServiceState.voiceRat =
getVoiceRat(mPhone, getServiceStateForPhone(mPhone));
+ newServiceState.isIwlanCrossSim = isCrossSimCallingRegistered(mPhone);
return new TimestampedServiceState(newServiceState, now);
});
addServiceState(lastState, now);
@@ -132,6 +134,7 @@
newState.foldState = mDeviceStateHelper.getFoldState();
newState.overrideVoiceService = mOverrideVoiceService.get();
newState.isDataEnabled = mPhone.getDataSettingsManager().isDataEnabled();
+ newState.isIwlanCrossSim = isCrossSimCallingRegistered(mPhone);
TimestampedServiceState prevState =
mLastState.getAndSet(new TimestampedServiceState(newState, now));
addServiceStateAndSwitch(
@@ -302,6 +305,7 @@
copy.foldState = state.foldState;
copy.overrideVoiceService = state.overrideVoiceService;
copy.isDataEnabled = state.isDataEnabled;
+ copy.isIwlanCrossSim = state.isIwlanCrossSim;
return copy;
}
@@ -360,6 +364,14 @@
}
}
+ private boolean isCrossSimCallingRegistered(Phone phone) {
+ if (phone.getImsPhone() != null) {
+ return phone.getImsPhone().getImsRegistrationTech()
+ == ImsRegistrationImplBase.REGISTRATION_TECH_CROSS_SIM;
+ }
+ return false;
+ }
+
/** Returns RAT used by WWAN if WWAN is in service. */
public static @NetworkType int getRat(
ServiceState state, @NetworkRegistrationInfo.Domain int domain) {
diff --git a/src/java/com/android/internal/telephony/metrics/VoiceCallSessionStats.java b/src/java/com/android/internal/telephony/metrics/VoiceCallSessionStats.java
index 5de9902..5dbf645 100644
--- a/src/java/com/android/internal/telephony/metrics/VoiceCallSessionStats.java
+++ b/src/java/com/android/internal/telephony/metrics/VoiceCallSessionStats.java
@@ -53,6 +53,7 @@
import android.telephony.data.ApnSetting;
import android.telephony.ims.ImsReasonInfo;
import android.telephony.ims.ImsStreamMediaProfile;
+import android.telephony.ims.stub.ImsRegistrationImplBase;
import android.util.LongSparseArray;
import android.util.SparseArray;
import android.util.SparseIntArray;
@@ -484,6 +485,11 @@
proto.videoEnabled = videoState != VideoProfile.STATE_AUDIO_ONLY ? true : false;
proto.handoverInProgress = isHandoverInProgress(bearer, proto.isEmergency);
+ boolean isCrossSimCall = isCrossSimCall(conn);
+ proto.isIwlanCrossSimAtStart = isCrossSimCall;
+ proto.isIwlanCrossSimAtEnd = isCrossSimCall;
+ proto.isIwlanCrossSimAtConnected = isCrossSimCall;
+
// internal fields for tracking
if (getDirection(conn) == VOICE_CALL_SESSION__DIRECTION__CALL_DIRECTION_MT) {
// MT call setup hasn't begun hence set to 0
@@ -609,7 +615,9 @@
proto.setupFailed = false;
// Track RAT when voice call is connected.
ServiceState serviceState = getServiceState();
- proto.ratAtConnected = getVoiceRatWithVoNRFix(mPhone, serviceState, proto.bearerAtEnd);
+ @NetworkType int rat = getVoiceRatWithVoNRFix(mPhone, serviceState, proto.bearerAtEnd);
+ proto.ratAtConnected = rat;
+ proto.isIwlanCrossSimAtConnected = isCrossSimCall(conn);
// Reset list of codecs with the last codec at the present time. In this way, we
// track codec quality only after call is connected and not while ringing.
resetCodecList(conn);
@@ -646,6 +654,7 @@
proto.lastKnownRat = rat;
}
}
+ proto.isIwlanCrossSimAtEnd = isCrossSimCall(mPhone);
}
private void finishImsCall(int id, ImsReasonInfo reasonInfo, long durationMillis) {
@@ -905,6 +914,21 @@
return conn == null ? 0 : (int) conn.getCreateTime();
}
+ private boolean isCrossSimCall(Connection conn) {
+ if (conn instanceof ImsPhoneConnection) {
+ return ((ImsPhoneConnection) conn).isCrossSimCall();
+ }
+ return false;
+ }
+
+ private boolean isCrossSimCall(Phone phone) {
+ if (phone.getImsPhone() != null) {
+ return phone.getImsPhone().getImsRegistrationTech()
+ == ImsRegistrationImplBase.REGISTRATION_TECH_CROSS_SIM;
+ }
+ return false;
+ }
+
@VisibleForTesting
protected long getTimeMillis() {
return SystemClock.elapsedRealtime();
diff --git a/src/java/com/android/internal/telephony/nitz/TEST_MAPPING b/src/java/com/android/internal/telephony/nitz/TEST_MAPPING
index 2bcb04e..4063803 100644
--- a/src/java/com/android/internal/telephony/nitz/TEST_MAPPING
+++ b/src/java/com/android/internal/telephony/nitz/TEST_MAPPING
@@ -1,6 +1,5 @@
{
- // TODO(b/182461754): Change to "presubmit" when go/test-mapping-slo-guide allows.
- "postsubmit": [
+ "presubmit": [
{
"name": "FrameworksTelephonyTests",
"options": [
diff --git a/src/java/com/android/internal/telephony/satellite/DatagramDispatcher.java b/src/java/com/android/internal/telephony/satellite/DatagramDispatcher.java
index ddd0a69..e4d16e7 100644
--- a/src/java/com/android/internal/telephony/satellite/DatagramDispatcher.java
+++ b/src/java/com/android/internal/telephony/satellite/DatagramDispatcher.java
@@ -344,6 +344,10 @@
SatelliteManager.SATELLITE_DATAGRAM_TRANSFER_STATE_SENDING,
getPendingDatagramCount(), SatelliteManager.SATELLITE_RESULT_SUCCESS);
sendRequestAsync(CMD_SEND_SATELLITE_DATAGRAM, datagramArgs, phone);
+ } else {
+ logd("sendSatelliteDatagram: mSendingDatagramInProgress="
+ + mSendingDatagramInProgress + ", isPollingInIdleState="
+ + mDatagramController.isPollingInIdleState());
}
}
}
diff --git a/src/java/com/android/internal/telephony/satellite/DatagramReceiver.java b/src/java/com/android/internal/telephony/satellite/DatagramReceiver.java
index 695a563..3ac1bbd 100644
--- a/src/java/com/android/internal/telephony/satellite/DatagramReceiver.java
+++ b/src/java/com/android/internal/telephony/satellite/DatagramReceiver.java
@@ -392,6 +392,10 @@
case EVENT_RECEIVED_ACK: {
DatagramRetryArgument argument = (DatagramRetryArgument) msg.obj;
+ if (!sInstance.mPendingAckCountHashMap.containsKey(argument.datagramId)) {
+ logd("The datagram " + argument.datagramId + " should have been deleted.");
+ return;
+ }
int pendingAckCount = sInstance.mPendingAckCountHashMap
.get(argument.datagramId);
pendingAckCount -= 1;
diff --git a/src/java/com/android/internal/telephony/satellite/SatelliteController.java b/src/java/com/android/internal/telephony/satellite/SatelliteController.java
index 00e3189..b29cf26 100644
--- a/src/java/com/android/internal/telephony/satellite/SatelliteController.java
+++ b/src/java/com/android/internal/telephony/satellite/SatelliteController.java
@@ -1735,6 +1735,7 @@
if (!mSatelliteModemInterface.isSatelliteServiceSupported()) {
return SatelliteManager.SATELLITE_RESULT_NOT_SUPPORTED;
}
+ logd("registerForSatelliteDatagram: callback=" + callback);
return mDatagramController.registerForSatelliteDatagram(subId, callback);
}
@@ -1755,6 +1756,7 @@
if (!mSatelliteModemInterface.isSatelliteServiceSupported()) {
return;
}
+ logd("unregisterForSatelliteDatagram: callback=" + callback);
mDatagramController.unregisterForSatelliteDatagram(subId, callback);
}
diff --git a/src/java/com/android/internal/telephony/satellite/SatelliteModemInterface.java b/src/java/com/android/internal/telephony/satellite/SatelliteModemInterface.java
index 3d629db..03481c6 100644
--- a/src/java/com/android/internal/telephony/satellite/SatelliteModemInterface.java
+++ b/src/java/com/android/internal/telephony/satellite/SatelliteModemInterface.java
@@ -103,12 +103,14 @@
@Override
public void onSatelliteDatagramReceived(
android.telephony.satellite.stub.SatelliteDatagram datagram, int pendingCount) {
+ logd("onSatelliteDatagramReceived: pendingCount=" + pendingCount);
mSatelliteDatagramsReceivedRegistrants.notifyResult(new Pair<>(
SatelliteServiceUtils.fromSatelliteDatagram(datagram), pendingCount));
}
@Override
public void onPendingDatagrams() {
+ logd("onPendingDatagrams");
mPendingDatagramsRegistrants.notifyResult(null);
}
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/src/java/com/android/internal/telephony/subscription/SubscriptionManagerService.java b/src/java/com/android/internal/telephony/subscription/SubscriptionManagerService.java
index 1bf866b..a8d05a3 100644
--- a/src/java/com/android/internal/telephony/subscription/SubscriptionManagerService.java
+++ b/src/java/com/android/internal/telephony/subscription/SubscriptionManagerService.java
@@ -1879,6 +1879,8 @@
*
* @param callingPackage The package making the call.
* @param callingFeatureId The feature in the package.
+ * @param isForAllProfiles whether the caller intends to see all subscriptions regardless
+ * association.
*
* @return Sorted list of the currently {@link SubscriptionInfo} records available on the
* device.
@@ -1891,7 +1893,7 @@
"carrier privileges",
})
public List<SubscriptionInfo> getActiveSubscriptionInfoList(@NonNull String callingPackage,
- @Nullable String callingFeatureId) {
+ @Nullable String callingFeatureId, boolean isForAllProfiles) {
// Check if the caller has READ_PHONE_STATE, READ_PRIVILEGED_PHONE_STATE, or carrier
// privilege on any active subscription. The carrier app will get full subscription infos
// on the subs it has carrier privilege.
@@ -1905,7 +1907,13 @@
+ "permission. Returning empty list here.");
return Collections.emptyList();
}
- return getSubscriptionInfoStreamAsUser(BINDER_WRAPPER.getCallingUserHandle())
+ if (isForAllProfiles && !hasAcrossAllUsersPermission()) {
+ //TODO(b/308809058 to determine whether the permission enforcement is needed)
+ loge("getActiveSubscriptionInfoList: "
+ + callingPackage + " has no appropriate permission.");
+ }
+ return getSubscriptionInfoStreamAsUser(isForAllProfiles
+ ? UserHandle.ALL : BINDER_WRAPPER.getCallingUserHandle())
.filter(SubscriptionInfoInternal::isActive)
// Remove the identifier if the caller does not have sufficient permission.
// carrier apps will get full subscription info on the subscriptions associated
@@ -1922,6 +1930,8 @@
*
* @param callingPackage The package making the call.
* @param callingFeatureId The feature in the package.
+ * @param isForAllProfiles whether the caller intends to see all subscriptions regardless
+ * association.
*
* @return the number of active subscriptions.
*
@@ -1934,14 +1944,27 @@
"carrier privileges",
})
public int getActiveSubInfoCount(@NonNull String callingPackage,
- @Nullable String callingFeatureId) {
+ @Nullable String callingFeatureId, boolean isForAllProfiles) {
if (!TelephonyPermissions.checkReadPhoneStateOnAnyActiveSub(mContext,
Binder.getCallingPid(), Binder.getCallingUid(), callingPackage, callingFeatureId,
"getAllSubInfoList")) {
throw new SecurityException("Need READ_PHONE_STATE, READ_PRIVILEGED_PHONE_STATE, or "
+ "carrier privilege");
}
- return getActiveSubIdListAsUser(false, BINDER_WRAPPER.getCallingUserHandle()).length;
+ if (isForAllProfiles && !hasAcrossAllUsersPermission()) {
+ //TODO(b/308809058 to determine whether the permission enforcement is needed)
+ loge("getActiveSubInfoCount: "
+ + callingPackage + " has no appropriate permission.");
+ }
+ return getActiveSubIdListAsUser(false, isForAllProfiles
+ ? UserHandle.ALL : BINDER_WRAPPER.getCallingUserHandle()).length;
+ }
+
+ /**@return {@code true} if the caller is permitted to see all subscriptions. */
+ private boolean hasAcrossAllUsersPermission() {
+ return hasPermissions(Manifest.permission.INTERACT_ACROSS_USERS,
+ Manifest.permission.INTERACT_ACROSS_USERS_FULL,
+ Manifest.permission.INTERACT_ACROSS_PROFILES);
}
/**
@@ -2856,12 +2879,14 @@
* @return The subscription Id default to use.
*/
private int getDefaultAsUser(@UserIdInt int userId, int defaultValue) {
- List<SubscriptionInfoInternal> subInfos =
- getSubscriptionInfoStreamAsUser(UserHandle.of(userId))
- .filter(SubscriptionInfoInternal::isActive)
- .toList();
- if (subInfos.size() == 1) {
- return subInfos.get(0).getSubscriptionId();
+ if (mFeatureFlags.workProfileApiSplit()) {
+ List<SubscriptionInfoInternal> subInfos =
+ getSubscriptionInfoStreamAsUser(UserHandle.of(userId))
+ .filter(SubscriptionInfoInternal::isActive)
+ .toList();
+ if (subInfos.size() == 1) {
+ return subInfos.get(0).getSubscriptionId();
+ }
}
return defaultValue;
}
@@ -3885,16 +3910,6 @@
}
/**
- * @return All active subscriptions.
- */
- @NonNull
- private List<SubscriptionInfoInternal> getActiveSubscriptionInfoListAllUser() {
- return mSubscriptionDatabaseManager.getAllSubscriptions().stream()
- .filter(SubscriptionInfoInternal::isActive)
- .collect(Collectors.toList());
- }
-
- /**
* Get subscriptions accessible to the caller user.
*
* @param user The user to check.
@@ -4136,7 +4151,10 @@
*/
@VisibleForTesting
public void updateGroupDisabled() {
- List<SubscriptionInfoInternal> activeSubscriptions = getActiveSubscriptionInfoListAllUser();
+ List<SubscriptionInfoInternal> activeSubscriptions = mSubscriptionDatabaseManager
+ .getAllSubscriptions().stream()
+ .filter(SubscriptionInfoInternal::isActive)
+ .collect(Collectors.toList());
for (SubscriptionInfo oppSubInfo : getOpportunisticSubscriptions(
mContext.getOpPackageName(), mContext.getFeatureId())) {
boolean groupDisabled = activeSubscriptions.stream()
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/DefaultPhoneNotifierTest.java b/tests/telephonytests/src/com/android/internal/telephony/DefaultPhoneNotifierTest.java
index 827511d..f7f67a5 100644
--- a/tests/telephonytests/src/com/android/internal/telephony/DefaultPhoneNotifierTest.java
+++ b/tests/telephonytests/src/com/android/internal/telephony/DefaultPhoneNotifierTest.java
@@ -23,6 +23,7 @@
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
import android.telephony.CellIdentityGsm;
import android.telephony.CellInfo;
@@ -34,12 +35,14 @@
import android.telephony.ims.ImsCallProfile;
import android.test.suitebuilder.annotation.SmallTest;
+import com.android.internal.telephony.flags.FeatureFlags;
import com.android.internal.telephony.imsphone.ImsPhoneCall;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import org.mockito.ArgumentCaptor;
+import org.mockito.Mockito;
import java.util.ArrayList;
import java.util.Collections;
@@ -51,6 +54,8 @@
private DefaultPhoneNotifier mDefaultPhoneNotifierUT;
+ private FeatureFlags mFeatureFlags;
+
// Mocked classes
SignalStrength mSignalStrength;
CellInfo mCellInfo;
@@ -66,13 +71,14 @@
super.setUp(getClass().getSimpleName());
mSignalStrength = mock(SignalStrength.class);
mCellInfo = mock(CellInfo.class);
+ mFeatureFlags = Mockito.mock(FeatureFlags.class);
mForeGroundCall = mock(GsmCdmaCall.class);
mBackGroundCall = mock(GsmCdmaCall.class);
mRingingCall = mock(GsmCdmaCall.class);
mImsForeGroundCall = mock(ImsPhoneCall.class);
mImsBackGroundCall = mock(ImsPhoneCall.class);
mImsRingingCall = mock(ImsPhoneCall.class);
- mDefaultPhoneNotifierUT = new DefaultPhoneNotifier(mContext);
+ mDefaultPhoneNotifierUT = new DefaultPhoneNotifier(mContext, mFeatureFlags);
}
@After
@@ -94,6 +100,22 @@
@Test @SmallTest
public void testNotifyDataActivity() throws Exception {
+ when(mFeatureFlags.notifyDataActivityChangedWithSlot()).thenReturn(false);
+ //mock data activity state
+ doReturn(TelephonyManager.DATA_ACTIVITY_NONE).when(mPhone).getDataActivityState();
+ mDefaultPhoneNotifierUT.notifyDataActivity(mPhone);
+ verify(mTelephonyRegistryManager).notifyDataActivityChanged(eq(0),
+ eq(TelephonyManager.DATA_ACTIVITY_NONE));
+
+ doReturn(1).when(mPhone).getSubId();
+ doReturn(TelephonyManager.DATA_ACTIVITY_IN).when(mPhone).getDataActivityState();
+ mDefaultPhoneNotifierUT.notifyDataActivity(mPhone);
+ verify(mTelephonyRegistryManager).notifyDataActivityChanged(eq(1),
+ eq(TelephonyManager.DATA_ACTIVITY_IN));
+ }
+ @Test @SmallTest
+ public void testNotifyDataActivityWithSlot() throws Exception {
+ when(mFeatureFlags.notifyDataActivityChangedWithSlot()).thenReturn(true);
//mock data activity state
doReturn(TelephonyManager.DATA_ACTIVITY_NONE).when(mPhone).getDataActivityState();
doReturn(PHONE_ID).when(mPhone).getPhoneId();
diff --git a/tests/telephonytests/src/com/android/internal/telephony/GsmCdmaCallTrackerTest.java b/tests/telephonytests/src/com/android/internal/telephony/GsmCdmaCallTrackerTest.java
index 2fdff9e..369980c 100644
--- a/tests/telephonytests/src/com/android/internal/telephony/GsmCdmaCallTrackerTest.java
+++ b/tests/telephonytests/src/com/android/internal/telephony/GsmCdmaCallTrackerTest.java
@@ -41,7 +41,6 @@
import androidx.test.filters.FlakyTest;
import com.android.internal.telephony.PhoneInternalInterface.DialArgs;
-import com.android.internal.telephony.domainselection.DomainSelectionResolver;
import org.junit.After;
import org.junit.Assert;
@@ -67,16 +66,12 @@
// Mocked classes
private GsmCdmaConnection mConnection;
private Handler mHandler;
- private DomainSelectionResolver mDomainSelectionResolver;
@Before
public void setUp() throws Exception {
super.setUp(getClass().getSimpleName());
mConnection = mock(GsmCdmaConnection.class);
mHandler = mock(Handler.class);
- mDomainSelectionResolver = mock(DomainSelectionResolver.class);
- doReturn(false).when(mDomainSelectionResolver).isDomainSelectionSupported();
- DomainSelectionResolver.setDomainSelectionResolver(mDomainSelectionResolver);
mSimulatedCommands.setRadioPower(true, null);
mPhone.mCi = this.mSimulatedCommands;
@@ -91,7 +86,6 @@
@After
public void tearDown() throws Exception {
mCTUT = null;
- DomainSelectionResolver.setDomainSelectionResolver(null);
super.tearDown();
}
diff --git a/tests/telephonytests/src/com/android/internal/telephony/GsmCdmaPhoneTest.java b/tests/telephonytests/src/com/android/internal/telephony/GsmCdmaPhoneTest.java
index 2563fdf..c8510eb 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;
@@ -131,7 +132,6 @@
private UiccSlot mUiccSlot;
private CommandsInterface mMockCi;
private AdnRecordCache adnRecordCache;
- private DomainSelectionResolver mDomainSelectionResolver;
//mPhoneUnderTest
private GsmCdmaPhone mPhoneUT;
@@ -172,13 +172,10 @@
mUiccPort = Mockito.mock(UiccPort.class);
mMockCi = Mockito.mock(CommandsInterface.class);
adnRecordCache = Mockito.mock(AdnRecordCache.class);
- mDomainSelectionResolver = Mockito.mock(DomainSelectionResolver.class);
mFeatureFlags = Mockito.mock(FeatureFlags.class);
doReturn(false).when(mSST).isDeviceShuttingDown();
doReturn(true).when(mImsManager).isVolteEnabledByPlatform();
- doReturn(false).when(mDomainSelectionResolver).isDomainSelectionSupported();
- DomainSelectionResolver.setDomainSelectionResolver(mDomainSelectionResolver);
mPhoneUT = new GsmCdmaPhone(mContext, mSimulatedCommands, mNotifier, true, 0,
PhoneConstants.PHONE_TYPE_GSM, mTelephonyComponentFactory, (c, p) -> mImsManager,
@@ -197,7 +194,6 @@
public void tearDown() throws Exception {
mPhoneUT.removeCallbacksAndMessages(null);
mPhoneUT = null;
- DomainSelectionResolver.setDomainSelectionResolver(null);
try {
DeviceConfig.setProperties(mPreTestProperties);
} catch (DeviceConfig.BadConfigException e) {
@@ -2761,4 +2757,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/MultiSimSettingControllerTest.java b/tests/telephonytests/src/com/android/internal/telephony/MultiSimSettingControllerTest.java
index a41dbe1..7893e78 100644
--- a/tests/telephonytests/src/com/android/internal/telephony/MultiSimSettingControllerTest.java
+++ b/tests/telephonytests/src/com/android/internal/telephony/MultiSimSettingControllerTest.java
@@ -198,7 +198,7 @@
}
return subscriptionInfoList;
}).when(mSubscriptionManagerService).getActiveSubscriptionInfoList(
- anyString(), nullable(String.class));
+ anyString(), nullable(String.class), anyBoolean());
doAnswer(invocation -> {
final boolean visibleOnly = (boolean) invocation.getArguments()[0];
diff --git a/tests/telephonytests/src/com/android/internal/telephony/PhoneConfigurationManagerTest.java b/tests/telephonytests/src/com/android/internal/telephony/PhoneConfigurationManagerTest.java
index 700a246..4f2d8db 100644
--- a/tests/telephonytests/src/com/android/internal/telephony/PhoneConfigurationManagerTest.java
+++ b/tests/telephonytests/src/com/android/internal/telephony/PhoneConfigurationManagerTest.java
@@ -43,6 +43,8 @@
import android.testing.AndroidTestingRunner;
import android.testing.TestableLooper;
+import com.android.internal.telephony.flags.FeatureFlags;
+
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
@@ -62,6 +64,7 @@
private static final int EVENT_MULTI_SIM_CONFIG_CHANGED = 1;
PhoneConfigurationManager mPcm;
+ private FeatureFlags mFeatureFlags;
@Before
public void setUp() throws Exception {
@@ -69,6 +72,7 @@
mHandler = mock(Handler.class);
mMockCi0 = mock(CommandsInterface.class);
mMockCi1 = mock(CommandsInterface.class);
+ mFeatureFlags = Mockito.mock(FeatureFlags.class);
mPhone1 = mock(Phone.class);
mMi = mock(PhoneConfigurationManager.MockableInterface.class);
mPhone.mCi = mMockCi0;
@@ -89,7 +93,7 @@
private void init(int numOfSim) throws Exception {
doReturn(numOfSim).when(mTelephonyManager).getActiveModemCount();
replaceInstance(PhoneConfigurationManager.class, "sInstance", null, null);
- mPcm = PhoneConfigurationManager.init(mContext);
+ mPcm = PhoneConfigurationManager.init(mContext, mFeatureFlags);
replaceInstance(PhoneConfigurationManager.class, "mMi", mPcm, mMi);
processAllMessages();
}
diff --git a/tests/telephonytests/src/com/android/internal/telephony/ServiceStateTrackerTest.java b/tests/telephonytests/src/com/android/internal/telephony/ServiceStateTrackerTest.java
index 9e067a2..c542857 100644
--- a/tests/telephonytests/src/com/android/internal/telephony/ServiceStateTrackerTest.java
+++ b/tests/telephonytests/src/com/android/internal/telephony/ServiceStateTrackerTest.java
@@ -99,6 +99,7 @@
import com.android.internal.telephony.cdma.CdmaSubscriptionSourceManager;
import com.android.internal.telephony.data.AccessNetworksManager;
import com.android.internal.telephony.data.DataNetworkController;
+import com.android.internal.telephony.emergency.EmergencyStateTracker;
import com.android.internal.telephony.metrics.ServiceStateStats;
import com.android.internal.telephony.satellite.SatelliteController;
import com.android.internal.telephony.subscription.SubscriptionInfoInternal;
@@ -145,6 +146,7 @@
private ServiceStateTrackerTestHandler mSSTTestHandler;
private PersistableBundle mBundle;
private SatelliteController mSatelliteController;
+ private EmergencyStateTracker mEmergencyStateTracker;
private static final int EVENT_REGISTERED_TO_NETWORK = 1;
private static final int EVENT_SUBSCRIPTION_INFO_READY = 2;
@@ -390,6 +392,9 @@
sendCarrierConfigUpdate(PHONE_ID);
waitForLastHandlerAction(mSSTTestHandler.getThreadHandler());
+ mEmergencyStateTracker = Mockito.mock(EmergencyStateTracker.class);
+ replaceInstance(EmergencyStateTracker.class, "INSTANCE", null, mEmergencyStateTracker);
+
logd("ServiceStateTrackerTest -Setup!");
}
@@ -480,6 +485,66 @@
waitForLastHandlerAction(mSSTTestHandler.getThreadHandler());
verify(mDataNetworkController, times(1)).unregisterDataNetworkControllerCallback(any());
assertEquals(TelephonyManager.RADIO_POWER_OFF, mSimulatedCommands.getRadioState());
+ verify(mEmergencyStateTracker, never()).onCellularRadioPowerOffRequested();
+ }
+
+ @Test
+ public void testSetRadioPowerExitEmergencyMode() throws Exception {
+ doReturn(true).when(mDomainSelectionResolver).isDomainSelectionSupported();
+
+ // Set up DSDS environment
+ GsmCdmaPhone phone2 = Mockito.mock(GsmCdmaPhone.class);
+ DataNetworkController dataNetworkController_phone2 =
+ Mockito.mock(DataNetworkController.class);
+ mPhones = new Phone[] {mPhone, phone2};
+ replaceInstance(PhoneFactory.class, "sPhones", null, mPhones);
+ doReturn(dataNetworkController_phone2).when(phone2).getDataNetworkController();
+ doReturn(mSST).when(phone2).getServiceStateTracker();
+ doReturn(false).when(mDataNetworkController).areAllDataDisconnected();
+ doReturn(false).when(dataNetworkController_phone2).areAllDataDisconnected();
+ doReturn(1).when(mPhone).getSubId();
+ doReturn(2).when(phone2).getSubId();
+
+ // Start with radio on
+ sst.setRadioPower(true);
+ waitForLastHandlerAction(mSSTTestHandler.getThreadHandler());
+ assertEquals(TelephonyManager.RADIO_POWER_ON, mSimulatedCommands.getRadioState());
+
+ // Turn on APM
+ sst.setRadioPower(false);
+ waitForLastHandlerAction(mSSTTestHandler.getThreadHandler());
+ assertEquals(TelephonyManager.RADIO_POWER_ON, mSimulatedCommands.getRadioState());
+
+ // Verify checking emergency mode
+ verify(mEmergencyStateTracker).onCellularRadioPowerOffRequested();
+
+ // Verify that both subs are waiting for all data disconnected
+ verify(mDataNetworkController).tearDownAllDataNetworks(
+ eq(3 /* TEAR_DOWN_REASON_AIRPLANE_MODE_ON */));
+ verify(dataNetworkController_phone2, never()).tearDownAllDataNetworks(anyInt());
+ ArgumentCaptor<DataNetworkController.DataNetworkControllerCallback> callback1 =
+ ArgumentCaptor.forClass(DataNetworkController.DataNetworkControllerCallback.class);
+ ArgumentCaptor<DataNetworkController.DataNetworkControllerCallback> callback2 =
+ ArgumentCaptor.forClass(DataNetworkController.DataNetworkControllerCallback.class);
+ verify(mDataNetworkController, times(1)).registerDataNetworkControllerCallback(
+ callback1.capture());
+ verify(dataNetworkController_phone2, times(1)).registerDataNetworkControllerCallback(
+ callback2.capture());
+
+ // Data disconnected on sub 2, still waiting for data disconnected on sub 1
+ doReturn(true).when(dataNetworkController_phone2).areAllDataDisconnected();
+ callback2.getValue().onAnyDataNetworkExistingChanged(false);
+ waitForLastHandlerAction(mSSTTestHandler.getThreadHandler());
+ assertEquals(TelephonyManager.RADIO_POWER_ON, mSimulatedCommands.getRadioState());
+ verify(dataNetworkController_phone2, times(1)).unregisterDataNetworkControllerCallback(
+ any());
+
+ // Data disconnected on sub 1, radio should power off now
+ doReturn(true).when(mDataNetworkController).areAllDataDisconnected();
+ callback1.getValue().onAnyDataNetworkExistingChanged(false);
+ waitForLastHandlerAction(mSSTTestHandler.getThreadHandler());
+ verify(mDataNetworkController, times(1)).unregisterDataNetworkControllerCallback(any());
+ assertEquals(TelephonyManager.RADIO_POWER_OFF, mSimulatedCommands.getRadioState());
}
@Test
diff --git a/tests/telephonytests/src/com/android/internal/telephony/TelephonyRegistryTest.java b/tests/telephonytests/src/com/android/internal/telephony/TelephonyRegistryTest.java
index 95361b3..5a5e11f 100644
--- a/tests/telephonytests/src/com/android/internal/telephony/TelephonyRegistryTest.java
+++ b/tests/telephonytests/src/com/android/internal/telephony/TelephonyRegistryTest.java
@@ -1499,7 +1499,7 @@
}
@Test
- public void testNotifyDataActivityForSubscriber() {
+ public void testNotifyDataActivityForSubscriberWithSlot() {
final int subId = 1;
int[] events = {TelephonyCallback.EVENT_DATA_ACTIVITY_CHANGED};
doReturn(mMockSubInfo).when(mSubscriptionManager).getActiveSubscriptionInfo(anyInt());
@@ -1509,14 +1509,14 @@
mTelephonyRegistry.listenWithEventList(false, false, subId, mContext.getOpPackageName(),
mContext.getAttributionTag(), mTelephonyCallback.callback, events, true);
- mTelephonyRegistry.notifyDataActivityForSubscriber(0/*phoneId*/, subId,
+ mTelephonyRegistry.notifyDataActivityForSubscriberWithSlot(0/*phoneId*/, subId,
TelephonyManager.DATA_ACTIVITY_INOUT);
processAllMessages();
assertEquals(TelephonyManager.DATA_ACTIVITY_INOUT, mDataActivity);
}
@Test
- public void testNotifyDataActivityForSubscriberForInvalidSubId() {
+ public void testNotifyDataActivityForSubscriberWithSlotForInvalidSubId() {
final int subId = INVALID_SUBSCRIPTION_ID;
int[] events = {TelephonyCallback.EVENT_DATA_ACTIVITY_CHANGED};
doReturn(mMockSubInfo).when(mSubscriptionManager).getActiveSubscriptionInfo(anyInt());
@@ -1526,7 +1526,7 @@
mTelephonyRegistry.listenWithEventList(false, false, subId, mContext.getOpPackageName(),
mContext.getAttributionTag(), mTelephonyCallback.callback, events, true);
- mTelephonyRegistry.notifyDataActivityForSubscriber(0/*phoneId*/, subId,
+ mTelephonyRegistry.notifyDataActivityForSubscriberWithSlot(0/*phoneId*/, subId,
TelephonyManager.DATA_ACTIVITY_OUT);
processAllMessages();
assertEquals(TelephonyManager.DATA_ACTIVITY_OUT, mDataActivity);
diff --git a/tests/telephonytests/src/com/android/internal/telephony/TelephonyTest.java b/tests/telephonytests/src/com/android/internal/telephony/TelephonyTest.java
index b8d875c..9212567 100644
--- a/tests/telephonytests/src/com/android/internal/telephony/TelephonyTest.java
+++ b/tests/telephonytests/src/com/android/internal/telephony/TelephonyTest.java
@@ -108,6 +108,7 @@
import com.android.internal.telephony.data.DataSettingsManager;
import com.android.internal.telephony.data.LinkBandwidthEstimator;
import com.android.internal.telephony.data.PhoneSwitcher;
+import com.android.internal.telephony.domainselection.DomainSelectionResolver;
import com.android.internal.telephony.emergency.EmergencyNumberTracker;
import com.android.internal.telephony.flags.FeatureFlags;
import com.android.internal.telephony.imsphone.ImsExternalCallTracker;
@@ -122,6 +123,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 +281,8 @@
protected ServiceStateStats mServiceStateStats;
protected SatelliteController mSatelliteController;
protected DeviceStateHelper mDeviceStateHelper;
+ protected CellularIdentifierDisclosureNotifier mIdentifierDisclosureNotifier;
+ protected DomainSelectionResolver mDomainSelectionResolver;
// Initialized classes
protected ActivityManager mActivityManager;
@@ -549,6 +553,8 @@
mServiceStateStats = Mockito.mock(ServiceStateStats.class);
mSatelliteController = Mockito.mock(SatelliteController.class);
mDeviceStateHelper = Mockito.mock(DeviceStateHelper.class);
+ mIdentifierDisclosureNotifier = Mockito.mock(CellularIdentifierDisclosureNotifier.class);
+ mDomainSelectionResolver = Mockito.mock(DomainSelectionResolver.class);
TelephonyManager.disableServiceHandleCaching();
PropertyInvalidatedCache.disableForTestMode();
@@ -662,6 +668,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();
@@ -882,6 +891,9 @@
.getFoldState();
doReturn(null).when(mContext).getSystemService(eq(Context.DEVICE_STATE_SERVICE));
+ doReturn(false).when(mDomainSelectionResolver).isDomainSelectionSupported();
+ DomainSelectionResolver.setDomainSelectionResolver(mDomainSelectionResolver);
+
//Use reflection to mock singletons
replaceInstance(CallManager.class, "INSTANCE", null, mCallManager);
replaceInstance(TelephonyComponentFactory.class, "sInstance", null,
@@ -984,6 +996,7 @@
mTestableLoopers.clear();
mTestableLoopers = null;
mTestableLooper = null;
+ DomainSelectionResolver.setDomainSelectionResolver(null);
}
protected static void logd(String s) {
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/DataProfileManagerTest.java b/tests/telephonytests/src/com/android/internal/telephony/data/DataProfileManagerTest.java
index f8d22cd..ff14f9a 100644
--- a/tests/telephonytests/src/com/android/internal/telephony/data/DataProfileManagerTest.java
+++ b/tests/telephonytests/src/com/android/internal/telephony/data/DataProfileManagerTest.java
@@ -54,7 +54,6 @@
import com.android.internal.telephony.data.DataConfigManager.DataConfigManagerCallback;
import com.android.internal.telephony.data.DataNetworkController.DataNetworkControllerCallback;
import com.android.internal.telephony.data.DataProfileManager.DataProfileManagerCallback;
-import com.android.internal.telephony.flags.FeatureFlags;
import org.junit.After;
import org.junit.Before;
@@ -100,8 +99,6 @@
private DataProfileManager mDataProfileManagerUT;
- private FeatureFlags mFeatureFlags;
-
private final ApnSettingContentProvider mApnSettingContentProvider =
new ApnSettingContentProvider();
@@ -835,7 +832,6 @@
logd("DataProfileManagerTest +Setup!");
super.setUp(getClass().getSimpleName());
mDataProfileManagerCallback = Mockito.mock(DataProfileManagerCallback.class);
- mFeatureFlags = Mockito.mock(FeatureFlags.class);
((MockContentResolver) mContext.getContentResolver()).addProvider(
Telephony.Carriers.CONTENT_URI.getAuthority(), mApnSettingContentProvider);
@@ -1035,6 +1031,7 @@
@Test
public void testSetPreferredDataProfile() {
+ doReturn(true).when(mFeatureFlags).refinePreferredDataProfileSelection();
TelephonyNetworkRequest tnr = new TelephonyNetworkRequest(
new NetworkRequest.Builder()
.addCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET)
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 dd95ff0..2541bd1 100644
--- a/tests/telephonytests/src/com/android/internal/telephony/data/DataRetryManagerTest.java
+++ b/tests/telephonytests/src/com/android/internal/telephony/data/DataRetryManagerTest.java
@@ -786,6 +786,7 @@
@Test
public void testDataRetryLongTimer() {
+ doReturn(true).when(mFeatureFlags).useAlarmCallback();
// Rule requires a long timer
DataSetupRetryRule retryRule = new DataSetupRetryRule(
"capabilities=internet, retry_interval=120000, maximum_retries=2");
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/domainselection/DomainSelectionResolverTest.java b/tests/telephonytests/src/com/android/internal/telephony/domainselection/DomainSelectionResolverTest.java
index 7095909..eaf11a4 100644
--- a/tests/telephonytests/src/com/android/internal/telephony/domainselection/DomainSelectionResolverTest.java
+++ b/tests/telephonytests/src/com/android/internal/telephony/domainselection/DomainSelectionResolverTest.java
@@ -83,6 +83,8 @@
@Test
@SmallTest
public void testGetInstance() throws IllegalStateException {
+ DomainSelectionResolver.setDomainSelectionResolver(null);
+
assertThrows(IllegalStateException.class, () -> {
DomainSelectionResolver.getInstance();
});
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 0000000..b9112be
--- /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/emergency/EmergencyStateTrackerTest.java b/tests/telephonytests/src/com/android/internal/telephony/emergency/EmergencyStateTrackerTest.java
index 1eff979..fff1b68 100644
--- a/tests/telephonytests/src/com/android/internal/telephony/emergency/EmergencyStateTrackerTest.java
+++ b/tests/telephonytests/src/com/android/internal/telephony/emergency/EmergencyStateTrackerTest.java
@@ -886,6 +886,42 @@
}
/**
+ * Test that once endCall() is called and we enter ECM, then we exit ECM when turning on
+ * airplane mode.
+ */
+ @Test
+ @SmallTest
+ public void endCall_entersEcm_thenExitsEcmWhenTurnOnAirplaneMode() {
+ // Setup EmergencyStateTracker
+ EmergencyStateTracker emergencyStateTracker = setupEmergencyStateTracker(
+ /* isSuplDdsSwitchRequiredForEmergencyCall= */ true);
+ // Create test Phone
+ Phone testPhone = setupTestPhoneForEmergencyCall(/* isRoaming= */ true,
+ /* isRadioOn= */ true);
+ setUpAsyncResultForSetEmergencyMode(testPhone, E_REG_RESULT);
+ setUpAsyncResultForExitEmergencyMode(testPhone);
+ CompletableFuture<Integer> unused = emergencyStateTracker.startEmergencyCall(testPhone,
+ TEST_CALL_ID, false);
+ // Set call to ACTIVE
+ emergencyStateTracker.onEmergencyCallStateChanged(Call.State.ACTIVE, TEST_CALL_ID);
+ // Set ecm as supported
+ setEcmSupportedConfig(testPhone, /* ecmSupported= */ true);
+
+ processAllMessages();
+
+ emergencyStateTracker.endCall(TEST_CALL_ID);
+
+ assertTrue(emergencyStateTracker.isInEcm());
+
+ emergencyStateTracker.onCellularRadioPowerOffRequested();
+
+ // Verify exitEmergencyMode() is called.
+ verify(testPhone).exitEmergencyMode(any(Message.class));
+ assertFalse(emergencyStateTracker.isInEcm());
+ assertFalse(emergencyStateTracker.isInEmergencyMode());
+ }
+
+ /**
* Test that after exitEmergencyCallbackMode() is called, the correct intents are sent and
* emergency mode is exited on the modem.
*/
diff --git a/tests/telephonytests/src/com/android/internal/telephony/imsphone/ImsPhoneCallTrackerTest.java b/tests/telephonytests/src/com/android/internal/telephony/imsphone/ImsPhoneCallTrackerTest.java
index 04ae9d0..bfa702c 100644
--- a/tests/telephonytests/src/com/android/internal/telephony/imsphone/ImsPhoneCallTrackerTest.java
+++ b/tests/telephonytests/src/com/android/internal/telephony/imsphone/ImsPhoneCallTrackerTest.java
@@ -126,7 +126,6 @@
import com.android.internal.telephony.SrvccConnection;
import com.android.internal.telephony.TelephonyTest;
import com.android.internal.telephony.d2d.RtpTransport;
-import com.android.internal.telephony.domainselection.DomainSelectionResolver;
import com.android.internal.telephony.imsphone.ImsPhoneCallTracker.VtDataUsageProvider;
import com.android.internal.telephony.subscription.SubscriptionInfoInternal;
@@ -174,7 +173,6 @@
private INetworkStatsProviderCallback mVtDataUsageProviderCb;
private ImsPhoneCallTracker.ConnectorFactory mConnectorFactory;
private CommandsInterface mMockCi;
- private DomainSelectionResolver mDomainSelectionResolver;
private CarrierConfigManager.CarrierConfigChangeListener mCarrierConfigChangeListener;
private final Executor mExecutor = Runnable::run;
@@ -242,7 +240,6 @@
doReturn(ImsFeature.STATE_READY).when(mImsManager).getImsServiceState();
doReturn(mImsCallProfile).when(mImsManager).createCallProfile(anyInt(), anyInt());
mContextFixture.addSystemFeature(PackageManager.FEATURE_TELEPHONY_IMS);
- mDomainSelectionResolver = mock(DomainSelectionResolver.class);
doReturn(new SubscriptionInfoInternal.Builder().setSimSlotIndex(0).setId(1).build())
.when(mSubscriptionManagerService).getSubscriptionInfoInternal(anyInt());
@@ -281,9 +278,6 @@
return mMockConnector;
}).when(mConnectorFactory).create(any(), anyInt(), anyString(), any(), any());
- DomainSelectionResolver.setDomainSelectionResolver(mDomainSelectionResolver);
- doReturn(false).when(mDomainSelectionResolver).isDomainSelectionSupported();
-
doReturn(false)
.when(mFeatureFlags).updateImsServiceByGatheringProvisioningChanges();
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..f491041 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;
@@ -123,7 +125,6 @@
private ImsPhoneCall mBackgroundCall;
private ImsPhoneCall mRingingCall;
private Handler mTestHandler;
- private DomainSelectionResolver mDomainSelectionResolver;
Connection mConnection;
ImsUtInterface mImsUtInterface;
private FeatureFlags mFeatureFlags;
@@ -150,10 +151,7 @@
mTestHandler = mock(Handler.class);
mConnection = mock(Connection.class);
mImsUtInterface = mock(ImsUtInterface.class);
- mDomainSelectionResolver = mock(DomainSelectionResolver.class);
mFeatureFlags = mock(FeatureFlags.class);
- doReturn(false).when(mDomainSelectionResolver).isDomainSelectionSupported();
- DomainSelectionResolver.setDomainSelectionResolver(mDomainSelectionResolver);
mImsCT.mForegroundCall = mForegroundCall;
mImsCT.mBackgroundCall = mBackgroundCall;
@@ -198,7 +196,6 @@
public void tearDown() throws Exception {
mImsPhoneUT = null;
mBundle = null;
- DomainSelectionResolver.setDomainSelectionResolver(null);
super.tearDown();
}
@@ -1484,6 +1481,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/metrics/ImsStatsTest.java b/tests/telephonytests/src/com/android/internal/telephony/metrics/ImsStatsTest.java
index 7c7c5b2..df8bd85 100644
--- a/tests/telephonytests/src/com/android/internal/telephony/metrics/ImsStatsTest.java
+++ b/tests/telephonytests/src/com/android/internal/telephony/metrics/ImsStatsTest.java
@@ -23,6 +23,7 @@
import static android.telephony.ims.feature.MmTelFeature.MmTelCapabilities.CAPABILITY_TYPE_UT;
import static android.telephony.ims.feature.MmTelFeature.MmTelCapabilities.CAPABILITY_TYPE_VIDEO;
import static android.telephony.ims.feature.MmTelFeature.MmTelCapabilities.CAPABILITY_TYPE_VOICE;
+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 android.telephony.ims.stub.ImsRegistrationImplBase.REGISTRATION_TECH_NR;
@@ -40,6 +41,7 @@
import android.telephony.NetworkRegistrationInfo;
import android.telephony.TelephonyManager;
import android.telephony.ims.ImsReasonInfo;
+import android.telephony.ims.ImsRegistrationAttributes;
import android.telephony.ims.ProvisioningManager;
import android.telephony.ims.feature.MmTelFeature.MmTelCapabilities;
import android.telephony.ims.feature.MmTelFeature.MmTelCapabilities.MmTelCapability;
@@ -67,6 +69,13 @@
private static final int CARRIER1_ID = 1;
private static final int CARRIER2_ID = 1187;
+ private ImsRegistrationAttributes mWwanAttributes =
+ new ImsRegistrationAttributes.Builder(REGISTRATION_TECH_LTE).build();
+ private ImsRegistrationAttributes mIwlanAttributes =
+ new ImsRegistrationAttributes.Builder(REGISTRATION_TECH_IWLAN).build();
+ private ImsRegistrationAttributes mCrossSimAttributes =
+ new ImsRegistrationAttributes.Builder(REGISTRATION_TECH_CROSS_SIM).build();
+
@MmTelCapability
private static final int CAPABILITY_TYPE_ALL =
MmTelCapabilities.CAPABILITY_TYPE_VOICE
@@ -164,7 +173,7 @@
CAPABILITY_TYPE_SMS,
REGISTRATION_TECH_LTE,
ProvisioningManager.PROVISIONING_VALUE_ENABLED);
- mImsStats.onImsRegistered(TRANSPORT_TYPE_WWAN);
+ mImsStats.onImsRegistered(mWwanAttributes);
mImsStats.onImsCapabilitiesChanged(
REGISTRATION_TECH_LTE, new MmTelCapabilities(CAPABILITY_TYPE_ALL));
@@ -211,7 +220,7 @@
CAPABILITY_TYPE_SMS,
REGISTRATION_TECH_LTE,
ProvisioningManager.PROVISIONING_VALUE_ENABLED);
- mImsStats.onImsRegistered(TRANSPORT_TYPE_WWAN);
+ mImsStats.onImsRegistered(mWwanAttributes);
mImsStats.onImsCapabilitiesChanged(
REGISTRATION_TECH_LTE, new MmTelCapabilities(CAPABILITY_TYPE_VOICE));
@@ -258,7 +267,7 @@
CAPABILITY_TYPE_UT,
REGISTRATION_TECH_LTE,
ProvisioningManager.PROVISIONING_VALUE_ENABLED);
- mImsStats.onImsRegistered(TRANSPORT_TYPE_WLAN);
+ mImsStats.onImsRegistered(mIwlanAttributes);
mImsStats.onImsCapabilitiesChanged(
REGISTRATION_TECH_IWLAN, new MmTelCapabilities(CAPABILITY_TYPE_VOICE));
@@ -287,6 +296,35 @@
@Test
@SmallTest
+ public void conclude_registeredVoiceOnly_crossSimCalling() throws Exception {
+ mImsStats.onSetFeatureResponse(
+ CAPABILITY_TYPE_VOICE,
+ REGISTRATION_TECH_CROSS_SIM,
+ ProvisioningManager.PROVISIONING_VALUE_ENABLED);
+ mImsStats.onImsRegistered(mCrossSimAttributes);
+ mImsStats.onImsCapabilitiesChanged(
+ REGISTRATION_TECH_CROSS_SIM, new MmTelCapabilities(CAPABILITY_TYPE_VOICE));
+
+ mImsStats.incTimeMillis(2000L);
+ mImsStats.conclude();
+
+ // Duration should be counted
+ ArgumentCaptor<ImsRegistrationStats> captor =
+ ArgumentCaptor.forClass(ImsRegistrationStats.class);
+ verify(mPersistAtomsStorage).addImsRegistrationStats(captor.capture());
+ ImsRegistrationStats stats = captor.getValue();
+ assertEquals(CARRIER1_ID, stats.carrierId);
+ assertEquals(0, stats.simSlotIndex);
+ assertEquals(TelephonyManager.NETWORK_TYPE_IWLAN, stats.rat);
+ assertEquals(true, stats.isIwlanCrossSim);
+ assertEquals(2000L, stats.registeredMillis);
+ assertEquals(2000L, stats.voiceCapableMillis);
+ assertEquals(2000L, stats.voiceAvailableMillis);
+ verifyNoMoreInteractions(mPersistAtomsStorage);
+ }
+
+ @Test
+ @SmallTest
public void conclude_notRegistered() throws Exception {
// IMS over LTE
mImsStats.onSetFeatureResponse(
@@ -333,7 +371,7 @@
ImsRegistrationStats stats = statsCaptor.getValue();
assertEquals(CARRIER1_ID, stats.carrierId);
assertEquals(0, stats.simSlotIndex);
- assertEquals(TelephonyManager.NETWORK_TYPE_UNKNOWN, stats.rat);
+ assertEquals(TelephonyManager.NETWORK_TYPE_LTE, stats.rat);
assertEquals(2000L, stats.unregisteredMillis);
verifyNoMoreInteractions(mPersistAtomsStorage);
}
@@ -380,12 +418,129 @@
@Test
@SmallTest
+ public void conclude_serviceStateChanged_afterRatUnknown() throws Exception {
+ // IMS over LTE
+ mImsStats.onSetFeatureResponse(
+ CAPABILITY_TYPE_VOICE,
+ REGISTRATION_TECH_LTE,
+ ProvisioningManager.PROVISIONING_VALUE_ENABLED);
+ mImsStats.onSetFeatureResponse(
+ CAPABILITY_TYPE_VIDEO,
+ REGISTRATION_TECH_LTE,
+ ProvisioningManager.PROVISIONING_VALUE_ENABLED);
+ mImsStats.onSetFeatureResponse(
+ CAPABILITY_TYPE_UT,
+ REGISTRATION_TECH_LTE,
+ ProvisioningManager.PROVISIONING_VALUE_ENABLED);
+ mImsStats.onSetFeatureResponse(
+ CAPABILITY_TYPE_SMS,
+ REGISTRATION_TECH_LTE,
+ ProvisioningManager.PROVISIONING_VALUE_ENABLED);
+ mImsStats.onImsCapabilitiesChanged(
+ REGISTRATION_TECH_LTE, new MmTelCapabilities(CAPABILITY_TYPE_ALL));
+
+ mImsStats.onImsUnregistered(
+ new ImsReasonInfo(ImsReasonInfo.CODE_REGISTRATION_ERROR, 999, "Timeout"));
+
+ doReturn(TelephonyManager.NETWORK_TYPE_UNKNOWN)
+ .when(mServiceState)
+ .getDataNetworkType();
+ mImsStats.onServiceStateChanged(mServiceState);
+
+ mImsStats.incTimeMillis(2000L);
+
+ doReturn(TelephonyManager.NETWORK_TYPE_LTE)
+ .when(mServiceState)
+ .getDataNetworkType();
+ mImsStats.onServiceStateChanged(mServiceState);
+ mImsStats.conclude();
+
+ // Atom with termination info should be generated
+ ArgumentCaptor<ImsRegistrationTermination> terminationCaptor =
+ ArgumentCaptor.forClass(ImsRegistrationTermination.class);
+ verify(mPersistAtomsStorage).addImsRegistrationTermination(terminationCaptor.capture());
+ ImsRegistrationTermination termination = terminationCaptor.getValue();
+ assertEquals(CARRIER1_ID, termination.carrierId);
+ assertFalse(termination.isMultiSim);
+ assertEquals(TelephonyManager.NETWORK_TYPE_LTE, termination.ratAtEnd);
+ assertTrue(termination.setupFailed);
+ assertEquals(ImsReasonInfo.CODE_REGISTRATION_ERROR, termination.reasonCode);
+ assertEquals(999, termination.extraCode);
+ assertEquals("Timeout", termination.extraMessage);
+ verifyNoMoreInteractions(mPersistAtomsStorage);
+ }
+
+ @Test
+ @SmallTest
+ public void conclude_serviceStateChanged_afterRatLte() throws Exception {
+ // IMS over LTE
+ mImsStats.onSetFeatureResponse(
+ CAPABILITY_TYPE_VOICE,
+ REGISTRATION_TECH_LTE,
+ ProvisioningManager.PROVISIONING_VALUE_ENABLED);
+ mImsStats.onSetFeatureResponse(
+ CAPABILITY_TYPE_VIDEO,
+ REGISTRATION_TECH_LTE,
+ ProvisioningManager.PROVISIONING_VALUE_ENABLED);
+ mImsStats.onSetFeatureResponse(
+ CAPABILITY_TYPE_UT,
+ REGISTRATION_TECH_LTE,
+ ProvisioningManager.PROVISIONING_VALUE_ENABLED);
+ mImsStats.onSetFeatureResponse(
+ CAPABILITY_TYPE_SMS,
+ REGISTRATION_TECH_LTE,
+ ProvisioningManager.PROVISIONING_VALUE_ENABLED);
+ mImsStats.onImsCapabilitiesChanged(
+ REGISTRATION_TECH_LTE, new MmTelCapabilities(CAPABILITY_TYPE_ALL));
+
+ mImsStats.onImsUnregistered(
+ new ImsReasonInfo(ImsReasonInfo.CODE_REGISTRATION_ERROR, 999, "Timeout"));
+
+ doReturn(TelephonyManager.NETWORK_TYPE_LTE)
+ .when(mServiceState)
+ .getDataNetworkType();
+ mImsStats.onServiceStateChanged(mServiceState);
+
+ mImsStats.incTimeMillis(2000L);
+
+ doReturn(TelephonyManager.NETWORK_TYPE_UNKNOWN)
+ .when(mServiceState)
+ .getDataNetworkType();
+ mImsStats.onServiceStateChanged(mServiceState);
+ mImsStats.conclude();
+
+ // Atom with termination info and durations should be generated
+ ArgumentCaptor<ImsRegistrationTermination> terminationCaptor =
+ ArgumentCaptor.forClass(ImsRegistrationTermination.class);
+ verify(mPersistAtomsStorage).addImsRegistrationTermination(terminationCaptor.capture());
+ ImsRegistrationTermination termination = terminationCaptor.getValue();
+ assertEquals(CARRIER1_ID, termination.carrierId);
+ assertFalse(termination.isMultiSim);
+ assertEquals(TelephonyManager.NETWORK_TYPE_LTE, termination.ratAtEnd);
+ assertTrue(termination.setupFailed);
+ assertEquals(ImsReasonInfo.CODE_REGISTRATION_ERROR, termination.reasonCode);
+ assertEquals(999, termination.extraCode);
+ assertEquals("Timeout", termination.extraMessage);
+
+ ArgumentCaptor<ImsRegistrationStats> statsCaptor =
+ ArgumentCaptor.forClass(ImsRegistrationStats.class);
+ verify(mPersistAtomsStorage).addImsRegistrationStats(statsCaptor.capture());
+ ImsRegistrationStats stats = statsCaptor.getValue();
+ assertEquals(CARRIER1_ID, stats.carrierId);
+ assertEquals(0, stats.simSlotIndex);
+ assertEquals(TelephonyManager.NETWORK_TYPE_LTE, stats.rat);
+ assertEquals(2000L, stats.unregisteredMillis);
+ verifyNoMoreInteractions(mPersistAtomsStorage);
+ }
+
+ @Test
+ @SmallTest
public void onImsCapabilitiesChanged_sameTech() throws Exception {
mImsStats.onSetFeatureResponse(
CAPABILITY_TYPE_VOICE,
REGISTRATION_TECH_LTE,
ProvisioningManager.PROVISIONING_VALUE_ENABLED);
- mImsStats.onImsRegistered(TRANSPORT_TYPE_WWAN);
+ mImsStats.onImsRegistered(mWwanAttributes);
mImsStats.incTimeMillis(2000L);
mImsStats.onImsCapabilitiesChanged(
@@ -420,7 +575,7 @@
CAPABILITY_TYPE_VOICE,
REGISTRATION_TECH_LTE,
ProvisioningManager.PROVISIONING_VALUE_ENABLED);
- mImsStats.onImsRegistered(TRANSPORT_TYPE_WWAN);
+ mImsStats.onImsRegistered(mWwanAttributes);
mImsStats.onImsCapabilitiesChanged(
REGISTRATION_TECH_LTE, new MmTelCapabilities(CAPABILITY_TYPE_VOICE));
@@ -459,7 +614,7 @@
CAPABILITY_TYPE_SMS,
REGISTRATION_TECH_LTE,
ProvisioningManager.PROVISIONING_VALUE_ENABLED);
- mImsStats.onImsRegistered(TRANSPORT_TYPE_WWAN);
+ mImsStats.onImsRegistered(mWwanAttributes);
mImsStats.onImsCapabilitiesChanged(
REGISTRATION_TECH_LTE, new MmTelCapabilities(CAPABILITY_TYPE_SMS));
@@ -498,7 +653,7 @@
CAPABILITY_TYPE_VOICE,
REGISTRATION_TECH_LTE,
ProvisioningManager.PROVISIONING_VALUE_ENABLED);
- mImsStats.onImsRegistered(TRANSPORT_TYPE_WWAN);
+ mImsStats.onImsRegistered(mWwanAttributes);
mImsStats.incTimeMillis(2000L);
mImsStats.onSetFeatureResponse(
@@ -529,11 +684,11 @@
@Test
@SmallTest
public void onImsRegistered_differentTech() throws Exception {
- mImsStats.onImsRegistered(TRANSPORT_TYPE_WWAN);
+ mImsStats.onImsRegistered(mWwanAttributes);
mImsStats.incTimeMillis(2000L);
- mImsStats.onImsRegistered(TRANSPORT_TYPE_WLAN);
+ mImsStats.onImsRegistered(mIwlanAttributes);
mImsStats.incTimeMillis(2000L);
- mImsStats.onImsRegistered(TRANSPORT_TYPE_WWAN);
+ mImsStats.onImsRegistered(mWwanAttributes);
// At this point, the first 2 registrations should have their durations counted
ArgumentCaptor<ImsRegistrationStats> captor =
@@ -574,7 +729,7 @@
public void onImsRegistered_afterImsRegistering() throws Exception {
mImsStats.onImsRegistering(TRANSPORT_TYPE_WWAN);
mImsStats.incTimeMillis(2000L);
- mImsStats.onImsRegistered(TRANSPORT_TYPE_WWAN);
+ mImsStats.onImsRegistered(mWwanAttributes);
// Registering duration should be counted
ArgumentCaptor<ImsRegistrationStats> captor =
@@ -591,6 +746,11 @@
@Test
@SmallTest
public void onImsRegistering_afterImsUnregistered() throws Exception {
+ doReturn(TelephonyManager.NETWORK_TYPE_LTE)
+ .when(mServiceState)
+ .getDataNetworkType();
+ mImsStats.onServiceStateChanged(mServiceState);
+
mImsStats.onImsUnregistered(
new ImsReasonInfo(ImsReasonInfo.CODE_REGISTRATION_ERROR, 999, "Timeout"));
mImsStats.incTimeMillis(2000L);
@@ -615,7 +775,7 @@
ImsRegistrationStats stats = statsCaptor.getValue();
assertEquals(CARRIER1_ID, stats.carrierId);
assertEquals(0, stats.simSlotIndex);
- assertEquals(TelephonyManager.NETWORK_TYPE_UNKNOWN, stats.rat);
+ assertEquals(TelephonyManager.NETWORK_TYPE_LTE, stats.rat);
assertEquals(2000L, stats.unregisteredMillis);
verifyNoMoreInteractions(mPersistAtomsStorage);
}
@@ -649,7 +809,7 @@
mImsStats.onImsUnregistered(
new ImsReasonInfo(ImsReasonInfo.CODE_REGISTRATION_ERROR, 999, "Timeout"));
- // Atom with termination info should be generated
+ // Atom with termination info and durations should be generated
ArgumentCaptor<ImsRegistrationStats> statsCaptor =
ArgumentCaptor.forClass(ImsRegistrationStats.class);
verify(mPersistAtomsStorage).addImsRegistrationStats(statsCaptor.capture());
@@ -677,7 +837,7 @@
@Test
@SmallTest
public void onImsUnregistered_afterRegistered() throws Exception {
- mImsStats.onImsRegistered(TRANSPORT_TYPE_WWAN);
+ mImsStats.onImsRegistered(mWwanAttributes);
mImsStats.incTimeMillis(2000L);
mImsStats.onImsUnregistered(
new ImsReasonInfo(ImsReasonInfo.CODE_REGISTRATION_ERROR, 999, "Timeout"));
@@ -879,9 +1039,7 @@
}
}
- @Test
- @SmallTest
- public void onImsUnregistered_multiSim() throws Exception {
+ void secondSimMockSetup() {
doReturn(mSecondImsPhone).when(mSecondPhone).getImsPhone();
doReturn(mSecondPhone).when(mSecondImsPhone).getDefaultPhone();
doReturn(1).when(mSecondPhone).getPhoneId();
@@ -898,8 +1056,14 @@
// Reusing service state tracker from phone 0 for simplicity
doReturn(mSST).when(mSecondPhone).getServiceStateTracker();
doReturn(mSST).when(mSecondImsPhone).getServiceStateTracker();
+ }
+
+ @Test
+ @SmallTest
+ public void onImsUnregistered_multiSim() throws Exception {
+ secondSimMockSetup();
mImsStats = new TestableImsStats(mSecondImsPhone);
- mImsStats.onImsRegistered(TRANSPORT_TYPE_WWAN);
+ mImsStats.onImsRegistered(mWwanAttributes);
mImsStats.incTimeMillis(2000L);
mImsStats.onImsUnregistered(
new ImsReasonInfo(ImsReasonInfo.CODE_REGISTRATION_ERROR, 999, "Timeout"));
@@ -937,6 +1101,42 @@
@Test
@SmallTest
+ public void onImsUnregistered_crossSim() throws Exception {
+ secondSimMockSetup();
+ mImsStats = new TestableImsStats(mSecondImsPhone);
+ mImsStats.onImsRegistered(mCrossSimAttributes);
+ mImsStats.incTimeMillis(2000L);
+ mImsStats.onImsUnregistered(
+ new ImsReasonInfo(ImsReasonInfo.CODE_REGISTRATION_ERROR, 999, "Timeout"));
+
+ // Atom with termination info and durations should be generated
+ ArgumentCaptor<ImsRegistrationStats> statsCaptor =
+ ArgumentCaptor.forClass(ImsRegistrationStats.class);
+ verify(mPersistAtomsStorage).addImsRegistrationStats(statsCaptor.capture());
+ ImsRegistrationStats stats = statsCaptor.getValue();
+ assertEquals(CARRIER2_ID, stats.carrierId);
+ assertEquals(1, stats.simSlotIndex);
+ assertEquals(TelephonyManager.NETWORK_TYPE_IWLAN, stats.rat);
+ assertEquals(true, stats.isIwlanCrossSim);
+ assertEquals(2000L, stats.registeredMillis);
+
+ ArgumentCaptor<ImsRegistrationTermination> terminationCaptor =
+ ArgumentCaptor.forClass(ImsRegistrationTermination.class);
+ verify(mPersistAtomsStorage).addImsRegistrationTermination(terminationCaptor.capture());
+ ImsRegistrationTermination termination = terminationCaptor.getValue();
+ assertEquals(CARRIER2_ID, termination.carrierId);
+ assertTrue(termination.isMultiSim);
+ assertEquals(TelephonyManager.NETWORK_TYPE_IWLAN, termination.ratAtEnd);
+ assertEquals(true, termination.isIwlanCrossSim);
+ assertFalse(termination.setupFailed);
+ assertEquals(ImsReasonInfo.CODE_REGISTRATION_ERROR, termination.reasonCode);
+ assertEquals(999, termination.extraCode);
+ assertEquals("Timeout", termination.extraMessage);
+ verifyNoMoreInteractions(mPersistAtomsStorage);
+ }
+
+ @Test
+ @SmallTest
public void getImsVoiceRadioTech_noRegistration() throws Exception {
// Do nothing
@@ -946,7 +1146,7 @@
@Test
@SmallTest
public void getImsVoiceRadioTech_noVoiceRegistration() throws Exception {
- mImsStats.onImsRegistered(TRANSPORT_TYPE_WWAN);
+ mImsStats.onImsRegistered(mWwanAttributes);
mImsStats.onImsCapabilitiesChanged(
REGISTRATION_TECH_LTE, new MmTelCapabilities(CAPABILITY_TYPE_SMS));
@@ -956,7 +1156,7 @@
@Test
@SmallTest
public void getImsVoiceRadioTech_cellularRegistration() throws Exception {
- mImsStats.onImsRegistered(TRANSPORT_TYPE_WWAN);
+ mImsStats.onImsRegistered(mWwanAttributes);
mImsStats.onImsCapabilitiesChanged(
REGISTRATION_TECH_LTE, new MmTelCapabilities(CAPABILITY_TYPE_VOICE));
@@ -966,7 +1166,7 @@
@Test
@SmallTest
public void getImsVoiceRadioTech_wifiRegistration() throws Exception {
- mImsStats.onImsRegistered(TRANSPORT_TYPE_WLAN);
+ mImsStats.onImsRegistered(mIwlanAttributes);
mImsStats.onImsCapabilitiesChanged(
REGISTRATION_TECH_IWLAN, new MmTelCapabilities(CAPABILITY_TYPE_VOICE));
@@ -975,8 +1175,18 @@
@Test
@SmallTest
+ public void getImsVoiceRadioTech_crossSimRegistration() throws Exception {
+ mImsStats.onImsRegistered(mCrossSimAttributes);
+ mImsStats.onImsCapabilitiesChanged(
+ REGISTRATION_TECH_CROSS_SIM, new MmTelCapabilities(CAPABILITY_TYPE_VOICE));
+
+ assertEquals(TelephonyManager.NETWORK_TYPE_IWLAN, mImsStats.getImsVoiceRadioTech());
+ }
+
+ @Test
+ @SmallTest
public void getImsVoiceRadioTech_unregistered() throws Exception {
- mImsStats.onImsRegistered(TRANSPORT_TYPE_WWAN);
+ mImsStats.onImsRegistered(mWwanAttributes);
mImsStats.onImsCapabilitiesChanged(
REGISTRATION_TECH_LTE, new MmTelCapabilities(CAPABILITY_TYPE_VOICE));
mImsStats.onImsUnregistered(
@@ -995,17 +1205,14 @@
@Test
@SmallTest
public void getImsVoiceRadioTech_serviceStateChanged() throws Exception {
- mImsStats.onImsRegistered(TRANSPORT_TYPE_WWAN);
+ mImsStats.onImsRegistered(mWwanAttributes);
mImsStats.onImsCapabilitiesChanged(
REGISTRATION_TECH_LTE, new MmTelCapabilities(CAPABILITY_TYPE_VOICE));
- doReturn(
- new NetworkRegistrationInfo.Builder()
- .setAccessNetworkTechnology(TelephonyManager.NETWORK_TYPE_NR)
- .setRegistrationState(
- NetworkRegistrationInfo.REGISTRATION_STATE_HOME)
- .build())
+
+ doReturn(TelephonyManager.NETWORK_TYPE_NR)
.when(mServiceState)
- .getNetworkRegistrationInfo(DOMAIN_PS, TRANSPORT_TYPE_WWAN);
+ .getDataNetworkType();
+
mImsStats.onServiceStateChanged(mServiceState);
assertEquals(TelephonyManager.NETWORK_TYPE_NR, mImsStats.getImsVoiceRadioTech());
}
@@ -1013,17 +1220,14 @@
@Test
@SmallTest
public void getImsVoiceRadioTech_serviceStateChanged_wlan() throws Exception {
- mImsStats.onImsRegistered(TRANSPORT_TYPE_WWAN);
+ mImsStats.onImsRegistered(mWwanAttributes);
mImsStats.onImsCapabilitiesChanged(
REGISTRATION_TECH_IWLAN, new MmTelCapabilities(CAPABILITY_TYPE_VOICE));
- doReturn(
- new NetworkRegistrationInfo.Builder()
- .setAccessNetworkTechnology(TelephonyManager.NETWORK_TYPE_NR)
- .setRegistrationState(
- NetworkRegistrationInfo.REGISTRATION_STATE_HOME)
- .build())
+
+ doReturn(TelephonyManager.NETWORK_TYPE_IWLAN)
.when(mServiceState)
- .getNetworkRegistrationInfo(DOMAIN_PS, TRANSPORT_TYPE_WWAN);
+ .getDataNetworkType();
+
mImsStats.onServiceStateChanged(mServiceState);
assertEquals(TelephonyManager.NETWORK_TYPE_IWLAN, mImsStats.getImsVoiceRadioTech());
}
diff --git a/tests/telephonytests/src/com/android/internal/telephony/metrics/MetricsCollectorTest.java b/tests/telephonytests/src/com/android/internal/telephony/metrics/MetricsCollectorTest.java
index 66bf482..b8ae894 100644
--- a/tests/telephonytests/src/com/android/internal/telephony/metrics/MetricsCollectorTest.java
+++ b/tests/telephonytests/src/com/android/internal/telephony/metrics/MetricsCollectorTest.java
@@ -23,6 +23,7 @@
import static com.android.internal.telephony.TelephonyStatsLog.SUPPORTED_RADIO_ACCESS_FAMILY;
import static com.android.internal.telephony.TelephonyStatsLog.VOICE_CALL_RAT_USAGE;
import static com.android.internal.telephony.TelephonyStatsLog.VOICE_CALL_SESSION;
+import static com.android.internal.telephony.util.TelephonyUtils.IS_DEBUGGABLE;
import static com.google.common.truth.Truth.assertThat;
@@ -67,6 +68,8 @@
.setCoolDownMillis(24L * 3600L * 1000L)
.build();
private static final long MIN_COOLDOWN_MILLIS = 23L * 3600L * 1000L;
+ private static final long CELL_SERVICE_MIN_COOLDOWN_MILLIS =
+ IS_DEBUGGABLE ? 4L * 60L * 1000L : MIN_COOLDOWN_MILLIS;
private static final long MIN_CALLS_PER_BUCKET = 5L;
// NOTE: these fields are currently 32-bit internally and padded to 64-bit by TelephonyManager
@@ -398,7 +401,8 @@
assertThat(actualAtoms).hasSize(0);
assertThat(result).isEqualTo(StatsManager.PULL_SKIP);
- verify(mPersistAtomsStorage, times(1)).getCellularServiceStates(eq(MIN_COOLDOWN_MILLIS));
+ verify(mPersistAtomsStorage, times(1)).getCellularServiceStates(
+ eq(CELL_SERVICE_MIN_COOLDOWN_MILLIS));
verifyNoMoreInteractions(mPersistAtomsStorage);
}
diff --git a/tests/telephonytests/src/com/android/internal/telephony/metrics/PerSimStatusTest.java b/tests/telephonytests/src/com/android/internal/telephony/metrics/PerSimStatusTest.java
index dc9be1c..e03dfe4 100644
--- a/tests/telephonytests/src/com/android/internal/telephony/metrics/PerSimStatusTest.java
+++ b/tests/telephonytests/src/com/android/internal/telephony/metrics/PerSimStatusTest.java
@@ -107,6 +107,7 @@
.when(imsMmTelManager1)
.getVoWiFiRoamingModeSetting();
doReturn(false).when(imsMmTelManager1).isVtSettingEnabled();
+ doReturn(true).when(imsMmTelManager1).isCrossSimCallingEnabled();
doReturn(false).when(mPhone).getDataRoamingEnabled();
doReturn(1L)
.when(mPhone)
@@ -152,6 +153,7 @@
.when(imsMmTelManager2)
.getVoWiFiRoamingModeSetting();
doReturn(true).when(imsMmTelManager2).isVtSettingEnabled();
+ doReturn(false).when(imsMmTelManager2).isCrossSimCallingEnabled();
doReturn(false).when(mSecondPhone).getDataRoamingEnabled();
doReturn(1L)
.when(mSecondPhone)
@@ -191,6 +193,8 @@
perSimStatus1.minimumVoltageClass);
assertEquals(NETWORK_TYPE_BITMASK_GSM, perSimStatus1.unmeteredNetworks);
assertEquals(false, perSimStatus1.vonrEnabled);
+ assertEquals(true, perSimStatus1.crossSimCallingEnabled);
+
assertEquals(101, perSimStatus2.carrierId);
assertEquals(1, perSimStatus2.phoneNumberSourceUicc);
assertEquals(2, perSimStatus2.phoneNumberSourceCarrier);
@@ -210,6 +214,7 @@
perSimStatus2.minimumVoltageClass);
assertEquals(NETWORK_TYPE_BITMASK_GSM, perSimStatus2.unmeteredNetworks);
assertEquals(false, perSimStatus2.vonrEnabled);
+ assertEquals(false, perSimStatus2.crossSimCallingEnabled);
}
@Test
@@ -279,6 +284,7 @@
perSimStatus.minimumVoltageClass);
assertEquals(NETWORK_TYPE_BITMASK_GSM, perSimStatus.unmeteredNetworks);
assertEquals(true, perSimStatus.vonrEnabled);
+ assertEquals(false, perSimStatus.crossSimCallingEnabled);
}
@Test
@@ -340,6 +346,7 @@
perSimStatus.minimumVoltageClass);
assertEquals(NETWORK_TYPE_BITMASK_GSM, perSimStatus.unmeteredNetworks);
assertEquals(true, perSimStatus.vonrEnabled);
+ assertEquals(false, perSimStatus.crossSimCallingEnabled);
}
@Test
@@ -397,5 +404,6 @@
perSimStatus.minimumVoltageClass);
assertEquals(NETWORK_TYPE_BITMASK_GSM, perSimStatus.unmeteredNetworks);
assertEquals(true, perSimStatus.vonrEnabled);
+ assertEquals(false, perSimStatus.crossSimCallingEnabled);
}
}
diff --git a/tests/telephonytests/src/com/android/internal/telephony/metrics/ServiceStateStatsTest.java b/tests/telephonytests/src/com/android/internal/telephony/metrics/ServiceStateStatsTest.java
index 2509b8c..c66cfa7 100644
--- a/tests/telephonytests/src/com/android/internal/telephony/metrics/ServiceStateStatsTest.java
+++ b/tests/telephonytests/src/com/android/internal/telephony/metrics/ServiceStateStatsTest.java
@@ -44,6 +44,7 @@
import android.telephony.NetworkRegistrationInfo;
import android.telephony.ServiceState;
import android.telephony.TelephonyManager;
+import android.telephony.ims.stub.ImsRegistrationImplBase;
import android.test.suitebuilder.annotation.SmallTest;
import com.android.internal.telephony.Phone;
@@ -401,6 +402,30 @@
@Test
@SmallTest
+ public void onImsVoiceRegistrationChanged_crossSimCalling() throws Exception {
+ mServiceStateStats.onServiceStateChanged(mServiceState);
+ mockWwanPsRat(TelephonyManager.NETWORK_TYPE_UNKNOWN);
+ doReturn(TelephonyManager.NETWORK_TYPE_IWLAN).when(mImsStats).getImsVoiceRadioTech();
+ doReturn(ImsRegistrationImplBase.REGISTRATION_TECH_CROSS_SIM).when(mImsPhone)
+ .getImsRegistrationTech();
+ mServiceStateStats.incTimeMillis(100L);
+ mServiceStateStats.onImsVoiceRegistrationChanged();
+ mServiceStateStats.incTimeMillis(200L);
+ mServiceStateStats.conclude();
+
+ ArgumentCaptor<CellularServiceState> captor =
+ ArgumentCaptor.forClass(CellularServiceState.class);
+ verify(mPersistAtomsStorage, times(2))
+ .addCellularServiceStateAndCellularDataServiceSwitch(captor.capture(), eq(null));
+ CellularServiceState state = captor.getAllValues().get(1);
+
+ assertEquals(200L, state.totalTimeMillis);
+ assertEquals(TelephonyManager.NETWORK_TYPE_IWLAN, state.voiceRat);
+ assertTrue(state.isIwlanCrossSim);
+ }
+
+ @Test
+ @SmallTest
public void onInternetDataNetworkDisconnected() throws Exception {
// Using default service state for LTE
mServiceStateStats.onServiceStateChanged(mServiceState);
diff --git a/tests/telephonytests/src/com/android/internal/telephony/metrics/VoiceCallSessionStatsTest.java b/tests/telephonytests/src/com/android/internal/telephony/metrics/VoiceCallSessionStatsTest.java
index 5412992..00ba0f8 100644
--- a/tests/telephonytests/src/com/android/internal/telephony/metrics/VoiceCallSessionStatsTest.java
+++ b/tests/telephonytests/src/com/android/internal/telephony/metrics/VoiceCallSessionStatsTest.java
@@ -56,6 +56,7 @@
import android.telephony.data.ApnSetting;
import android.telephony.ims.ImsReasonInfo;
import android.telephony.ims.ImsStreamMediaProfile;
+import android.telephony.ims.stub.ImsRegistrationImplBase;
import android.test.suitebuilder.annotation.SmallTest;
import com.android.internal.telephony.Call;
@@ -196,6 +197,7 @@
doReturn(PhoneConstants.PHONE_TYPE_IMS).when(mImsConnection0).getPhoneType();
doReturn(false).when(mImsConnection0).isEmergencyCall();
+ doReturn(false).when(mImsConnection0).isCrossSimCall();
doReturn(PhoneConstants.PHONE_TYPE_IMS).when(mImsConnection1).getPhoneType();
doReturn(false).when(mImsConnection1).isEmergencyCall();
doReturn(PhoneConstants.PHONE_TYPE_GSM).when(mGsmConnection0).getPhoneType();
@@ -203,6 +205,9 @@
doReturn(PhoneConstants.PHONE_TYPE_GSM).when(mGsmConnection1).getPhoneType();
doReturn(false).when(mGsmConnection1).isEmergencyCall();
+ doReturn(ImsRegistrationImplBase.REGISTRATION_TECH_LTE).when(mImsPhone)
+ .getImsRegistrationTech();
+
if (Looper.myLooper() == null) {
Looper.prepare();
}
@@ -241,7 +246,6 @@
ImsReasonInfo.CODE_REMOTE_CALL_DECLINE);
expectedCall.setupDurationMillis = 200;
expectedCall.setupFailed = true;
- expectedCall.ratAtConnected = TelephonyManager.NETWORK_TYPE_UNKNOWN;
expectedCall.codecBitmask = 1L << AudioCodec.AUDIO_CODEC_EVS_SWB;
expectedCall.mainCodecQuality =
VOICE_CALL_SESSION__MAIN_CODEC_QUALITY__CODEC_QUALITY_SUPER_WIDEBAND;
@@ -1519,6 +1523,75 @@
@Test
@SmallTest
+ public void singleCrossSimCall_moAccepted() {
+ setServiceStateWithWifiCalling(mServiceState, TelephonyManager.NETWORK_TYPE_LTE);
+ doReturn(mImsPhone).when(mPhone).getImsPhone();
+ doReturn(ImsRegistrationImplBase.REGISTRATION_TECH_CROSS_SIM).when(mImsPhone)
+ .getImsRegistrationTech();
+ doReturn(TelephonyManager.NETWORK_TYPE_IWLAN).when(mImsStats).getImsVoiceRadioTech();
+ doReturn(false).when(mImsConnection0).isIncoming();
+ doReturn(true).when(mImsConnection0).isCrossSimCall();
+ doReturn(2000L).when(mImsConnection0).getCreateTime();
+ doReturn(1000L).when(mImsConnection0).getDurationMillis();
+ doReturn(mImsCall0).when(mImsConnection0).getCall();
+ doReturn(new ArrayList(List.of(mImsConnection0))).when(mImsCall0).getConnections();
+ VoiceCallSession expectedCall =
+ makeSlot0CallProto(
+ VOICE_CALL_SESSION__BEARER_AT_END__CALL_BEARER_IMS,
+ VOICE_CALL_SESSION__DIRECTION__CALL_DIRECTION_MO,
+ TelephonyManager.NETWORK_TYPE_IWLAN,
+ ImsReasonInfo.CODE_USER_TERMINATED_BY_REMOTE);
+ expectedCall.isIwlanCrossSimAtStart = true;
+ expectedCall.isIwlanCrossSimAtEnd = true;
+ expectedCall.isIwlanCrossSimAtConnected = true;
+
+ expectedCall.bandAtEnd = 0; // not configured for IWLAN
+ expectedCall.setupDurationMillis = 200;
+ expectedCall.setupFailed = false;
+ expectedCall.codecBitmask = 1L << AudioCodec.AUDIO_CODEC_EVS_SWB;
+ expectedCall.mainCodecQuality =
+ VOICE_CALL_SESSION__MAIN_CODEC_QUALITY__CODEC_QUALITY_SUPER_WIDEBAND;
+ expectedCall.disconnectExtraMessage = "normal call clearing";
+ expectedCall.callDuration =
+ VOICE_CALL_SESSION__CALL_DURATION__CALL_DURATION_LESS_THAN_ONE_MINUTE;
+ VoiceCallRatUsage expectedRatUsage =
+ makeRatUsageProto(
+ CARRIER_ID_SLOT_0, TelephonyManager.NETWORK_TYPE_IWLAN, 2000L, 100000L, 1L);
+ final AtomicReference<VoiceCallRatUsage[]> ratUsage = setupRatUsageCapture();
+
+ mVoiceCallSessionStats0.setTimeMillis(2000L);
+ doReturn(Call.State.DIALING).when(mImsCall0).getState();
+ doReturn(Call.State.DIALING).when(mImsConnection0).getState();
+ mVoiceCallSessionStats0.onImsDial(mImsConnection0);
+ mVoiceCallSessionStats0.setTimeMillis(2100L);
+ mVoiceCallSessionStats0.onAudioCodecChanged(
+ mImsConnection0, ImsStreamMediaProfile.AUDIO_QUALITY_EVS_SWB);
+ mVoiceCallSessionStats0.setTimeMillis(2200L);
+ doReturn(Call.State.ALERTING).when(mImsCall0).getState();
+ doReturn(Call.State.ALERTING).when(mImsConnection0).getState();
+ mVoiceCallSessionStats0.onCallStateChanged(mImsCall0);
+ mVoiceCallSessionStats0.setTimeMillis(12000L);
+ doReturn(Call.State.ACTIVE).when(mImsCall0).getState();
+ doReturn(Call.State.ACTIVE).when(mImsConnection0).getState();
+ mVoiceCallSessionStats0.onCallStateChanged(mImsCall0);
+ mVoiceCallSessionStats0.setTimeMillis(100000L);
+ mVoiceCallSessionStats0.onImsCallTerminated(
+ mImsConnection0,
+ new ImsReasonInfo(
+ ImsReasonInfo.CODE_USER_TERMINATED_BY_REMOTE, 0, "normal call clearing"));
+
+ ArgumentCaptor<VoiceCallSession> callCaptor =
+ ArgumentCaptor.forClass(VoiceCallSession.class);
+ verify(mPersistAtomsStorage, times(1)).addVoiceCallSession(callCaptor.capture());
+ verify(mPersistAtomsStorage, times(1)).addVoiceCallRatUsage(any());
+ verifyNoMoreInteractions(mPersistAtomsStorage);
+ assertProtoEquals(expectedCall, callCaptor.getValue());
+ assertThat(ratUsage.get()).hasLength(1);
+ assertProtoEquals(expectedRatUsage, ratUsage.get()[0]);
+ }
+
+ @Test
+ @SmallTest
public void singleCsCall_moRejected() {
doReturn(false).when(mGsmConnection0).isIncoming();
doReturn(2000L).when(mGsmConnection0).getCreateTime();
@@ -2518,6 +2591,8 @@
public void singleWifiCall_preferred() {
setServiceStateWithWifiCalling(mServiceState, TelephonyManager.NETWORK_TYPE_LTE);
doReturn(mImsPhone).when(mPhone).getImsPhone();
+ doReturn(ImsRegistrationImplBase.REGISTRATION_TECH_IWLAN).when(mImsPhone)
+ .getImsRegistrationTech();
doReturn(TelephonyManager.NETWORK_TYPE_IWLAN).when(mImsStats).getImsVoiceRadioTech();
doReturn(true).when(mImsConnection0).isIncoming();
doReturn(2000L).when(mImsConnection0).getCreateTime();
@@ -2566,6 +2641,8 @@
public void singleWifiCall_airPlaneMode() {
setServiceStateWithWifiCalling(mServiceState, TelephonyManager.NETWORK_TYPE_UNKNOWN);
doReturn(mImsPhone).when(mPhone).getImsPhone();
+ doReturn(ImsRegistrationImplBase.REGISTRATION_TECH_IWLAN).when(mImsPhone)
+ .getImsRegistrationTech();
doReturn(TelephonyManager.NETWORK_TYPE_IWLAN).when(mImsStats).getImsVoiceRadioTech();
doReturn(true).when(mImsConnection0).isIncoming();
doReturn(2000L).when(mImsConnection0).getCreateTime();
diff --git a/tests/telephonytests/src/com/android/internal/telephony/nitz/TEST_MAPPING b/tests/telephonytests/src/com/android/internal/telephony/nitz/TEST_MAPPING
index 2bcb04e..4063803 100644
--- a/tests/telephonytests/src/com/android/internal/telephony/nitz/TEST_MAPPING
+++ b/tests/telephonytests/src/com/android/internal/telephony/nitz/TEST_MAPPING
@@ -1,6 +1,5 @@
{
- // TODO(b/182461754): Change to "presubmit" when go/test-mapping-slo-guide allows.
- "postsubmit": [
+ "presubmit": [
{
"name": "FrameworksTelephonyTests",
"options": [
diff --git a/tests/telephonytests/src/com/android/internal/telephony/satellite/DatagramDispatcherTest.java b/tests/telephonytests/src/com/android/internal/telephony/satellite/DatagramDispatcherTest.java
index 0a1ab02..fd5f6ab 100644
--- a/tests/telephonytests/src/com/android/internal/telephony/satellite/DatagramDispatcherTest.java
+++ b/tests/telephonytests/src/com/android/internal/telephony/satellite/DatagramDispatcherTest.java
@@ -428,7 +428,7 @@
processAllMessages();
// As modem is busy receiving datagrams, sending datagram did not proceed further.
mInOrder.verify(mMockDatagramController).needsWaitingForSatelliteConnected();
- mInOrder.verify(mMockDatagramController).isPollingInIdleState();
+ mInOrder.verify(mMockDatagramController, times(2)).isPollingInIdleState();
verifyNoMoreInteractions(mMockDatagramController);
}
diff --git a/tests/telephonytests/src/com/android/internal/telephony/satellite/DatagramReceiverTest.java b/tests/telephonytests/src/com/android/internal/telephony/satellite/DatagramReceiverTest.java
index 94f56b4..0e16e25 100644
--- a/tests/telephonytests/src/com/android/internal/telephony/satellite/DatagramReceiverTest.java
+++ b/tests/telephonytests/src/com/android/internal/telephony/satellite/DatagramReceiverTest.java
@@ -23,6 +23,7 @@
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.Mockito.anyInt;
@@ -38,6 +39,7 @@
import static org.mockito.Mockito.when;
import android.annotation.NonNull;
+import android.annotation.Nullable;
import android.content.Context;
import android.os.AsyncResult;
import android.os.IBinder;
@@ -66,6 +68,7 @@
import org.mockito.MockitoAnnotations;
import java.util.concurrent.LinkedBlockingQueue;
+import java.util.concurrent.Semaphore;
import java.util.concurrent.TimeUnit;
@RunWith(AndroidTestingRunner.class)
@@ -272,10 +275,13 @@
@Test
public void testSatelliteDatagramReceived_success_zeroPendingCount() {
+ TestSatelliteDatagramCallback testSatelliteDatagramCallback =
+ new TestSatelliteDatagramCallback();
+
+ mSatelliteDatagramListenerHandler.addListener(testSatelliteDatagramCallback);
mSatelliteDatagramListenerHandler.obtainMessage(1 /*EVENT_SATELLITE_DATAGRAM_RECEIVED*/,
new AsyncResult(null, new Pair<>(mDatagram, 0), null))
.sendToTarget();
-
processAllMessages();
mInOrder.verify(mMockDatagramController)
@@ -286,6 +292,14 @@
.updateReceiveStatus(eq(SUB_ID),
eq(SatelliteManager.SATELLITE_DATAGRAM_TRANSFER_STATE_IDLE),
eq(0), eq(SatelliteManager.SATELLITE_RESULT_SUCCESS));
+ assertTrue(testSatelliteDatagramCallback.waitForOnSatelliteDatagramReceived());
+
+ assertTrue(testSatelliteDatagramCallback.sendInternalAck());
+ try {
+ processAllFutureMessages();
+ } catch (Exception e) {
+ fail("Unexpected exception e=" + e);
+ }
}
@Test
@@ -475,4 +489,57 @@
mLong = duration;
}
}
+
+ private static class TestSatelliteDatagramCallback extends ISatelliteDatagramCallback.Stub {
+ @Nullable private IVoidConsumer mInternalAck;
+ private final Semaphore mSemaphore = new Semaphore(0);
+
+ @Override
+ public void onSatelliteDatagramReceived(long datagramId,
+ @NonNull SatelliteDatagram datagram, int pendingCount,
+ @NonNull IVoidConsumer internalAck) {
+ logd("onSatelliteDatagramReceived");
+ mInternalAck = internalAck;
+ try {
+ internalAck.accept();
+ } catch (RemoteException e) {
+ logd("onSatelliteDatagramReceived: accept e=" + e);
+ return;
+ }
+
+ try {
+ mSemaphore.release();
+ } catch (Exception e) {
+ logd("onSatelliteDatagramReceived: release e=" + e);
+ }
+ }
+
+ public boolean waitForOnSatelliteDatagramReceived() {
+ logd("waitForOnSatelliteDatagramReceived");
+ try {
+ if (!mSemaphore.tryAcquire(1000, TimeUnit.MILLISECONDS)) {
+ logd("Timed out to receive onSatelliteDatagramReceived");
+ return false;
+ }
+ } catch (InterruptedException e) {
+ logd("waitForOnSatelliteDatagramReceived: e=" + e);
+ return false;
+ }
+ return true;
+ }
+
+ public boolean sendInternalAck() {
+ if (mInternalAck == null) {
+ logd("sendInternalAck: mInternalAck is null");
+ return false;
+ }
+ try {
+ mInternalAck.accept();
+ } catch (RemoteException e) {
+ logd("sendInternalAck: accept e=" + e);
+ return false;
+ }
+ return true;
+ }
+ }
}
diff --git a/tests/telephonytests/src/com/android/internal/telephony/security/CellularIdentifierDisclosureTest.java b/tests/telephonytests/src/com/android/internal/telephony/security/CellularIdentifierDisclosureTest.java
new file mode 100644
index 0000000..327a1cb
--- /dev/null
+++ b/tests/telephonytests/src/com/android/internal/telephony/security/CellularIdentifierDisclosureTest.java
@@ -0,0 +1,128 @@
+/*
+ * 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 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 com.android.internal.telephony.RILUtils;
+
+import org.junit.Test;
+
+public class CellularIdentifierDisclosureTest {
+
+ @Test
+ public void testEqualsAndHash() {
+ android.telephony.CellularIdentifierDisclosure disclosure =
+ new android.telephony.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() {
+ android.telephony.CellularIdentifierDisclosure imsiDisclosure =
+ new android.telephony.CellularIdentifierDisclosure(
+ NAS_PROTOCOL_MESSAGE_ATTACH_REQUEST,
+ CELLULAR_IDENTIFIER_IMSI,
+ "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());
+ }
+
+ @Test
+ public void testGetters() {
+ 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());
+ assertEquals(false, disclosure.isEmergency());
+ assertEquals("001001", disclosure.getPlmn());
+ }
+
+ @Test
+ public void testParcel() {
+ 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);
+
+ 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));
+ }
+}
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 e4e2434..eecaf90 100644
--- a/tests/telephonytests/src/com/android/internal/telephony/subscription/SubscriptionManagerServiceTest.java
+++ b/tests/telephonytests/src/com/android/internal/telephony/subscription/SubscriptionManagerServiceTest.java
@@ -766,13 +766,13 @@
// Should get an empty list without READ_PHONE_STATE.
assertThat(mSubscriptionManagerServiceUT.getActiveSubscriptionInfoList(
- CALLING_PACKAGE, CALLING_FEATURE)).isEmpty();
+ CALLING_PACKAGE, CALLING_FEATURE, true)).isEmpty();
// Grant READ_PHONE_STATE permission for insertion.
mContextFixture.addCallingOrSelfPermission(Manifest.permission.READ_PHONE_STATE);
List<SubscriptionInfo> subInfos = mSubscriptionManagerServiceUT
- .getActiveSubscriptionInfoList(CALLING_PACKAGE, CALLING_FEATURE);
+ .getActiveSubscriptionInfoList(CALLING_PACKAGE, CALLING_FEATURE, true);
assertThat(subInfos).hasSize(1);
assertThat(subInfos.get(0).getIccId()).isEmpty();
assertThat(subInfos.get(0).getCardString()).isEmpty();
@@ -783,7 +783,7 @@
setCarrierPrivilegesForSubId(true, 1);
subInfos = mSubscriptionManagerServiceUT
- .getActiveSubscriptionInfoList(CALLING_PACKAGE, CALLING_FEATURE);
+ .getActiveSubscriptionInfoList(CALLING_PACKAGE, CALLING_FEATURE, true);
assertThat(subInfos).hasSize(1);
assertThat(subInfos.get(0)).isEqualTo(FAKE_SUBSCRIPTION_INFO1.toSubscriptionInfo());
}
@@ -963,11 +963,11 @@
// Should fail without READ_PHONE_STATE
assertThrows(SecurityException.class, () -> mSubscriptionManagerServiceUT
- .getActiveSubInfoCount(CALLING_PACKAGE, CALLING_FEATURE));
+ .getActiveSubInfoCount(CALLING_PACKAGE, CALLING_FEATURE, true));
mContextFixture.addCallingOrSelfPermission(Manifest.permission.READ_PRIVILEGED_PHONE_STATE);
assertThat(mSubscriptionManagerServiceUT.getActiveSubInfoCount(
- CALLING_PACKAGE, CALLING_FEATURE)).isEqualTo(2);
+ CALLING_PACKAGE, CALLING_FEATURE, true)).isEqualTo(2);
}
@Test
@@ -1252,7 +1252,7 @@
.isEqualTo(new int[]{subId1, subId2});
// Test get getActiveSubInfoCount
assertThat(mSubscriptionManagerServiceUT.getActiveSubInfoCount(
- CALLING_PACKAGE, CALLING_FEATURE)).isEqualTo(1);
+ CALLING_PACKAGE, CALLING_FEATURE, false)).isEqualTo(1);
// Test getActiveSubscriptionInfo
assertThat(mSubscriptionManagerServiceUT.getActiveSubscriptionInfo(
subId1, CALLING_PACKAGE, CALLING_FEATURE).getSubscriptionId()).isEqualTo(subId1);
@@ -1274,7 +1274,8 @@
.isEqualTo(subId2);
// Test getActiveSubscriptionInfoList
assertThat(mSubscriptionManagerServiceUT.getActiveSubscriptionInfoList(
- CALLING_PACKAGE, CALLING_FEATURE).stream().map(SubscriptionInfo::getSubscriptionId)
+ CALLING_PACKAGE, CALLING_FEATURE, false)
+ .stream().map(SubscriptionInfo::getSubscriptionId)
.toList()).isEqualTo(List.of(subId1));
// Test getAllSubInfoList
assertThat(mSubscriptionManagerServiceUT.getAllSubInfoList(CALLING_PACKAGE,
@@ -1368,7 +1369,7 @@
.isEqualTo(new int[]{subId1, subId2});
// Test get getActiveSubInfoCount
assertThat(mSubscriptionManagerServiceUT.getActiveSubInfoCount(
- CALLING_PACKAGE, CALLING_FEATURE)).isEqualTo(1);
+ CALLING_PACKAGE, CALLING_FEATURE, false)).isEqualTo(1);
// Test getActiveSubscriptionInfo
assertThat(mSubscriptionManagerServiceUT.getActiveSubscriptionInfo(
subId1, CALLING_PACKAGE, CALLING_FEATURE).getSubscriptionId()).isEqualTo(subId1);
@@ -1390,7 +1391,7 @@
.isEqualTo(subId2);
// Test getActiveSubscriptionInfoList
assertThat(mSubscriptionManagerServiceUT.getActiveSubscriptionInfoList(
- CALLING_PACKAGE, CALLING_FEATURE).stream()
+ CALLING_PACKAGE, CALLING_FEATURE, false).stream()
.map(SubscriptionInfo::getSubscriptionId)
.toList()).isEqualTo(List.of(subId1));
// Test getAllSubInfoList
@@ -2151,7 +2152,7 @@
assertThat(mSubscriptionManagerServiceUT.getAllSubInfoList(
CALLING_PACKAGE, CALLING_FEATURE).isEmpty()).isTrue();
assertThat(mSubscriptionManagerServiceUT.getActiveSubscriptionInfoList(
- CALLING_PACKAGE, CALLING_FEATURE)).isEmpty();
+ CALLING_PACKAGE, CALLING_FEATURE, true)).isEmpty();
}
@Test
@@ -2357,7 +2358,7 @@
verify(mEuiccController).blockingGetEuiccProfileInfoList(eq(1));
List<SubscriptionInfo> subInfoList = mSubscriptionManagerServiceUT
- .getActiveSubscriptionInfoList(CALLING_PACKAGE, CALLING_FEATURE);
+ .getActiveSubscriptionInfoList(CALLING_PACKAGE, CALLING_FEATURE, true);
assertThat(subInfoList).hasSize(1);
assertThat(subInfoList.get(0).getSimSlotIndex()).isEqualTo(1);
assertThat(subInfoList.get(0).getSubscriptionId()).isEqualTo(1);
@@ -2475,7 +2476,7 @@
processAllMessages();
List<SubscriptionInfo> subInfoList = mSubscriptionManagerServiceUT
- .getActiveSubscriptionInfoList(CALLING_PACKAGE, CALLING_FEATURE);
+ .getActiveSubscriptionInfoList(CALLING_PACKAGE, CALLING_FEATURE, true);
assertThat(subInfoList).hasSize(1);
assertThat(subInfoList.get(0).isActive()).isTrue();
@@ -2595,16 +2596,17 @@
CALLING_PACKAGE, CALLING_FEATURE)).isEmpty();
assertThat(mSubscriptionManagerServiceUT.getActiveSubIdList(false)).isEmpty();
assertThat(mSubscriptionManagerServiceUT.getActiveSubscriptionInfoList(
- CALLING_PACKAGE, CALLING_FEATURE)).isEmpty();
+ CALLING_PACKAGE, CALLING_FEATURE, true)).isEmpty();
setIdentifierAccess(true);
mSubscriptionManagerServiceUT.addSubInfo(FAKE_MAC_ADDRESS2, FAKE_CARRIER_NAME2,
0, SubscriptionManager.SUBSCRIPTION_TYPE_REMOTE_SIM);
assertThat(mSubscriptionManagerServiceUT.getActiveSubIdList(false)).isNotEmpty();
assertThat(mSubscriptionManagerServiceUT.getActiveSubscriptionInfoList(
- CALLING_PACKAGE, CALLING_FEATURE)).isNotEmpty();
+ CALLING_PACKAGE, CALLING_FEATURE, true)).isNotEmpty();
assertThat(mSubscriptionManagerServiceUT.getActiveSubscriptionInfoList(
- CALLING_PACKAGE, CALLING_FEATURE).get(0).getIccId()).isEqualTo(FAKE_MAC_ADDRESS2);
+ CALLING_PACKAGE, CALLING_FEATURE, true).get(0).getIccId())
+ .isEqualTo(FAKE_MAC_ADDRESS2);
}
@Test