Merge "Fix NPE in TestSatelliteService" into main
diff --git a/ecc/input/eccdata.txt b/ecc/input/eccdata.txt
index 83b5c39..fe11383 100644
--- a/ecc/input/eccdata.txt
+++ b/ecc/input/eccdata.txt
@@ -906,6 +906,16 @@
types: TYPE_UNSPECIFIED
routing: NORMAL
}
+ eccs {
+ phone_number: "028"
+ types: TYPE_UNSPECIFIED
+ routing: NORMAL
+ }
+ eccs {
+ phone_number: "116000"
+ types: TYPE_UNSPECIFIED
+ routing: NORMAL
+ }
ecc_fallback: "112"
}
countries {
diff --git a/ecc/output/eccdata b/ecc/output/eccdata
index 3f28a3a..55d8151 100644
--- a/ecc/output/eccdata
+++ b/ecc/output/eccdata
Binary files differ
diff --git a/res/values-pa/strings.xml b/res/values-pa/strings.xml
index c27fee6..8dd6abd 100644
--- a/res/values-pa/strings.xml
+++ b/res/values-pa/strings.xml
@@ -850,7 +850,7 @@
<string name="radio_info_ims_reg_status_not_registered" msgid="8045821447288876085">"ਰਜਿਸਟਰ ਨਹੀਂ ਕੀਤੀ ਗਈ"</string>
<string name="radio_info_ims_feature_status_available" msgid="6493200914756969292">"ਉਪਲਬਧ"</string>
<string name="radio_info_ims_feature_status_unavailable" msgid="8930391136839759778">"ਅਣਉਪਲਬਧ"</string>
- <string name="radio_info_ims_reg_status" msgid="25582845222446390">"IMS ਰਜਿਸਟਰੇਸ਼ਨ: <xliff:g id="STATUS">%1$s</xliff:g>\nLTE \'ਤੇ ਅਵਾਜ਼: <xliff:g id="AVAILABILITY_0">%2$s</xliff:g>\nਵਾਈ-ਫਾਈ \'ਤੇ ਅਵਾਜ਼ੀ ਕਾਲ: <xliff:g id="AVAILABILITY_1">%3$s</xliff:g>\nਵੀਡੀਓ ਕਾਲਿੰਗ: <xliff:g id="AVAILABILITY_2">%4$s</xliff:g>\nUT ਇੰਟਰਫੇਸ: <xliff:g id="AVAILABILITY_3">%5$s</xliff:g>"</string>
+ <string name="radio_info_ims_reg_status" msgid="25582845222446390">"IMS ਰਜਿਸਟਰੇਸ਼ਨ: <xliff:g id="STATUS">%1$s</xliff:g>\nLTE \'ਤੇ ਅਵਾਜ਼: <xliff:g id="AVAILABILITY_0">%2$s</xliff:g>\nਵਾਈ-ਫਾਈ \'ਤੇ ਅਵਾਜ਼ੀ ਕਾਲ: <xliff:g id="AVAILABILITY_1">%3$s</xliff:g>\nਵੀਡੀਓ ਕਾਲਿੰਗ: <xliff:g id="AVAILABILITY_2">%4$s</xliff:g>\nUT ਇੰਟਰਫ਼ੇਸ: <xliff:g id="AVAILABILITY_3">%5$s</xliff:g>"</string>
<string name="radioInfo_service_in" msgid="45753418231446400">"ਸੇਵਾ ਵਿੱਚ"</string>
<string name="radioInfo_service_out" msgid="287972405416142312">"ਸੇਵਾ ਵਿੱਚ ਨਹੀਂ"</string>
<string name="radioInfo_service_emergency" msgid="4763879891415016848">"ਸਿਰਫ਼ ਸੰਕਟਕਾਲੀਨ ਕਾਲਾਂ"</string>
diff --git a/src/com/android/phone/PhoneGlobals.java b/src/com/android/phone/PhoneGlobals.java
index b11431c..4773a83 100644
--- a/src/com/android/phone/PhoneGlobals.java
+++ b/src/com/android/phone/PhoneGlobals.java
@@ -554,7 +554,7 @@
mKeyguardManager = (KeyguardManager) getSystemService(Context.KEYGUARD_SERVICE);
- phoneMgr = PhoneInterfaceManager.init(this);
+ phoneMgr = PhoneInterfaceManager.init(this, featureFlags);
imsRcsController = ImsRcsController.init(this);
diff --git a/src/com/android/phone/PhoneInterfaceManager.java b/src/com/android/phone/PhoneInterfaceManager.java
index 26d1e73..4e673d8 100644
--- a/src/com/android/phone/PhoneInterfaceManager.java
+++ b/src/com/android/phone/PhoneInterfaceManager.java
@@ -209,6 +209,7 @@
import com.android.internal.telephony.domainselection.DomainSelectionResolver;
import com.android.internal.telephony.emergency.EmergencyNumberTracker;
import com.android.internal.telephony.euicc.EuiccConnector;
+import com.android.internal.telephony.flags.FeatureFlags;
import com.android.internal.telephony.ims.ImsResolver;
import com.android.internal.telephony.imsphone.ImsPhone;
import com.android.internal.telephony.imsphone.ImsPhoneCallTracker;
@@ -402,6 +403,7 @@
private static List<String> sThermalMitigationAllowlistedPackages = new ArrayList<>();
private final PhoneGlobals mApp;
+ private final FeatureFlags mFeatureFlags;
private final CallManager mCM;
private final ImsResolver mImsResolver;
@@ -2212,8 +2214,8 @@
onCompleted = obtainMessage(EVENT_PURCHASE_PREMIUM_CAPABILITY_DONE, request);
PurchasePremiumCapabilityArgument arg =
(PurchasePremiumCapabilityArgument) request.argument;
- SlicePurchaseController.getInstance(request.phone).purchasePremiumCapability(
- arg.capability, onCompleted);
+ SlicePurchaseController.getInstance(request.phone, mFeatureFlags)
+ .purchasePremiumCapability(arg.capability, onCompleted);
break;
}
@@ -2426,10 +2428,10 @@
* Initialize the singleton PhoneInterfaceManager instance.
* This is only done once, at startup, from PhoneApp.onCreate().
*/
- /* package */ static PhoneInterfaceManager init(PhoneGlobals app) {
+ /* package */ static PhoneInterfaceManager init(PhoneGlobals app, FeatureFlags featureFlags) {
synchronized (PhoneInterfaceManager.class) {
if (sInstance == null) {
- sInstance = new PhoneInterfaceManager(app);
+ sInstance = new PhoneInterfaceManager(app, featureFlags);
} else {
Log.wtf(LOG_TAG, "init() called multiple times! sInstance = " + sInstance);
}
@@ -2438,8 +2440,9 @@
}
/** Private constructor; @see init() */
- private PhoneInterfaceManager(PhoneGlobals app) {
+ private PhoneInterfaceManager(PhoneGlobals app, FeatureFlags featureFlags) {
mApp = app;
+ mFeatureFlags = featureFlags;
mCM = PhoneGlobals.getInstance().mCM;
mImsResolver = ImsResolver.getInstance();
mSatelliteController = SatelliteController.getInstance();
@@ -11542,7 +11545,7 @@
}
final long identity = Binder.clearCallingIdentity();
try {
- return SlicePurchaseController.getInstance(phone)
+ return SlicePurchaseController.getInstance(phone, mFeatureFlags)
.isPremiumCapabilityAvailableForPurchase(capability);
} finally {
Binder.restoreCallingIdentity(identity);
diff --git a/src/com/android/phone/slice/SlicePurchaseController.java b/src/com/android/phone/slice/SlicePurchaseController.java
index 26d70d2..9a42e16 100644
--- a/src/com/android/phone/slice/SlicePurchaseController.java
+++ b/src/com/android/phone/slice/SlicePurchaseController.java
@@ -58,6 +58,7 @@
import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.telephony.Phone;
+import com.android.internal.telephony.flags.FeatureFlags;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
@@ -309,6 +310,8 @@
/** The Phone instance used to create the SlicePurchaseController. */
@NonNull private final Phone mPhone;
+ /** Feature flags to control behavior and errors. */
+ @NonNull private final FeatureFlags mFeatureFlags;
/** The set of capabilities that are pending network setup. */
@NonNull private final Set<Integer> mPendingSetupCapabilities = new HashSet<>();
/** The set of throttled capabilities. */
@@ -417,10 +420,11 @@
logd("Slice purchase application unable to show notification for capability: "
+ TelephonyManager.convertPremiumCapabilityToString(capability)
+ " because the user has disabled notifications.");
+ int error = mFeatureFlags.slicingAdditionalErrorCodes()
+ ? TelephonyManager.PURCHASE_PREMIUM_CAPABILITY_RESULT_USER_DISABLED
+ : TelephonyManager.PURCHASE_PREMIUM_CAPABILITY_RESULT_USER_CANCELED;
SlicePurchaseController.getInstance(phoneId)
- .handlePurchaseResult(capability,
- TelephonyManager.PURCHASE_PREMIUM_CAPABILITY_RESULT_USER_DISABLED,
- true);
+ .handlePurchaseResult(capability, error, true);
break;
}
case ACTION_SLICE_PURCHASE_APP_RESPONSE_SUCCESS: {
@@ -449,14 +453,16 @@
* @param phone The Phone to get the SlicePurchaseController for.
* @return The static SlicePurchaseController instance.
*/
- @NonNull public static synchronized SlicePurchaseController getInstance(@NonNull Phone phone) {
+ @NonNull public static synchronized SlicePurchaseController getInstance(@NonNull Phone phone,
+ @NonNull FeatureFlags featureFlags) {
// TODO: Add listeners for multi sim setting changed (maybe carrier config changed too)
// that dismiss notifications and update SlicePurchaseController instance
int phoneId = phone.getPhoneId();
if (sInstances.get(phoneId) == null) {
HandlerThread handlerThread = new HandlerThread("SlicePurchaseController");
handlerThread.start();
- sInstances.put(phoneId, new SlicePurchaseController(phone, handlerThread.getLooper()));
+ sInstances.put(phoneId,
+ new SlicePurchaseController(phone, featureFlags, handlerThread.getLooper()));
}
return sInstances.get(phoneId);
}
@@ -476,12 +482,15 @@
* Create a SlicePurchaseController for the given phone on the given looper.
*
* @param phone The Phone to create the SlicePurchaseController for.
+ * @param featureFlags The FeatureFlags that are supported.
* @param looper The Looper to run the SlicePurchaseController on.
*/
@VisibleForTesting
- public SlicePurchaseController(@NonNull Phone phone, @NonNull Looper looper) {
+ public SlicePurchaseController(@NonNull Phone phone, @NonNull FeatureFlags featureFlags,
+ @NonNull Looper looper) {
super(looper);
mPhone = phone;
+ mFeatureFlags = featureFlags;
// TODO: Create a cached value for slicing config in DataIndication and initialize here
mPhone.mCi.registerForSlicingConfigChanged(this, EVENT_SLICING_CONFIG_CHANGED, null);
mIsSlicingUpsellEnabled = DeviceConfig.getBoolean(
diff --git a/src/com/android/services/telephony/TelephonyConnectionService.java b/src/com/android/services/telephony/TelephonyConnectionService.java
index b7bba84..b925c43 100644
--- a/src/com/android/services/telephony/TelephonyConnectionService.java
+++ b/src/com/android/services/telephony/TelephonyConnectionService.java
@@ -590,6 +590,24 @@
releaseEmergencyCallDomainSelection(false);
}
}
+
+ @Override
+ public void onConnectionPropertiesChanged(Connection connection,
+ int connectionProperties) {
+ if ((connection == null) || (mEmergencyStateTracker == null)) {
+ return;
+ }
+ TelephonyConnection c = (TelephonyConnection) connection;
+ com.android.internal.telephony.Connection origConn = c.getOriginalConnection();
+ if ((origConn == null) || (!origConn.getState().isAlive())) {
+ // ignore if there is no original connection alive
+ Log.i(this, "onConnectionPropertiesChanged without orig connection alive");
+ return;
+ }
+ Log.i(this, "onConnectionPropertiesChanged prop=" + connectionProperties);
+ mEmergencyStateTracker.onEmergencyCallPropertiesChanged(connectionProperties,
+ c.getTelecomCallId());
+ }
};
private final TelephonyConnection.TelephonyConnectionListener
diff --git a/testapps/TestSatelliteApp/src/com/android/phone/testapps/satellitetestapp/TestSatelliteService.java b/testapps/TestSatelliteApp/src/com/android/phone/testapps/satellitetestapp/TestSatelliteService.java
index 047c8d4..929a2e5 100644
--- a/testapps/TestSatelliteApp/src/com/android/phone/testapps/satellitetestapp/TestSatelliteService.java
+++ b/testapps/TestSatelliteApp/src/com/android/phone/testapps/satellitetestapp/TestSatelliteService.java
@@ -21,6 +21,8 @@
import android.content.Intent;
import android.os.Binder;
import android.os.IBinder;
+import android.telephony.IBooleanConsumer;
+import android.telephony.IIntegerConsumer;
import android.telephony.satellite.AntennaDirection;
import android.telephony.satellite.AntennaPosition;
import android.telephony.satellite.SatelliteManager;
@@ -36,8 +38,6 @@
import android.telephony.satellite.stub.SatelliteService;
import android.util.Log;
-import com.android.internal.telephony.IBooleanConsumer;
-import com.android.internal.telephony.IIntegerConsumer;
import com.android.internal.util.FunctionalUtils;
import com.android.telephony.Rlog;
diff --git a/tests/src/com/android/phone/PhoneInterfaceManagerTest.java b/tests/src/com/android/phone/PhoneInterfaceManagerTest.java
index e702279..bea4271 100644
--- a/tests/src/com/android/phone/PhoneInterfaceManagerTest.java
+++ b/tests/src/com/android/phone/PhoneInterfaceManagerTest.java
@@ -44,6 +44,7 @@
import com.android.internal.telephony.IIntegerConsumer;
import com.android.internal.telephony.Phone;
import com.android.internal.telephony.RILConstants;
+import com.android.internal.telephony.flags.FeatureFlags;
import com.android.internal.telephony.subscription.SubscriptionManagerService;
import org.junit.Before;
@@ -66,6 +67,8 @@
PhoneGlobals mPhoneGlobals;
@Mock
Phone mPhone;
+ @Mock
+ FeatureFlags mFeatureFlags;
@Mock
private SubscriptionManagerService mSubscriptionManagerService;
@@ -78,7 +81,7 @@
// global singleton, but the context that is passed in is unused if the phone app is already
// alive on a test devices. You must use the spy to mock behavior. Mocks stemming from the
// passed context will remain unused.
- mPhoneInterfaceManager = spy(PhoneInterfaceManager.init(mPhoneGlobals));
+ mPhoneInterfaceManager = spy(PhoneInterfaceManager.init(mPhoneGlobals, mFeatureFlags));
doReturn(mSubscriptionManagerService).when(mPhoneInterfaceManager)
.getSubscriptionManagerService();
TelephonyManager.setupISubForTest(mSubscriptionManagerService);
diff --git a/tests/src/com/android/phone/slice/SlicePurchaseControllerTest.java b/tests/src/com/android/phone/slice/SlicePurchaseControllerTest.java
index ca67d63..5637c3a 100644
--- a/tests/src/com/android/phone/slice/SlicePurchaseControllerTest.java
+++ b/tests/src/com/android/phone/slice/SlicePurchaseControllerTest.java
@@ -62,6 +62,7 @@
import com.android.internal.telephony.CommandsInterface;
import com.android.internal.telephony.Phone;
import com.android.internal.telephony.data.DataSettingsManager;
+import com.android.internal.telephony.flags.FeatureFlags;
import org.junit.Before;
import org.junit.Test;
@@ -92,6 +93,7 @@
private static final long THROTTLE_TIMEOUT = 4000;
@Mock Phone mPhone;
+ @Mock FeatureFlags mFeatureFlags;
@Mock CarrierConfigManager mCarrierConfigManager;
@Mock CommandsInterface mCommandsInterface;
@Mock ServiceState mServiceState;
@@ -153,7 +155,7 @@
// create a spy to mock final PendingIntent methods
SlicePurchaseController slicePurchaseController =
- new SlicePurchaseController(mPhone, mHandler.getLooper());
+ new SlicePurchaseController(mPhone, mFeatureFlags, mHandler.getLooper());
mSlicePurchaseController = spy(slicePurchaseController);
doReturn(null).when(mSlicePurchaseController).createPendingIntent(
anyString(), anyInt(), anyBoolean());
@@ -644,6 +646,7 @@
@Test
public void testPurchasePremiumCapabilityResultNotificationsDisabled() {
+ doReturn(true).when(mFeatureFlags).slicingAdditionalErrorCodes();
sendValidPurchaseRequest();
// broadcast NOTIFICATIONS_DISABLED response from slice purchase application
diff --git a/tests/src/com/android/services/telephony/TelephonyConnectionServiceTest.java b/tests/src/com/android/services/telephony/TelephonyConnectionServiceTest.java
index f0d19f1..d467def 100644
--- a/tests/src/com/android/services/telephony/TelephonyConnectionServiceTest.java
+++ b/tests/src/com/android/services/telephony/TelephonyConnectionServiceTest.java
@@ -16,6 +16,7 @@
package com.android.services.telephony;
+import static android.telecom.Connection.PROPERTY_WIFI;
import static android.telephony.DisconnectCause.EMERGENCY_PERM_FAILURE;
import static android.telephony.DisconnectCause.EMERGENCY_TEMP_FAILURE;
import static android.telephony.DisconnectCause.ERROR_UNSPECIFIED;
@@ -3018,6 +3019,52 @@
}
@Test
+ public void testDomainSelectionListenOriginalConnectionPropertiesChange() throws Exception {
+ setupForCallTest();
+
+ int selectedDomain = DOMAIN_PS;
+
+ setupForDialForDomainSelection(mPhone0, selectedDomain, true);
+
+ mTestConnectionService.onCreateOutgoingConnection(PHONE_ACCOUNT_HANDLE_1,
+ createConnectionRequest(PHONE_ACCOUNT_HANDLE_1,
+ TEST_EMERGENCY_NUMBER, TELECOM_CALL_ID1));
+
+ verify(mDomainSelectionResolver)
+ .getDomainSelectionConnection(eq(mPhone0), eq(SELECTOR_TYPE_CALLING), eq(true));
+ verify(mEmergencyStateTracker)
+ .startEmergencyCall(eq(mPhone0), eq(TELECOM_CALL_ID1), eq(false));
+ verify(mEmergencyCallDomainSelectionConnection).createEmergencyConnection(any(), any());
+ verify(mPhone0).dial(anyString(), any(), any());
+
+ TestTelephonyConnection c = new TestTelephonyConnection();
+ c.setTelecomCallId(TELECOM_CALL_ID1);
+ c.setIsImsConnection(true);
+ Connection orgConn = c.getOriginalConnection();
+ doReturn(PhoneConstants.PHONE_TYPE_IMS).when(orgConn).getPhoneType();
+
+ TelephonyConnection.TelephonyConnectionListener connectionListener =
+ mTestConnectionService.getEmergencyConnectionListener();
+
+ doReturn(Call.State.DISCONNECTING).when(orgConn).getState();
+ connectionListener.onConnectionPropertiesChanged(c, PROPERTY_WIFI);
+
+ verify(mEmergencyStateTracker, times(0)).onEmergencyCallPropertiesChanged(
+ anyInt(), anyString());
+
+ doReturn(Call.State.ACTIVE).when(orgConn).getState();
+ connectionListener.onConnectionPropertiesChanged(c, PROPERTY_WIFI);
+
+ verify(mEmergencyStateTracker, times(1)).onEmergencyCallPropertiesChanged(
+ eq(PROPERTY_WIFI), eq(TELECOM_CALL_ID1));
+
+ connectionListener.onConnectionPropertiesChanged(c, 0);
+
+ verify(mEmergencyStateTracker, times(1)).onEmergencyCallPropertiesChanged(
+ eq(0), eq(TELECOM_CALL_ID1));
+ }
+
+ @Test
public void testDomainSelectionTempFailure() throws Exception {
setupForCallTest();