Merge "adb shell command to trigger phone.notifyCarrierRoamingNtnEligibleStateChanged API." into main
diff --git a/flags/Android.bp b/flags/Android.bp
index 1885032..edcfc3f 100644
--- a/flags/Android.bp
+++ b/flags/Android.bp
@@ -33,6 +33,7 @@
"subscription.aconfig",
"uicc.aconfig",
"satellite.aconfig",
- "iwlan.aconfig"
+ "iwlan.aconfig",
+ "carrier.aconfig",
],
}
diff --git a/flags/carrier.aconfig b/flags/carrier.aconfig
new file mode 100644
index 0000000..dca2ad3
--- /dev/null
+++ b/flags/carrier.aconfig
@@ -0,0 +1,11 @@
+package: "com.android.internal.telephony.flags"
+container: "system"
+
+# OWNER=nharold TARGET=24Q4
+flag {
+ name: "async_init_carrier_privileges_tracker"
+ is_exported: true
+ namespace: "telephony"
+ description: "Offload the heavyweight initialization of CarrierPrivilegesTracker to a worker thread"
+ bug:"357096337"
+}
diff --git a/src/java/com/android/internal/telephony/CarrierPrivilegesTracker.java b/src/java/com/android/internal/telephony/CarrierPrivilegesTracker.java
index 522cf77..6326d6c 100644
--- a/src/java/com/android/internal/telephony/CarrierPrivilegesTracker.java
+++ b/src/java/com/android/internal/telephony/CarrierPrivilegesTracker.java
@@ -46,6 +46,7 @@
import android.net.Uri;
import android.os.Bundle;
import android.os.Handler;
+import android.os.HandlerThread;
import android.os.Looper;
import android.os.Message;
import android.os.PersistableBundle;
@@ -68,7 +69,6 @@
import com.android.internal.annotations.GuardedBy;
import com.android.internal.telephony.flags.FeatureFlags;
-import com.android.internal.telephony.uicc.IccUtils;
import com.android.internal.telephony.uicc.UiccPort;
import com.android.internal.telephony.uicc.UiccProfile;
import com.android.telephony.Rlog;
@@ -80,7 +80,6 @@
import java.util.Collection;
import java.util.Collections;
import java.util.List;
-import java.util.Locale;
import java.util.Map;
import java.util.Objects;
import java.util.Set;
@@ -179,6 +178,8 @@
private static final int ACTION_SET_TEST_OVERRIDE_CARRIER_SERVICE_PACKAGE = 11;
private final Context mContext;
+ @NonNull
+ private final FeatureFlags mFeatureFlags;
private final Phone mPhone;
private final PackageManager mPackageManager;
private final UserManager mUserManager;
@@ -198,7 +199,7 @@
@Nullable private List<UiccAccessRule> mTestOverrideRules = null;
@Nullable private String mTestOverrideCarrierServicePackage = null;
// Map of PackageName -> Certificate hashes for that Package
- @NonNull private final Map<String, Set<String>> mInstalledPackageCerts = new ArrayMap<>();
+ @NonNull private final Map<String, Set<Integer>> mInstalledPackageCertHashes = new ArrayMap<>();
// Map of PackageName -> UIDs for that Package
@NonNull private final Map<String, Set<Integer>> mCachedUids = new ArrayMap<>();
@@ -226,8 +227,7 @@
"mPrivilegedPackageInfoLock.writeLock()"})
private boolean mSimIsReadyButNotLoaded = false;
- @NonNull
- private final FeatureFlags mFeatureFlags;
+ private volatile Handler mCurrentHandler;
/** Small snapshot to hold package names and UIDs of privileged packages. */
private static final class PrivilegedPackageInfo {
@@ -303,7 +303,9 @@
return;
}
- sendMessage(obtainMessage(ACTION_SIM_STATE_UPDATED, slotId, simState));
+ mCurrentHandler.sendMessage(
+ mCurrentHandler.obtainMessage(
+ ACTION_SIM_STATE_UPDATED, slotId, simState));
break;
}
case Intent.ACTION_PACKAGE_ADDED: // fall through
@@ -335,19 +337,21 @@
? ACTION_PACKAGE_REMOVED_OR_DISABLED_BY_USER
: ACTION_PACKAGE_ADDED_REPLACED_OR_CHANGED;
- sendMessage(obtainMessage(what, pkgName));
+ mCurrentHandler.sendMessage(
+ mCurrentHandler.obtainMessage(what, pkgName));
break;
}
}
}
};
- public CarrierPrivilegesTracker(@NonNull Looper looper, @NonNull Phone phone,
- @NonNull Context context, @NonNull FeatureFlags flags) {
+ public CarrierPrivilegesTracker(
+ @NonNull Looper looper, @NonNull Phone phone,
+ @NonNull Context context, @NonNull FeatureFlags featureFlags) {
super(looper);
- mContext = context;
- mFeatureFlags = flags;
mPhone = phone;
+ mContext = context;
+ mFeatureFlags = featureFlags;
mPackageManager = mContext.getPackageManager();
mUserManager = (UserManager) mContext.getSystemService(Context.USER_SERVICE);
mCarrierConfigManager =
@@ -363,6 +367,56 @@
(TelephonyRegistryManager)
mContext.getSystemService(Context.TELEPHONY_REGISTRY_SERVICE);
+ if (mFeatureFlags.asyncInitCarrierPrivilegesTracker()) {
+ final Object localLock = new Object();
+ HandlerThread initializerThread =
+ new HandlerThread("CarrierPrivilegesTracker Initializer") {
+ @Override
+ protected void onLooperPrepared() {
+ synchronized (localLock) {
+ localLock.notifyAll();
+ }
+ }
+ };
+ synchronized (localLock) {
+ initializerThread.start();
+ while (true) {
+ try {
+ localLock.wait();
+ break;
+ } catch (InterruptedException ie) {
+ }
+ }
+ }
+ mCurrentHandler = new Handler(initializerThread.getLooper()) {
+ @Override
+ public void handleMessage(Message msg) {
+ switch(msg.what) {
+ case ACTION_INITIALIZE_TRACKER:
+ handleInitializeTracker();
+ if (!hasMessagesOrCallbacks()) {
+ mCurrentHandler = CarrierPrivilegesTracker.this;
+ initializerThread.quitSafely();
+ }
+ break;
+ default:
+ Message m = CarrierPrivilegesTracker.this.obtainMessage();
+ m.copyFrom(msg);
+ m.sendToTarget();
+ if (!hasMessagesOrCallbacks()) {
+ mCurrentHandler = CarrierPrivilegesTracker.this;
+ initializerThread.quitSafely();
+ }
+ break;
+ }
+ }
+ };
+ } else {
+ mCurrentHandler = this;
+ }
+
+ mCurrentHandler.sendMessage(obtainMessage(ACTION_INITIALIZE_TRACKER));
+
IntentFilter certFilter = new IntentFilter();
certFilter.addAction(TelephonyManager.ACTION_SIM_CARD_STATE_CHANGED);
certFilter.addAction(TelephonyManager.ACTION_SIM_APPLICATION_STATE_CHANGED);
@@ -391,7 +445,6 @@
mContext.registerReceiver(mIntentReceiver, packageFilter);
}
- sendMessage(obtainMessage(ACTION_INITIALIZE_TRACKER));
}
@Override
@@ -499,7 +552,7 @@
&& mClearUiccRulesUptimeMillis == CLEAR_UICC_RULE_NOT_SCHEDULED) {
mClearUiccRulesUptimeMillis =
SystemClock.uptimeMillis() + CLEAR_UICC_RULES_DELAY_MILLIS;
- sendMessageAtTime(obtainMessage(ACTION_CLEAR_UICC_RULES),
+ mCurrentHandler.sendMessageAtTime(obtainMessage(ACTION_CLEAR_UICC_RULES),
mClearUiccRulesUptimeMillis);
mLocalLog.log("SIM is gone, simState=" + TelephonyManager.simStateToString(simState)
+ ". Delay " + TimeUnit.MILLISECONDS.toSeconds(
@@ -556,25 +609,29 @@
return uiccProfile.getCarrierPrivilegeAccessRules();
}
- private void handlePackageAddedReplacedOrChanged(@Nullable String pkgName) {
- if (pkgName == null) return;
+ private PackageInfo getPackageInfoForPackage(@Nullable String pkgName) {
+ if (pkgName == null) return null;
PackageInfo pkg;
try {
- pkg =
- mFeatureFlags.supportCarrierServicesForHsum()
- ? mPackageManager.getPackageInfoAsUser(
- pkgName,
- INSTALLED_PACKAGES_QUERY_FLAGS,
- ActivityManager.getCurrentUser())
- : mPackageManager.getPackageInfo(
- pkgName, INSTALLED_PACKAGES_QUERY_FLAGS);
+ return mFeatureFlags.supportCarrierServicesForHsum()
+ ? mPackageManager.getPackageInfoAsUser(
+ pkgName,
+ INSTALLED_PACKAGES_QUERY_FLAGS,
+ ActivityManager.getCurrentUser())
+ : mPackageManager.getPackageInfo(
+ pkgName, INSTALLED_PACKAGES_QUERY_FLAGS);
} catch (NameNotFoundException e) {
Rlog.e(TAG, "Error getting installed package: " + pkgName, e);
- return;
+ return null;
}
+ }
- updateCertsForPackage(pkg);
+ private void handlePackageAddedReplacedOrChanged(@Nullable String pkgName) {
+ PackageInfo pkg = getPackageInfoForPackage(pkgName);
+ if (pkg == null) return;
+
+ updateCertHashHashesForPackage(pkg);
// Invalidate cache because this may be a package already on the device but getting
// installed for a user it wasn't installed in before, which means there will be an
// additional UID.
@@ -582,30 +639,46 @@
if (VDBG) {
Rlog.d(TAG, "Package added/replaced/changed:"
+ " pkg=" + Rlog.pii(TAG, pkgName)
- + " cert hashes=" + mInstalledPackageCerts.get(pkgName));
+ + " cert hashes=" + mInstalledPackageCertHashes.get(pkgName));
}
maybeUpdatePrivilegedPackagesAndNotifyRegistrants();
}
- private void updateCertsForPackage(@NonNull PackageInfo pkg) {
- Set<String> certs = new ArraySet<>(1);
+ private void updateCertHashHashesForPackage(@NonNull PackageInfo pkg) {
+ Set<Integer> certs = new ArraySet<>(2);
List<Signature> signatures = UiccAccessRule.getSignatures(pkg);
for (Signature signature : signatures) {
byte[] sha1 = UiccAccessRule.getCertHash(signature, SHA_1);
- certs.add(IccUtils.bytesToHexString(sha1).toUpperCase(Locale.ROOT));
+ certs.add(UiccAccessRule.getCertificateHashHashCode(sha1));
byte[] sha256 = UiccAccessRule.getCertHash(signature, SHA_256);
- certs.add(IccUtils.bytesToHexString(sha256).toUpperCase(Locale.ROOT));
+ certs.add(UiccAccessRule.getCertificateHashHashCode(sha256));
}
- mInstalledPackageCerts.put(pkg.packageName, certs);
+ mInstalledPackageCertHashes.put(pkg.packageName, certs);
+ }
+
+ private Set<byte[]> getCertsForPackage(@NonNull String pkgName) {
+ PackageInfo pkg = getPackageInfoForPackage(pkgName);
+ if (pkg == null) return Collections.emptySet();
+
+ List<Signature> signatures = UiccAccessRule.getSignatures(pkg);
+
+ ArraySet<byte[]> certs = new ArraySet<>(2);
+ for (Signature signature : signatures) {
+ certs.add(UiccAccessRule.getCertHash(signature, SHA_1));
+ certs.add(UiccAccessRule.getCertHash(signature, SHA_256));
+ }
+
+ return certs;
}
private void handlePackageRemovedOrDisabledByUser(@Nullable String pkgName) {
if (pkgName == null) return;
- if (mInstalledPackageCerts.remove(pkgName) == null || mCachedUids.remove(pkgName) == null) {
+ if (mInstalledPackageCertHashes.remove(pkgName) == null
+ || mCachedUids.remove(pkgName) == null) {
Rlog.e(TAG, "Unknown package was uninstalled or disabled by user: " + pkgName);
return;
}
@@ -637,7 +710,7 @@
msg +=
" installed pkgs="
+ getObfuscatedPackages(
- mInstalledPackageCerts.entrySet(),
+ mInstalledPackageCertHashes.entrySet(),
e -> "pkg(" + Rlog.pii(TAG, e.getKey()) + ")=" + e.getValue());
}
mLocalLog.log(msg);
@@ -651,7 +724,7 @@
? ActivityManager.getCurrentUser()
: UserHandle.SYSTEM.getIdentifier());
for (PackageInfo pkg : installedPackages) {
- updateCertsForPackage(pkg);
+ updateCertHashHashesForPackage(pkg);
// This may be unnecessary before initialization, but invalidate the cache all the time
// just in case to ensure consistency.
getUidsForPackage(pkg.packageName, /* invalidateCache= */ true);
@@ -740,8 +813,12 @@
Set<String> carrierServiceEligiblePackages = new ArraySet<>();
Set<String> privilegedPackageNames = new ArraySet<>();
Set<Integer> privilegedUids = new ArraySet<>();
- for (Map.Entry<String, Set<String>> e : mInstalledPackageCerts.entrySet()) {
- final int priv = getPackagePrivilegedStatus(e.getKey(), e.getValue());
+ for (Map.Entry<String, Set<Integer>> e : mInstalledPackageCertHashes.entrySet()) {
+ if (!isPackageMaybePrivileged(e.getKey(), e.getValue())) continue;
+
+ Set<byte[]> fullCerts = getCertsForPackage(e.getKey());
+
+ final int priv = getPackagePrivilegedStatus(e.getKey(), fullCerts);
switch (priv) {
case PACKAGE_PRIVILEGED_FROM_SIM:
case PACKAGE_PRIVILEGED_FROM_CARRIER_SERVICE_TEST_OVERRIDE: // fallthrough
@@ -760,32 +837,58 @@
getCarrierService(carrierServiceEligiblePackages));
}
+ private boolean isPackageMaybePrivileged(
+ @NonNull String pkgName, @NonNull Set<Integer> hashHashes) {
+ for (Integer hashHash : hashHashes) {
+ // Non-null (whether empty or not) test override rule will ignore the UICC and CC rules
+ if (mTestOverrideRules != null) {
+ for (UiccAccessRule rule : mTestOverrideRules) {
+ if (rule.hasMatchingCertificateHashHashAndPackageName(hashHash, pkgName)) {
+ return true;
+ }
+ }
+ } else {
+ for (UiccAccessRule rule : mUiccRules) {
+ if (rule.hasMatchingCertificateHashHashAndPackageName(hashHash, pkgName)) {
+ return true;
+ }
+ }
+ for (UiccAccessRule rule : mCarrierConfigRules) {
+ if (rule.hasMatchingCertificateHashHashAndPackageName(hashHash, pkgName)) {
+ return true;
+ }
+ }
+ }
+ }
+ return false;
+ }
+
/**
* Returns the privilege status of the provided package.
*
* <p>Returned privilege status depends on whether a package matches the certificates from
* carrier config, from test overrides or from certificates stored on the SIM.
*/
- private int getPackagePrivilegedStatus(@NonNull String pkgName, @NonNull Set<String> certs) {
+ private int getPackagePrivilegedStatus(@NonNull String pkgName, @NonNull Set<byte[]> certs) {
// Double-nested for loops, but each collection should contain at most 2 elements in nearly
// every case.
// TODO(b/184382310) find a way to speed this up
- for (String cert : certs) {
+ for (byte[] cert : certs) {
// Non-null (whether empty or not) test override rule will ignore the UICC and CC rules
if (mTestOverrideRules != null) {
for (UiccAccessRule rule : mTestOverrideRules) {
- if (rule.matches(cert, pkgName)) {
+ if (rule.hasMatchingCertificateHashAndPackageName(cert, pkgName)) {
return PACKAGE_PRIVILEGED_FROM_SIM;
}
}
} else {
for (UiccAccessRule rule : mUiccRules) {
- if (rule.matches(cert, pkgName)) {
+ if (rule.hasMatchingCertificateHashAndPackageName(cert, pkgName)) {
return PACKAGE_PRIVILEGED_FROM_SIM;
}
}
for (UiccAccessRule rule : mCarrierConfigRules) {
- if (rule.matches(cert, pkgName)) {
+ if (rule.hasMatchingCertificateHashAndPackageName(cert, pkgName)) {
return pkgName.equals(mTestOverrideCarrierServicePackage)
? PACKAGE_PRIVILEGED_FROM_CARRIER_SERVICE_TEST_OVERRIDE
: PACKAGE_PRIVILEGED_FROM_CARRIER_CONFIG;
@@ -856,7 +959,7 @@
pw.println(
"CarrierPrivilegesTracker - Obfuscated Pkgs + Certs: "
+ getObfuscatedPackages(
- mInstalledPackageCerts.entrySet(),
+ mInstalledPackageCertHashes.entrySet(),
e -> "pkg(" + Rlog.pii(TAG, e.getKey()) + ")=" + e.getValue()));
}
pw.println("mClearUiccRulesUptimeMillis: " + mClearUiccRulesUptimeMillis);
@@ -872,7 +975,8 @@
* @see TelephonyManager#setCarrierTestOverride
*/
public void setTestOverrideCarrierPrivilegeRules(@Nullable String carrierPrivilegeRules) {
- sendMessage(obtainMessage(ACTION_SET_TEST_OVERRIDE_RULE, carrierPrivilegeRules));
+ mCurrentHandler.sendMessage(
+ obtainMessage(ACTION_SET_TEST_OVERRIDE_RULE, carrierPrivilegeRules));
}
/**
@@ -888,7 +992,7 @@
* @see TelephonyManager#setCarrierServicePackageOverride
*/
public void setTestOverrideCarrierServicePackage(@Nullable String carrierServicePackage) {
- sendMessage(obtainMessage(
+ mCurrentHandler.sendMessage(obtainMessage(
ACTION_SET_TEST_OVERRIDE_CARRIER_SERVICE_PACKAGE, carrierServicePackage));
}
diff --git a/src/java/com/android/internal/telephony/GsmCdmaPhone.java b/src/java/com/android/internal/telephony/GsmCdmaPhone.java
index 5d59327..2e1a89f 100644
--- a/src/java/com/android/internal/telephony/GsmCdmaPhone.java
+++ b/src/java/com/android/internal/telephony/GsmCdmaPhone.java
@@ -391,8 +391,8 @@
mCarrierResolver = mTelephonyComponentFactory.inject(CarrierResolver.class.getName())
.makeCarrierResolver(this, featureFlags);
- mCarrierPrivilegesTracker = new CarrierPrivilegesTracker(Looper.myLooper(), this, context,
- featureFlags);
+ mCarrierPrivilegesTracker = new CarrierPrivilegesTracker(
+ Looper.myLooper(), this, context, featureFlags);
getCarrierActionAgent().registerForCarrierAction(
CarrierActionAgent.CARRIER_ACTION_SET_METERED_APNS_ENABLED, this,
diff --git a/src/java/com/android/internal/telephony/MultiSimSettingController.java b/src/java/com/android/internal/telephony/MultiSimSettingController.java
index 3c35f1a..881adde 100644
--- a/src/java/com/android/internal/telephony/MultiSimSettingController.java
+++ b/src/java/com/android/internal/telephony/MultiSimSettingController.java
@@ -513,8 +513,8 @@
SatelliteController satelliteController = SatelliteController.getInstance();
boolean isSatelliteEnabledOrBeingEnabled = false;
if (satelliteController != null) {
- isSatelliteEnabledOrBeingEnabled = satelliteController.isSatelliteEnabled()
- || satelliteController.isSatelliteBeingEnabled();
+ isSatelliteEnabledOrBeingEnabled =
+ satelliteController.isSatelliteEnabledOrBeingEnabled();
}
if (DBG) {
diff --git a/src/java/com/android/internal/telephony/emergency/EmergencyStateTracker.java b/src/java/com/android/internal/telephony/emergency/EmergencyStateTracker.java
index f983108..53a3fe8 100644
--- a/src/java/com/android/internal/telephony/emergency/EmergencyStateTracker.java
+++ b/src/java/com/android/internal/telephony/emergency/EmergencyStateTracker.java
@@ -1588,7 +1588,7 @@
final boolean isAirplaneModeOn = isAirplaneModeOn(mContext);
boolean needToTurnOnRadio = !isRadioOn() || isAirplaneModeOn;
final SatelliteController satelliteController = SatelliteController.getInstance();
- boolean needToTurnOffSatellite = satelliteController.isSatelliteEnabled();
+ boolean needToTurnOffSatellite = satelliteController.isSatelliteEnabledOrBeingEnabled();
if (isAirplaneModeOn && !isPowerOff()
&& !phone.getServiceStateTracker().getDesiredPowerState()) {
@@ -1614,7 +1614,7 @@
@Override
public void onComplete(RadioOnStateListener listener, boolean isRadioReady) {
if (!isRadioReady) {
- if (satelliteController.isSatelliteEnabled()) {
+ if (satelliteController.isSatelliteEnabledOrBeingEnabled()) {
// Could not turn satellite off
Rlog.e(TAG, "Failed to turn off satellite modem.");
completeEmergencyMode(emergencyType, DisconnectCause.SATELLITE_ENABLED);
@@ -1647,7 +1647,7 @@
return false;
}
return phone.getServiceStateTracker().isRadioOn()
- && !satelliteController.isSatelliteEnabled();
+ && !satelliteController.isSatelliteEnabledOrBeingEnabled();
}
@Override
@@ -1659,7 +1659,7 @@
}
// onTimeout shall be called only with the Phone for emergency
return phone.getServiceStateTracker().isRadioOn()
- && !satelliteController.isSatelliteEnabled();
+ && !satelliteController.isSatelliteEnabledOrBeingEnabled();
}
}, !isTestEmergencyNumber, phone, isTestEmergencyNumber, waitForInServiceTimeout,
/* forNormalRoutingEmergencyCall */ false);
diff --git a/src/java/com/android/internal/telephony/emergency/RadioOnHelper.java b/src/java/com/android/internal/telephony/emergency/RadioOnHelper.java
index 26da1c2..11162b8 100644
--- a/src/java/com/android/internal/telephony/emergency/RadioOnHelper.java
+++ b/src/java/com/android/internal/telephony/emergency/RadioOnHelper.java
@@ -104,11 +104,8 @@
}
powerOnRadio(forEmergencyCall, phoneForEmergencyCall, isTestEmergencyNumber,
forNormalRoutingEmergencyCall);
- if (SatelliteController.getInstance().isSatelliteEnabled()
- || SatelliteController.getInstance().isSatelliteBeingEnabled()) {
- // TODO: phoneForEmergencyCall is actually ignored, SatelliteController#mSatelliePhone
- // is being used instead.
- powerOffSatellite(phoneForEmergencyCall);
+ if (SatelliteController.getInstance().isSatelliteEnabledOrBeingEnabled()) {
+ powerOffSatellite();
}
}
@@ -162,7 +159,7 @@
* Attempt to power off the satellite modem. We'll eventually get an
* onSatelliteModemStateChanged() callback when the satellite modem is successfully disabled.
*/
- private void powerOffSatellite(Phone phoneForEmergencyCall) {
+ private void powerOffSatellite() {
SatelliteController satelliteController = SatelliteController.getInstance();
satelliteController.requestSatelliteEnabled(
false /* enableSatellite */, false /* enableDemoMode */, false /* isEmergency */,
diff --git a/src/java/com/android/internal/telephony/emergency/RadioOnStateListener.java b/src/java/com/android/internal/telephony/emergency/RadioOnStateListener.java
index 1b1922c..3a3f6c8 100644
--- a/src/java/com/android/internal/telephony/emergency/RadioOnStateListener.java
+++ b/src/java/com/android/internal/telephony/emergency/RadioOnStateListener.java
@@ -230,7 +230,7 @@
// Register for RADIO_OFF to handle cases where emergency call is dialed before
// we receive UNSOL_RESPONSE_RADIO_STATE_CHANGED with RADIO_OFF.
registerForRadioOff();
- if (mSatelliteController.isSatelliteEnabled()) {
+ if (mSatelliteController.isSatelliteEnabledOrBeingEnabled()) {
// Register for satellite modem state changed to notify when satellite is disabled.
registerForSatelliteEnabledChanged();
}
@@ -401,7 +401,7 @@
Rlog.d(TAG, "Trying (again) to turn the radio on and satellite modem off.");
mPhone.setRadioPower(true, mForEmergencyCall, mSelectedPhoneForEmergencyCall,
false);
- if (mSatelliteController.isSatelliteEnabled()) {
+ if (mSatelliteController.isSatelliteEnabledOrBeingEnabled()) {
mSatelliteController.requestSatelliteEnabled(
false /* enableSatellite */, false /* enableDemoMode */,
false /* isEmergency*/,
diff --git a/src/java/com/android/internal/telephony/satellite/SatelliteController.java b/src/java/com/android/internal/telephony/satellite/SatelliteController.java
index cb74fed..0f724e4 100644
--- a/src/java/com/android/internal/telephony/satellite/SatelliteController.java
+++ b/src/java/com/android/internal/telephony/satellite/SatelliteController.java
@@ -2095,13 +2095,15 @@
*
* @return {@code true} if the satellite modem is enabled and {@code false} otherwise.
*/
- public boolean isSatelliteEnabled() {
+ private boolean isSatelliteEnabled() {
if (!mFeatureFlags.oemEnabledSatelliteFlag()) {
plogd("isSatelliteEnabled: oemEnabledSatelliteFlag is disabled");
return false;
}
- if (mIsSatelliteEnabled == null) return false;
- return mIsSatelliteEnabled;
+ synchronized (mIsSatelliteEnabledLock) {
+ if (mIsSatelliteEnabled == null) return false;
+ return mIsSatelliteEnabled;
+ }
}
/**
@@ -2109,7 +2111,7 @@
*
* @return {@code true} if the satellite modem is being enabled and {@code false} otherwise.
*/
- public boolean isSatelliteBeingEnabled() {
+ private boolean isSatelliteBeingEnabled() {
if (!mFeatureFlags.oemEnabledSatelliteFlag()) {
plogd("isSatelliteBeingEnabled: oemEnabledSatelliteFlag is disabled");
return false;
@@ -2122,6 +2124,17 @@
}
/**
+ * Get whether the satellite modem is enabled or being enabled.
+ * This will return the cached value instead of querying the satellite modem.
+ *
+ * @return {@code true} if the satellite modem is enabled or being enabled, {@code false}
+ * otherwise.
+ */
+ public boolean isSatelliteEnabledOrBeingEnabled() {
+ return isSatelliteEnabled() || isSatelliteBeingEnabled();
+ }
+
+ /**
* Get whether satellite modem is being disabled.
*
* @return {@code true} if the satellite modem is being disabled and {@code false} otherwise.
@@ -3503,7 +3516,7 @@
return false;
}
- if (!isSatelliteEnabled()) {
+ if (!isSatelliteEnabledOrBeingEnabled()) {
plogd("iisInCarrierRoamingNbIotNtn: satellite is disabled");
return false;
}
@@ -4140,7 +4153,7 @@
mWaitingForSatelliteModemOff = false;
}
} else {
- if (isSatelliteEnabled() || isSatelliteBeingEnabled() || isSatelliteBeingDisabled()) {
+ if (isSatelliteEnabledOrBeingEnabled() || isSatelliteBeingDisabled()) {
notifyModemStateChangedToSessionController(state);
} else {
// Telephony framework and modem are out of sync. We need to disable modem
@@ -5635,7 +5648,7 @@
return;
}
- if (!isSatelliteEnabled()) {
+ if (!isSatelliteEnabledOrBeingEnabled()) {
plogd("handleCmdUpdateNtnSignalStrengthReporting: ignore request, satellite is "
+ "disabled");
return;
diff --git a/src/java/com/android/internal/telephony/satellite/SatelliteSessionController.java b/src/java/com/android/internal/telephony/satellite/SatelliteSessionController.java
index 540d106..6e74ddb 100644
--- a/src/java/com/android/internal/telephony/satellite/SatelliteSessionController.java
+++ b/src/java/com/android/internal/telephony/satellite/SatelliteSessionController.java
@@ -986,6 +986,9 @@
@Override
public void accept(int result) {
plogd("requestSatelliteEnabled result=" + result);
+ if (result == SatelliteManager.SATELLITE_RESULT_SUCCESS) {
+ mSessionMetricsStats.addCountOfAutoExitDueToTnNetwork();
+ }
}
});
}
@@ -1710,7 +1713,6 @@
if (result == SATELLITE_RESULT_SUCCESS) {
mSessionMetricsStats.addCountOfAutoExitDueToScreenOff();
}
- // TODO(b/364738085): Add CountOfAutoExitDueToTnNetwork
}
});
}
diff --git a/src/java/com/android/internal/telephony/subscription/SubscriptionManagerService.java b/src/java/com/android/internal/telephony/subscription/SubscriptionManagerService.java
index 353493b..4e28d00 100644
--- a/src/java/com/android/internal/telephony/subscription/SubscriptionManagerService.java
+++ b/src/java/com/android/internal/telephony/subscription/SubscriptionManagerService.java
@@ -1450,8 +1450,8 @@
SatelliteController satelliteController = SatelliteController.getInstance();
boolean isSatelliteEnabledOrBeingEnabled = false;
if (satelliteController != null) {
- isSatelliteEnabledOrBeingEnabled = satelliteController.isSatelliteEnabled()
- || satelliteController.isSatelliteBeingEnabled();
+ isSatelliteEnabledOrBeingEnabled =
+ satelliteController.isSatelliteEnabledOrBeingEnabled();
}
if (!isSatelliteEnabledOrBeingEnabled) {
diff --git a/tests/telephonytests/src/com/android/internal/telephony/CarrierPrivilegesTrackerTest.java b/tests/telephonytests/src/com/android/internal/telephony/CarrierPrivilegesTrackerTest.java
index a860dff..1c58ef2 100644
--- a/tests/telephonytests/src/com/android/internal/telephony/CarrierPrivilegesTrackerTest.java
+++ b/tests/telephonytests/src/com/android/internal/telephony/CarrierPrivilegesTrackerTest.java
@@ -220,8 +220,9 @@
// Capture CarrierConfigChangeListener to emulate the carrier config change notification
ArgumentCaptor<CarrierConfigManager.CarrierConfigChangeListener> listenerArgumentCaptor =
ArgumentCaptor.forClass(CarrierConfigManager.CarrierConfigChangeListener.class);
- CarrierPrivilegesTracker cpt = new CarrierPrivilegesTracker(mTestableLooper.getLooper(),
- mPhone, mContext, mFeatureFlags);
+ CarrierPrivilegesTracker cpt =
+ new CarrierPrivilegesTracker(
+ mTestableLooper.getLooper(), mPhone, mContext, mFeatureFlags);
verify(mCarrierConfigManager).registerCarrierConfigChangeListener(any(),
listenerArgumentCaptor.capture());
mCarrierConfigChangeListener = listenerArgumentCaptor.getAllValues().get(0);
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 25e9715..2664ff3 100644
--- a/tests/telephonytests/src/com/android/internal/telephony/emergency/EmergencyStateTrackerTest.java
+++ b/tests/telephonytests/src/com/android/internal/telephony/emergency/EmergencyStateTrackerTest.java
@@ -346,7 +346,7 @@
true /* isRadioOn */);
when(mSST.isRadioOn()).thenReturn(true);
// Satellite enabled
- when(mSatelliteController.isSatelliteEnabled()).thenReturn(true);
+ when(mSatelliteController.isSatelliteEnabledOrBeingEnabled()).thenReturn(true);
setConfigForDdsSwitch(testPhone, null,
CarrierConfigManager.Gps.SUPL_EMERGENCY_MODE_TYPE_DP_ONLY, "150");
@@ -363,7 +363,7 @@
// isOkToCall() should return true once satellite modem is off
assertFalse(callback.getValue()
.isOkToCall(testPhone, ServiceState.STATE_IN_SERVICE, false));
- when(mSatelliteController.isSatelliteEnabled()).thenReturn(false);
+ when(mSatelliteController.isSatelliteEnabledOrBeingEnabled()).thenReturn(false);
assertTrue(callback.getValue()
.isOkToCall(testPhone, ServiceState.STATE_IN_SERVICE, false));
// Once radio on is complete, trigger delay dial
@@ -391,7 +391,7 @@
Phone testPhone = setupTestPhoneForEmergencyCall(false /* isRoaming */,
true /* isRadioOn */);
// Satellite enabled
- when(mSatelliteController.isSatelliteEnabled()).thenReturn(true);
+ when(mSatelliteController.isSatelliteEnabledOrBeingEnabled()).thenReturn(true);
CompletableFuture<Integer> future = emergencyStateTracker.startEmergencyCall(testPhone,
mTestConnection1, false);
diff --git a/tests/telephonytests/src/com/android/internal/telephony/emergency/RadioOnStateListenerTest.java b/tests/telephonytests/src/com/android/internal/telephony/emergency/RadioOnStateListenerTest.java
index bb349a7..e9bff91 100644
--- a/tests/telephonytests/src/com/android/internal/telephony/emergency/RadioOnStateListenerTest.java
+++ b/tests/telephonytests/src/com/android/internal/telephony/emergency/RadioOnStateListenerTest.java
@@ -104,7 +104,7 @@
*/
@Test
public void testRegisterForSatelliteCallback() {
- doReturn(true).when(mSatelliteController).isSatelliteEnabled();
+ doReturn(true).when(mSatelliteController).isSatelliteEnabledOrBeingEnabled();
mListener.waitForRadioOn(mMockPhone, mCallback, false, false, 0);
waitForHandlerAction(mListener.getHandler(), TIMEOUT_MS);
@@ -229,7 +229,7 @@
@Test
public void testTimeout_RetryFailure_WithSatellite() {
- doReturn(true).when(mSatelliteController).isSatelliteEnabled();
+ doReturn(true).when(mSatelliteController).isSatelliteEnabledOrBeingEnabled();
ServiceState state = new ServiceState();
state.setState(ServiceState.STATE_POWER_OFF);
when(mMockPhone.getState()).thenReturn(PhoneConstants.State.IDLE);
diff --git a/tests/telephonytests/src/com/android/internal/telephony/satellite/SatelliteControllerTest.java b/tests/telephonytests/src/com/android/internal/telephony/satellite/SatelliteControllerTest.java
index 64c1d58..1e30f82 100644
--- a/tests/telephonytests/src/com/android/internal/telephony/satellite/SatelliteControllerTest.java
+++ b/tests/telephonytests/src/com/android/internal/telephony/satellite/SatelliteControllerTest.java
@@ -1548,7 +1548,7 @@
public void testIsSatelliteEnabled() {
logd("testIsSatelliteEnabled: starting");
setUpResponseForRequestIsSatelliteEnabled(true, SATELLITE_RESULT_SUCCESS);
- assertFalse(mSatelliteControllerUT.isSatelliteEnabled());
+ assertFalse(mSatelliteControllerUT.isSatelliteEnabledOrBeingEnabled());
mIsSatelliteEnabledSemaphore.drainPermits();
mSatelliteControllerUT.requestIsSatelliteEnabled(mIsSatelliteEnabledReceiver);
processAllMessages();
@@ -1564,7 +1564,8 @@
mSatelliteControllerUT.requestIsSatelliteEnabled(mIsSatelliteEnabledReceiver);
processAllMessages();
assertEquals(SATELLITE_RESULT_SUCCESS, mQueriedIsSatelliteEnabledResultCode);
- assertEquals(mSatelliteControllerUT.isSatelliteEnabled(), mQueriedIsSatelliteEnabled);
+ assertEquals(mSatelliteControllerUT.isSatelliteEnabledOrBeingEnabled(),
+ mQueriedIsSatelliteEnabled);
}
@Test
diff --git a/tests/telephonytests/src/com/android/internal/telephony/satellite/SatelliteSessionControllerTest.java b/tests/telephonytests/src/com/android/internal/telephony/satellite/SatelliteSessionControllerTest.java
index a617182..bcada19 100644
--- a/tests/telephonytests/src/com/android/internal/telephony/satellite/SatelliteSessionControllerTest.java
+++ b/tests/telephonytests/src/com/android/internal/telephony/satellite/SatelliteSessionControllerTest.java
@@ -26,17 +26,21 @@
import static android.telephony.satellite.SatelliteManager.SATELLITE_DATAGRAM_TRANSFER_STATE_SENDING;
import static android.telephony.satellite.SatelliteManager.SATELLITE_DATAGRAM_TRANSFER_STATE_SEND_FAILED;
import static android.telephony.satellite.SatelliteManager.SATELLITE_DATAGRAM_TRANSFER_STATE_WAITING_TO_CONNECT;
+import static android.telephony.satellite.SatelliteManager.SATELLITE_RESULT_SUCCESS;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertTrue;
import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.ArgumentMatchers.anyBoolean;
import static org.mockito.ArgumentMatchers.anyInt;
import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.Mockito.clearInvocations;
+import static org.mockito.Mockito.doAnswer;
import static org.mockito.Mockito.doNothing;
import static org.mockito.Mockito.never;
+import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
@@ -58,6 +62,7 @@
import com.android.internal.telephony.IIntegerConsumer;
import com.android.internal.telephony.TelephonyTest;
import com.android.internal.telephony.flags.FeatureFlags;
+import com.android.internal.telephony.satellite.metrics.SessionMetricsStats;
import org.junit.After;
import org.junit.Before;
@@ -106,6 +111,7 @@
@Mock private DatagramDispatcher mMockDatagramDispatcher;
@Mock private DatagramController mMockDatagramController;
@Mock private ServiceState mMockServiceState;
+ @Mock private SessionMetricsStats mMockSessionMetricsStats;
@Captor ArgumentCaptor<Handler> mHandlerCaptor;
@Captor ArgumentCaptor<Integer> mMsgCaptor;
@@ -123,6 +129,8 @@
mMockSatelliteController);
replaceInstance(DatagramController.class, "sInstance", null,
mMockDatagramController);
+ replaceInstance(SessionMetricsStats.class, "sInstance", null,
+ mMockSessionMetricsStats);
Resources resources = mContext.getResources();
when(resources.getInteger(anyInt())).thenReturn(TEST_SATELLITE_TIMEOUT_MILLIS);
@@ -133,6 +141,10 @@
anyInt())).thenReturn(false);
when(mMockSatelliteController.isSatelliteEsosSupported(anyInt())).thenReturn(false);
when(mMockSatelliteController.getSatellitePhone()).thenReturn(mPhone);
+ when(mMockSessionMetricsStats.addCountOfAutoExitDueToScreenOff()).thenReturn(
+ mMockSessionMetricsStats);
+ when(mMockSessionMetricsStats.addCountOfAutoExitDueToTnNetwork()).thenReturn(
+ mMockSessionMetricsStats);
mSatelliteModemInterface = new TestSatelliteModemInterface(
mContext, mMockSatelliteController, Looper.myLooper(), mFeatureFlags);
mTestSatelliteSessionController = new TestSatelliteSessionController(mContext,
@@ -381,6 +393,7 @@
eq(mTestSatelliteSessionController.getHandler()), anyInt(), any());
when(mMockSatelliteController.isSatelliteAttachRequired()).thenReturn(false);
when(mPhone.getServiceState()).thenReturn(mMockServiceState);
+ setUpResponseForRequestSatelliteEnabled(SATELLITE_RESULT_SUCCESS);
// Since satellite is supported, SatelliteSessionController should move to POWER_OFF state.
assertNotNull(mTestSatelliteSessionController);
@@ -406,6 +419,7 @@
// Should not disable satellite
verify(mMockSatelliteController, never()).requestSatelliteEnabled(
eq(false), eq(false), eq(isEmergency), any(IIntegerConsumer.Stub.class));
+ verify(mMockSessionMetricsStats, never()).addCountOfAutoExitDueToTnNetwork();
// Notify cellular service is in STATE_IN_SERVICE.
ServiceState serviceState = new ServiceState();
@@ -419,6 +433,7 @@
// Should not disable satellite
verify(mMockSatelliteController, never()).requestSatelliteEnabled(
eq(false), eq(false), eq(isEmergency), any(IIntegerConsumer.Stub.class));
+ verify(mMockSessionMetricsStats, never()).addCountOfAutoExitDueToTnNetwork();
// Satellite is in emergency mode but emergency communication was not established.
// Disabling satellite was not allowed
@@ -431,7 +446,7 @@
// Should not disable satellite
verify(mMockSatelliteController, never()).requestSatelliteEnabled(
eq(false), eq(false), eq(isEmergency), any(IIntegerConsumer.Stub.class));
-
+ verify(mMockSessionMetricsStats, never()).addCountOfAutoExitDueToTnNetwork();
// Satellite is in emergency mode but emergency communication was not established.
// Disabling satellite was allowed
when(mMockSatelliteController.turnOffSatelliteSessionForEmergencyCall(
@@ -442,6 +457,7 @@
// Should disable satellite
verify(mMockSatelliteController).requestSatelliteEnabled(
eq(false), eq(false), eq(isEmergency), any(IIntegerConsumer.Stub.class));
+ verify(mMockSessionMetricsStats, times(1)).addCountOfAutoExitDueToTnNetwork();
}
@Test
@@ -1672,4 +1688,14 @@
msg.obj = new AsyncResult(null, screenOn, null);
h.sendMessage(msg);
}
+
+ private void setUpResponseForRequestSatelliteEnabled(
+ @SatelliteManager.SatelliteResult int expectedResult) {
+ doAnswer(invocation -> {
+ IIntegerConsumer integerConsumer = invocation.getArgument(3);
+ integerConsumer.accept(expectedResult);
+ return null;
+ }).when(mMockSatelliteController).requestSatelliteEnabled(anyBoolean(), anyBoolean(),
+ anyBoolean(), any(IIntegerConsumer.class));
+ }
}