diff options
9 files changed, 208 insertions, 16 deletions
diff --git a/proto/src/persist_atoms.proto b/proto/src/persist_atoms.proto index ca689128d1..8d87a27057 100644 --- a/proto/src/persist_atoms.proto +++ b/proto/src/persist_atoms.proto @@ -748,6 +748,7 @@ message SatelliteSession { optional int32 count_of_auto_exit_due_to_tn_network = 17; optional bool is_emergency = 18; optional bool is_ntn_only_carrier = 19; + optional int32 max_inactivity_duration_sec = 20; } message SatelliteIncomingDatagram { diff --git a/src/java/com/android/internal/telephony/metrics/MetricsCollector.java b/src/java/com/android/internal/telephony/metrics/MetricsCollector.java index 5ef4c5bc7c..8ef5a8f6bd 100644 --- a/src/java/com/android/internal/telephony/metrics/MetricsCollector.java +++ b/src/java/com/android/internal/telephony/metrics/MetricsCollector.java @@ -1507,7 +1507,8 @@ public class MetricsCollector implements StatsManager.StatsPullAtomCallback { satelliteSession.countOfAutoExitDueToScreenOff, satelliteSession.countOfAutoExitDueToTnNetwork, satelliteSession.isEmergency, - satelliteSession.isNtnOnlyCarrier); + satelliteSession.isNtnOnlyCarrier, + satelliteSession.maxInactivityDurationSec); } private static StatsEvent buildStatsEvent(SatelliteIncomingDatagram stats) { diff --git a/src/java/com/android/internal/telephony/metrics/PersistAtomsStorage.java b/src/java/com/android/internal/telephony/metrics/PersistAtomsStorage.java index f828876f7e..581d54ca4e 100644 --- a/src/java/com/android/internal/telephony/metrics/PersistAtomsStorage.java +++ b/src/java/com/android/internal/telephony/metrics/PersistAtomsStorage.java @@ -2347,7 +2347,8 @@ public class PersistAtomsStorage { == key.countOfSatelliteNotificationDisplayed && stats.countOfAutoExitDueToScreenOff == key.countOfAutoExitDueToScreenOff && stats.countOfAutoExitDueToTnNetwork == key.countOfAutoExitDueToTnNetwork - && stats.isEmergency == key.isEmergency) { + && stats.isEmergency == key.isEmergency + && stats.maxInactivityDurationSec == key.maxInactivityDurationSec) { return stats; } } diff --git a/src/java/com/android/internal/telephony/metrics/SatelliteStats.java b/src/java/com/android/internal/telephony/metrics/SatelliteStats.java index 4513f6ca0e..c17c8ab9e8 100644 --- a/src/java/com/android/internal/telephony/metrics/SatelliteStats.java +++ b/src/java/com/android/internal/telephony/metrics/SatelliteStats.java @@ -804,6 +804,7 @@ public class SatelliteStats { private final int mCountOfAutoExitDueToScreenOff; private final int mCountOfAutoExitDueToTnNetwork; private final boolean mIsEmergency; + private final int mMaxInactivityDurationSec; private final boolean mIsNtnOnlyCarrier; private SatelliteSessionParams(Builder builder) { @@ -828,6 +829,7 @@ public class SatelliteStats { this.mCountOfAutoExitDueToTnNetwork = builder.mCountOfAutoExitDueToTnNetwork; this.mIsEmergency = builder.mIsEmergency; this.mIsNtnOnlyCarrier = builder.mIsNtnOnlyCarrier; + this.mMaxInactivityDurationSec = builder.mMaxInactivityDurationSec; } public int getSatelliteServiceInitializationResult() { @@ -902,6 +904,10 @@ public class SatelliteStats { return mIsNtnOnlyCarrier; } + public int getMaxInactivityDurationSec() { + return mMaxInactivityDurationSec; + } + /** * A builder class to create {@link SatelliteSessionParams} data structure class */ @@ -925,6 +931,7 @@ public class SatelliteStats { private int mCountOfAutoExitDueToTnNetwork = -1; private boolean mIsEmergency = false; private boolean mIsNtnOnlyCarrier = false; + private int mMaxInactivityDurationSec = -1; /** * Sets satelliteServiceInitializationResult value of {@link SatelliteSession} @@ -1058,6 +1065,12 @@ public class SatelliteStats { return this; } + /** Sets the max user inactivity duration in seconds. */ + public Builder setMaxInactivityDurationSec(int maxInactivityDurationSec) { + this.mMaxInactivityDurationSec = maxInactivityDurationSec; + return this; + } + /** * Returns SessionParams, which contains whole component of * {@link SatelliteSession} atom @@ -1090,6 +1103,7 @@ public class SatelliteStats { + ", CountOfAutoExitDueToTnNetwork" + mCountOfAutoExitDueToTnNetwork + ", IsEmergency=" + mIsEmergency + ", IsNtnOnlyCarrier=" + mIsNtnOnlyCarrier + + ", MaxInactivityDurationSec=" + mMaxInactivityDurationSec + ")"; } } @@ -2715,6 +2729,7 @@ public class SatelliteStats { proto.countOfAutoExitDueToTnNetwork = param.getCountOfAutoExitDueToTnNetwork(); proto.isEmergency = param.getIsEmergency(); proto.isNtnOnlyCarrier = param.isNtnOnlyCarrier(); + proto.maxInactivityDurationSec = param.getMaxInactivityDurationSec(); mAtomsStorage.addSatelliteSessionStats(proto); } diff --git a/src/java/com/android/internal/telephony/satellite/SatelliteSessionController.java b/src/java/com/android/internal/telephony/satellite/SatelliteSessionController.java index 5cf3c13dd6..a002457530 100644 --- a/src/java/com/android/internal/telephony/satellite/SatelliteSessionController.java +++ b/src/java/com/android/internal/telephony/satellite/SatelliteSessionController.java @@ -21,6 +21,7 @@ import static android.telephony.CarrierConfigManager.KEY_SATELLITE_ROAMING_P2P_S import static android.telephony.CarrierConfigManager.KEY_SATELLITE_ROAMING_SCREEN_OFF_INACTIVITY_TIMEOUT_SEC_INT; import static android.telephony.satellite.SatelliteManager.DATAGRAM_TYPE_SMS; import static android.telephony.satellite.SatelliteManager.DATAGRAM_TYPE_SOS_MESSAGE; +import static android.telephony.satellite.SatelliteManager.DATAGRAM_TYPE_UNKNOWN; import static android.telephony.satellite.SatelliteManager.SATELLITE_DATAGRAM_TRANSFER_STATE_IDLE; import static android.telephony.satellite.SatelliteManager.SATELLITE_DATAGRAM_TRANSFER_STATE_RECEIVE_FAILED; import static android.telephony.satellite.SatelliteManager.SATELLITE_DATAGRAM_TRANSFER_STATE_RECEIVE_NONE; @@ -30,6 +31,7 @@ import static android.telephony.satellite.SatelliteManager.SATELLITE_DATAGRAM_TR import static android.telephony.satellite.SatelliteManager.SATELLITE_DATAGRAM_TRANSFER_STATE_SEND_FAILED; import static android.telephony.satellite.SatelliteManager.SATELLITE_DATAGRAM_TRANSFER_STATE_SEND_SUCCESS; import static android.telephony.satellite.SatelliteManager.SATELLITE_DATAGRAM_TRANSFER_STATE_WAITING_TO_CONNECT; +import static android.telephony.satellite.SatelliteManager.SATELLITE_DATAGRAM_TRANSFER_STATE_UNKNOWN; import static android.telephony.satellite.SatelliteManager.SATELLITE_MODEM_STATE_CONNECTED; import static android.telephony.satellite.SatelliteManager.SATELLITE_MODEM_STATE_DATAGRAM_TRANSFERRING; import static android.telephony.satellite.SatelliteManager.SATELLITE_MODEM_STATE_ENABLING_SATELLITE; @@ -143,6 +145,7 @@ public class SatelliteSessionController extends StateMachine { private static final int DEFAULT_SCREEN_OFF_INACTIVITY_TIMEOUT_SEC = 30; private static final int DEFAULT_P2P_SMS_INACTIVITY_TIMEOUT_SEC = 180; private static final int DEFAULT_ESOS_INACTIVITY_TIMEOUT_SEC = 600; + private static final long UNDEFINED_TIMESTAMP = 0L; @NonNull private final ExponentialBackoff mExponentialBackoff; @NonNull private final Object mLock = new Object(); @@ -181,6 +184,12 @@ public class SatelliteSessionController extends StateMachine { // Interested in screen off, so use default value true boolean mIsScreenOn = true; private boolean mIsDeviceAlignedWithSatellite = false; + private long mInactivityStartTimestamp = UNDEFINED_TIMESTAMP; + private DatagramTransferState mLastDatagramTransferState = + new DatagramTransferState( + SATELLITE_DATAGRAM_TRANSFER_STATE_UNKNOWN, + SATELLITE_DATAGRAM_TRANSFER_STATE_UNKNOWN, + DATAGRAM_TYPE_UNKNOWN); @NonNull private final SatelliteController mSatelliteController; @NonNull private final DatagramController mDatagramController; @@ -334,11 +343,21 @@ public class SatelliteSessionController extends StateMachine { @SatelliteManager.SatelliteDatagramTransferState int sendState, @SatelliteManager.SatelliteDatagramTransferState int receiveState, @SatelliteManager.DatagramType int datagramType) { - sendMessage(EVENT_DATAGRAM_TRANSFER_STATE_CHANGED, - new DatagramTransferState(sendState, receiveState, datagramType)); + DatagramTransferState datagramTransferState = + new DatagramTransferState(sendState, receiveState, datagramType); + mLastDatagramTransferState = datagramTransferState; + + sendMessage(EVENT_DATAGRAM_TRANSFER_STATE_CHANGED, datagramTransferState); + if (sendState == SATELLITE_DATAGRAM_TRANSFER_STATE_SENDING) { mIsSendingTriggeredDuringTransferringState.set(true); } + + if (datagramTransferState.isIdle()) { + checkForInactivity(); + } else { + endUserInactivity(); + } } /** @@ -556,11 +575,13 @@ public class SatelliteSessionController extends StateMachine { if (mIsDeviceAlignedWithSatellite) { stopEsosInactivityTimer(); stopP2pSmsInactivityTimer(); + endUserInactivity(); } else { if (mCurrentState == SatelliteManager.SATELLITE_MODEM_STATE_NOT_CONNECTED) { evaluateStartingEsosInactivityTimer(); evaluateStartingP2pSmsInactivityTimer(); } + checkForInactivity(); } } @@ -591,6 +612,7 @@ public class SatelliteSessionController extends StateMachine { public void cleanUpResource() { plogd("cleanUpResource"); mIsDeviceAlignedWithSatellite = false; + mInactivityStartTimestamp = UNDEFINED_TIMESTAMP; unregisterForScreenStateChanged(); if (mAlarmManager != null) { mAlarmManager.cancel(mAlarmListener); @@ -648,6 +670,11 @@ public class SatelliteSessionController extends StateMachine { this.receiveState = receiveState; this.datagramType = datagramType; } + + public boolean isIdle() { + return (sendState == SATELLITE_DATAGRAM_TRANSFER_STATE_IDLE + && receiveState == SATELLITE_DATAGRAM_TRANSFER_STATE_IDLE); + } } private class UnavailableState extends State { @@ -678,6 +705,7 @@ public class SatelliteSessionController extends StateMachine { mIsSendingTriggeredDuringTransferringState.set(false); unbindService(); stopNbIotInactivityTimer(); + endUserInactivity(); DemoSimulator.getInstance().onSatelliteModeOff(); notifyStateChangedEvent(SatelliteManager.SATELLITE_MODEM_STATE_OFF); @@ -1834,6 +1862,50 @@ public class SatelliteSessionController extends StateMachine { return hasMessages(EVENT_P2P_SMS_INACTIVITY_TIMER_TIMED_OUT); } + /** + * Initializes the inactivity start timestamp. + * + * <p>This method is called when 1) the datagram transfer state changes to idle or 2) the + * device is unaligned with the satellite. + */ + private void checkForInactivity() { + if (!mFeatureFlags.carrierRoamingNbIotNtn()) { + return; + } + + // If the inactivity start timestamp is not undefined, it means the inactivity has already + // started. + if (mInactivityStartTimestamp != UNDEFINED_TIMESTAMP) { + return; + } + + boolean isInactive = mLastDatagramTransferState.isIdle() && !mIsDeviceAlignedWithSatellite; + if (isInactive) { + mInactivityStartTimestamp = SystemClock.elapsedRealtime(); + } + } + + /** + * Updates the max inactivity duration session metric. + * + * <p>This method is called when 1) the datagram transfer state changes to not idle, 2) the + * device is aligned with the satellite, or 3) modem state moves to PowerOffState. + */ + private void endUserInactivity() { + if (!mFeatureFlags.carrierRoamingNbIotNtn()) { + plogd("endUserInactivity: carrierRoamingNbIotNtn is disabled"); + return; + } + + if (mInactivityStartTimestamp != UNDEFINED_TIMESTAMP) { + long inactivityDurationMs = SystemClock.elapsedRealtime() - mInactivityStartTimestamp; + int inactivityDurationSec = (int) (inactivityDurationMs / 1000); + mSessionMetricsStats.updateMaxInactivityDurationSec(inactivityDurationSec); + + mInactivityStartTimestamp = UNDEFINED_TIMESTAMP; + } + } + private void handleEventScreenOffInactivityTimerTimedOut() { if (mSatelliteController.getRequestIsEmergency()) { loge("handleEventScreenOffInactivityTimerTimedOut: Emergency mode"); diff --git a/src/java/com/android/internal/telephony/satellite/metrics/SessionMetricsStats.java b/src/java/com/android/internal/telephony/satellite/metrics/SessionMetricsStats.java index c0f8cc1403..6b10ff1c1a 100644 --- a/src/java/com/android/internal/telephony/satellite/metrics/SessionMetricsStats.java +++ b/src/java/com/android/internal/telephony/satellite/metrics/SessionMetricsStats.java @@ -63,6 +63,7 @@ public class SessionMetricsStats { private int mCountOfAutoExitDueToTnNetwork; private boolean mIsEmergency; private boolean mIsNtnOnlyCarrier; + private int mMaxInactivityDurationSec; private SatelliteSessionStats mDatagramStats; private SessionMetricsStats() { @@ -275,6 +276,18 @@ public class SessionMetricsStats { return this; } + /** Updates the max inactivity duration session metric. */ + public SessionMetricsStats updateMaxInactivityDurationSec(int inactivityDurationSec) { + if (inactivityDurationSec > mMaxInactivityDurationSec) { + mMaxInactivityDurationSec = inactivityDurationSec; + } + logd("updateMaxInactivityDurationSec: latest inactivty duration (sec)=" + + inactivityDurationSec + + ", max inactivity duration=" + + mMaxInactivityDurationSec); + return this; + } + /** Report the session metrics atoms to PersistAtomsStorage in telephony. */ public void reportSessionMetrics() { SatelliteStats.SatelliteSessionParams sessionParams = @@ -298,6 +311,7 @@ public class SessionMetricsStats { .setCountOfAutoExitDueToTnNetwork(mCountOfAutoExitDueToTnNetwork) .setIsEmergency(mIsEmergency) .setIsNtnOnlyCarrier(mIsNtnOnlyCarrier) + .setMaxInactivityDurationSec(mMaxInactivityDurationSec) .build(); logd("reportSessionMetrics: " + sessionParams.toString()); SatelliteStats.getInstance().onSatelliteSessionMetrics(sessionParams); @@ -357,6 +371,7 @@ public class SessionMetricsStats { mCountOfAutoExitDueToTnNetwork = 0; mIsEmergency = false; mIsNtnOnlyCarrier = false; + mMaxInactivityDurationSec = 0; } public void resetSessionStatsShadowCounters() { diff --git a/tests/telephonytests/src/com/android/internal/telephony/metrics/PersistAtomsStorageTest.java b/tests/telephonytests/src/com/android/internal/telephony/metrics/PersistAtomsStorageTest.java index 2645dbf614..1c0febfcac 100644 --- a/tests/telephonytests/src/com/android/internal/telephony/metrics/PersistAtomsStorageTest.java +++ b/tests/telephonytests/src/com/android/internal/telephony/metrics/PersistAtomsStorageTest.java @@ -1216,6 +1216,7 @@ public class PersistAtomsStorageTest extends TelephonyTest { mSatelliteSession1.countOfAutoExitDueToScreenOff = 6; mSatelliteSession1.countOfAutoExitDueToTnNetwork = 7; mSatelliteSession1.isEmergency = true; + mSatelliteSession1.maxInactivityDurationSec = 8; mSatelliteSession2 = new SatelliteSession(); mSatelliteSession2.satelliteServiceInitializationResult = @@ -1239,6 +1240,7 @@ public class PersistAtomsStorageTest extends TelephonyTest { mSatelliteSession2.countOfAutoExitDueToScreenOff = 60; mSatelliteSession2.countOfAutoExitDueToTnNetwork = 70; mSatelliteSession2.isEmergency = false; + mSatelliteSession2.maxInactivityDurationSec = 80; mSatelliteSessions = new SatelliteSession[] { @@ -6060,32 +6062,33 @@ public class PersistAtomsStorageTest extends TelephonyTest { int actualCount = 0; for (SatelliteSession stats : tested) { if (stats.satelliteServiceInitializationResult - == expectedStats.satelliteServiceInitializationResult + == expectedStats.satelliteServiceInitializationResult && stats.satelliteTechnology == expectedStats.satelliteTechnology && stats.satelliteServiceTerminationResult - == expectedStats.satelliteServiceTerminationResult + == expectedStats.satelliteServiceTerminationResult && stats.initializationProcessingTimeMillis - == expectedStats.initializationProcessingTimeMillis + == expectedStats.initializationProcessingTimeMillis && stats.terminationProcessingTimeMillis - == expectedStats.terminationProcessingTimeMillis + == expectedStats.terminationProcessingTimeMillis && stats.sessionDurationSeconds == expectedStats.sessionDurationSeconds && stats.countOfOutgoingDatagramSuccess - == expectedStats.countOfOutgoingDatagramSuccess + == expectedStats.countOfOutgoingDatagramSuccess && stats.countOfOutgoingDatagramFailed - == expectedStats.countOfOutgoingDatagramFailed + == expectedStats.countOfOutgoingDatagramFailed && stats.countOfIncomingDatagramSuccess - == expectedStats.countOfIncomingDatagramSuccess + == expectedStats.countOfIncomingDatagramSuccess && stats.countOfIncomingDatagramFailed - == expectedStats.countOfIncomingDatagramFailed + == expectedStats.countOfIncomingDatagramFailed && stats.isDemoMode == expectedStats.isDemoMode && stats.carrierId == expectedStats.carrierId && stats.countOfSatelliteNotificationDisplayed - == expectedStats.countOfSatelliteNotificationDisplayed + == expectedStats.countOfSatelliteNotificationDisplayed && stats.countOfAutoExitDueToScreenOff - == expectedStats.countOfAutoExitDueToScreenOff + == expectedStats.countOfAutoExitDueToScreenOff && stats.countOfAutoExitDueToTnNetwork - == expectedStats.countOfAutoExitDueToTnNetwork - && stats.isEmergency == expectedStats.isEmergency) { + == expectedStats.countOfAutoExitDueToTnNetwork + && stats.isEmergency == expectedStats.isEmergency + && stats.maxInactivityDurationSec == expectedStats.maxInactivityDurationSec) { actualCount = stats.count; } } diff --git a/tests/telephonytests/src/com/android/internal/telephony/metrics/SatelliteStatsTest.java b/tests/telephonytests/src/com/android/internal/telephony/metrics/SatelliteStatsTest.java index 51ae7a7fb8..e981e88dfe 100644 --- a/tests/telephonytests/src/com/android/internal/telephony/metrics/SatelliteStatsTest.java +++ b/tests/telephonytests/src/com/android/internal/telephony/metrics/SatelliteStatsTest.java @@ -254,6 +254,7 @@ public class SatelliteStatsTest extends TelephonyTest { .setCountOfAutoExitDueToScreenOff(7) .setCountOfAutoExitDueToTnNetwork(3) .setIsEmergency(true) + .setMaxInactivityDurationSec(10) .build(); mSatelliteStats.onSatelliteSessionMetrics(param); @@ -283,6 +284,7 @@ public class SatelliteStatsTest extends TelephonyTest { assertEquals(param.getCountOfAutoExitDueToScreenOff(), stats.countOfAutoExitDueToScreenOff); assertEquals(param.getCountOfAutoExitDueToTnNetwork(), stats.countOfAutoExitDueToTnNetwork); assertEquals(param.getIsEmergency(), stats.isEmergency); + assertEquals(param.getMaxInactivityDurationSec(), stats.maxInactivityDurationSec); verifyNoMoreInteractions(mPersistAtomsStorage); } 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 b5b639e8a3..766d1fbeed 100644 --- a/tests/telephonytests/src/com/android/internal/telephony/satellite/SatelliteSessionControllerTest.java +++ b/tests/telephonytests/src/com/android/internal/telephony/satellite/SatelliteSessionControllerTest.java @@ -24,12 +24,14 @@ import static android.telephony.satellite.SatelliteManager.DATAGRAM_TYPE_SOS_MES import static android.telephony.satellite.SatelliteManager.DATAGRAM_TYPE_UNKNOWN; import static android.telephony.satellite.SatelliteManager.SATELLITE_DATAGRAM_TRANSFER_STATE_IDLE; import static android.telephony.satellite.SatelliteManager.SATELLITE_DATAGRAM_TRANSFER_STATE_RECEIVE_FAILED; +import static android.telephony.satellite.SatelliteManager.SATELLITE_DATAGRAM_TRANSFER_STATE_RECEIVE_NONE; import static android.telephony.satellite.SatelliteManager.SATELLITE_DATAGRAM_TRANSFER_STATE_RECEIVE_SUCCESS; import static android.telephony.satellite.SatelliteManager.SATELLITE_DATAGRAM_TRANSFER_STATE_RECEIVING; 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_SEND_SUCCESS; import static android.telephony.satellite.SatelliteManager.SATELLITE_DATAGRAM_TRANSFER_STATE_WAITING_TO_CONNECT; +import static android.telephony.satellite.SatelliteManager.SATELLITE_DATAGRAM_TRANSFER_STATE_UNKNOWN; import static android.telephony.satellite.SatelliteManager.SATELLITE_RESULT_SUCCESS; import static org.junit.Assert.assertEquals; @@ -2166,6 +2168,86 @@ public class SatelliteSessionControllerTest extends TelephonyTest { eq(false), eq(false), eq(false), any(IIntegerConsumer.Stub.class)); } + @Test + public void testSetDeviceAlignedWithSatellite_updatesMaxInactivityDuration() { + when(mFeatureFlags.carrierRoamingNbIotNtn()).thenReturn(true); + setUserInactivityStart(); + + mTestSatelliteSessionController.setDeviceAlignedWithSatellite(true); + + verify(mMockSessionMetricsStats, times(1)).updateMaxInactivityDurationSec(anyInt()); + } + + @Test + public void + testSetDeviceAlignedWithSatellite_setsInactivityStartTimestampUndefinedAfterUpdate() { + when(mFeatureFlags.carrierRoamingNbIotNtn()).thenReturn(true); + setUserInactivityStart(); + mTestSatelliteSessionController.setDeviceAlignedWithSatellite(true); + + mTestSatelliteSessionController.setDeviceAlignedWithSatellite(true); + + // There should be only one call to updateMaxInactivityDurationSec since the inactivity + // start timestamp is reset to undefined. + verify(mMockSessionMetricsStats, times(1)).updateMaxInactivityDurationSec(anyInt()); + } + + @Test + public void + testSetDeviceAlignedWithSatellite_noInactivityStart_noUpdateMaxInactivityDuration() { + when(mFeatureFlags.carrierRoamingNbIotNtn()).thenReturn(true); + + mTestSatelliteSessionController.setDeviceAlignedWithSatellite(true); + + verify(mMockSessionMetricsStats, times(0)).updateMaxInactivityDurationSec(anyInt()); + } + + @Test + public void testSetDeviceAlignedWithSatellite_flagOff_noUpdateMaxInactivityDuration() { + when(mFeatureFlags.carrierRoamingNbIotNtn()).thenReturn(false); + setUserInactivityStart(); + + mTestSatelliteSessionController.setDeviceAlignedWithSatellite(true); + + verify(mMockSessionMetricsStats, times(0)).updateMaxInactivityDurationSec(anyInt()); + } + + @Test + public void testOnDatagramTransferStateChanged_notIdle_updatesMaxInactivityDuration() { + when(mFeatureFlags.carrierRoamingNbIotNtn()).thenReturn(true); + setUserInactivityStart(); + + mTestSatelliteSessionController.onDatagramTransferStateChanged( + SATELLITE_DATAGRAM_TRANSFER_STATE_WAITING_TO_CONNECT, + SATELLITE_DATAGRAM_TRANSFER_STATE_IDLE, + DATAGRAM_TYPE_UNKNOWN); + + // Since both the send and receive datagram transfer state is not idle, the max inactivity + // duration should be updated. + verify(mMockSessionMetricsStats, times(1)).updateMaxInactivityDurationSec(anyInt()); + } + + @Test + public void testOnDatagramTransferStateChanged_idle_updatesMaxInactivityDuration() { + when(mFeatureFlags.carrierRoamingNbIotNtn()).thenReturn(true); + setUserInactivityStart(); + moveToIdleState(); + + moveToPowerOffState(); + + verify(mMockSessionMetricsStats, times(1)).updateMaxInactivityDurationSec(anyInt()); + } + + private void setUserInactivityStart() { + // Set DatagramTransferState to idle and unaligned with satellite to define inactivity start + // timestamp + mTestSatelliteSessionController.onDatagramTransferStateChanged( + SATELLITE_DATAGRAM_TRANSFER_STATE_IDLE, + SATELLITE_DATAGRAM_TRANSFER_STATE_IDLE, + DATAGRAM_TYPE_UNKNOWN); + mTestSatelliteSessionController.setDeviceAlignedWithSatellite(false); + } + private void verifyEsosP2pSmsInactivityTimer(boolean esosTimer, boolean p2pSmsTimer) { assertEquals(mTestSatelliteSessionController.isEsosInActivityTimerStarted(), esosTimer); assertEquals(mTestSatelliteSessionController.isP2pSmsInActivityTimerStarted(), |