Loading src/java/com/android/internal/telephony/dataconnection/DcController.java +19 −6 Original line number Diff line number Diff line Loading @@ -29,6 +29,7 @@ import android.telephony.DataFailCause; import android.telephony.data.ApnSetting; import android.telephony.data.DataCallResponse; import com.android.internal.annotations.VisibleForTesting; import com.android.internal.telephony.DctConstants; import com.android.internal.telephony.Phone; import com.android.internal.telephony.dataconnection.DataConnection.UpdateLinkPropertyResult; Loading Loading @@ -89,8 +90,8 @@ public class DcController extends Handler { /** * Aggregated physical link state from all data connections. This reflects the device's RRC * connection state. * // TODO: Instead of tracking the RRC state here, we should make PhysicalChannelConfig work in * S. * If {@link CarrierConfigManager.KEY_LTE_ENDC_USING_USER_DATA_FOR_RRC_DETECTION_BOOL} is true, * then This reflects "internet data connection" instead of RRC state. */ private @PhysicalLinkState int mPhysicalLinkState = PHYSICAL_LINK_UNKNOWN; Loading Loading @@ -229,6 +230,7 @@ public class DcController extends Handler { boolean isAnyDataCallDormant = false; boolean isAnyDataCallActive = false; boolean isInternetDataCallActive = false; for (DataCallResponse newState : dcsList) { Loading @@ -249,6 +251,11 @@ public class DcController extends Handler { log("onDataStateChanged: Found ConnId=" + newState.getId() + " newState=" + newState.toString()); } if (apnContexts.stream().anyMatch( i -> ApnSetting.TYPE_DEFAULT_STRING.equals(i.getApnType())) && newState.getLinkStatus() == DataConnActiveStatus.ACTIVE) { isInternetDataCallActive = true; } if (newState.getLinkStatus() == DataConnActiveStatus.INACTIVE) { if (mDct.isCleanupRequired.get()) { apnsToCleanup.addAll(apnContexts); Loading Loading @@ -360,7 +367,11 @@ public class DcController extends Handler { if (mDataServiceManager.getTransportType() == AccessNetworkConstants.TRANSPORT_TYPE_WWAN) { int physicalLinkState = isAnyDataCallActive boolean isPhysicalLinkStateFocusingOnInternetData = mDct.getLteEndcUsingUserDataForIdleDetection(); int physicalLinkState = (isPhysicalLinkStateFocusingOnInternetData ? isInternetDataCallActive : isAnyDataCallActive) ? PHYSICAL_LINK_ACTIVE : PHYSICAL_LINK_NOT_ACTIVE; if (mPhysicalLinkState != physicalLinkState) { mPhysicalLinkState = physicalLinkState; Loading Loading @@ -409,11 +420,13 @@ public class DcController extends Handler { /** * Register for physical link state (i.e. RRC state) changed event. * * if {@link CarrierConfigManager.KEY_LTE_ENDC_USING_USER_DATA_FOR_RRC_DETECTION_BOOL} is true, * then physical link state is focusing on "internet data connection" instead of RRC state. * @param h The handler * @param what The event */ void registerForPhysicalLinkStateChanged(Handler h, int what) { @VisibleForTesting public void registerForPhysicalLinkStateChanged(Handler h, int what) { mPhysicalLinkStateChangedRegistrants.addUnique(h, what, null); } Loading src/java/com/android/internal/telephony/dataconnection/DcTracker.java +11 −0 Original line number Diff line number Diff line Loading @@ -352,6 +352,9 @@ public class DcTracker extends Handler { private boolean mNrSaSub6Unmetered = false; private boolean mNrNsaRoamingUnmetered = false; // it effect the PhysicalLinkStateChanged private boolean mLteEndcUsingUserDataForRrcDetection = false; // stats per data call recovery event private DataStallRecoveryStats mDataStallRecoveryStats; Loading Loading @@ -5597,13 +5600,21 @@ public class DcTracker extends Handler { CarrierConfigManager.KEY_UNMETERED_NR_SA_SUB6_BOOL); mNrNsaRoamingUnmetered = b.getBoolean( CarrierConfigManager.KEY_UNMETERED_NR_NSA_WHEN_ROAMING_BOOL); mLteEndcUsingUserDataForRrcDetection = b.getBoolean( CarrierConfigManager.KEY_LTE_ENDC_USING_USER_DATA_FOR_RRC_DETECTION_BOOL); } } updateLinkBandwidths(bandwidths, useLte); } public boolean getLteEndcUsingUserDataForIdleDetection() { return mLteEndcUsingUserDataForRrcDetection; } /** * Register for physical link state (i.e. RRC state) changed event. * if {@link CarrierConfigManager.KEY_LTE_ENDC_USING_USER_DATA_FOR_RRC_DETECTION_BOOL} is true, * then physical link state is focusing on "internet data connection" instead of RRC state. * * @param h The handler * @param what The event Loading tests/telephonytests/src/com/android/internal/telephony/dataconnection/DcControllerTest.java +137 −0 Original line number Diff line number Diff line Loading @@ -22,7 +22,9 @@ import static com.android.internal.telephony.dataconnection.DcTrackerTest.FAKE_G import static com.android.internal.telephony.dataconnection.DcTrackerTest.FAKE_IFNAME; import static com.android.internal.telephony.dataconnection.DcTrackerTest.FAKE_PCSCF_ADDRESS; import static org.junit.Assert.assertEquals; import static org.junit.Assert.fail; import static org.mockito.ArgumentMatchers.anyLong; import static org.mockito.Mockito.any; import static org.mockito.Mockito.doReturn; import static org.mockito.Mockito.eq; Loading @@ -33,7 +35,9 @@ import android.net.InetAddresses; import android.net.LinkAddress; import android.net.LinkProperties; import android.os.AsyncResult; import android.os.Handler; import android.os.Looper; import android.os.Message; import android.telephony.AccessNetworkConstants; import android.telephony.data.ApnSetting; import android.telephony.data.DataCallResponse; Loading @@ -51,6 +55,7 @@ import org.junit.After; import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.ArgumentCaptor; import org.mockito.Mock; import java.lang.reflect.Method; Loading @@ -63,7 +68,10 @@ import java.util.List; public class DcControllerTest extends TelephonyTest { private static final int DATA_CONNECTION_ACTIVE_PH_LINK_DORMANT = 1; private static final int DATA_CONNECTION_ACTIVE_PH_LINK_ACTIVE = 2; private static final int EVENT_DATA_STATE_CHANGED = 0x00040007; private static final int EVENT_PHYSICAL_LINK_STATE_CHANGED = 1; @Mock private DataConnection mDc; Loading @@ -71,6 +79,8 @@ public class DcControllerTest extends TelephonyTest { private List<ApnContext> mApnContexts; @Mock private DataServiceManager mDataServiceManager; @Mock private Handler mTestHandler; UpdateLinkPropertyResult mResult; Loading Loading @@ -142,4 +152,131 @@ public class DcControllerTest extends TelephonyTest { verify(mDcTracker, times(1)).sendStopNetStatPoll(eq(DctConstants.Activity.DORMANT)); } @Test @SmallTest public void testPhysicalLinkStateChanged_defaultApnTypeAndDormant_registrantNotifyResult() throws Exception { ArrayList<DataCallResponse> l = new ArrayList<>(); DataCallResponse dcResponse = new DataCallResponse.Builder() .setCause(0) .setRetryDurationMillis(-1) .setId(1) .setLinkStatus(DATA_CONNECTION_ACTIVE_PH_LINK_DORMANT) .setProtocolType(ApnSetting.PROTOCOL_IP) .setInterfaceName(FAKE_IFNAME) .setAddresses(Arrays.asList( new LinkAddress(InetAddresses.parseNumericAddress(FAKE_ADDRESS), 0))) .setDnsAddresses(Arrays.asList(InetAddresses.parseNumericAddress(FAKE_DNS))) .setGatewayAddresses(Arrays.asList(InetAddresses.parseNumericAddress(FAKE_GATEWAY))) .setPcscfAddresses( Arrays.asList(InetAddresses.parseNumericAddress(FAKE_PCSCF_ADDRESS))) .setMtuV4(1440) .setMtuV6(1440) .build(); l.add(dcResponse); mDc.mCid = 1; mDcc.addActiveDcByCid(mDc); ApnContext apnContext = new ApnContext(mPhone, ApnSetting.TYPE_DEFAULT, TAG, mDcTracker, 1); List<ApnContext> apnContextList = new ArrayList<>(); apnContextList.add(apnContext); doReturn(apnContextList).when(mDc).getApnContexts(); doReturn(true).when(mDcTracker).getLteEndcUsingUserDataForIdleDetection(); mDcc.registerForPhysicalLinkStateChanged(mTestHandler, EVENT_PHYSICAL_LINK_STATE_CHANGED); mDcc.sendMessage(mDcc.obtainMessage(EVENT_DATA_STATE_CHANGED, new AsyncResult(null, l, null))); processAllMessages(); ArgumentCaptor<Message> messageCaptor = ArgumentCaptor.forClass(Message.class); verify(mTestHandler, times(1)).sendMessageDelayed(messageCaptor.capture(), anyLong()); Message message = messageCaptor.getValue(); assertEquals(EVENT_PHYSICAL_LINK_STATE_CHANGED, message.what); AsyncResult ar = (AsyncResult) message.obj; assertEquals(DcController.PHYSICAL_LINK_NOT_ACTIVE, (int) ar.result); } @Test @SmallTest public void testPhysicalLinkStateChanged_imsApnTypeAndDormant_NoNotifyResult() throws Exception { testPhysicalLinkStateChanged_defaultApnTypeAndDormant_registrantNotifyResult(); ArrayList<DataCallResponse> l = new ArrayList<>(); DataCallResponse dcResponse = new DataCallResponse.Builder() .setCause(0) .setRetryDurationMillis(-1) .setId(1) .setLinkStatus(DATA_CONNECTION_ACTIVE_PH_LINK_ACTIVE) .setProtocolType(ApnSetting.PROTOCOL_IP) .setInterfaceName(FAKE_IFNAME) .setAddresses(Arrays.asList( new LinkAddress(InetAddresses.parseNumericAddress(FAKE_ADDRESS), 0))) .setDnsAddresses(Arrays.asList(InetAddresses.parseNumericAddress(FAKE_DNS))) .setGatewayAddresses(Arrays.asList(InetAddresses.parseNumericAddress(FAKE_GATEWAY))) .setPcscfAddresses( Arrays.asList(InetAddresses.parseNumericAddress(FAKE_PCSCF_ADDRESS))) .setMtuV4(1440) .setMtuV6(1440) .build(); l.add(dcResponse); mDc.mCid = 1; mDcc.addActiveDcByCid(mDc); ApnContext apnContext = new ApnContext(mPhone, ApnSetting.TYPE_IMS, TAG, mDcTracker, 1); List<ApnContext> apnContextList = new ArrayList<>(); apnContextList.add(apnContext); doReturn(apnContextList).when(mDc).getApnContexts(); doReturn(true).when(mDcTracker).getLteEndcUsingUserDataForIdleDetection(); mDcc.sendMessage(mDcc.obtainMessage(EVENT_DATA_STATE_CHANGED, new AsyncResult(null, l, null))); processAllMessages(); ArgumentCaptor<Message> messageCaptor = ArgumentCaptor.forClass(Message.class); verify(mTestHandler, times(1)).sendMessageDelayed(messageCaptor.capture(), anyLong()); } @Test @SmallTest public void testPhysicalLinkStateChanged_defaultApnTypeAndStateChanged_registrantNotifyResult() throws Exception { testPhysicalLinkStateChanged_imsApnTypeAndDormant_NoNotifyResult(); ArrayList<DataCallResponse> l = new ArrayList<>(); DataCallResponse dcResponse = new DataCallResponse.Builder() .setCause(0) .setRetryDurationMillis(-1) .setId(1) .setLinkStatus(DATA_CONNECTION_ACTIVE_PH_LINK_ACTIVE) .setProtocolType(ApnSetting.PROTOCOL_IP) .setInterfaceName(FAKE_IFNAME) .setAddresses(Arrays.asList( new LinkAddress(InetAddresses.parseNumericAddress(FAKE_ADDRESS), 0))) .setDnsAddresses(Arrays.asList(InetAddresses.parseNumericAddress(FAKE_DNS))) .setGatewayAddresses(Arrays.asList(InetAddresses.parseNumericAddress(FAKE_GATEWAY))) .setPcscfAddresses( Arrays.asList(InetAddresses.parseNumericAddress(FAKE_PCSCF_ADDRESS))) .setMtuV4(1440) .setMtuV6(1440) .build(); l.add(dcResponse); mDc.mCid = 1; mDcc.addActiveDcByCid(mDc); ApnContext apnContext = new ApnContext(mPhone, ApnSetting.TYPE_DEFAULT, TAG, mDcTracker, 1); List<ApnContext> apnContextList = new ArrayList<>(); apnContextList.add(apnContext); doReturn(apnContextList).when(mDc).getApnContexts(); doReturn(true).when(mDcTracker).getLteEndcUsingUserDataForIdleDetection(); mDcc.sendMessage(mDcc.obtainMessage(EVENT_DATA_STATE_CHANGED, new AsyncResult(null, l, null))); processAllMessages(); ArgumentCaptor<Message> messageCaptor = ArgumentCaptor.forClass(Message.class); verify(mTestHandler, times(2)).sendMessageDelayed(messageCaptor.capture(), anyLong()); Message message = messageCaptor.getValue(); assertEquals(EVENT_PHYSICAL_LINK_STATE_CHANGED, message.what); AsyncResult ar = (AsyncResult) message.obj; assertEquals(DcController.PHYSICAL_LINK_ACTIVE, (int) ar.result); } } No newline at end of file Loading
src/java/com/android/internal/telephony/dataconnection/DcController.java +19 −6 Original line number Diff line number Diff line Loading @@ -29,6 +29,7 @@ import android.telephony.DataFailCause; import android.telephony.data.ApnSetting; import android.telephony.data.DataCallResponse; import com.android.internal.annotations.VisibleForTesting; import com.android.internal.telephony.DctConstants; import com.android.internal.telephony.Phone; import com.android.internal.telephony.dataconnection.DataConnection.UpdateLinkPropertyResult; Loading Loading @@ -89,8 +90,8 @@ public class DcController extends Handler { /** * Aggregated physical link state from all data connections. This reflects the device's RRC * connection state. * // TODO: Instead of tracking the RRC state here, we should make PhysicalChannelConfig work in * S. * If {@link CarrierConfigManager.KEY_LTE_ENDC_USING_USER_DATA_FOR_RRC_DETECTION_BOOL} is true, * then This reflects "internet data connection" instead of RRC state. */ private @PhysicalLinkState int mPhysicalLinkState = PHYSICAL_LINK_UNKNOWN; Loading Loading @@ -229,6 +230,7 @@ public class DcController extends Handler { boolean isAnyDataCallDormant = false; boolean isAnyDataCallActive = false; boolean isInternetDataCallActive = false; for (DataCallResponse newState : dcsList) { Loading @@ -249,6 +251,11 @@ public class DcController extends Handler { log("onDataStateChanged: Found ConnId=" + newState.getId() + " newState=" + newState.toString()); } if (apnContexts.stream().anyMatch( i -> ApnSetting.TYPE_DEFAULT_STRING.equals(i.getApnType())) && newState.getLinkStatus() == DataConnActiveStatus.ACTIVE) { isInternetDataCallActive = true; } if (newState.getLinkStatus() == DataConnActiveStatus.INACTIVE) { if (mDct.isCleanupRequired.get()) { apnsToCleanup.addAll(apnContexts); Loading Loading @@ -360,7 +367,11 @@ public class DcController extends Handler { if (mDataServiceManager.getTransportType() == AccessNetworkConstants.TRANSPORT_TYPE_WWAN) { int physicalLinkState = isAnyDataCallActive boolean isPhysicalLinkStateFocusingOnInternetData = mDct.getLteEndcUsingUserDataForIdleDetection(); int physicalLinkState = (isPhysicalLinkStateFocusingOnInternetData ? isInternetDataCallActive : isAnyDataCallActive) ? PHYSICAL_LINK_ACTIVE : PHYSICAL_LINK_NOT_ACTIVE; if (mPhysicalLinkState != physicalLinkState) { mPhysicalLinkState = physicalLinkState; Loading Loading @@ -409,11 +420,13 @@ public class DcController extends Handler { /** * Register for physical link state (i.e. RRC state) changed event. * * if {@link CarrierConfigManager.KEY_LTE_ENDC_USING_USER_DATA_FOR_RRC_DETECTION_BOOL} is true, * then physical link state is focusing on "internet data connection" instead of RRC state. * @param h The handler * @param what The event */ void registerForPhysicalLinkStateChanged(Handler h, int what) { @VisibleForTesting public void registerForPhysicalLinkStateChanged(Handler h, int what) { mPhysicalLinkStateChangedRegistrants.addUnique(h, what, null); } Loading
src/java/com/android/internal/telephony/dataconnection/DcTracker.java +11 −0 Original line number Diff line number Diff line Loading @@ -352,6 +352,9 @@ public class DcTracker extends Handler { private boolean mNrSaSub6Unmetered = false; private boolean mNrNsaRoamingUnmetered = false; // it effect the PhysicalLinkStateChanged private boolean mLteEndcUsingUserDataForRrcDetection = false; // stats per data call recovery event private DataStallRecoveryStats mDataStallRecoveryStats; Loading Loading @@ -5597,13 +5600,21 @@ public class DcTracker extends Handler { CarrierConfigManager.KEY_UNMETERED_NR_SA_SUB6_BOOL); mNrNsaRoamingUnmetered = b.getBoolean( CarrierConfigManager.KEY_UNMETERED_NR_NSA_WHEN_ROAMING_BOOL); mLteEndcUsingUserDataForRrcDetection = b.getBoolean( CarrierConfigManager.KEY_LTE_ENDC_USING_USER_DATA_FOR_RRC_DETECTION_BOOL); } } updateLinkBandwidths(bandwidths, useLte); } public boolean getLteEndcUsingUserDataForIdleDetection() { return mLteEndcUsingUserDataForRrcDetection; } /** * Register for physical link state (i.e. RRC state) changed event. * if {@link CarrierConfigManager.KEY_LTE_ENDC_USING_USER_DATA_FOR_RRC_DETECTION_BOOL} is true, * then physical link state is focusing on "internet data connection" instead of RRC state. * * @param h The handler * @param what The event Loading
tests/telephonytests/src/com/android/internal/telephony/dataconnection/DcControllerTest.java +137 −0 Original line number Diff line number Diff line Loading @@ -22,7 +22,9 @@ import static com.android.internal.telephony.dataconnection.DcTrackerTest.FAKE_G import static com.android.internal.telephony.dataconnection.DcTrackerTest.FAKE_IFNAME; import static com.android.internal.telephony.dataconnection.DcTrackerTest.FAKE_PCSCF_ADDRESS; import static org.junit.Assert.assertEquals; import static org.junit.Assert.fail; import static org.mockito.ArgumentMatchers.anyLong; import static org.mockito.Mockito.any; import static org.mockito.Mockito.doReturn; import static org.mockito.Mockito.eq; Loading @@ -33,7 +35,9 @@ import android.net.InetAddresses; import android.net.LinkAddress; import android.net.LinkProperties; import android.os.AsyncResult; import android.os.Handler; import android.os.Looper; import android.os.Message; import android.telephony.AccessNetworkConstants; import android.telephony.data.ApnSetting; import android.telephony.data.DataCallResponse; Loading @@ -51,6 +55,7 @@ import org.junit.After; import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.ArgumentCaptor; import org.mockito.Mock; import java.lang.reflect.Method; Loading @@ -63,7 +68,10 @@ import java.util.List; public class DcControllerTest extends TelephonyTest { private static final int DATA_CONNECTION_ACTIVE_PH_LINK_DORMANT = 1; private static final int DATA_CONNECTION_ACTIVE_PH_LINK_ACTIVE = 2; private static final int EVENT_DATA_STATE_CHANGED = 0x00040007; private static final int EVENT_PHYSICAL_LINK_STATE_CHANGED = 1; @Mock private DataConnection mDc; Loading @@ -71,6 +79,8 @@ public class DcControllerTest extends TelephonyTest { private List<ApnContext> mApnContexts; @Mock private DataServiceManager mDataServiceManager; @Mock private Handler mTestHandler; UpdateLinkPropertyResult mResult; Loading Loading @@ -142,4 +152,131 @@ public class DcControllerTest extends TelephonyTest { verify(mDcTracker, times(1)).sendStopNetStatPoll(eq(DctConstants.Activity.DORMANT)); } @Test @SmallTest public void testPhysicalLinkStateChanged_defaultApnTypeAndDormant_registrantNotifyResult() throws Exception { ArrayList<DataCallResponse> l = new ArrayList<>(); DataCallResponse dcResponse = new DataCallResponse.Builder() .setCause(0) .setRetryDurationMillis(-1) .setId(1) .setLinkStatus(DATA_CONNECTION_ACTIVE_PH_LINK_DORMANT) .setProtocolType(ApnSetting.PROTOCOL_IP) .setInterfaceName(FAKE_IFNAME) .setAddresses(Arrays.asList( new LinkAddress(InetAddresses.parseNumericAddress(FAKE_ADDRESS), 0))) .setDnsAddresses(Arrays.asList(InetAddresses.parseNumericAddress(FAKE_DNS))) .setGatewayAddresses(Arrays.asList(InetAddresses.parseNumericAddress(FAKE_GATEWAY))) .setPcscfAddresses( Arrays.asList(InetAddresses.parseNumericAddress(FAKE_PCSCF_ADDRESS))) .setMtuV4(1440) .setMtuV6(1440) .build(); l.add(dcResponse); mDc.mCid = 1; mDcc.addActiveDcByCid(mDc); ApnContext apnContext = new ApnContext(mPhone, ApnSetting.TYPE_DEFAULT, TAG, mDcTracker, 1); List<ApnContext> apnContextList = new ArrayList<>(); apnContextList.add(apnContext); doReturn(apnContextList).when(mDc).getApnContexts(); doReturn(true).when(mDcTracker).getLteEndcUsingUserDataForIdleDetection(); mDcc.registerForPhysicalLinkStateChanged(mTestHandler, EVENT_PHYSICAL_LINK_STATE_CHANGED); mDcc.sendMessage(mDcc.obtainMessage(EVENT_DATA_STATE_CHANGED, new AsyncResult(null, l, null))); processAllMessages(); ArgumentCaptor<Message> messageCaptor = ArgumentCaptor.forClass(Message.class); verify(mTestHandler, times(1)).sendMessageDelayed(messageCaptor.capture(), anyLong()); Message message = messageCaptor.getValue(); assertEquals(EVENT_PHYSICAL_LINK_STATE_CHANGED, message.what); AsyncResult ar = (AsyncResult) message.obj; assertEquals(DcController.PHYSICAL_LINK_NOT_ACTIVE, (int) ar.result); } @Test @SmallTest public void testPhysicalLinkStateChanged_imsApnTypeAndDormant_NoNotifyResult() throws Exception { testPhysicalLinkStateChanged_defaultApnTypeAndDormant_registrantNotifyResult(); ArrayList<DataCallResponse> l = new ArrayList<>(); DataCallResponse dcResponse = new DataCallResponse.Builder() .setCause(0) .setRetryDurationMillis(-1) .setId(1) .setLinkStatus(DATA_CONNECTION_ACTIVE_PH_LINK_ACTIVE) .setProtocolType(ApnSetting.PROTOCOL_IP) .setInterfaceName(FAKE_IFNAME) .setAddresses(Arrays.asList( new LinkAddress(InetAddresses.parseNumericAddress(FAKE_ADDRESS), 0))) .setDnsAddresses(Arrays.asList(InetAddresses.parseNumericAddress(FAKE_DNS))) .setGatewayAddresses(Arrays.asList(InetAddresses.parseNumericAddress(FAKE_GATEWAY))) .setPcscfAddresses( Arrays.asList(InetAddresses.parseNumericAddress(FAKE_PCSCF_ADDRESS))) .setMtuV4(1440) .setMtuV6(1440) .build(); l.add(dcResponse); mDc.mCid = 1; mDcc.addActiveDcByCid(mDc); ApnContext apnContext = new ApnContext(mPhone, ApnSetting.TYPE_IMS, TAG, mDcTracker, 1); List<ApnContext> apnContextList = new ArrayList<>(); apnContextList.add(apnContext); doReturn(apnContextList).when(mDc).getApnContexts(); doReturn(true).when(mDcTracker).getLteEndcUsingUserDataForIdleDetection(); mDcc.sendMessage(mDcc.obtainMessage(EVENT_DATA_STATE_CHANGED, new AsyncResult(null, l, null))); processAllMessages(); ArgumentCaptor<Message> messageCaptor = ArgumentCaptor.forClass(Message.class); verify(mTestHandler, times(1)).sendMessageDelayed(messageCaptor.capture(), anyLong()); } @Test @SmallTest public void testPhysicalLinkStateChanged_defaultApnTypeAndStateChanged_registrantNotifyResult() throws Exception { testPhysicalLinkStateChanged_imsApnTypeAndDormant_NoNotifyResult(); ArrayList<DataCallResponse> l = new ArrayList<>(); DataCallResponse dcResponse = new DataCallResponse.Builder() .setCause(0) .setRetryDurationMillis(-1) .setId(1) .setLinkStatus(DATA_CONNECTION_ACTIVE_PH_LINK_ACTIVE) .setProtocolType(ApnSetting.PROTOCOL_IP) .setInterfaceName(FAKE_IFNAME) .setAddresses(Arrays.asList( new LinkAddress(InetAddresses.parseNumericAddress(FAKE_ADDRESS), 0))) .setDnsAddresses(Arrays.asList(InetAddresses.parseNumericAddress(FAKE_DNS))) .setGatewayAddresses(Arrays.asList(InetAddresses.parseNumericAddress(FAKE_GATEWAY))) .setPcscfAddresses( Arrays.asList(InetAddresses.parseNumericAddress(FAKE_PCSCF_ADDRESS))) .setMtuV4(1440) .setMtuV6(1440) .build(); l.add(dcResponse); mDc.mCid = 1; mDcc.addActiveDcByCid(mDc); ApnContext apnContext = new ApnContext(mPhone, ApnSetting.TYPE_DEFAULT, TAG, mDcTracker, 1); List<ApnContext> apnContextList = new ArrayList<>(); apnContextList.add(apnContext); doReturn(apnContextList).when(mDc).getApnContexts(); doReturn(true).when(mDcTracker).getLteEndcUsingUserDataForIdleDetection(); mDcc.sendMessage(mDcc.obtainMessage(EVENT_DATA_STATE_CHANGED, new AsyncResult(null, l, null))); processAllMessages(); ArgumentCaptor<Message> messageCaptor = ArgumentCaptor.forClass(Message.class); verify(mTestHandler, times(2)).sendMessageDelayed(messageCaptor.capture(), anyLong()); Message message = messageCaptor.getValue(); assertEquals(EVENT_PHYSICAL_LINK_STATE_CHANGED, message.what); AsyncResult ar = (AsyncResult) message.obj; assertEquals(DcController.PHYSICAL_LINK_ACTIVE, (int) ar.result); } } No newline at end of file