Loading src/java/com/android/internal/telephony/imsphone/ImsPhoneCallTracker.java +61 −2 Original line number Diff line number Diff line Loading @@ -16,9 +16,11 @@ package com.android.internal.telephony.imsphone; import static com.android.internal.annotations.VisibleForTesting.Visibility.PRIVATE; import static com.android.internal.telephony.Phone.CS_FALLBACK; import android.annotation.NonNull; import android.app.usage.NetworkStatsManager; import android.compat.annotation.UnsupportedAppUsage; import android.content.BroadcastReceiver; import android.content.Context; Loading @@ -32,6 +34,8 @@ import android.net.NetworkCapabilities; import android.net.NetworkInfo; import android.net.NetworkRequest; import android.net.NetworkStats; import android.net.netstats.provider.AbstractNetworkStatsProvider; import android.net.netstats.provider.NetworkStatsProviderCallback; import android.os.AsyncResult; import android.os.Bundle; import android.os.Handler; Loading @@ -44,6 +48,7 @@ import android.os.SystemClock; import android.preference.PreferenceManager; import android.provider.Settings; import android.sysprop.TelephonyProperties; import android.telecom.Connection.VideoProvider; import android.telecom.TelecomManager; import android.telecom.VideoProfile; import android.telephony.CallQuality; Loading Loading @@ -255,6 +260,49 @@ public class ImsPhoneCallTracker extends CallTracker implements ImsPullCall { } } /** * A class implementing {@link AbstractNetworkStatsProvider} to report VT data usage to system. */ // TODO: 1. Directly reports diff in updateVtDataUsage. // 2. Remove unused getVtDataUsage. @VisibleForTesting(visibility = PRIVATE) public class VtDataUsageProvider extends AbstractNetworkStatsProvider { private int mToken = 0; private NetworkStats mIfaceSnapshot = new NetworkStats(0L, 0); private NetworkStats mUidSnapshot = new NetworkStats(0L, 0); @Override public void requestStatsUpdate(int token) { // If there is an ongoing VT call, request the latest VT usage from the modem. The // latest usage will return asynchronously so it won't be counted in this round, but it // will be eventually counted when next requestStatsUpdate is called. if (mState != PhoneConstants.State.IDLE) { for (ImsPhoneConnection conn : mConnections) { final VideoProvider videoProvider = conn.getVideoProvider(); if (videoProvider != null) { videoProvider.onRequestConnectionDataUsage(); } } } final NetworkStats ifaceDiff = mVtDataUsageSnapshot.subtract(mIfaceSnapshot); final NetworkStats uidDiff = mVtDataUsageUidSnapshot.subtract(mUidSnapshot); mVtDataUsageProviderCb.onStatsUpdated(mToken, ifaceDiff, uidDiff); mIfaceSnapshot = mIfaceSnapshot.add(ifaceDiff); mUidSnapshot = mUidSnapshot.add(uidDiff); mToken = token; } @Override public void setLimit(String iface, long quotaBytes) { // No-op } @Override public void setAlert(long quotaBytes) { // No-op } } private BroadcastReceiver mReceiver = new BroadcastReceiver() { @Override public void onReceive(Context context, Intent intent) { Loading Loading @@ -390,6 +438,7 @@ public class ImsPhoneCallTracker extends CallTracker implements ImsPullCall { private volatile NetworkStats mVtDataUsageSnapshot = null; private volatile NetworkStats mVtDataUsageUidSnapshot = null; private final NetworkStatsProviderCallback mVtDataUsageProviderCb; private final AtomicInteger mDefaultDialerUid = new AtomicInteger(NetworkStats.UID_ALL); Loading Loading @@ -823,6 +872,11 @@ public class ImsPhoneCallTracker extends CallTracker implements ImsPullCall { long currentTime = SystemClock.elapsedRealtime(); mVtDataUsageSnapshot = new NetworkStats(currentTime, 1); mVtDataUsageUidSnapshot = new NetworkStats(currentTime, 1); final NetworkStatsManager statsManager = (NetworkStatsManager) mPhone.getContext().getSystemService( Context.NETWORK_STATS_SERVICE); mVtDataUsageProviderCb = statsManager.registerNetworkStatsProvider(LOG_TAG, new VtDataUsageProvider()); // Allow the executor to be specified for testing. mImsManagerConnector = new FeatureConnector<>( Loading Loading @@ -972,6 +1026,10 @@ public class ImsPhoneCallTracker extends CallTracker implements ImsPullCall { mPhone.getContext().unregisterReceiver(mReceiver); mPhone.getDefaultPhone().getDataEnabledSettings().unregisterForDataEnabledChanged(this); mImsManagerConnector.disconnect(); if (mVtDataUsageProviderCb != null) { mVtDataUsageProviderCb.unregister(); } } @Override Loading Loading @@ -3865,7 +3923,8 @@ public class ImsPhoneCallTracker extends CallTracker implements ImsPullCall { * @param call The IMS call * @param dataUsage The aggregated data usage for the call */ private void updateVtDataUsage(ImsCall call, long dataUsage) { @VisibleForTesting(visibility = PRIVATE) public void updateVtDataUsage(ImsCall call, long dataUsage) { long oldUsage = 0L; if (mVtDataUsageMap.containsKey(call.uniqueId)) { oldUsage = mVtDataUsageMap.get(call.uniqueId); Loading Loading @@ -4299,7 +4358,7 @@ public class ImsPhoneCallTracker extends CallTracker implements ImsPullCall { // eventually counted when next getVtDataUsage is called. if (mState != PhoneConstants.State.IDLE) { for (ImsPhoneConnection conn : mConnections) { android.telecom.Connection.VideoProvider videoProvider = conn.getVideoProvider(); VideoProvider videoProvider = conn.getVideoProvider(); if (videoProvider != null) { videoProvider.onRequestConnectionDataUsage(); } Loading tests/telephonytests/Android.bp +1 −0 Original line number Diff line number Diff line Loading @@ -16,6 +16,7 @@ android_test { "frameworks-base-testutils", "guava", "mockito-target-minus-junit4", "net-tests-utils", "platform-test-annotations", "services.core", "services.net", Loading tests/telephonytests/src/com/android/internal/telephony/TelephonyTest.java +4 −0 Original line number Diff line number Diff line Loading @@ -30,6 +30,7 @@ import static org.mockito.Mockito.eq; import android.app.ActivityManager; import android.app.IActivityManager; import android.app.usage.NetworkStatsManager; import android.content.ContentResolver; import android.content.Context; import android.content.IIntentSender; Loading Loading @@ -270,6 +271,8 @@ public abstract class TelephonyTest { protected MultiSimSettingController mMultiSimSettingController; @Mock protected IccCard mIccCard; @Mock protected NetworkStatsManager mStatsManager; protected ImsCallProfile mImsCallProfile; protected TelephonyManager mTelephonyManager; Loading Loading @@ -575,6 +578,7 @@ public abstract class TelephonyTest { doAnswer((invocation)->Math.max(mTelephonyManager.getActiveModemCount(), mTelephonyManager.getPhoneCount())) .when(mTelephonyManager).getSupportedModemCount(); doReturn(mStatsManager).when(mContext).getSystemService(eq(Context.NETWORK_STATS_SERVICE)); //Data //Initial state is: userData enabled, provisioned. Loading tests/telephonytests/src/com/android/internal/telephony/imsphone/ImsPhoneCallTrackerTest.java +85 −1 Original line number Diff line number Diff line Loading @@ -15,11 +15,21 @@ */ package com.android.internal.telephony.imsphone; import static android.net.NetworkStats.DEFAULT_NETWORK_YES; import static android.net.NetworkStats.METERED_YES; import static android.net.NetworkStats.ROAMING_NO; import static android.net.NetworkStats.SET_FOREGROUND; import static android.net.NetworkStats.TAG_NONE; import static android.net.NetworkStats.UID_ALL; import static com.android.testutils.NetworkStatsUtilsKt.assertNetworkStatsEquals; import static junit.framework.TestCase.fail; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertTrue; import static org.mockito.ArgumentMatchers.anyString; import static org.mockito.ArgumentMatchers.nullable; import static org.mockito.Mockito.any; import static org.mockito.Mockito.anyBoolean; Loading @@ -32,6 +42,7 @@ import static org.mockito.Mockito.eq; import static org.mockito.Mockito.isNull; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.never; import static org.mockito.Mockito.reset; import static org.mockito.Mockito.spy; import static org.mockito.Mockito.times; import static org.mockito.Mockito.verify; Loading @@ -40,6 +51,9 @@ import static org.mockito.Mockito.when; import android.content.Context; import android.content.SharedPreferences; import android.content.pm.PackageManager; import android.net.NetworkStats; import android.net.NetworkStats.Entry; import android.net.netstats.provider.NetworkStatsProviderCallback; import android.os.Bundle; import android.os.Message; import android.os.PersistableBundle; Loading Loading @@ -72,6 +86,7 @@ import com.android.internal.telephony.CommandsInterface; import com.android.internal.telephony.Connection; import com.android.internal.telephony.PhoneConstants; import com.android.internal.telephony.TelephonyTest; import com.android.internal.telephony.imsphone.ImsPhoneCallTracker.VtDataUsageProvider; import org.junit.After; import org.junit.Assert; Loading @@ -94,6 +109,8 @@ public class ImsPhoneCallTrackerTest extends TelephonyTest { private ImsCall mImsCall; private ImsCall mSecondImsCall; private Bundle mBundle = new Bundle(); private final ArgumentCaptor<VtDataUsageProvider> mVtDataUsageProviderCaptor = ArgumentCaptor.forClass(VtDataUsageProvider.class); @Mock private ImsCallSession mImsCallSession; @Mock Loading @@ -104,6 +121,8 @@ public class ImsPhoneCallTrackerTest extends TelephonyTest { private ImsConfig mImsConfig; @Mock private ImsPhoneConnection mImsPhoneConnection; @Mock private NetworkStatsProviderCallback mVtDataUsageProviderCb; private void imsCallMocking(final ImsCall imsCall) throws Exception { Loading Loading @@ -209,6 +228,9 @@ public class ImsPhoneCallTrackerTest extends TelephonyTest { doNothing().when(mImsManager).addNotifyStatusChangedCallbackIfAvailable(any()); doReturn(mVtDataUsageProviderCb).when(mStatsManager).registerNetworkStatsProvider( anyString(), any()); mCTUT = new ImsPhoneCallTracker(mImsPhone, Runnable::run); mCTUT.addReasonCodeRemapping(null, "Wifi signal lost.", ImsReasonInfo.CODE_WIFI_LOST); mCTUT.addReasonCodeRemapping(501, "Call answered elsewhere.", Loading @@ -224,6 +246,8 @@ public class ImsPhoneCallTrackerTest extends TelephonyTest { "service not allowed in this location", ImsReasonInfo.CODE_WFC_SERVICE_NOT_AVAILABLE_IN_THIS_LOCATION); mCTUT.setDataEnabled(true); verify(mStatsManager).registerNetworkStatsProvider(anyString(), mVtDataUsageProviderCaptor.capture()); logd("ImsPhoneCallTracker initiated"); processAllMessages(); Loading Loading @@ -1005,6 +1029,66 @@ public class ImsPhoneCallTrackerTest extends TelephonyTest { mCTUT.getImsCallListener().onCallHoldFailed(mImsPhoneConnection.getImsCall(), info); } @Test @SmallTest public void testVtDataUsageProvider() { final VtDataUsageProvider provider = mVtDataUsageProviderCaptor.getValue(); provider.requestStatsUpdate(11); // Verify that requestStatsUpdate triggers onStatsUpdated, where the initial token should // be reported with current stats. assertVtDataUsageUpdated(0, 0, 0); // Establish a MT call. testImsMTCallAccept(); final ImsPhoneConnection connection = mCTUT.mForegroundCall.getFirstConnection(); final ImsCall call = connection.getImsCall(); mCTUT.updateVtDataUsage(call, 51); // Make another request, and verify stats updated accordingly, with previously issued token. reset(mVtDataUsageProviderCb); provider.requestStatsUpdate(13); assertVtDataUsageUpdated(11, 25, 25); // Update accumulated data usage twice. updateVtDataUsage takes accumulated stats from // boot up. reset(mVtDataUsageProviderCb); mCTUT.updateVtDataUsage(call, 70); mCTUT.updateVtDataUsage(call, 91); verify(mVtDataUsageProviderCb, never()).onStatsUpdated(anyInt(), any(), any()); // Verify that diff stats from last update is reported accordingly. provider.requestStatsUpdate(13); // Rounding error occurs so (70-51)/2 + (91-70)/2 = 19 is expected for both direction. assertVtDataUsageUpdated(13, 19, 19); } private void assertVtDataUsageUpdated(int expectedToken, long rxBytes, long txBytes) { final ArgumentCaptor<NetworkStats> ifaceStatsCaptor = ArgumentCaptor.forClass( NetworkStats.class); final ArgumentCaptor<NetworkStats> uidStatsCaptor = ArgumentCaptor.forClass( NetworkStats.class); verify(mVtDataUsageProviderCb).onStatsUpdated(eq(expectedToken), ifaceStatsCaptor.capture(), uidStatsCaptor.capture()); // Default dialer's package uid is not set during test, thus the uid stats looks the same // as iface stats and the records are always merged into the same entry. // TODO: Mock different dialer's uid and verify uid stats has corresponding uid in the // records. NetworkStats expectedStats = new NetworkStats(0L, 0); if (rxBytes != 0 || txBytes != 0) { expectedStats = expectedStats.addValues( new Entry(NetworkStats.IFACE_VT, UID_ALL, SET_FOREGROUND, TAG_NONE, METERED_YES, ROAMING_NO, DEFAULT_NETWORK_YES, rxBytes, 0L, txBytes, 0L, 0L)); } assertNetworkStatsEquals(expectedStats, ifaceStatsCaptor.getValue()); assertNetworkStatsEquals(expectedStats, uidStatsCaptor.getValue()); } private ImsPhoneConnection placeCallAndMakeActive() { try { doAnswer(new Answer<ImsCall>() { Loading Loading
src/java/com/android/internal/telephony/imsphone/ImsPhoneCallTracker.java +61 −2 Original line number Diff line number Diff line Loading @@ -16,9 +16,11 @@ package com.android.internal.telephony.imsphone; import static com.android.internal.annotations.VisibleForTesting.Visibility.PRIVATE; import static com.android.internal.telephony.Phone.CS_FALLBACK; import android.annotation.NonNull; import android.app.usage.NetworkStatsManager; import android.compat.annotation.UnsupportedAppUsage; import android.content.BroadcastReceiver; import android.content.Context; Loading @@ -32,6 +34,8 @@ import android.net.NetworkCapabilities; import android.net.NetworkInfo; import android.net.NetworkRequest; import android.net.NetworkStats; import android.net.netstats.provider.AbstractNetworkStatsProvider; import android.net.netstats.provider.NetworkStatsProviderCallback; import android.os.AsyncResult; import android.os.Bundle; import android.os.Handler; Loading @@ -44,6 +48,7 @@ import android.os.SystemClock; import android.preference.PreferenceManager; import android.provider.Settings; import android.sysprop.TelephonyProperties; import android.telecom.Connection.VideoProvider; import android.telecom.TelecomManager; import android.telecom.VideoProfile; import android.telephony.CallQuality; Loading Loading @@ -255,6 +260,49 @@ public class ImsPhoneCallTracker extends CallTracker implements ImsPullCall { } } /** * A class implementing {@link AbstractNetworkStatsProvider} to report VT data usage to system. */ // TODO: 1. Directly reports diff in updateVtDataUsage. // 2. Remove unused getVtDataUsage. @VisibleForTesting(visibility = PRIVATE) public class VtDataUsageProvider extends AbstractNetworkStatsProvider { private int mToken = 0; private NetworkStats mIfaceSnapshot = new NetworkStats(0L, 0); private NetworkStats mUidSnapshot = new NetworkStats(0L, 0); @Override public void requestStatsUpdate(int token) { // If there is an ongoing VT call, request the latest VT usage from the modem. The // latest usage will return asynchronously so it won't be counted in this round, but it // will be eventually counted when next requestStatsUpdate is called. if (mState != PhoneConstants.State.IDLE) { for (ImsPhoneConnection conn : mConnections) { final VideoProvider videoProvider = conn.getVideoProvider(); if (videoProvider != null) { videoProvider.onRequestConnectionDataUsage(); } } } final NetworkStats ifaceDiff = mVtDataUsageSnapshot.subtract(mIfaceSnapshot); final NetworkStats uidDiff = mVtDataUsageUidSnapshot.subtract(mUidSnapshot); mVtDataUsageProviderCb.onStatsUpdated(mToken, ifaceDiff, uidDiff); mIfaceSnapshot = mIfaceSnapshot.add(ifaceDiff); mUidSnapshot = mUidSnapshot.add(uidDiff); mToken = token; } @Override public void setLimit(String iface, long quotaBytes) { // No-op } @Override public void setAlert(long quotaBytes) { // No-op } } private BroadcastReceiver mReceiver = new BroadcastReceiver() { @Override public void onReceive(Context context, Intent intent) { Loading Loading @@ -390,6 +438,7 @@ public class ImsPhoneCallTracker extends CallTracker implements ImsPullCall { private volatile NetworkStats mVtDataUsageSnapshot = null; private volatile NetworkStats mVtDataUsageUidSnapshot = null; private final NetworkStatsProviderCallback mVtDataUsageProviderCb; private final AtomicInteger mDefaultDialerUid = new AtomicInteger(NetworkStats.UID_ALL); Loading Loading @@ -823,6 +872,11 @@ public class ImsPhoneCallTracker extends CallTracker implements ImsPullCall { long currentTime = SystemClock.elapsedRealtime(); mVtDataUsageSnapshot = new NetworkStats(currentTime, 1); mVtDataUsageUidSnapshot = new NetworkStats(currentTime, 1); final NetworkStatsManager statsManager = (NetworkStatsManager) mPhone.getContext().getSystemService( Context.NETWORK_STATS_SERVICE); mVtDataUsageProviderCb = statsManager.registerNetworkStatsProvider(LOG_TAG, new VtDataUsageProvider()); // Allow the executor to be specified for testing. mImsManagerConnector = new FeatureConnector<>( Loading Loading @@ -972,6 +1026,10 @@ public class ImsPhoneCallTracker extends CallTracker implements ImsPullCall { mPhone.getContext().unregisterReceiver(mReceiver); mPhone.getDefaultPhone().getDataEnabledSettings().unregisterForDataEnabledChanged(this); mImsManagerConnector.disconnect(); if (mVtDataUsageProviderCb != null) { mVtDataUsageProviderCb.unregister(); } } @Override Loading Loading @@ -3865,7 +3923,8 @@ public class ImsPhoneCallTracker extends CallTracker implements ImsPullCall { * @param call The IMS call * @param dataUsage The aggregated data usage for the call */ private void updateVtDataUsage(ImsCall call, long dataUsage) { @VisibleForTesting(visibility = PRIVATE) public void updateVtDataUsage(ImsCall call, long dataUsage) { long oldUsage = 0L; if (mVtDataUsageMap.containsKey(call.uniqueId)) { oldUsage = mVtDataUsageMap.get(call.uniqueId); Loading Loading @@ -4299,7 +4358,7 @@ public class ImsPhoneCallTracker extends CallTracker implements ImsPullCall { // eventually counted when next getVtDataUsage is called. if (mState != PhoneConstants.State.IDLE) { for (ImsPhoneConnection conn : mConnections) { android.telecom.Connection.VideoProvider videoProvider = conn.getVideoProvider(); VideoProvider videoProvider = conn.getVideoProvider(); if (videoProvider != null) { videoProvider.onRequestConnectionDataUsage(); } Loading
tests/telephonytests/Android.bp +1 −0 Original line number Diff line number Diff line Loading @@ -16,6 +16,7 @@ android_test { "frameworks-base-testutils", "guava", "mockito-target-minus-junit4", "net-tests-utils", "platform-test-annotations", "services.core", "services.net", Loading
tests/telephonytests/src/com/android/internal/telephony/TelephonyTest.java +4 −0 Original line number Diff line number Diff line Loading @@ -30,6 +30,7 @@ import static org.mockito.Mockito.eq; import android.app.ActivityManager; import android.app.IActivityManager; import android.app.usage.NetworkStatsManager; import android.content.ContentResolver; import android.content.Context; import android.content.IIntentSender; Loading Loading @@ -270,6 +271,8 @@ public abstract class TelephonyTest { protected MultiSimSettingController mMultiSimSettingController; @Mock protected IccCard mIccCard; @Mock protected NetworkStatsManager mStatsManager; protected ImsCallProfile mImsCallProfile; protected TelephonyManager mTelephonyManager; Loading Loading @@ -575,6 +578,7 @@ public abstract class TelephonyTest { doAnswer((invocation)->Math.max(mTelephonyManager.getActiveModemCount(), mTelephonyManager.getPhoneCount())) .when(mTelephonyManager).getSupportedModemCount(); doReturn(mStatsManager).when(mContext).getSystemService(eq(Context.NETWORK_STATS_SERVICE)); //Data //Initial state is: userData enabled, provisioned. Loading
tests/telephonytests/src/com/android/internal/telephony/imsphone/ImsPhoneCallTrackerTest.java +85 −1 Original line number Diff line number Diff line Loading @@ -15,11 +15,21 @@ */ package com.android.internal.telephony.imsphone; import static android.net.NetworkStats.DEFAULT_NETWORK_YES; import static android.net.NetworkStats.METERED_YES; import static android.net.NetworkStats.ROAMING_NO; import static android.net.NetworkStats.SET_FOREGROUND; import static android.net.NetworkStats.TAG_NONE; import static android.net.NetworkStats.UID_ALL; import static com.android.testutils.NetworkStatsUtilsKt.assertNetworkStatsEquals; import static junit.framework.TestCase.fail; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertTrue; import static org.mockito.ArgumentMatchers.anyString; import static org.mockito.ArgumentMatchers.nullable; import static org.mockito.Mockito.any; import static org.mockito.Mockito.anyBoolean; Loading @@ -32,6 +42,7 @@ import static org.mockito.Mockito.eq; import static org.mockito.Mockito.isNull; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.never; import static org.mockito.Mockito.reset; import static org.mockito.Mockito.spy; import static org.mockito.Mockito.times; import static org.mockito.Mockito.verify; Loading @@ -40,6 +51,9 @@ import static org.mockito.Mockito.when; import android.content.Context; import android.content.SharedPreferences; import android.content.pm.PackageManager; import android.net.NetworkStats; import android.net.NetworkStats.Entry; import android.net.netstats.provider.NetworkStatsProviderCallback; import android.os.Bundle; import android.os.Message; import android.os.PersistableBundle; Loading Loading @@ -72,6 +86,7 @@ import com.android.internal.telephony.CommandsInterface; import com.android.internal.telephony.Connection; import com.android.internal.telephony.PhoneConstants; import com.android.internal.telephony.TelephonyTest; import com.android.internal.telephony.imsphone.ImsPhoneCallTracker.VtDataUsageProvider; import org.junit.After; import org.junit.Assert; Loading @@ -94,6 +109,8 @@ public class ImsPhoneCallTrackerTest extends TelephonyTest { private ImsCall mImsCall; private ImsCall mSecondImsCall; private Bundle mBundle = new Bundle(); private final ArgumentCaptor<VtDataUsageProvider> mVtDataUsageProviderCaptor = ArgumentCaptor.forClass(VtDataUsageProvider.class); @Mock private ImsCallSession mImsCallSession; @Mock Loading @@ -104,6 +121,8 @@ public class ImsPhoneCallTrackerTest extends TelephonyTest { private ImsConfig mImsConfig; @Mock private ImsPhoneConnection mImsPhoneConnection; @Mock private NetworkStatsProviderCallback mVtDataUsageProviderCb; private void imsCallMocking(final ImsCall imsCall) throws Exception { Loading Loading @@ -209,6 +228,9 @@ public class ImsPhoneCallTrackerTest extends TelephonyTest { doNothing().when(mImsManager).addNotifyStatusChangedCallbackIfAvailable(any()); doReturn(mVtDataUsageProviderCb).when(mStatsManager).registerNetworkStatsProvider( anyString(), any()); mCTUT = new ImsPhoneCallTracker(mImsPhone, Runnable::run); mCTUT.addReasonCodeRemapping(null, "Wifi signal lost.", ImsReasonInfo.CODE_WIFI_LOST); mCTUT.addReasonCodeRemapping(501, "Call answered elsewhere.", Loading @@ -224,6 +246,8 @@ public class ImsPhoneCallTrackerTest extends TelephonyTest { "service not allowed in this location", ImsReasonInfo.CODE_WFC_SERVICE_NOT_AVAILABLE_IN_THIS_LOCATION); mCTUT.setDataEnabled(true); verify(mStatsManager).registerNetworkStatsProvider(anyString(), mVtDataUsageProviderCaptor.capture()); logd("ImsPhoneCallTracker initiated"); processAllMessages(); Loading Loading @@ -1005,6 +1029,66 @@ public class ImsPhoneCallTrackerTest extends TelephonyTest { mCTUT.getImsCallListener().onCallHoldFailed(mImsPhoneConnection.getImsCall(), info); } @Test @SmallTest public void testVtDataUsageProvider() { final VtDataUsageProvider provider = mVtDataUsageProviderCaptor.getValue(); provider.requestStatsUpdate(11); // Verify that requestStatsUpdate triggers onStatsUpdated, where the initial token should // be reported with current stats. assertVtDataUsageUpdated(0, 0, 0); // Establish a MT call. testImsMTCallAccept(); final ImsPhoneConnection connection = mCTUT.mForegroundCall.getFirstConnection(); final ImsCall call = connection.getImsCall(); mCTUT.updateVtDataUsage(call, 51); // Make another request, and verify stats updated accordingly, with previously issued token. reset(mVtDataUsageProviderCb); provider.requestStatsUpdate(13); assertVtDataUsageUpdated(11, 25, 25); // Update accumulated data usage twice. updateVtDataUsage takes accumulated stats from // boot up. reset(mVtDataUsageProviderCb); mCTUT.updateVtDataUsage(call, 70); mCTUT.updateVtDataUsage(call, 91); verify(mVtDataUsageProviderCb, never()).onStatsUpdated(anyInt(), any(), any()); // Verify that diff stats from last update is reported accordingly. provider.requestStatsUpdate(13); // Rounding error occurs so (70-51)/2 + (91-70)/2 = 19 is expected for both direction. assertVtDataUsageUpdated(13, 19, 19); } private void assertVtDataUsageUpdated(int expectedToken, long rxBytes, long txBytes) { final ArgumentCaptor<NetworkStats> ifaceStatsCaptor = ArgumentCaptor.forClass( NetworkStats.class); final ArgumentCaptor<NetworkStats> uidStatsCaptor = ArgumentCaptor.forClass( NetworkStats.class); verify(mVtDataUsageProviderCb).onStatsUpdated(eq(expectedToken), ifaceStatsCaptor.capture(), uidStatsCaptor.capture()); // Default dialer's package uid is not set during test, thus the uid stats looks the same // as iface stats and the records are always merged into the same entry. // TODO: Mock different dialer's uid and verify uid stats has corresponding uid in the // records. NetworkStats expectedStats = new NetworkStats(0L, 0); if (rxBytes != 0 || txBytes != 0) { expectedStats = expectedStats.addValues( new Entry(NetworkStats.IFACE_VT, UID_ALL, SET_FOREGROUND, TAG_NONE, METERED_YES, ROAMING_NO, DEFAULT_NETWORK_YES, rxBytes, 0L, txBytes, 0L, 0L)); } assertNetworkStatsEquals(expectedStats, ifaceStatsCaptor.getValue()); assertNetworkStatsEquals(expectedStats, uidStatsCaptor.getValue()); } private ImsPhoneConnection placeCallAndMakeActive() { try { doAnswer(new Answer<ImsCall>() { Loading