blob: 0fe4fc103d7b912f204139f52a1499ca8b0220ff [file] [log] [blame]
/*
* Copyright (C) 2019 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.metrics;
import static org.junit.Assert.assertEquals;
import static org.mockito.Mockito.when;
import android.telephony.CallQuality;
import android.telephony.CellSignalStrengthCdma;
import android.telephony.CellSignalStrengthGsm;
import android.telephony.CellSignalStrengthLte;
import android.telephony.CellSignalStrengthNr;
import android.telephony.CellSignalStrengthTdscdma;
import android.telephony.CellSignalStrengthWcdma;
import android.telephony.SignalStrength;
import android.test.suitebuilder.annotation.SmallTest;
import com.android.internal.telephony.TelephonyTest;
import com.android.internal.telephony.nano.TelephonyProto.TelephonyCallSession.Event.CallQualitySummary;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
public class CallQualityMetricsTest extends TelephonyTest {
private CallQualityMetrics mCallQualityMetrics;
@Before
public void setUp() throws Exception {
super.setUp(getClass().getSimpleName());
mCallQualityMetrics = new CallQualityMetrics(mPhone);
// the ImsPhone does not return a ServiceStateTracker, so CallQualityMetrics gets the
// default phone from the ImsPhone and uses that to get the ServiceStateTracker, therefore
// we need to mock the default phone as well.
when(mPhone.getDefaultPhone()).thenReturn(mPhone);
}
@After
public void tearDown() throws Exception {
super.tearDown();
}
private CallQuality constructCallQuality(int dlQuality, int ulQuality, int durationMs) {
return new CallQuality(
dlQuality,
ulQuality,
durationMs,
0, 0, 0, 0, 0, 0, 0, 0); // packets, jitter and codec (okay to ignore for testing)
}
/**
* Verify that good/bad quality and total duration stats are correct.
*/
@Test
@SmallTest
public void testTotalDurations() {
// Call quality in the following sequence:
//
// DL: GOOD GOOD BAD
// UL: GOOD BAD GOOD
// |----------|----------|--------|
// 0 5 10 14
//
// 0s = Start of call. Assumed to be good quality
// 5s = Switches to UL bad quality
// 10s = Switches to UL good quality, DL bad quality
// 14s = End of call. Switches to UL bad quality, DL good quality
CallQuality cq1 = constructCallQuality(CallQuality.CALL_QUALITY_EXCELLENT,
CallQuality.CALL_QUALITY_BAD, 5000);
CallQuality cq2 = constructCallQuality(CallQuality.CALL_QUALITY_BAD,
CallQuality.CALL_QUALITY_EXCELLENT, 10000);
CallQuality cq3 = constructCallQuality(CallQuality.CALL_QUALITY_EXCELLENT,
CallQuality.CALL_QUALITY_BAD, 14000);
mCallQualityMetrics.saveCallQuality(cq1);
mCallQualityMetrics.saveCallQuality(cq2);
mCallQualityMetrics.saveCallQuality(cq3);
// verify UL quality durations
CallQualitySummary dlSummary = mCallQualityMetrics.getCallQualitySummaryDl();
assertEquals(9, dlSummary.totalGoodQualityDurationInSeconds);
assertEquals(5, dlSummary.totalBadQualityDurationInSeconds);
assertEquals(14, dlSummary.totalDurationWithQualityInformationInSeconds);
// verify DL quality durations
CallQualitySummary ulSummary = mCallQualityMetrics.getCallQualitySummaryUl();
assertEquals(5, ulSummary.totalGoodQualityDurationInSeconds);
assertEquals(9, ulSummary.totalBadQualityDurationInSeconds);
assertEquals(14, ulSummary.totalDurationWithQualityInformationInSeconds);
}
/**
* Verify that a new CallQualityMetrics object is able to return empty summaries if no
* CallQuality is reported for the duration of a call.
*/
@Test
@SmallTest
public void testNoQualityReported() {
// getting the summary for a new CallQualityMetrics object should not fail, and all
// durations should be 0
CallQualitySummary dlSummary = mCallQualityMetrics.getCallQualitySummaryDl();
assertEquals(0, dlSummary.totalGoodQualityDurationInSeconds);
assertEquals(0, dlSummary.totalBadQualityDurationInSeconds);
assertEquals(0, dlSummary.totalDurationWithQualityInformationInSeconds);
CallQualitySummary ulSummary = mCallQualityMetrics.getCallQualitySummaryUl();
assertEquals(0, ulSummary.totalGoodQualityDurationInSeconds);
assertEquals(0, ulSummary.totalBadQualityDurationInSeconds);
assertEquals(0, ulSummary.totalDurationWithQualityInformationInSeconds);
}
/**
* Verify that if either UL or DL call quality level is not available, the CallQuality update is
* ignored.
*/
@Test
@SmallTest
public void testNotAvailableIsIgnored() {
// CallQuality updates from the IMS service with CALL_QUALITY_NOT_AVAILABLE should be
// ignored
CallQuality cq1 = constructCallQuality(CallQuality.CALL_QUALITY_NOT_AVAILABLE,
CallQuality.CALL_QUALITY_BAD, 5000);
CallQuality cq2 = constructCallQuality(CallQuality.CALL_QUALITY_BAD,
CallQuality.CALL_QUALITY_NOT_AVAILABLE, 10000);
mCallQualityMetrics.saveCallQuality(cq1);
mCallQualityMetrics.saveCallQuality(cq2);
CallQualitySummary dlSummary = mCallQualityMetrics.getCallQualitySummaryDl();
assertEquals(0, dlSummary.totalGoodQualityDurationInSeconds);
assertEquals(0, dlSummary.totalBadQualityDurationInSeconds);
assertEquals(0, dlSummary.totalDurationWithQualityInformationInSeconds);
CallQualitySummary ulSummary = mCallQualityMetrics.getCallQualitySummaryUl();
assertEquals(0, ulSummary.totalGoodQualityDurationInSeconds);
assertEquals(0, ulSummary.totalBadQualityDurationInSeconds);
assertEquals(0, ulSummary.totalDurationWithQualityInformationInSeconds);
}
/**
* Test that the best and worst SignalStrength (currently just LTE RSSNR) is correctly kept
* track of. CallQualityMetrics should log the best and worst SS for good and bad quality, but
* this just tests for good quality since the logic is the same.
*/
@Test
@SmallTest
public void testBestAndWorstSs() {
// save good quality with high rssnr
CallQuality cq1 = constructCallQuality(CallQuality.CALL_QUALITY_EXCELLENT,
CallQuality.CALL_QUALITY_EXCELLENT, 5000);
int rssnr1 = 300;
// ignore everything except rssnr
CellSignalStrengthLte lteSs1 = new CellSignalStrengthLte(0, 0, 0, rssnr1, 0, 0);
SignalStrength ss1 = new SignalStrength(
new CellSignalStrengthCdma(),
new CellSignalStrengthGsm(),
new CellSignalStrengthWcdma(),
new CellSignalStrengthTdscdma(),
lteSs1,
new CellSignalStrengthNr());
when(mSST.getSignalStrength()).thenReturn(ss1);
mCallQualityMetrics.saveCallQuality(cq1);
// save good quality with low rssnr
CallQuality cq2 = constructCallQuality(CallQuality.CALL_QUALITY_EXCELLENT,
CallQuality.CALL_QUALITY_EXCELLENT, 10000);
int rssnr2 = -200;
// ignore everything except rssnr
CellSignalStrengthLte lteSs2 = new CellSignalStrengthLte(0, 0, 0, rssnr2, 0, 0);
SignalStrength ss2 = new SignalStrength(
new CellSignalStrengthCdma(),
new CellSignalStrengthGsm(),
new CellSignalStrengthWcdma(),
new CellSignalStrengthTdscdma(),
lteSs2,
new CellSignalStrengthNr());
when(mSST.getSignalStrength()).thenReturn(ss2);
mCallQualityMetrics.saveCallQuality(cq1);
CallQualitySummary dlSummary = mCallQualityMetrics.getCallQualitySummaryDl();
assertEquals(rssnr1, dlSummary.bestSsWithGoodQuality.lteSnr);
assertEquals(rssnr2, dlSummary.worstSsWithGoodQuality.lteSnr);
}
/**
* Verifies that the snapshot of the end (the last reported call quality) is correct.
* Currently this just checks the duration since the logic is all the same and it doesn't seem
* likely that one field would be preserved and others would be lost.
*/
@Test
@SmallTest
public void testSnapshotOfEndDuration() {
CallQuality cq1 = constructCallQuality(CallQuality.CALL_QUALITY_EXCELLENT,
CallQuality.CALL_QUALITY_BAD, 5000);
CallQuality cq2 = constructCallQuality(CallQuality.CALL_QUALITY_BAD,
CallQuality.CALL_QUALITY_EXCELLENT, 10000);
CallQuality cq3 = constructCallQuality(CallQuality.CALL_QUALITY_EXCELLENT,
CallQuality.CALL_QUALITY_BAD, 14000);
mCallQualityMetrics.saveCallQuality(cq1);
mCallQualityMetrics.saveCallQuality(cq2);
mCallQualityMetrics.saveCallQuality(cq3);
// verify snapshot of end
CallQualitySummary dlSummary = mCallQualityMetrics.getCallQualitySummaryDl();
assertEquals(14, dlSummary.snapshotOfEnd.durationInSeconds);
CallQualitySummary ulSummary = mCallQualityMetrics.getCallQualitySummaryUl();
assertEquals(14, ulSummary.snapshotOfEnd.durationInSeconds);
}
}