Merge "Add additional field into sms atoms for satellite service" into 24D1-dev
diff --git a/src/java/com/android/internal/telephony/emergency/EmergencyStateTracker.java b/src/java/com/android/internal/telephony/emergency/EmergencyStateTracker.java
index e2a23f2..1c8b696 100644
--- a/src/java/com/android/internal/telephony/emergency/EmergencyStateTracker.java
+++ b/src/java/com/android/internal/telephony/emergency/EmergencyStateTracker.java
@@ -19,7 +19,9 @@
import static android.telecom.Connection.STATE_ACTIVE;
import static android.telecom.Connection.STATE_DISCONNECTED;
import static android.telephony.CarrierConfigManager.ImsEmergency.KEY_EMERGENCY_CALLBACK_MODE_SUPPORTED_BOOL;
+import static android.telephony.CarrierConfigManager.KEY_BROADCAST_EMERGENCY_CALL_STATE_CHANGES_BOOL;
+import static com.android.internal.telephony.TelephonyIntents.ACTION_EMERGENCY_CALL_STATE_CHANGED;
import static com.android.internal.telephony.emergency.EmergencyConstants.MODE_EMERGENCY_CALLBACK;
import static com.android.internal.telephony.emergency.EmergencyConstants.MODE_EMERGENCY_NONE;
import static com.android.internal.telephony.emergency.EmergencyConstants.MODE_EMERGENCY_WWAN;
@@ -159,6 +161,7 @@
private boolean mIsTestEmergencyNumber;
private Runnable mOnEcmExitCompleteRunnable;
private int mOngoingCallProperties;
+ private boolean mSentEmergencyCallState;
/** For emergency SMS */
private final Set<String> mOngoingEmergencySmsIds = new ArraySet<>();
@@ -174,6 +177,8 @@
private final android.util.ArrayMap<Integer, Boolean> mNoSimEcbmSupported =
new android.util.ArrayMap<>();
+ private final android.util.ArrayMap<Integer, Boolean> mBroadcastEmergencyCallStateChanges =
+ new android.util.ArrayMap<>();
private final CarrierConfigManager.CarrierConfigChangeListener mCarrierConfigChangeListener =
(slotIndex, subId, carrierId, specificCarrierId) -> onCarrierConfigurationChanged(
slotIndex, subId);
@@ -466,6 +471,9 @@
mTelephonyManagerProxy = new TelephonyManagerProxyImpl(context);
registerForNewRingingConnection();
+
+ // To recover the abnormal state after crash of com.android.phone process
+ maybeResetEmergencyCallStateChangedIntent();
}
/**
@@ -581,6 +589,7 @@
mPhone = phone;
mOngoingConnection = c;
mIsTestEmergencyNumber = isTestEmergencyNumber;
+ sendEmergencyCallStateChange(mPhone, true);
maybeRejectIncomingCall(null);
return mCallEmergencyModeFuture;
}
@@ -589,6 +598,7 @@
mPhone = phone;
mOngoingConnection = c;
mIsTestEmergencyNumber = isTestEmergencyNumber;
+ sendEmergencyCallStateChange(mPhone, true);
maybeRejectIncomingCall(result -> {
Rlog.i(TAG, "maybeRejectIncomingCall : result = " + result);
turnOnRadioAndSwitchDds(mPhone, EMERGENCY_TYPE_CALL, mIsTestEmergencyNumber);
@@ -611,6 +621,7 @@
if (Objects.equals(mOngoingConnection, c)) {
mOngoingConnection = null;
mOngoingCallProperties = 0;
+ sendEmergencyCallStateChange(mPhone, false);
}
if (wasActive && mActiveEmergencyCalls.isEmpty()
@@ -1199,6 +1210,18 @@
&& mEmergencyCallDomain == NetworkRegistrationInfo.DOMAIN_CS && isInEcm();
}
+ private void sendEmergencyCallStateChange(Phone phone, boolean isAlive) {
+ if ((isAlive && !mSentEmergencyCallState && getBroadcastEmergencyCallStateChanges(phone))
+ || (!isAlive && mSentEmergencyCallState)) {
+ mSentEmergencyCallState = isAlive;
+ Rlog.i(TAG, "sendEmergencyCallStateChange: " + isAlive);
+ Intent intent = new Intent(ACTION_EMERGENCY_CALL_STATE_CHANGED);
+ intent.putExtra(TelephonyManager.EXTRA_PHONE_IN_EMERGENCY_CALL, isAlive);
+ SubscriptionManager.putPhoneIdAndSubIdExtra(intent, phone.getPhoneId());
+ mContext.sendStickyBroadcastAsUser(intent, UserHandle.ALL);
+ }
+ }
+
/**
* Starts the process of an emergency SMS.
*
@@ -1654,9 +1677,9 @@
private boolean getConfig(int subId, String key, boolean defVal) {
return getConfigBundle(subId, key).getBoolean(key, defVal);
}
- private PersistableBundle getConfigBundle(int subId, String key) {
+ private PersistableBundle getConfigBundle(int subId, String... keys) {
if (mConfigManager == null) return new PersistableBundle();
- return mConfigManager.getConfigForSubId(subId, key);
+ return mConfigManager.getConfigForSubId(subId, keys);
}
/**
@@ -1710,10 +1733,6 @@
return;
}
- updateNoSimEcbmSupported(slotIndex, subId);
- }
-
- private void updateNoSimEcbmSupported(int slotIndex, int subId) {
SharedPreferences sp = null;
Boolean savedConfig = mNoSimEcbmSupported.get(Integer.valueOf(slotIndex));
if (savedConfig == null) {
@@ -1721,8 +1740,8 @@
savedConfig = Boolean.valueOf(
sp.getBoolean(KEY_NO_SIM_ECBM_SUPPORT + slotIndex, false));
mNoSimEcbmSupported.put(Integer.valueOf(slotIndex), savedConfig);
- Rlog.i(TAG, "updateNoSimEcbmSupported load from preference slotIndex=" + slotIndex
- + ", supported=" + savedConfig);
+ Rlog.i(TAG, "onCarrierConfigChanged load from preference slotIndex=" + slotIndex
+ + ", ecbmSupported=" + savedConfig);
}
if (!SubscriptionManager.isValidSubscriptionId(subId)) {
@@ -1730,17 +1749,28 @@
return;
}
- PersistableBundle b = getConfigBundle(subId, KEY_EMERGENCY_CALLBACK_MODE_SUPPORTED_BOOL);
+ PersistableBundle b = getConfigBundle(subId,
+ KEY_EMERGENCY_CALLBACK_MODE_SUPPORTED_BOOL,
+ KEY_BROADCAST_EMERGENCY_CALL_STATE_CHANGES_BOOL);
if (b.isEmpty()) {
- Rlog.e(TAG, "updateNoSimEcbmSupported empty result");
+ Rlog.e(TAG, "onCarrierConfigChanged empty result");
return;
}
if (!CarrierConfigManager.isConfigForIdentifiedCarrier(b)) {
- Rlog.i(TAG, "updateNoSimEcbmSupported not carrier specific configuration");
+ Rlog.i(TAG, "onCarrierConfigChanged not carrier specific configuration");
return;
}
+ // KEY_BROADCAST_EMERGENCY_CALL_STATE_CHANGES_BOOL
+ boolean broadcast = b.getBoolean(KEY_BROADCAST_EMERGENCY_CALL_STATE_CHANGES_BOOL);
+ mBroadcastEmergencyCallStateChanges.put(
+ Integer.valueOf(slotIndex), Boolean.valueOf(broadcast));
+
+ Rlog.i(TAG, "onCarrierConfigChanged slotIndex=" + slotIndex
+ + ", broadcastEmergencyCallStateChanges=" + broadcast);
+
+ // KEY_EMERGENCY_CALLBACK_MODE_SUPPORTED_BOOL
boolean carrierConfig = b.getBoolean(KEY_EMERGENCY_CALLBACK_MODE_SUPPORTED_BOOL);
if (carrierConfig == savedConfig) {
return;
@@ -1755,8 +1785,34 @@
editor.putBoolean(KEY_NO_SIM_ECBM_SUPPORT + slotIndex, carrierConfig);
editor.apply();
- Rlog.i(TAG, "updateNoSimEcbmSupported preference updated slotIndex=" + slotIndex
- + ", supported=" + carrierConfig);
+ Rlog.i(TAG, "onCarrierConfigChanged preference updated slotIndex=" + slotIndex
+ + ", ecbmSupported=" + carrierConfig);
+ }
+
+ private boolean getBroadcastEmergencyCallStateChanges(Phone phone) {
+ Boolean broadcast = mBroadcastEmergencyCallStateChanges.get(
+ Integer.valueOf(phone.getPhoneId()));
+ return (broadcast == null) ? false : broadcast;
+ }
+
+ /**
+ * Resets the emergency call state if it's in alive state.
+ */
+ @VisibleForTesting
+ public void maybeResetEmergencyCallStateChangedIntent() {
+ Intent intent = mContext.registerReceiver(null,
+ new IntentFilter(ACTION_EMERGENCY_CALL_STATE_CHANGED), Context.RECEIVER_NOT_EXPORTED);
+ if (intent != null
+ && ACTION_EMERGENCY_CALL_STATE_CHANGED.equals(intent.getAction())) {
+ boolean isAlive = intent.getBooleanExtra(
+ TelephonyManager.EXTRA_PHONE_IN_EMERGENCY_CALL, false);
+ Rlog.i(TAG, "maybeResetEmergencyCallStateChangedIntent isAlive=" + isAlive);
+ if (isAlive) {
+ intent = new Intent(ACTION_EMERGENCY_CALL_STATE_CHANGED);
+ intent.putExtra(TelephonyManager.EXTRA_PHONE_IN_EMERGENCY_CALL, false);
+ mContext.sendStickyBroadcastAsUser(intent, UserHandle.ALL);
+ }
+ }
}
/**
diff --git a/src/java/com/android/internal/telephony/satellite/SatelliteConfig.java b/src/java/com/android/internal/telephony/satellite/SatelliteConfig.java
index 8d7e723..60950f2 100644
--- a/src/java/com/android/internal/telephony/satellite/SatelliteConfig.java
+++ b/src/java/com/android/internal/telephony/satellite/SatelliteConfig.java
@@ -228,6 +228,10 @@
*/
@VisibleForTesting(visibility = VisibleForTesting.Visibility.PRIVATE)
public boolean isFileExist(Path filePath) {
+ if (filePath == null) {
+ Log.d(TAG, "isFileExist : filePath is null");
+ return false;
+ }
return Files.exists(filePath);
}
}
diff --git a/src/java/com/android/internal/telephony/satellite/SatelliteSessionController.java b/src/java/com/android/internal/telephony/satellite/SatelliteSessionController.java
index 5c79c28..458e8e7 100644
--- a/src/java/com/android/internal/telephony/satellite/SatelliteSessionController.java
+++ b/src/java/com/android/internal/telephony/satellite/SatelliteSessionController.java
@@ -431,6 +431,9 @@
case EVENT_SATELLITE_ENABLED_STATE_CHANGED:
handleSatelliteEnabledStateChanged((boolean) msg.obj);
break;
+ case EVENT_SATELLITE_MODEM_STATE_CHANGED:
+ deferMessage(msg);
+ break;
}
// Ignore all unexpected events.
return HANDLED;
@@ -443,6 +446,14 @@
} else {
transitionTo(mIdleState);
}
+ } else {
+ /*
+ * During the state transition from POWER_OFF to NOT_CONNECTED, modem might be
+ * reset. In such cases, we need to remove all deferred
+ * EVENT_SATELLITE_MODEM_STATE_CHANGED events so that they will not mess up our
+ * state machine later.
+ */
+ removeDeferredMessages(EVENT_SATELLITE_MODEM_STATE_CHANGED);
}
}
}
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 2acc667..699ee7b 100644
--- a/tests/telephonytests/src/com/android/internal/telephony/emergency/EmergencyStateTrackerTest.java
+++ b/tests/telephonytests/src/com/android/internal/telephony/emergency/EmergencyStateTrackerTest.java
@@ -36,6 +36,7 @@
import static org.mockito.Mockito.any;
import static org.mockito.Mockito.anyBoolean;
import static org.mockito.Mockito.anyInt;
+import static org.mockito.Mockito.anyVararg;
import static org.mockito.Mockito.doAnswer;
import static org.mockito.Mockito.doNothing;
import static org.mockito.Mockito.doReturn;
@@ -49,10 +50,12 @@
import android.content.Context;
import android.content.Intent;
+import android.content.IntentFilter;
import android.os.AsyncResult;
import android.os.Handler;
import android.os.Looper;
import android.os.Message;
+import android.os.PersistableBundle;
import android.os.UserHandle;
import android.provider.Settings;
import android.telephony.AccessNetworkConstants;
@@ -74,6 +77,7 @@
import com.android.internal.telephony.GsmCdmaPhone;
import com.android.internal.telephony.Phone;
import com.android.internal.telephony.PhoneConstants;
+import com.android.internal.telephony.TelephonyIntents;
import com.android.internal.telephony.TelephonyTest;
import com.android.internal.telephony.data.PhoneSwitcher;
@@ -2326,6 +2330,8 @@
false /* isRadioOn */);
when(phone.getSubId()).thenReturn(1);
setEcmSupportedConfig(phone, true);
+ PersistableBundle bundle = mCarrierConfigManager.getConfigForSubId(phone.getSubId());
+ doReturn(bundle).when(mCarrierConfigManager).getConfigForSubId(anyInt(), anyVararg());
EmergencyStateTracker testEst = setupEmergencyStateTracker(
false /* isSuplDdsSwitchRequiredForEmergencyCall */);
@@ -2675,6 +2681,162 @@
}
}
+ /**
+ * Test that emergency call state changes are sent.
+ */
+ @Test
+ @SmallTest
+ public void testSendEmergencyCallStateChanges() {
+ mContextFixture.getCarrierConfigBundle().putBoolean(
+ CarrierConfigManager.KEY_CARRIER_CONFIG_APPLIED_BOOL, true);
+ // Setup EmergencyStateTracker
+ EmergencyStateTracker emergencyStateTracker = setupEmergencyStateTracker(
+ /* isSuplDdsSwitchRequiredForEmergencyCall= */ true);
+ // Create test Phone
+ Phone testPhone = setupTestPhoneForEmergencyCall(/* isRoaming= */ true,
+ /* isRadioOn= */ true);
+ when(testPhone.getSubId()).thenReturn(1);
+ ArgumentCaptor<CarrierConfigManager.CarrierConfigChangeListener> listenerArgumentCaptor =
+ ArgumentCaptor.forClass(CarrierConfigManager.CarrierConfigChangeListener.class);
+ CarrierConfigManager cfgManager = (CarrierConfigManager) mContext
+ .getSystemService(Context.CARRIER_CONFIG_SERVICE);
+
+ verify(cfgManager).registerCarrierConfigChangeListener(any(),
+ listenerArgumentCaptor.capture());
+
+ CarrierConfigManager.CarrierConfigChangeListener carrierConfigChangeListener =
+ listenerArgumentCaptor.getAllValues().get(0);
+
+ assertNotNull(carrierConfigChangeListener);
+
+ PersistableBundle bundle = mCarrierConfigManager.getConfigForSubId(testPhone.getSubId());
+ bundle.putBoolean(CarrierConfigManager.KEY_BROADCAST_EMERGENCY_CALL_STATE_CHANGES_BOOL,
+ true);
+ doReturn(bundle).when(mCarrierConfigManager).getConfigForSubId(anyInt(), anyVararg());
+ // onCarrierConfigChanged with valid subscription
+ carrierConfigChangeListener.onCarrierConfigChanged(
+ testPhone.getPhoneId(), testPhone.getSubId(),
+ TelephonyManager.UNKNOWN_CARRIER_ID, TelephonyManager.UNKNOWN_CARRIER_ID);
+
+ // Start emergency call
+ CompletableFuture<Integer> unused = emergencyStateTracker.startEmergencyCall(testPhone,
+ mTestConnection1, false);
+
+ // Verify intent is sent that emergency call state is changed
+ ArgumentCaptor<Intent> intentCaptor = ArgumentCaptor.forClass(Intent.class);
+ verify(mContext, times(1)).sendStickyBroadcastAsUser(
+ intentCaptor.capture(), eq(UserHandle.ALL));
+ Intent intent = intentCaptor.getValue();
+ assertNotNull(intent);
+ assertEquals(TelephonyIntents.ACTION_EMERGENCY_CALL_STATE_CHANGED, intent.getAction());
+ assertTrue(intent.getBooleanExtra(TelephonyManager.EXTRA_PHONE_IN_EMERGENCY_CALL, true));
+
+ // End emergency call
+ emergencyStateTracker.endCall(mTestConnection1);
+
+ // Verify intent is sent that emergency call state is changed
+ verify(mContext, times(2)).sendStickyBroadcastAsUser(
+ intentCaptor.capture(), eq(UserHandle.ALL));
+ intent = intentCaptor.getValue();
+ assertNotNull(intent);
+ assertEquals(TelephonyIntents.ACTION_EMERGENCY_CALL_STATE_CHANGED, intent.getAction());
+ assertFalse(intent.getBooleanExtra(TelephonyManager.EXTRA_PHONE_IN_EMERGENCY_CALL, false));
+ }
+
+ /**
+ * Test that emergency call state change is reset after crash.
+ */
+ @Test
+ @SmallTest
+ public void testResetEmergencyCallStateChanges() {
+ Intent intent = new Intent(TelephonyIntents.ACTION_EMERGENCY_CALL_STATE_CHANGED);
+ intent.putExtra(TelephonyManager.EXTRA_PHONE_IN_EMERGENCY_CALL, true);
+ doReturn(intent).when(mContext).registerReceiver(eq(null), any(),
+ eq(Context.RECEIVER_NOT_EXPORTED));
+ // Setup EmergencyStateTracker
+ EmergencyStateTracker emergencyStateTracker = setupEmergencyStateTracker(
+ /* isSuplDdsSwitchRequiredForEmergencyCall= */ true);
+ emergencyStateTracker.maybeResetEmergencyCallStateChangedIntent();
+
+ ArgumentCaptor<IntentFilter> filterCaptor = ArgumentCaptor.forClass(IntentFilter.class);
+
+ verify(mContext).registerReceiver(eq(null), filterCaptor.capture(),
+ eq(Context.RECEIVER_NOT_EXPORTED));
+
+ IntentFilter filter = filterCaptor.getValue();
+
+ assertNotNull(filter);
+ assertTrue(filter.hasAction(TelephonyIntents.ACTION_EMERGENCY_CALL_STATE_CHANGED));
+
+ ArgumentCaptor<Intent> intentCaptor = ArgumentCaptor.forClass(Intent.class);
+
+ // Verify intent is sent that emergency call state is changed
+ verify(mContext).sendStickyBroadcastAsUser(
+ intentCaptor.capture(), eq(UserHandle.ALL));
+ intent = intentCaptor.getValue();
+ assertNotNull(intent);
+ assertEquals(TelephonyIntents.ACTION_EMERGENCY_CALL_STATE_CHANGED, intent.getAction());
+ assertFalse(intent.getBooleanExtra(TelephonyManager.EXTRA_PHONE_IN_EMERGENCY_CALL, false));
+ }
+
+ /**
+ * Test that emergency call state is not reset after crash
+ * if it's already reset.
+ */
+ @Test
+ @SmallTest
+ public void testResetEmergencyCallStateChangesAlreadyReset() {
+ Intent intent = new Intent(TelephonyIntents.ACTION_EMERGENCY_CALL_STATE_CHANGED);
+ intent.putExtra(TelephonyManager.EXTRA_PHONE_IN_EMERGENCY_CALL, false);
+ doReturn(intent).when(mContext).registerReceiver(eq(null), any(),
+ eq(Context.RECEIVER_NOT_EXPORTED));
+ // Setup EmergencyStateTracker
+ EmergencyStateTracker emergencyStateTracker = setupEmergencyStateTracker(
+ /* isSuplDdsSwitchRequiredForEmergencyCall= */ true);
+ emergencyStateTracker.maybeResetEmergencyCallStateChangedIntent();
+
+ ArgumentCaptor<IntentFilter> filterCaptor = ArgumentCaptor.forClass(IntentFilter.class);
+
+ verify(mContext).registerReceiver(eq(null), filterCaptor.capture(),
+ eq(Context.RECEIVER_NOT_EXPORTED));
+
+ IntentFilter filter = filterCaptor.getValue();
+
+ assertNotNull(filter);
+ assertTrue(filter.hasAction(TelephonyIntents.ACTION_EMERGENCY_CALL_STATE_CHANGED));
+
+ // Verify intent is not sent.
+ verify(mContext, never()).sendStickyBroadcastAsUser(any(), any());
+ }
+
+ /**
+ * Test that emergency call state is not reset after crash
+ * if it has never been sent.
+ */
+ @Test
+ @SmallTest
+ public void testResetEmergencyCallStateChangesNotSent() {
+ doReturn(null).when(mContext).registerReceiver(eq(null), any(),
+ eq(Context.RECEIVER_NOT_EXPORTED));
+ // Setup EmergencyStateTracker
+ EmergencyStateTracker emergencyStateTracker = setupEmergencyStateTracker(
+ /* isSuplDdsSwitchRequiredForEmergencyCall= */ true);
+ emergencyStateTracker.maybeResetEmergencyCallStateChangedIntent();
+
+ ArgumentCaptor<IntentFilter> filterCaptor = ArgumentCaptor.forClass(IntentFilter.class);
+
+ verify(mContext).registerReceiver(eq(null), filterCaptor.capture(),
+ eq(Context.RECEIVER_NOT_EXPORTED));
+
+ IntentFilter filter = filterCaptor.getValue();
+
+ assertNotNull(filter);
+ assertTrue(filter.hasAction(TelephonyIntents.ACTION_EMERGENCY_CALL_STATE_CHANGED));
+
+ // Verify intent is not sent.
+ verify(mContext, never()).sendStickyBroadcastAsUser(any(), any());
+ }
+
private EmergencyStateTracker setupEmergencyStateTracker(
boolean isSuplDdsSwitchRequiredForEmergencyCall) {
doReturn(mPhoneSwitcher).when(mPhoneSwitcherProxy).getPhoneSwitcher();
diff --git a/tests/telephonytests/src/com/android/internal/telephony/satellite/SatelliteConfigParserTest.java b/tests/telephonytests/src/com/android/internal/telephony/satellite/SatelliteConfigParserTest.java
index e4f0255..5e1dd05 100644
--- a/tests/telephonytests/src/com/android/internal/telephony/satellite/SatelliteConfigParserTest.java
+++ b/tests/telephonytests/src/com/android/internal/telephony/satellite/SatelliteConfigParserTest.java
@@ -17,6 +17,7 @@
package com.android.internal.telephony.satellite;
import static junit.framework.Assert.assertNotNull;
+import static junit.framework.TestCase.assertFalse;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotEquals;
@@ -185,27 +186,26 @@
final String filePath = "/data/user_de/0/com.android.phone/app_satellite/s2_cell_file";
Path targetSatS2FilePath = Paths.get(filePath);
- SatelliteConfigParser mockedSatelliteConfigParserNull = spy(
+ SatelliteConfigParser spySatelliteConfigParserNull = spy(
new SatelliteConfigParser((byte[]) null));
- assertNotNull(mockedSatelliteConfigParserNull);
- assertNull(mockedSatelliteConfigParserNull.getConfig());
+ assertNotNull(spySatelliteConfigParserNull);
+ assertNull(spySatelliteConfigParserNull.getConfig());
- SatelliteConfigParser mockedSatelliteConfigParserPlaceholder = spy(
+ SatelliteConfigParser spySatelliteConfigParserPlaceholder = spy(
new SatelliteConfigParser("test".getBytes()));
- assertNotNull(mockedSatelliteConfigParserPlaceholder);
- assertNull(mockedSatelliteConfigParserPlaceholder.getConfig());
+ assertNotNull(spySatelliteConfigParserPlaceholder);
+ assertNull(spySatelliteConfigParserPlaceholder.getConfig());
- SatelliteConfigParser mockedSatelliteConfigParser =
+ SatelliteConfigParser spySatelliteConfigParser =
spy(new SatelliteConfigParser(mBytesProtoBuffer));
+ assertNotNull(spySatelliteConfigParser.getConfig());
+ assertFalse(spySatelliteConfigParser.getConfig().isFileExist(null));
+
SatelliteConfig mockedSatelliteConfig = Mockito.mock(SatelliteConfig.class);
doReturn(targetSatS2FilePath).when(mockedSatelliteConfig).getSatelliteS2CellFile(any());
- doReturn(mockedSatelliteConfig).when(mockedSatelliteConfigParser).getConfig();
-// assertNotNull(mockedSatelliteConfigParser.getConfig());
-// doReturn(false).when(mockedSatelliteConfigParser).getConfig().isFileExist(any());
-// doReturn(targetSatS2FilePath).when(mockedSatelliteConfigParser).getConfig()
-// .copySatS2FileToPhoneDirectory(any(), any());
+ doReturn(mockedSatelliteConfig).when(spySatelliteConfigParser).getConfig();
assertEquals(targetSatS2FilePath,
- mockedSatelliteConfigParser.getConfig().getSatelliteS2CellFile(mContext));
+ spySatelliteConfigParser.getConfig().getSatelliteS2CellFile(mContext));
}
@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 a1c2cfc..f0a18e8 100644
--- a/tests/telephonytests/src/com/android/internal/telephony/satellite/SatelliteSessionControllerTest.java
+++ b/tests/telephonytests/src/com/android/internal/telephony/satellite/SatelliteSessionControllerTest.java
@@ -53,6 +53,8 @@
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
+import java.util.ArrayList;
+import java.util.List;
import java.util.concurrent.Semaphore;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicInteger;
@@ -804,6 +806,93 @@
assertSuccessfulModemStateChangedCallback(mTestSatelliteModemStateCallback,
SatelliteManager.SATELLITE_MODEM_STATE_IDLE);
assertEquals(STATE_IDLE, mTestSatelliteSessionController.getCurrentStateName());
+
+ // Power off the modem.
+ mTestSatelliteSessionController.onSatelliteEnabledStateChanged(false);
+ processAllMessages();
+
+ // SatelliteSessionController should move to POWER_OFF
+ assertSuccessfulModemStateChangedCallback(
+ mTestSatelliteModemStateCallback, SatelliteManager.SATELLITE_MODEM_STATE_OFF);
+ assertEquals(STATE_POWER_OFF, mTestSatelliteSessionController.getCurrentStateName());
+
+ mTestSatelliteSessionController.onSatelliteModemStateChanged(
+ SatelliteManager.SATELLITE_MODEM_STATE_NOT_CONNECTED);
+ mTestSatelliteSessionController.onSatelliteModemStateChanged(
+ SatelliteManager.SATELLITE_MODEM_STATE_CONNECTED);
+ mTestSatelliteSessionController.onSatelliteModemStateChanged(
+ SatelliteManager.SATELLITE_MODEM_STATE_NOT_CONNECTED);
+ processAllMessages();
+
+ // The modem state changed events should be deferred
+ assertModemStateChangedCallbackNotCalled(mTestSatelliteModemStateCallback);
+ assertEquals(STATE_POWER_OFF, mTestSatelliteSessionController.getCurrentStateName());
+ assertTrue(mTestSatelliteSessionController.isEventDeferred(
+ 4 /* EVENT_SATELLITE_MODEM_STATE_CHANGED */));
+
+ // Power on the modem.
+ mTestSatelliteModemStateCallback.clearModemStates();
+ mTestSatelliteSessionController.onSatelliteEnabledStateChanged(true);
+ processAllMessages();
+
+ // SatelliteSessionController should move to NOT_CONNECTED state after the satellite modem
+ // is powered on. Then, it should move to CONNECTED and then back to NOT_CONNECTED state
+ // because of the above deferred events.
+ assertEquals(3, mTestSatelliteModemStateCallback.getNumberOfModemStates());
+ assertEquals(SatelliteManager.SATELLITE_MODEM_STATE_NOT_CONNECTED,
+ mTestSatelliteModemStateCallback.getModemState(0));
+ assertEquals(SatelliteManager.SATELLITE_MODEM_STATE_CONNECTED,
+ mTestSatelliteModemStateCallback.getModemState(1));
+ assertEquals(SatelliteManager.SATELLITE_MODEM_STATE_NOT_CONNECTED,
+ mTestSatelliteModemStateCallback.getModemState(2));
+ assertEquals(STATE_NOT_CONNECTED, mTestSatelliteSessionController.getCurrentStateName());
+
+ // Power off the modem.
+ mTestSatelliteSessionController.onSatelliteEnabledStateChanged(false);
+ processAllMessages();
+
+ // SatelliteSessionController should move to POWER_OFF
+ assertSuccessfulModemStateChangedCallback(
+ mTestSatelliteModemStateCallback, SatelliteManager.SATELLITE_MODEM_STATE_OFF);
+ assertEquals(STATE_POWER_OFF, mTestSatelliteSessionController.getCurrentStateName());
+
+ mTestSatelliteModemStateCallback.clearSemaphorePermits();
+ mTestSatelliteSessionController.onSatelliteModemStateChanged(
+ SatelliteManager.SATELLITE_MODEM_STATE_NOT_CONNECTED);
+ mTestSatelliteSessionController.onSatelliteModemStateChanged(
+ SatelliteManager.SATELLITE_MODEM_STATE_CONNECTED);
+ mTestSatelliteSessionController.onSatelliteModemStateChanged(
+ SatelliteManager.SATELLITE_MODEM_STATE_NOT_CONNECTED);
+ processAllMessages();
+
+ // The modem state changed events should be deferred
+ assertModemStateChangedCallbackNotCalled(mTestSatelliteModemStateCallback);
+ assertEquals(STATE_POWER_OFF, mTestSatelliteSessionController.getCurrentStateName());
+ assertTrue(mTestSatelliteSessionController.isEventDeferred(
+ 4 /* EVENT_SATELLITE_MODEM_STATE_CHANGED */));
+
+ // Modem got reset. The deferred messages should be removed.
+ mTestSatelliteModemStateCallback.clearSemaphorePermits();
+ mTestSatelliteSessionController.onSatelliteEnabledStateChanged(false);
+ processAllMessages();
+ assertModemStateChangedCallbackNotCalled(mTestSatelliteModemStateCallback);
+ assertEquals(STATE_POWER_OFF, mTestSatelliteSessionController.getCurrentStateName());
+ assertFalse(mTestSatelliteSessionController.isEventDeferred(
+ 4 /* EVENT_SATELLITE_MODEM_STATE_CHANGED */));
+
+ // Power on the modem.
+ mTestSatelliteModemStateCallback.clearModemStates();
+ mTestSatelliteSessionController.onSatelliteEnabledStateChanged(true);
+ processAllMessages();
+
+ // SatelliteSessionController should move to NOT_CONNECTED state after the satellite modem
+ // is powered on.
+ assertSuccessfulModemStateChangedCallback(mTestSatelliteModemStateCallback,
+ SatelliteManager.SATELLITE_MODEM_STATE_NOT_CONNECTED);
+ assertEquals(1, mTestSatelliteModemStateCallback.getNumberOfModemStates());
+ assertEquals(SatelliteManager.SATELLITE_MODEM_STATE_NOT_CONNECTED,
+ mTestSatelliteModemStateCallback.getModemState(0));
+ assertEquals(STATE_NOT_CONNECTED, mTestSatelliteSessionController.getCurrentStateName());
}
private void setupDatagramTransferringState(boolean isTransferring) {
@@ -878,17 +967,26 @@
boolean isNbIotInactivityTimerStarted() {
return hasMessages(EVENT_NB_IOT_INACTIVITY_TIMER_TIMED_OUT);
}
+
+ boolean isEventDeferred(int event) {
+ return hasDeferredMessages(event);
+ }
}
private static class TestSatelliteModemStateCallback extends ISatelliteModemStateCallback.Stub {
private final AtomicInteger mModemState = new AtomicInteger(
SatelliteManager.SATELLITE_MODEM_STATE_OFF);
private final Semaphore mSemaphore = new Semaphore(0);
+ private final Object mLock = new Object();
+ private final List<Integer> mModemStates = new ArrayList<>();
@Override
public void onSatelliteModemStateChanged(int state) {
logd("onSatelliteModemStateChanged: state=" + state);
mModemState.set(state);
+ synchronized (mLock) {
+ mModemStates.add(state);
+ }
try {
mSemaphore.release();
} catch (Exception ex) {
@@ -912,6 +1010,28 @@
public int getModemState() {
return mModemState.get();
}
+
+ public int getModemState(int index) {
+ synchronized (mLock) {
+ return mModemStates.get(index);
+ }
+ }
+
+ public void clearModemStates() {
+ synchronized (mLock) {
+ mModemStates.clear();
+ }
+ }
+
+ public int getNumberOfModemStates() {
+ synchronized (mLock) {
+ return mModemStates.size();
+ }
+ }
+
+ public void clearSemaphorePermits() {
+ mSemaphore.drainPermits();
+ }
}
private static void assertSuccessfulModemStateChangedCallback(