blob: 6cd754253fa8a185ff5e79fd9c29589e83c83daf [file] [log] [blame]
/*
* Copyright (C) 2021 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.android.internal.telephony.data;
import static android.net.NetworkCapabilities.TRANSPORT_CELLULAR;
import static com.android.internal.telephony.data.LinkBandwidthEstimator.BW_STATS_COUNT_THRESHOLD;
import static com.android.internal.telephony.data.LinkBandwidthEstimator.LINK_RX;
import static com.android.internal.telephony.data.LinkBandwidthEstimator.LINK_TX;
import static com.android.internal.telephony.data.LinkBandwidthEstimator.MSG_ACTIVE_PHONE_CHANGED;
import static com.android.internal.telephony.data.LinkBandwidthEstimator.MSG_DEFAULT_NETWORK_CHANGED;
import static com.android.internal.telephony.data.LinkBandwidthEstimator.MSG_MODEM_ACTIVITY_RETURNED;
import static com.android.internal.telephony.data.LinkBandwidthEstimator.MSG_NR_FREQUENCY_CHANGED;
import static com.android.internal.telephony.data.LinkBandwidthEstimator.MSG_SCREEN_STATE_CHANGED;
import static com.android.internal.telephony.data.LinkBandwidthEstimator.MSG_SIGNAL_STRENGTH_CHANGED;
import static com.android.internal.telephony.data.LinkBandwidthEstimator.UNKNOWN_TAC;
import static org.junit.Assert.assertEquals;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.anyInt;
import static org.mockito.ArgumentMatchers.anyLong;
import static org.mockito.Mockito.atLeast;
import static org.mockito.Mockito.doAnswer;
import static org.mockito.Mockito.eq;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.never;
import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
import android.net.NetworkCapabilities;
import android.os.AsyncResult;
import android.os.Handler;
import android.os.Message;
import android.telephony.CellIdentityLte;
import android.telephony.ModemActivityInfo;
import android.telephony.NetworkRegistrationInfo;
import android.telephony.ServiceState;
import android.telephony.TelephonyManager;
import android.testing.AndroidTestingRunner;
import android.testing.TestableLooper;
import android.util.Pair;
import com.android.internal.telephony.TelephonyFacade;
import com.android.internal.telephony.TelephonyTest;
import com.android.internal.telephony.data.LinkBandwidthEstimator.LinkBandwidthEstimatorCallback;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.ArgumentCaptor;
import org.mockito.Mockito;
@RunWith(AndroidTestingRunner.class)
@TestableLooper.RunWithLooper
public class LinkBandwidthEstimatorTest extends TelephonyTest {
private LinkBandwidthEstimator mLBE;
private static final int [] TX_TIME_1_MS = new int[]{0, 0, 0, 0, 0};
private static final int [] TX_TIME_2_MS = new int[]{100, 0, 0, 0, 100};
private static final int RX_TIME_1_MS = 100;
private static final int RX_TIME_2_MS = 200;
private static final ModemActivityInfo MAI_INIT =
new ModemActivityInfo(0, 0, 0, TX_TIME_1_MS, RX_TIME_1_MS);
private static final ModemActivityInfo MAI_TX_RX_TIME_HIGH =
new ModemActivityInfo(100L, 0, 0, TX_TIME_2_MS, RX_TIME_2_MS);
private static final ModemActivityInfo MAI_RX_TIME_HIGH =
new ModemActivityInfo(100L, 0, 0, TX_TIME_1_MS, RX_TIME_2_MS);
private static final int EVENT_BANDWIDTH_ESTIMATOR_UPDATE = 1;
private NetworkCapabilities mNetworkCapabilities;
private CellIdentityLte mCellIdentity;
private long mElapsedTimeMs = 0;
private long mTxBytes = 0;
private long mRxBytes = 0;
private NetworkRegistrationInfo mNri;
// Mocked classes
TelephonyFacade mTelephonyFacade;
private Handler mTestHandler;
@Before
public void setUp() throws Exception {
super.setUp(getClass().getSimpleName());
mTelephonyFacade = mock(TelephonyFacade.class);
mTestHandler = mock(Handler.class);
mNetworkCapabilities = new NetworkCapabilities.Builder()
.addTransportType(TRANSPORT_CELLULAR)
.build();
mCellIdentity = new CellIdentityLte(310, 260, 1234, 123456, 366);
mNri = new NetworkRegistrationInfo.Builder()
.setAccessNetworkTechnology(TelephonyManager.NETWORK_TYPE_LTE)
.build();
when(mServiceState.getNetworkRegistrationInfo(anyInt(), anyInt())).thenReturn(mNri);
when(mServiceState.getOperatorNumeric()).thenReturn("310260");
when(mTelephonyFacade.getElapsedSinceBootMillis()).thenReturn(0L);
when(mTelephonyFacade.getMobileTxBytes()).thenReturn(0L);
when(mTelephonyFacade.getMobileTxBytes()).thenReturn(0L);
when(mPhone.getCurrentCellIdentity()).thenReturn(mCellIdentity);
// Note that signal level is 0 before 1st MSG_SIGNAL_STRENGTH_CHANGED
when(mPhone.getSubId()).thenReturn(1);
when(mSignalStrength.getDbm()).thenReturn(-100);
when(mSignalStrength.getLevel()).thenReturn(1);
mLBE = new LinkBandwidthEstimator(mPhone, mTelephonyFacade);
mLBE.registerForBandwidthChanged(mTestHandler, EVENT_BANDWIDTH_ESTIMATOR_UPDATE, null);
mLBE.obtainMessage(MSG_DEFAULT_NETWORK_CHANGED, mNetworkCapabilities).sendToTarget();
mLBE.obtainMessage(MSG_SCREEN_STATE_CHANGED, false).sendToTarget();
mLBE.obtainMessage(MSG_ACTIVE_PHONE_CHANGED, 1).sendToTarget();
processAllMessages();
}
private void addElapsedTime(long timeMs) {
mElapsedTimeMs += timeMs;
when(mTelephonyFacade.getElapsedSinceBootMillis()).thenReturn(mElapsedTimeMs);
}
private void addTxBytes(long txBytes) {
mTxBytes += txBytes;
when(mTelephonyFacade.getMobileTxBytes()).thenReturn(mTxBytes);
}
private void addRxBytes(long rxBytes) {
mRxBytes += rxBytes;
when(mTelephonyFacade.getMobileRxBytes()).thenReturn(mRxBytes);
}
private void subtractRxBytes(long rxBytes) {
mRxBytes -= rxBytes;
when(mTelephonyFacade.getMobileRxBytes()).thenReturn(mRxBytes);
}
@After
public void tearDown() throws Exception {
mLBE = null;
mNri = null;
mNetworkCapabilities = null;
mCellIdentity = null;
super.tearDown();
}
@Test
public void testScreenOnTxTrafficHighOneModemPoll() throws Exception {
addElapsedTime(4_100);
moveTimeForward(4_100);
mLBE.obtainMessage(MSG_SCREEN_STATE_CHANGED, true).sendToTarget();
addTxBytes(500_000L);
addRxBytes(10_000L);
addElapsedTime(2_100);
moveTimeForward(2_100);
processAllMessages();
verify(mTelephonyManager, times(1)).requestModemActivityInfo(any(), any());
}
@Test
public void testScreenOnTxTrafficHighNotActivePhoneNoModemPoll() throws Exception {
mLBE.obtainMessage(MSG_ACTIVE_PHONE_CHANGED, 0).sendToTarget();
addElapsedTime(4_100);
moveTimeForward(4_100);
processAllMessages();
mLBE.obtainMessage(MSG_SCREEN_STATE_CHANGED, true).sendToTarget();
addTxBytes(500_000L);
addRxBytes(10_000L);
addElapsedTime(2_100);
moveTimeForward(2_100);
processAllMessages();
verify(mTelephonyManager, times(0)).requestModemActivityInfo(any(), any());
}
private void verifyUpdateBandwidth(int txKbps, int rxKbps) {
ArgumentCaptor<Message> messageArgumentCaptor = ArgumentCaptor.forClass(Message.class);
verify(mTestHandler, atLeast(1))
.sendMessageAtTime(messageArgumentCaptor.capture(), anyLong());
assertEquals(EVENT_BANDWIDTH_ESTIMATOR_UPDATE, messageArgumentCaptor.getValue().what);
assertEquals(new Pair<Integer, Integer>(txKbps, rxKbps),
((AsyncResult) messageArgumentCaptor.getValue().obj).result);
}
@Test
public void testScreenOnTxRxTrafficHighTwoModemPoll() throws Exception {
addElapsedTime(4_100);
moveTimeForward(4_100);
mLBE.obtainMessage(MSG_SCREEN_STATE_CHANGED, true).sendToTarget();
processAllMessages();
addTxBytes(10_000L);
addRxBytes(20_000L);
addElapsedTime(2_100);
moveTimeForward(2_100);
processAllMessages();
verify(mTelephonyManager, times(1)).requestModemActivityInfo(any(), any());
mLBE.obtainMessage(MSG_MODEM_ACTIVITY_RETURNED, MAI_INIT).sendToTarget();
processAllMessages();
addTxBytes(100_000L);
addRxBytes(200_000L);
addElapsedTime(5_100);
moveTimeForward(5_100);
processAllMessages();
mLBE.obtainMessage(MSG_MODEM_ACTIVITY_RETURNED, MAI_TX_RX_TIME_HIGH).sendToTarget();
processAllMessages();
verify(mTelephonyManager, times(2)).requestModemActivityInfo(any(), any());
verifyUpdateBandwidth(-1, -1);
}
@Test
public void testScreenOnRxTrafficHighTwoModemPollRxTimeHigh() throws Exception {
addElapsedTime(4_100);
moveTimeForward(4_100);
mLBE.obtainMessage(MSG_SCREEN_STATE_CHANGED, true).sendToTarget();
processAllMessages();
addTxBytes(10_000L);
addRxBytes(20_000L);
addElapsedTime(2_100);
moveTimeForward(2_100);
processAllMessages();
verify(mTelephonyManager, times(1)).requestModemActivityInfo(any(), any());
mLBE.obtainMessage(MSG_MODEM_ACTIVITY_RETURNED, MAI_INIT).sendToTarget();
processAllMessages();
addTxBytes(100_000L);
addRxBytes(200_000L);
addElapsedTime(5_100);
moveTimeForward(5_100);
processAllMessages();
mLBE.obtainMessage(MSG_MODEM_ACTIVITY_RETURNED, MAI_RX_TIME_HIGH).sendToTarget();
processAllMessages();
verify(mTelephonyManager, times(2)).requestModemActivityInfo(any(), any());
verifyUpdateBandwidth(-1, -1);
}
@Test
public void testScreenOnTxRxTrafficLow() throws Exception {
addElapsedTime(4_100);
moveTimeForward(4_100);
mLBE.obtainMessage(MSG_SCREEN_STATE_CHANGED, true).sendToTarget();
addTxBytes(10_000L);
addRxBytes(10_000L);
addElapsedTime(2_100);
moveTimeForward(2_100);
processAllMessages();
verify(mTelephonyManager, never()).requestModemActivityInfo(any(), any());
}
@Test
public void testScreenOnTrafficLowSampleHighAcc() throws Exception {
addElapsedTime(4_100);
moveTimeForward(4_100);
mLBE.obtainMessage(MSG_SCREEN_STATE_CHANGED, true).sendToTarget();
for (int i = 0; i < 30; i++) {
addTxBytes(10_000L);
addRxBytes(19_000L);
addElapsedTime(1_100);
moveTimeForward(1_100);
processAllMessages();
}
verify(mTelephonyManager, times(2)).requestModemActivityInfo(any(), any());
}
@Test
public void testScreenOnDefaultNetworkToggleNoExtraTrafficPoll() throws Exception {
mLBE.obtainMessage(MSG_SCREEN_STATE_CHANGED, true).sendToTarget();
addElapsedTime(500);
moveTimeForward(500);
processAllMessages();
mLBE.obtainMessage(MSG_DEFAULT_NETWORK_CHANGED, null).sendToTarget();
addElapsedTime(500);
moveTimeForward(500);
processAllMessages();
mLBE.obtainMessage(MSG_DEFAULT_NETWORK_CHANGED, mNetworkCapabilities).sendToTarget();
for (int i = 0; i < 3; i++) {
addElapsedTime(1_100);
moveTimeForward(1_100);
processAllMessages();
}
verify(mTelephonyFacade, times(4)).getMobileTxBytes();
}
@Test
public void testRatChangeTriggerBandwidthUpdate() throws Exception {
mLBE.obtainMessage(MSG_SCREEN_STATE_CHANGED, true).sendToTarget();
addTxBytes(10_000L);
addRxBytes(19_000L);
addElapsedTime(2000);
moveTimeForward(2000);
processAllMessages();
addTxBytes(10_000L);
addRxBytes(19_000L);
mNri = new NetworkRegistrationInfo.Builder()
.setAccessNetworkTechnology(TelephonyManager.NETWORK_TYPE_NR)
.build();
when(mServiceState.getNetworkRegistrationInfo(anyInt(), anyInt())).thenReturn(mNri);
addElapsedTime(6000);
moveTimeForward(6000);
processAllMessages();
verify(mTelephonyManager, times(0)).requestModemActivityInfo(any(), any());
verifyUpdateBandwidth(-1, -1);
}
@Test
public void testSignalLevelChangeTriggerBandwidthUpdate() throws Exception {
mLBE.obtainMessage(MSG_SCREEN_STATE_CHANGED, true).sendToTarget();
processAllMessages();
for (int i = 0; i < BW_STATS_COUNT_THRESHOLD + 2; i++) {
addTxBytes(10_000L);
addRxBytes(500_000L);
addElapsedTime(5_100);
moveTimeForward(5_100);
processAllMessages();
mLBE.obtainMessage(MSG_MODEM_ACTIVITY_RETURNED, new ModemActivityInfo(
i * 5_100L, 0, 0, TX_TIME_2_MS, i * RX_TIME_2_MS)).sendToTarget();
processAllMessages();
}
verifyUpdateBandwidth(-1, 19_597);
when(mSignalStrength.getLevel()).thenReturn(1);
when(mSignalStrength.getDbm()).thenReturn(-110);
mLBE.obtainMessage(MSG_SIGNAL_STRENGTH_CHANGED, mSignalStrength).sendToTarget();
addElapsedTime(6000);
moveTimeForward(6000);
processAllMessages();
verifyUpdateBandwidth(-1, 19_535);
when(mSignalStrength.getLevel()).thenReturn(2);
when(mSignalStrength.getDbm()).thenReturn(-90);
mLBE.obtainMessage(MSG_SIGNAL_STRENGTH_CHANGED, mSignalStrength).sendToTarget();
addElapsedTime(6000);
moveTimeForward(6000);
processAllMessages();
verifyUpdateBandwidth(-1, -1);
for (int i = 0; i < BW_STATS_COUNT_THRESHOLD + 2; i++) {
addTxBytes(10_000L);
addRxBytes(1000_000L);
addElapsedTime(5_100);
moveTimeForward(5_100);
processAllMessages();
mLBE.obtainMessage(MSG_MODEM_ACTIVITY_RETURNED, new ModemActivityInfo(
i * 5_100L, 0, 0, TX_TIME_2_MS, i * RX_TIME_2_MS)).sendToTarget();
processAllMessages();
}
when(mSignalStrength.getLevel()).thenReturn(1);
when(mSignalStrength.getDbm()).thenReturn(-110);
mLBE.obtainMessage(MSG_SIGNAL_STRENGTH_CHANGED, mSignalStrength).sendToTarget();
addElapsedTime(6000);
moveTimeForward(6000);
processAllMessages();
verifyUpdateBandwidth(-1, 30_821);
}
@Test
public void testAvgBwForAllPossibleRat() throws Exception {
Pair<Integer, Integer> values = mLBE.getStaticAvgBw(TelephonyManager.NETWORK_TYPE_GPRS);
assertEquals(24, (int) values.second);
values = mLBE.getStaticAvgBw(TelephonyManager.NETWORK_TYPE_EDGE);
assertEquals(18, (int) values.second);
values = mLBE.getStaticAvgBw(TelephonyManager.NETWORK_TYPE_UMTS);
assertEquals(115, (int) values.second);
values = mLBE.getStaticAvgBw(TelephonyManager.NETWORK_TYPE_CDMA);
assertEquals(14, (int) values.second);
values = mLBE.getStaticAvgBw(TelephonyManager.NETWORK_TYPE_1xRTT);
assertEquals(30, (int) values.second);
values = mLBE.getStaticAvgBw(TelephonyManager.NETWORK_TYPE_EVDO_0);
assertEquals(48, (int) values.second);
values = mLBE.getStaticAvgBw(TelephonyManager.NETWORK_TYPE_EVDO_A);
assertEquals(550, (int) values.second);
values = mLBE.getStaticAvgBw(TelephonyManager.NETWORK_TYPE_HSDPA);
assertEquals(620, (int) values.second);
values = mLBE.getStaticAvgBw(TelephonyManager.NETWORK_TYPE_HSUPA);
assertEquals(1800, (int) values.second);
values = mLBE.getStaticAvgBw(TelephonyManager.NETWORK_TYPE_HSPA);
assertEquals(1800, (int) values.second);
values = mLBE.getStaticAvgBw(TelephonyManager.NETWORK_TYPE_EVDO_B);
assertEquals(550, (int) values.second);
values = mLBE.getStaticAvgBw(TelephonyManager.NETWORK_TYPE_EHRPD);
assertEquals(750, (int) values.first);
values = mLBE.getStaticAvgBw(TelephonyManager.NETWORK_TYPE_HSPAP);
assertEquals(3400, (int) values.second);
values = mLBE.getStaticAvgBw(TelephonyManager.NETWORK_TYPE_TD_SCDMA);
assertEquals(115, (int) values.first);
values = mLBE.getStaticAvgBw(TelephonyManager.NETWORK_TYPE_LTE);
assertEquals(15000, (int) values.second);
when(mServiceState.getNrState()).thenReturn(NetworkRegistrationInfo.NR_STATE_CONNECTED);
when(mServiceState.getNrFrequencyRange()).thenReturn(ServiceState.FREQUENCY_RANGE_MMWAVE);
values = mLBE.getStaticAvgBw(TelephonyManager.NETWORK_TYPE_LTE);
assertEquals(145000, (int) values.first);
when(mServiceState.getNrFrequencyRange()).thenReturn(ServiceState.FREQUENCY_RANGE_UNKNOWN);
values = mLBE.getStaticAvgBw(TelephonyManager.NETWORK_TYPE_LTE);
assertEquals(47000, (int) values.first);
values = mLBE.getStaticAvgBw(TelephonyManager.NETWORK_TYPE_NR);
assertEquals(145_000, (int) values.first);
when(mServiceState.getNrFrequencyRange()).thenReturn(ServiceState.FREQUENCY_RANGE_MMWAVE);
values = mLBE.getStaticAvgBw(TelephonyManager.NETWORK_TYPE_NR);
assertEquals("NR_MMWAVE", mLBE.getDataRatName(TelephonyManager.NETWORK_TYPE_NR));
assertEquals(145_000, (int) values.first);
}
@Test
public void testSwitchToNrMmwaveTriggerBandwidthUpdate() throws Exception {
mLBE.obtainMessage(MSG_SCREEN_STATE_CHANGED, true).sendToTarget();
addTxBytes(10_000L);
addRxBytes(19_000L);
addElapsedTime(2000);
moveTimeForward(2000);
processAllMessages();
addTxBytes(10_000L);
addRxBytes(19_000L);
when(mServiceState.getNrState()).thenReturn(NetworkRegistrationInfo.NR_STATE_CONNECTED);
when(mServiceState.getNrFrequencyRange()).thenReturn(ServiceState.FREQUENCY_RANGE_MMWAVE);
mLBE.obtainMessage(MSG_NR_FREQUENCY_CHANGED).sendToTarget();
addElapsedTime(6000);
moveTimeForward(6000);
processAllMessages();
verifyUpdateBandwidth(-1, -1);
}
@Test
public void testEnoughModemPollTriggerBwUpdate() throws Exception {
mLBE.obtainMessage(MSG_SCREEN_STATE_CHANGED, true).sendToTarget();
processAllMessages();
for (int i = 0; i < BW_STATS_COUNT_THRESHOLD + 2; i++) {
addTxBytes(10_000L);
addRxBytes(500_000L);
addElapsedTime(5_100);
moveTimeForward(5_100);
processAllMessages();
mLBE.obtainMessage(MSG_MODEM_ACTIVITY_RETURNED, new ModemActivityInfo(
i * 5_100L, 0, 0, TX_TIME_2_MS, i * RX_TIME_2_MS)).sendToTarget();
processAllMessages();
}
verify(mTelephonyManager, times(BW_STATS_COUNT_THRESHOLD + 2))
.requestModemActivityInfo(any(), any());
verifyUpdateBandwidth(-1, 19_597);
}
@Test
public void testAbnormalTrafficCountTriggerLessBwUpdate() throws Exception {
mLBE.obtainMessage(MSG_SCREEN_STATE_CHANGED, true).sendToTarget();
processAllMessages();
for (int i = 0; i < BW_STATS_COUNT_THRESHOLD + 2; i++) {
if (i == 1) {
addTxBytes(10_000L);
subtractRxBytes(500_000L);
} else {
addTxBytes(10_000L);
addRxBytes(500_000L);
}
addElapsedTime(5_100);
moveTimeForward(5_100);
processAllMessages();
mLBE.obtainMessage(MSG_MODEM_ACTIVITY_RETURNED, new ModemActivityInfo(
i * 5_100L, 0, 0, TX_TIME_2_MS, i * RX_TIME_2_MS)).sendToTarget();
processAllMessages();
}
verify(mTelephonyManager, times(BW_STATS_COUNT_THRESHOLD))
.requestModemActivityInfo(any(), any());
verifyUpdateBandwidth(-1, -1);
}
@Test
public void testUseCurrentTacStatsWithEnoughData() throws Exception {
mLBE.obtainMessage(MSG_SCREEN_STATE_CHANGED, true).sendToTarget();
processAllMessages();
for (int i = 0; i < BW_STATS_COUNT_THRESHOLD; i++) {
addTxBytes(10_000L);
addRxBytes(500_000L);
addElapsedTime(5_100);
moveTimeForward(5_100);
processAllMessages();
mLBE.obtainMessage(MSG_MODEM_ACTIVITY_RETURNED, new ModemActivityInfo(
i * 5_100L, 0, 0, TX_TIME_2_MS, i * RX_TIME_2_MS)).sendToTarget();
processAllMessages();
}
mCellIdentity = new CellIdentityLte(310, 260, 1235, 123457, 367);
when(mPhone.getCurrentCellIdentity()).thenReturn(mCellIdentity);
for (int i = BW_STATS_COUNT_THRESHOLD; i < 3 * BW_STATS_COUNT_THRESHOLD; i++) {
addTxBytes(10_000L);
addRxBytes(500_000L);
addElapsedTime(5_100);
moveTimeForward(5_100);
processAllMessages();
mLBE.obtainMessage(MSG_MODEM_ACTIVITY_RETURNED, new ModemActivityInfo(
i * 5_100L, 0, 0, TX_TIME_2_MS, i * RX_TIME_2_MS)).sendToTarget();
processAllMessages();
}
verifyUpdateBandwidth(-1, 19_597);
}
@Test
public void testUseAllTacStatsIfNoEnoughDataWithCurrentTac() throws Exception {
mLBE.obtainMessage(MSG_SCREEN_STATE_CHANGED, true).sendToTarget();
processAllMessages();
mLBE.obtainMessage(MSG_SIGNAL_STRENGTH_CHANGED, mSignalStrength).sendToTarget();
processAllMessages();
for (int i = 0; i < BW_STATS_COUNT_THRESHOLD; i++) {
addTxBytes(10_000L);
addRxBytes(900_000L);
addElapsedTime(5_100);
moveTimeForward(5_100);
processAllMessages();
mLBE.obtainMessage(MSG_MODEM_ACTIVITY_RETURNED, new ModemActivityInfo(
i * 5_100L, 0, 0, TX_TIME_2_MS, i * RX_TIME_2_MS)).sendToTarget();
processAllMessages();
}
mCellIdentity = new CellIdentityLte(310, 260, 1234, 123456, 367);
when(mPhone.getCurrentCellIdentity()).thenReturn(mCellIdentity);
for (int i = BW_STATS_COUNT_THRESHOLD; i < BW_STATS_COUNT_THRESHOLD * 3 / 2; i++) {
addTxBytes(10_000L);
addRxBytes(1_000_000L);
addElapsedTime(5_100);
moveTimeForward(5_100);
processAllMessages();
mLBE.obtainMessage(MSG_MODEM_ACTIVITY_RETURNED, new ModemActivityInfo(
i * 5_100L, 0, 0, TX_TIME_2_MS, i * RX_TIME_2_MS)).sendToTarget();
processAllMessages();
}
LinkBandwidthEstimator.NetworkBandwidth network = mLBE.lookupNetwork("310260", 366, "LTE");
assertEquals(BW_STATS_COUNT_THRESHOLD - 1, network.getCount(LINK_RX, 1));
assertEquals(900_000L * 8 * 1000 / 200 / 1024 * (BW_STATS_COUNT_THRESHOLD - 1),
network.getValue(LINK_RX, 1));
network = mLBE.lookupNetwork("310260", 367, "LTE");
assertEquals(1, network.getCount(LINK_RX, 1));
assertEquals(1_000_000L * 8 * 1000 / 200 / 1024,
network.getValue(LINK_RX, 1));
network = mLBE.lookupNetwork("310260", UNKNOWN_TAC, "LTE");
assertEquals(BW_STATS_COUNT_THRESHOLD * 3 / 2 - 2, network.getCount(LINK_RX, 1));
assertEquals(179_686, network.getValue(LINK_RX, 1));
verifyUpdateBandwidth(-1, 37_350);
}
@Test
public void testSwitchCarrierFallbackToColdStartValue() throws Exception {
mLBE.obtainMessage(MSG_SCREEN_STATE_CHANGED, true).sendToTarget();
processAllMessages();
for (int i = 0; i < BW_STATS_COUNT_THRESHOLD + 5; i++) {
addTxBytes(10_000L);
addRxBytes(500_000L);
addElapsedTime(5_100);
moveTimeForward(5_100);
processAllMessages();
mLBE.obtainMessage(MSG_MODEM_ACTIVITY_RETURNED, new ModemActivityInfo(
i * 5_100L, 0, 0, TX_TIME_2_MS, i * RX_TIME_2_MS)).sendToTarget();
processAllMessages();
}
verifyUpdateBandwidth(-1, 19_597);
mCellIdentity = new CellIdentityLte(320, 265, 1234, 123456, 366);
when(mPhone.getCurrentCellIdentity()).thenReturn(mCellIdentity);
when(mServiceState.getOperatorNumeric()).thenReturn("320265");
addTxBytes(10_000L);
addRxBytes(10_000L);
addElapsedTime(5_100);
moveTimeForward(5_100);
processAllMessages();
verifyUpdateBandwidth(-1, -1);
}
@Test
public void testIgnoreLowTxRxTime() throws Exception {
mLBE.obtainMessage(MSG_SCREEN_STATE_CHANGED, true).sendToTarget();
processAllMessages();
for (int i = 0; i < BW_STATS_COUNT_THRESHOLD + 5; i++) {
addTxBytes(10_000L);
addRxBytes(500_000L);
addElapsedTime(5_100);
moveTimeForward(5_100);
processAllMessages();
mLBE.obtainMessage(MSG_MODEM_ACTIVITY_RETURNED, new ModemActivityInfo(
i * 5_100L, 0, 0, TX_TIME_2_MS, i * 80)).sendToTarget();
processAllMessages();
}
verifyUpdateBandwidth(-1, -1);
}
@Test
public void testEdgeThenLteShouldIgnoreTransitionStats() throws Exception {
mLBE.obtainMessage(MSG_SCREEN_STATE_CHANGED, true).sendToTarget();
processAllMessages();
mNri = new NetworkRegistrationInfo.Builder()
.setAccessNetworkTechnology(TelephonyManager.NETWORK_TYPE_EDGE)
.build();
when(mServiceState.getNetworkRegistrationInfo(anyInt(), anyInt())).thenReturn(mNri);
mLBE.obtainMessage(MSG_SIGNAL_STRENGTH_CHANGED, mSignalStrength).sendToTarget();
processAllMessages();
for (int i = 0; i < BW_STATS_COUNT_THRESHOLD * 2; i++) {
addTxBytes(12_000L);
addRxBytes(24_000L);
addElapsedTime(5_100);
moveTimeForward(5_100);
processAllMessages();
mLBE.obtainMessage(MSG_MODEM_ACTIVITY_RETURNED, new ModemActivityInfo(
i * 5_100L, 0, 0, TX_TIME_2_MS, i * RX_TIME_2_MS * 5)).sendToTarget();
processAllMessages();
}
LinkBandwidthEstimator.NetworkBandwidth network = mLBE.lookupNetwork("310260", 366, "EDGE");
assertEquals(0, network.getCount(LINK_TX, 1));
assertEquals(BW_STATS_COUNT_THRESHOLD * 2 - 1, network.getCount(LINK_RX, 1));
assertEquals(24_000L * 8 / 1024 * (BW_STATS_COUNT_THRESHOLD * 2 - 1),
network.getValue(LINK_RX, 1));
mNri = new NetworkRegistrationInfo.Builder()
.setAccessNetworkTechnology(TelephonyManager.NETWORK_TYPE_LTE)
.build();
when(mServiceState.getNetworkRegistrationInfo(anyInt(), anyInt())).thenReturn(mNri);
for (int i = BW_STATS_COUNT_THRESHOLD * 2; i < BW_STATS_COUNT_THRESHOLD * 4; i++) {
addTxBytes(1_200_000L);
addRxBytes(2_400_000L);
addElapsedTime(5_100);
moveTimeForward(5_100);
processAllMessages();
mLBE.obtainMessage(MSG_MODEM_ACTIVITY_RETURNED, new ModemActivityInfo(
i * 5_100L, 0, 0, TX_TIME_2_MS, i * RX_TIME_2_MS * 10)).sendToTarget();
processAllMessages();
}
network = mLBE.lookupNetwork("310260", 366, "LTE");
assertEquals(BW_STATS_COUNT_THRESHOLD * 2 - 2, network.getCount(LINK_RX, 1));
assertEquals(0, network.getCount(LINK_TX, 1));
}
@Test
public void testVeryHighRxLinkBandwidthEstimationIgnored() throws Exception {
mLBE.obtainMessage(MSG_SCREEN_STATE_CHANGED, true).sendToTarget();
processAllMessages();
mLBE.obtainMessage(MSG_SIGNAL_STRENGTH_CHANGED, mSignalStrength).sendToTarget();
processAllMessages();
for (int i = 0; i < BW_STATS_COUNT_THRESHOLD + 5; i++) {
addTxBytes(8_000_000_000L);
addRxBytes(16_000_000_000L);
addElapsedTime(5_100);
moveTimeForward(5_100);
processAllMessages();
mLBE.obtainMessage(MSG_MODEM_ACTIVITY_RETURNED, new ModemActivityInfo(
i * 5_100L, 0, 0, TX_TIME_2_MS, i * RX_TIME_2_MS * 5)).sendToTarget();
processAllMessages();
}
// This will result in link bandwidth estimation value 128Gbps which is too high for LTE.
// So it will be ignored by the estimator.
LinkBandwidthEstimator.NetworkBandwidth network = mLBE.lookupNetwork("310260", 366, "LTE");
assertEquals(0, network.getCount(LINK_RX, 1));
assertEquals(0, network.getValue(LINK_TX, 1));
assertEquals(0, network.getValue(LINK_RX, 1));
}
@Test
public void testDataActivity() {
LinkBandwidthEstimatorCallback callback = Mockito.mock(
LinkBandwidthEstimatorCallback.class);
doAnswer(invocation -> {
((Runnable) invocation.getArguments()[0]).run();
return null;
}).when(callback).invokeFromExecutor(any(Runnable.class));
mLBE.registerCallback(callback);
mLBE.obtainMessage(MSG_SCREEN_STATE_CHANGED, true).sendToTarget();
addTxBytes(10_000L);
addRxBytes(19_000L);
addElapsedTime(2000);
moveTimeForward(2000);
processAllMessages();
verify(callback).onDataActivityChanged(eq(TelephonyManager.DATA_ACTIVITY_INOUT));
Mockito.clearInvocations(callback);
mLBE.obtainMessage(MSG_SIGNAL_STRENGTH_CHANGED, mSignalStrength).sendToTarget();
addTxBytes(10_000L);
addElapsedTime(2000);
moveTimeForward(2000);
processAllMessages();
verify(callback).onDataActivityChanged(eq(TelephonyManager.DATA_ACTIVITY_OUT));
Mockito.clearInvocations(callback);
mLBE.obtainMessage(MSG_SIGNAL_STRENGTH_CHANGED, mSignalStrength).sendToTarget();
addRxBytes(10_000L);
addElapsedTime(2000);
moveTimeForward(2000);
processAllMessages();
verify(callback).onDataActivityChanged(eq(TelephonyManager.DATA_ACTIVITY_IN));
Mockito.clearInvocations(callback);
}
}